Use initialize, not load, wherever possible.
[adiumx.git] / Source / AIMenuBarIcons.m
blob1f364f2f5db7024e17fe9ee1c7697c912e30feb9
1 /* 
2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
3  * with this source distribution.
4  * 
5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
11  * Public License for more details.
12  * 
13  * You should have received a copy of the GNU General Public License along with this program; if not,
14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
15  */
17 #import "AIMenuBarIcons.h"
18 #import <AIXtraInfo.h>
19 #import <AIUtilities/AIImageAdditions.h>
20 #import <QuartzCore/CoreImage.h>
22 #define KEY_ICONS_DICT  @"Icons"
24 @interface AIMenuBarIcons (PRIVATE)
25 - (NSImage *)imageForKey:(NSString *)keyName;
26 - (BOOL)keyOfTypeExists:(NSString *)keyName;
27 @end
29 @implementation AIMenuBarIcons
31 - (id)initWithURL:(NSURL *)url
33         if ((self = [super initWithURL:url])) {
34                 imageStates = [[NSMutableDictionary alloc] init];
35                 alternateImageStates = [[NSMutableDictionary alloc] init];
36                 iconInfo = [xtraBundle objectForInfoDictionaryKey:KEY_ICONS_DICT];
37         }
38         return self;
41 - (BOOL)showBadge
43         return [[xtraBundle objectForInfoDictionaryKey:@"Show Badge"] boolValue];
46 - (NSImage *)imageOfType:(NSString *)imageType alternate:(BOOL)alternate
48         NSImage *image;
50         // Default to Online if key not found.
51         if (![self keyOfTypeExists:imageType]) {
52                 imageType = @"Online";
53         }
55         image = [(alternate ? alternateImageStates : imageStates) objectForKey:imageType];
56         if (!image) { // Image not already stored.
57                 if (alternate) {
58                         NSImage *normalImage = [self imageOfType:imageType alternate:NO];
59                         image = [self alternateImageForImage:normalImage];
60                         [alternateImageStates setObject:image forKey:imageType];
61                 } else {
62                         image = [self imageForKey:imageType];
63                         if (image) { // Make sure the image exists.
64                                 [imageStates setObject:image forKey:imageType];
65                         }
66                 }
67         }
68         return image;
71 - (NSImage *)imageForKey:(NSString *)keyName
73         NSString *imagePath;
74         
75         // This set doesn't contain an Icons dictionary entry. It's invalid.
76         if (!iconInfo) {
77                 return nil;
78         }
79         
80         imagePath = [xtraBundle pathForImageResource:[iconInfo objectForKey:keyName]];
81         return [[[NSImage alloc] initWithContentsOfFile:imagePath] autorelease];
84 - (BOOL)keyOfTypeExists:(NSString *)keyName
86         if (!iconInfo || ![iconInfo objectForKey:keyName]) {
87                 return NO;
88         }
89         return YES;
92 - (void)dealloc
94         [imageStates release];
95         [alternateImageStates release];
96         [super dealloc];
99 #define PREVIEW_MENU_IMAGE_SIZE         18
100 #define PREVIEW_MENU_IMAGE_MARGIN       2
102 + (NSImage *)previewMenuImageForIconPackAtPath:(NSString *)inPath
104         NSImage                 *image;
105         NSBundle                *menuIconsBundle = [[NSBundle alloc] initWithPath:inPath];
106         NSDictionary    *imageInfo;
107         
108         if (!menuIconsBundle) {
109                 return nil;
110         }
111         
112         imageInfo = [menuIconsBundle objectForInfoDictionaryKey:KEY_ICONS_DICT];
113         
114         if (!imageInfo) {
115                 [menuIconsBundle release];
116                 return nil;
117         }
119         image = [[NSImage alloc] initWithSize:NSMakeSize((PREVIEW_MENU_IMAGE_SIZE + PREVIEW_MENU_IMAGE_MARGIN) * 2,
120                                                                                                          PREVIEW_MENU_IMAGE_SIZE)];
121                                                                                                          
123         if ([[menuIconsBundle objectForInfoDictionaryKey:@"XtraBundleVersion"] intValue] == 1) {
124                 NSEnumerator    *enumerator = [[NSArray arrayWithObjects:@"Online",@"Offline",nil] objectEnumerator];
125                 NSString                *iconID;
126                 int                             xOrigin = 0;
128                 [image lockFocus];
129                 while ((iconID = [enumerator nextObject])) {
130                         NSString        *anIconPath = [menuIconsBundle pathForImageResource:[imageInfo objectForKey:iconID]];
131                         NSImage         *anIcon;
133                         if ((anIcon = [[[NSImage alloc] initWithContentsOfFile:anIconPath] autorelease])) {
134                                 NSSize  anIconSize = [anIcon size];
135                                 NSRect  targetRect = NSMakeRect(xOrigin, 0, PREVIEW_MENU_IMAGE_SIZE, PREVIEW_MENU_IMAGE_SIZE);
137                                 if (anIconSize.width < targetRect.size.width) {
138                                         float difference = (targetRect.size.width - anIconSize.width)/2;
140                                         targetRect.size.width -= difference;
141                                         targetRect.origin.x += difference;
142                                 }
144                                 if (anIconSize.height < targetRect.size.height) {
145                                         float difference = (targetRect.size.height - anIconSize.height)/2;
147                                         targetRect.size.height -= difference;
148                                         targetRect.origin.y += difference;
149                                 }
151                                 [anIcon drawInRect:targetRect
152                                                         fromRect:NSMakeRect(0,0,anIconSize.width,anIconSize.height)
153                                                    operation:NSCompositeCopy
154                                                         fraction:1.0];
156                                 //Shift right in preparation for next image
157                                 xOrigin += PREVIEW_MENU_IMAGE_SIZE + PREVIEW_MENU_IMAGE_MARGIN;
158                         }
159                 }
160                 [image unlockFocus];
161                 [menuIconsBundle release];
162         }
164         return [image autorelease];
167 // Returns an inverted image.
168 - (NSImage *)alternateImageForImage:(NSImage *)inImage
170         NSImage                         *altImage = [[NSImage alloc] initWithSize:[inImage size]];
171         NSBitmapImageRep        *srcImageRep = [inImage bitmapRep];
173         id monochromeFilter, invertFilter, alphaFilter;
174         
175         monochromeFilter = [CIFilter filterWithName:@"CIColorMonochrome"];
176         [monochromeFilter setValue:[[[CIImage alloc] initWithBitmapImageRep:srcImageRep] autorelease]
177                                                 forKey:@"inputImage"]; 
178         [monochromeFilter setValue:[NSNumber numberWithFloat:1.0]
179                                                 forKey:@"inputIntensity"];
180         [monochromeFilter setValue:[[[CIColor alloc] initWithColor:[NSColor blackColor]] autorelease]
181                                                 forKey:@"inputColor"];
182         
183         //Now invert our greyscale image
184         invertFilter = [CIFilter filterWithName:@"CIColorInvert"];
185         [invertFilter setValue:[monochromeFilter valueForKey:@"outputImage"]
186                                         forKey:@"inputImage"]; 
187         
188         //And turn the parts that were previously white (are now black) into transparent
189         alphaFilter = [CIFilter filterWithName:@"CIMaskToAlpha"];
190         [alphaFilter setValue:[invertFilter valueForKey:@"outputImage"]
191                                    forKey:@"inputImage"]; 
192         
193         [altImage lockFocus];
194         id context = [CIContext contextWithCGContext:[[NSGraphicsContext currentContext] graphicsPort] 
195                                                                            options:nil];
196         id result = [alphaFilter valueForKey:@"outputImage"];
197         [context drawImage:result
198                            atPoint:CGPointZero
199                           fromRect:[result extent]];
200         [altImage unlockFocus];
201         
202         return [altImage autorelease];
205 @end