2 // AIAbstractListObjectMenu.m
5 // Created by Adam Iser on 5/31/05.
6 // Copyright 2006 The Adium Team. All rights reserved.
9 #import <Adium/AIAbstractListObjectMenu.h>
10 #import <AIUtilities/AIImageAdditions.h>
11 #import <Adium/AIListObject.h>
12 #import <Adium/AIServiceIcons.h>
13 #import <Adium/AIStatusIcons.h>
15 @interface AIAbstractListObjectMenu (PRIVATE)
16 - (void)_destroyMenuItems;
19 @implementation AIAbstractListObjectMenu
26 if((self = [super init])){
27 //Rebuild our menu when Adium's status or service icon set changes
28 [[adium notificationCenter] addObserver:self
29 selector:@selector(rebuildMenu)
30 name:AIStatusIconSetDidChangeNotification
33 [[adium notificationCenter] addObserver:self
34 selector:@selector(rebuildMenu)
35 name:AIServiceIconSetDidChangeNotification
44 [[adium notificationCenter] removeObserver:self name:AIStatusIconSetDidChangeNotification object:nil];
45 [[adium notificationCenter] removeObserver:self name:AIServiceIconSetDidChangeNotification object:nil];
46 [self _destroyMenuItems];
52 * @brief Returns an array of menu items
54 - (NSArray *)menuItems
57 menuItems = [[self buildMenuItems] retain];
64 * @brief Returns a menu containing our menu items
66 * Remember that menu items can only be in one menu at a time, so if you use this functions you cannot do anything
67 * manually the menu items
72 NSEnumerator *enumerator = [[self menuItems] objectEnumerator];
75 menu = [[NSMenu allocWithZone:[NSMenu zone]] init];
77 [menu setMenuChangedMessagesEnabled:NO];
78 while((menuItem = [enumerator nextObject])) [menu addItem:menuItem];
79 [menu setMenuChangedMessagesEnabled:YES];
86 * @brief Returns the existing menu item
91 - (NSMenuItem *)menuItemWithRepresentedObject:(id)object
93 NSEnumerator *enumerator = [[self menuItems] objectEnumerator];
96 while ((menuItem = [enumerator nextObject])) {
97 if ([menuItem representedObject] == object) {
98 return [[menuItem retain] autorelease];
99 } else if ([menuItem submenu]) {
100 NSEnumerator *submenuEnumerator = [[[menuItem submenu] itemArray] objectEnumerator];
101 NSMenuItem *submenuItem;
103 while ((submenuItem = [submenuEnumerator nextObject])) {
104 if ([submenuItem representedObject] == object) {
105 return [[submenuItem retain] autorelease];
115 * @brief Rebuild the menu
119 [self _destroyMenuItems];
123 * @brief Destroy menu items
125 - (void)_destroyMenuItems
127 [menu release]; menu = nil;
128 [menuItems release]; menuItems = nil;
132 //For Subclasses -------------------------------------------------------------------------------------------------------
133 #pragma mark For Subclasses
135 * @brief Builds and returns an array of menu items which should be in the listObjectMenu
137 * Subclass this method to build and return the menu items you want.
139 - (NSArray *)buildMenuItems
141 return [NSArray array];
145 * @brief Returns a menu image for the account
147 - (NSImage *)imageForListObject:(AIListObject *)listObject
149 NSImage *statusIcon, *serviceIcon;
150 NSSize statusSize, serviceSize, compositeSize;
151 NSRect compositeRect;
153 //Get the service and status icons
154 statusIcon = [AIStatusIcons statusIconForListObject:listObject type:AIStatusIconList direction:AIIconNormal];
155 statusSize = [statusIcon size];
156 serviceIcon = [AIServiceIcons serviceIconForObject:listObject type:AIServiceIconSmall direction:AIIconNormal];
157 serviceSize = [serviceIcon size];
159 //Composite them side by side (since we're only allowed one image in a menu and we want to see both)
160 compositeSize = NSMakeSize(statusSize.width + serviceSize.width + 1,
161 statusSize.height > serviceSize.height ? statusSize.height : serviceSize.height);
162 compositeRect = NSMakeRect(0, 0, compositeSize.width, compositeSize.height);
165 NSImage *composite = [[NSImage alloc] initWithSize:compositeSize];
166 [composite lockFocus];
167 [statusIcon drawInRect:compositeRect atSize:[statusIcon size] position:IMAGE_POSITION_LEFT fraction:1.0];
168 [serviceIcon drawInRect:compositeRect atSize:[serviceIcon size] position:IMAGE_POSITION_RIGHT fraction:1.0];
169 [composite unlockFocus];
171 return [composite autorelease];