2 // AIContactListRecentImagesWindowController.m
5 // Created by Evan Schoenberg on 12/19/05.
8 #import "AIContactListRecentImagesWindowController.h"
9 #import <Adium/AIAccountControllerProtocol.h>
10 #import <Adium/AIContactControllerProtocol.h>
11 #import <Adium/AIPreferenceControllerProtocol.h>
12 #import "AIStandardListWindowController.h"
13 #import "AIContactListImagePicker.h"
14 #import "AIMenuItemView.h"
15 #import <Adium/AIAccount.h>
16 #import <AIUtilities/AIImageGridView.h>
17 #import <AIUtilities/AIBorderlessWindow.h>
18 #import <AIUtilities/AIMenuAdditions.h>
19 #import <AIUtilities/AIStringAdditions.h>
20 #import <AIUtilities/AIColoredBoxView.h>
22 #import "NSIPRecentPicture.h"
24 #define FADE_INCREMENT 0.3
27 @interface AIContactListRecentImagesWindowController (PRIVATE)
28 - (id)initWithWindowNibName:(NSString *)inWindowNibName
29 imagePicker:(AIContactListImagePicker *)inPicker
30 recentPictureSelector:(SEL)inRecentPictureSelector;
31 - (void)fadeOutAndClose;
34 @implementation AIContactListRecentImagesWindowController
36 * @brief Show the widow
38 * @param inPoint The bottom-right corner of our parent view
40 + (void)showWindowFromPoint:(NSPoint)inPoint
41 imagePicker:(AIContactListImagePicker *)inPicker
42 recentPictureSelector:(SEL)inRecentPictureSelector
44 AIContactListRecentImagesWindowController *controller = [[self alloc] initWithWindowNibName:@"ContactListRecentImages"
46 recentPictureSelector:inRecentPictureSelector];
48 NSWindow *window = [controller window];
50 [controller positionFromPoint:inPoint];
51 [(AIBorderlessWindow *)window setMoveable:NO];
53 [controller showWindow:nil];
54 [window makeKeyAndOrderFront:nil];
57 - (id)initWithWindowNibName:(NSString *)inWindowNibName
58 imagePicker:(AIContactListImagePicker *)inPicker
59 recentPictureSelector:(SEL)inRecentPictureSelector
61 if ((self = [super initWithWindowNibName:inWindowNibName])) {
62 picker = [inPicker retain];
63 recentPictureSelector = inRecentPictureSelector;
65 [[NSNotificationCenter defaultCenter] addObserver:self
66 selector:@selector(parentWindowWillClose:)
67 name:NSWindowWillCloseNotification
68 object:[picker window]];
76 [[NSNotificationCenter defaultCenter] removeObserver:self];
84 [imageGridView setImageSize:NSMakeSize(30, 30)];
85 [coloredBox setColor:[NSColor windowBackgroundColor]];
86 currentHoveredIndex = -1;
89 - (void)positionFromPoint:(NSPoint)inPoint
91 NSWindow *window = [self window];
92 NSRect frame = [window frame];
93 NSRect screenFrame = [[window screen] visibleFrame];
95 frame.origin.x = inPoint.x - frame.size.width;
96 if (frame.origin.x < screenFrame.origin.x) {
97 frame.origin.x = screenFrame.origin.x;
98 } else if (frame.origin.x + frame.size.width > screenFrame.origin.x + screenFrame.size.width) {
99 frame.origin.x = screenFrame.origin.x + screenFrame.size.width - frame.size.width;
102 frame.origin.y = inPoint.y - frame.size.height;
103 if (frame.origin.y < screenFrame.origin.y) {
104 frame.origin.y = screenFrame.origin.y;
107 //Ensure our window is visible above the window of the imagePicker that created us
108 if ([window level] < [[picker window] level]) {
109 [window setLevel:[[picker window] level] + 1];
112 [window setFrame:frame display:NO animate:NO];
115 - (int)numberOfImagesInImageGridView:(AIImageGridView *)imageGridView
120 - (NSImage *)imageGridView:(AIImageGridView *)imageGridView imageAtIndex:(int)index
122 NSImage *displayImage;
124 if (index < [[NSIPRecentPicture recentSmallIcons] count]) {
125 NSImage *image = [[NSIPRecentPicture recentSmallIcons] objectAtIndex:index];
126 NSSize size = [image size];
127 NSBezierPath *fullPath = [NSBezierPath bezierPathWithRect:NSMakeRect(0, 0, size.width, size.height)];
128 displayImage = [image copy];
130 [displayImage setFlipped:YES];
131 [displayImage lockFocus];
133 if (index == currentHoveredIndex) {
134 [[[NSColor blueColor] colorWithAlphaComponent:0.30] set];
137 [[NSColor blueColor] set];
141 [[NSColor whiteColor] set];
145 [displayImage unlockFocus];
147 NSSize size = NSMakeSize(32, 32);
148 NSBezierPath *fullPath = [NSBezierPath bezierPathWithRect:NSMakeRect(0, 0, size.width, size.height)];
150 displayImage = [[NSImage alloc] initWithSize:size];
151 [displayImage lockFocus];
153 [[NSColor lightGrayColor] set];
156 [displayImage unlockFocus];
159 return [displayImage autorelease];
162 - (void)imageGridView:(AIImageGridView *)inImageGridView cursorIsHoveringImageAtIndex:(int)index
164 //Update our hovered index and redisplay the image
165 currentHoveredIndex = index;
166 [imageGridView setNeedsDisplayOfImageAtIndex:index];
169 - (void)imageGridViewSelectionDidChange:(NSNotification *)notification
171 int selectedIndex = [imageGridView selectedIndex];
172 NSArray *recentPictures = [NSIPRecentPicture recentPictures];
173 if (selectedIndex < [recentPictures count]) {
174 //Notify as if the image had been selected in the picker
175 [[picker delegate] imageViewWithImagePicker:picker
176 didChangeToImageData:[NSData dataWithContentsOfFile:[[recentPictures objectAtIndex:selectedIndex] originalImagePath]]];
179 [self fadeOutAndClose];
182 - (void)selectedAccount:(id)sender
184 AIAccount *activeAccount = [sender representedObject];
186 //Change the active account
187 [[adium preferenceController] setPreference:(activeAccount ? [activeAccount internalObjectID] : nil)
188 forKey:@"Active Icon Selection Account"
189 group:GROUP_ACCOUNT_STATUS];
191 [menuItemView setMenu:[self menuForMenuItemView:menuItemView]];
194 - (void)chooseIcon:(id)sender
196 [picker showImagePicker:nil];
198 [self fadeOutAndClose];
201 - (void)clearRecentPictures:(id)sender
203 [NSIPRecentPicture removeAllButCurrent];
204 [imageGridView reloadData];
207 - (void)windowDidResignMain:(NSNotification *)aNotification
209 [self fadeOutAndClose];
212 - (void)windowDidResignKey:(NSNotification *)aNotification
214 [self fadeOutAndClose];
217 - (void)parentWindowWillClose:(NSNotification *)aNotification
219 //Close, no fade, when our parent window closes
224 - (void)fadeOut:(NSTimer *)inTimer
226 float currentAlpha = [[self window] alphaValue];
227 currentAlpha -= 0.15;
229 if (currentAlpha <= 0) {
231 [inTimer invalidate];
234 [[self window] setAlphaValue:currentAlpha];
238 - (void)fadeOutAndClose
240 [NSTimer scheduledTimerWithTimeInterval:.01
242 selector:@selector(fadeOut:)
247 #pragma mark AIMenuItemView delegate
249 - (NSMenu *)menuForMenuItemView:(AIMenuItemView *)inMenuItemView
251 NSMenu *menu = [[NSMenu alloc] init];
252 NSMutableSet *onlineAccounts = [NSMutableSet set];
253 NSMutableSet *ownIconAccounts = [NSMutableSet set];
254 AIAccount *activeAccount = nil;
255 NSMenuItem *menuItem;
257 activeAccount = [AIStandardListWindowController activeAccountForIconsGettingOnlineAccounts:onlineAccounts
258 ownIconAccounts:ownIconAccounts];
260 int ownIconAccountsCount = [ownIconAccounts count];
261 int onlineAccountsCount = [onlineAccounts count];
262 if (ownIconAccountsCount && ((ownIconAccountsCount > 1) || (onlineAccountsCount > 1))) {
263 //There are at least some accounts using the global preference if the counts differ
264 BOOL includeGlobal = (onlineAccountsCount != ownIconAccountsCount);
266 NSEnumerator *enumerator;
268 menuItem = [[NSMenuItem alloc] initWithTitle:AILocalizedString(@"Change Icon For:", nil)
272 [menuItem setEnabled:NO];
273 [menu addItem:menuItem];
276 enumerator = [ownIconAccounts objectEnumerator];
277 while ((account = [enumerator nextObject])) {
278 //Put a check before the account if it is the active account
279 menuItem = [[NSMenuItem alloc] initWithTitle:[account formattedUID]
281 action:@selector(selectedAccount:)
283 [menuItem setRepresentedObject:account];
285 if (activeAccount == account) {
286 [menuItem setState:NSOnState];
288 [menuItem setIndentationLevel:1];
289 [menu addItem:menuItem];
295 menuItem = [[NSMenuItem alloc] initWithTitle:ALL_OTHER_ACCOUNTS
297 action:@selector(selectedAccount:)
299 if (!activeAccount) {
300 [menuItem setState:NSOnState];
302 [menuItem setIndentationLevel:1];
304 [menu addItem:menuItem];
308 [menu addItem:[NSMenuItem separatorItem]];
311 //All accounts are using the global preference
314 menuItem = [[NSMenuItem alloc] initWithTitle:[AILocalizedString(@"Choose Icon", nil) stringByAppendingEllipsis]
316 action:@selector(chooseIcon:)
318 [menu addItem:menuItem];
321 menuItem = [[NSMenuItem alloc] initWithTitle:AILocalizedString(@"Clear Recent Pictures", nil)
323 action:@selector(clearRecentPictures:)
325 [menu addItem:menuItem];
328 return [menu autorelease];
331 - (void)menuItemViewDidChangeMenu:(AIMenuItemView *)inMenuItemView
333 NSRect oldFrame = [inMenuItemView frame];
334 [inMenuItemView sizeToFit];
335 NSRect newFrame = [inMenuItemView frame];
337 float heightDifference = newFrame.size.height - oldFrame.size.height;
339 if (heightDifference != 0) {
340 NSRect myFrame = [[self window] frame];
342 myFrame.size.height += heightDifference;
343 myFrame.origin.y -= heightDifference;
345 [[self window] setFrame:myFrame display:YES animate:NO];