| 31 #import <string.h> |
31 #import <string.h> |
| 32 #import <stdarg.h> |
32 #import <stdarg.h> |
| 33 |
33 |
| 34 #import "menu.h" |
34 #import "menu.h" |
| 35 #import "window.h" |
35 #import "window.h" |
| 36 #import "stock.h" |
|
| 37 |
36 |
| 38 @implementation UiMenuDelegate |
37 static ui_menu_add_f createMenuItem[] = { |
| |
38 /* UI_MENU */ add_menu_widget, |
| |
39 /* UI_MENU_ITEM */ add_menuitem_widget, |
| |
40 /* UI_MENU_CHECK_ITEM */ add_checkitem_widget, |
| |
41 /* UI_MENU_RADIO_ITEM */ add_radioitem_widget, |
| |
42 /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget, |
| |
43 /* UI_MENU_CHECKITEM_LIST */ add_menuitem_list_widget, |
| |
44 /* UI_MENU_RADIOITEM_LIST */ add_menuitem_list_widget, |
| |
45 /* UI_MENU_SEPARATOR */ add_menuseparator_widget |
| |
46 }; |
| 39 |
47 |
| 40 - (UiMenuDelegate*) init { |
48 static void add_menu_items(NSMenu *parent, int i, UiMenu *menu) { |
| 41 items = NULL; |
49 UiMenuItemI *it = menu->items_begin; |
| 42 itemlists = NULL; |
50 int index = 0; |
| 43 return self; |
51 while(it) { |
| |
52 createMenuItem[it->type](parent, index, it); |
| |
53 it = it->next; |
| |
54 index++; |
| |
55 } |
| 44 } |
56 } |
| 45 |
57 |
| 46 - (void) menuNeedsUpdate:(NSMenu *) menu { |
58 void add_menu_widget(NSMenu *parent, int i, UiMenuItemI *item) { |
| 47 NSWindow *activeWindow = [NSApp keyWindow]; |
59 UiMenu *it = (UiMenu*)item; |
| 48 [(UiCocoaWindow*)activeWindow updateMenu: menu]; |
60 NSString *str = [[NSString alloc] initWithUTF8String:it->label]; |
| |
61 NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; |
| |
62 NSMenuItem *menuItem = [parent addItemWithTitle:str action:nil keyEquivalent:@""]; |
| |
63 [parent setSubmenu:menu forItem:menuItem]; |
| |
64 |
| |
65 add_menu_items(menu, i, it); |
| 49 } |
66 } |
| 50 |
67 |
| 51 - (void) addItem:(NSMenuItem*) item var: (char*)name { |
68 void add_menuitem_widget(NSMenu *parent, int i, UiMenuItemI *item) { |
| 52 UiStateItem *i = malloc(sizeof(UiStateItem)); |
69 UiMenuItem *it = (UiMenuItem*)item; |
| 53 i->item = item; |
70 NSString *str = [[NSString alloc] initWithUTF8String:it->label]; |
| 54 i->var = name; |
71 NSMenuItem *menuItem = [parent addItemWithTitle:str action:nil keyEquivalent:@""]; |
| 55 items = ucx_list_append(items, i); |
|
| 56 } |
72 } |
| 57 |
73 |
| 58 - (void) addList:(UiList*) list menu:(NSMenu*)menu index: (int)i callback: (ui_callback)f data:(void*) data { |
74 void add_menuseparator_widget(NSMenu *parent, int i, UiMenuItemI *item) { |
| 59 UiMenuItemList *itemList = malloc(sizeof(UiMenuItemList)); |
|
| 60 itemList->list = list; |
|
| 61 itemList->menu = menu; |
|
| 62 itemList->first = NULL; |
|
| 63 itemList->index = i; |
|
| 64 itemList->oldcount = 0; |
|
| 65 itemList->callback = f; |
|
| 66 itemList->data = data; |
|
| 67 itemlists = ucx_list_append(itemlists, itemList); |
|
| 68 } |
|
| 69 |
|
| 70 - (UcxList*) items { |
|
| 71 return items; |
|
| 72 } |
|
| 73 |
|
| 74 - (UcxList*) lists { |
|
| 75 return itemlists; |
|
| 76 |
75 |
| 77 } |
76 } |
| 78 |
77 |
| 79 @end |
78 void add_checkitem_widget(NSMenu *parent, int i, UiMenuItemI *item) { |
| 80 |
79 |
| 81 |
|
| 82 @implementation UiGroupMenuItem |
|
| 83 |
|
| 84 - (id)initWithTitle:(NSString*)title action:(SEL)action keyEquivalent:(NSString*)s { |
|
| 85 [super initWithTitle:title action:action keyEquivalent:s]; |
|
| 86 groups = [[NSMutableArray alloc]initWithCapacity: 8]; |
|
| 87 return self; |
|
| 88 } |
80 } |
| 89 |
81 |
| 90 - (void) addGroup:(int)group { |
82 void add_radioitem_widget(NSMenu *parent, int index, UiMenuItemI *item) { |
| 91 NSNumber *groupNumber = [NSNumber numberWithInteger:group]; |
83 |
| 92 [groups addObject:groupNumber]; |
|
| 93 } |
84 } |
| 94 |
85 |
| 95 - (void) checkGroups:(int*)g count:(int)n { |
86 void add_checkitemnv_widget(NSMenu *parent, int i, UiMenuItemI *item) { |
| 96 int c = [groups count]; |
|
| 97 |
87 |
| 98 char *check = calloc(1, c); |
|
| 99 for(int i=0;i<n;i++) { |
|
| 100 for(int k=0;k<c;k++) { |
|
| 101 NSNumber *groupNumber = [groups objectAtIndex:k]; |
|
| 102 if([groupNumber intValue] == g[i]) { |
|
| 103 check[k] = 1; |
|
| 104 break; |
|
| 105 } |
|
| 106 } |
|
| 107 } |
|
| 108 |
|
| 109 for(int j=0;j<c;j++) { |
|
| 110 if(check[j] == 0) { |
|
| 111 [self setEnabled:NO]; |
|
| 112 return; |
|
| 113 } |
|
| 114 } |
|
| 115 [self setEnabled:YES]; |
|
| 116 } |
88 } |
| 117 |
89 |
| 118 @end |
90 void add_menuitem_list_widget(NSMenu *parent, int i, UiMenuItemI *item) { |
| 119 |
91 |
| 120 |
|
| 121 //static NSMenu *currentMenu = NULL; |
|
| 122 |
|
| 123 static UcxList *current; |
|
| 124 |
|
| 125 static int currentItemIndex = 0; |
|
| 126 static UiMenuDelegate *delegate; |
|
| 127 |
|
| 128 void ui_menu_init() { |
|
| 129 delegate = [[UiMenuDelegate alloc]init]; |
|
| 130 } |
|
| 131 |
|
| 132 UiMenuDelegate* ui_menu_delegate() { |
|
| 133 return delegate; |
|
| 134 } |
92 } |
| 135 |
93 |
| 136 |
94 |
| 137 void ui_menu(char *title) { |
95 void ui_menu_init(void) { |
| 138 NSString *str = [[NSString alloc] initWithUTF8String:title]; |
96 UiMenu *menus_begin = uic_get_menu_list(); |
| 139 |
97 UiMenu *ls = menus_begin; |
| 140 NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; |
98 while(ls) { |
| 141 NSMenuItem *menuItem = [[NSApp mainMenu] addItemWithTitle:str |
99 if(ls->item.type == UI_MENU) { |
| 142 action:nil keyEquivalent:@""]; |
100 NSString *str = [[NSString alloc] initWithUTF8String:ls->label]; |
| 143 [menu setDelegate: delegate]; |
101 NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; |
| 144 [menu setAutoenablesItems:NO]; |
102 NSMenuItem *menuItem = [[NSApp mainMenu] addItemWithTitle:str action:nil keyEquivalent:@""]; |
| 145 |
103 [[NSApp mainMenu] setSubmenu:menu forItem:menuItem]; |
| 146 [[NSApp mainMenu] setSubmenu:menu forItem:menuItem]; |
104 |
| 147 //currentMenu = menu; |
105 add_menu_items(menu, 0, ls); |
| 148 currentItemIndex = 0; |
106 } |
| 149 |
107 ls = (UiMenu*)ls->item.next; |
| 150 current = ucx_list_prepend(NULL, menu); |
108 } |
| 151 } |
109 } |
| 152 |
|
| 153 void ui_submenu(char *title) { |
|
| 154 NSString *str = [[NSString alloc] initWithUTF8String:title]; |
|
| 155 NSMenu *currentMenu = current->data; |
|
| 156 |
|
| 157 NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; |
|
| 158 NSMenuItem *menuItem = [currentMenu addItemWithTitle:str |
|
| 159 action:nil keyEquivalent:@""]; |
|
| 160 [menu setDelegate: delegate]; |
|
| 161 [menu setAutoenablesItems:NO]; |
|
| 162 |
|
| 163 [currentMenu setSubmenu:menu forItem:menuItem]; |
|
| 164 //currentMenu = menu; |
|
| 165 currentItemIndex = 0; |
|
| 166 |
|
| 167 current = ucx_list_prepend(current, menu); |
|
| 168 } |
|
| 169 |
|
| 170 void ui_submenu_end() { |
|
| 171 if(ucx_list_size(current) < 2) { |
|
| 172 return; |
|
| 173 } |
|
| 174 current = ucx_list_remove(current, current); |
|
| 175 } |
|
| 176 |
|
| 177 void ui_menuitem(char *label, ui_callback f, void *data) { |
|
| 178 ui_menuitem_gr(label, f, data, -1); |
|
| 179 } |
|
| 180 |
|
| 181 void ui_menuitem_st(char *stockid, ui_callback f, void *data) { |
|
| 182 ui_menuitem_stgr(stockid, f, data, -1); |
|
| 183 } |
|
| 184 |
|
| 185 void ui_menuitem_gr(char *label, ui_callback f, void *userdata, ...) { |
|
| 186 // create menu item |
|
| 187 EventWrapper *event = [[EventWrapper alloc]initWithData:userdata callback:f]; |
|
| 188 NSString *title = [[NSString alloc] initWithUTF8String:label]; |
|
| 189 UiGroupMenuItem *item = [[UiGroupMenuItem alloc]initWithTitle:title action:@selector(handleEvent:) keyEquivalent:@""]; |
|
| 190 [item setTarget:event]; |
|
| 191 |
|
| 192 // add groups |
|
| 193 va_list ap; |
|
| 194 va_start(ap, userdata); |
|
| 195 int group; |
|
| 196 while((group = va_arg(ap, int)) != -1) { |
|
| 197 [item addGroup: group]; |
|
| 198 } |
|
| 199 va_end(ap); |
|
| 200 |
|
| 201 NSMenu *currentMenu = current->data; |
|
| 202 [currentMenu addItem:item]; |
|
| 203 |
|
| 204 currentItemIndex++; |
|
| 205 } |
|
| 206 |
|
| 207 void ui_menuitem_stgr(char *stockid, ui_callback f, void *userdata, ...) { |
|
| 208 // create menu item |
|
| 209 EventWrapper *event = [[EventWrapper alloc]initWithData:userdata callback:f]; |
|
| 210 UiStockItem *si = ui_get_stock_item(stockid); |
|
| 211 UiGroupMenuItem *item = [[UiGroupMenuItem alloc]initWithTitle:si->label |
|
| 212 action:@selector(handleEvent:) |
|
| 213 keyEquivalent:si->keyEquivalent]; |
|
| 214 [item setTarget:event]; |
|
| 215 |
|
| 216 // add groups |
|
| 217 va_list ap; |
|
| 218 va_start(ap, userdata); |
|
| 219 int group; |
|
| 220 while((group = va_arg(ap, int)) != -1) { |
|
| 221 [item addGroup: group]; |
|
| 222 } |
|
| 223 va_end(ap); |
|
| 224 |
|
| 225 NSMenu *currentMenu = current->data; |
|
| 226 [currentMenu addItem:item]; |
|
| 227 |
|
| 228 currentItemIndex++; |
|
| 229 } |
|
| 230 |
|
| 231 void ui_checkitem(char *label, ui_callback f, void *data) { |
|
| 232 EventWrapper *event = [[EventWrapper alloc]initWithData:data callback:f]; |
|
| 233 NSString *str = [[NSString alloc] initWithUTF8String:label]; |
|
| 234 |
|
| 235 NSMenu *currentMenu = current->data; |
|
| 236 NSMenuItem *item = [currentMenu addItemWithTitle:str |
|
| 237 action:@selector(handleStateEvent:) keyEquivalent:@""]; |
|
| 238 [item setTarget:event]; |
|
| 239 |
|
| 240 [delegate addItem: item var:NULL]; |
|
| 241 currentItemIndex++; |
|
| 242 } |
|
| 243 |
|
| 244 void ui_checkitem_nv(char *label, char *vname) { |
|
| 245 EventWrapper *event = [[EventWrapper alloc]initWithData:NULL callback:NULL]; |
|
| 246 NSString *str = [[NSString alloc] initWithUTF8String:label]; |
|
| 247 |
|
| 248 NSMenu *currentMenu = current->data; |
|
| 249 NSMenuItem *item = [currentMenu addItemWithTitle:str |
|
| 250 action:@selector(handleStateEvent:) keyEquivalent:@""]; |
|
| 251 [item setTarget:event]; |
|
| 252 |
|
| 253 [delegate addItem: item var:vname]; |
|
| 254 currentItemIndex++; |
|
| 255 } |
|
| 256 |
|
| 257 void ui_menuseparator() { |
|
| 258 NSMenu *currentMenu = current->data; |
|
| 259 [currentMenu addItem: [NSMenuItem separatorItem]]; |
|
| 260 currentItemIndex++; |
|
| 261 } |
|
| 262 |
|
| 263 void ui_menuitem_list (UiList *items, ui_callback f, void *data) { |
|
| 264 NSMenu *currentMenu = current->data; |
|
| 265 [delegate addList:items menu:currentMenu index:currentItemIndex callback:f data:data]; |
|
| 266 } |
|
| 267 |
|
| 268 |
|
| 269 |
|
| 270 int ui_menuitem_get(UiInteger *i) { |
|
| 271 UiMenuItem *item = i->obj; |
|
| 272 i->value = [item->item state]; |
|
| 273 return i->value; |
|
| 274 } |
|
| 275 |
|
| 276 void ui_menuitem_set(UiInteger *i, int value) { |
|
| 277 UiMenuItem *item = i->obj; |
|
| 278 [item->item setState: value]; |
|
| 279 i->value = value; |
|
| 280 item->state = value; |
|
| 281 } |
|
| 282 |
|
| 283 |
|
| 284 int ui_update_item(UiCocoaWindow *window, void *data) { |
|
| 285 UiMenuItem *item = data; |
|
| 286 [item->item setState: item->state]; |
|
| 287 return 0; |
|
| 288 } |
|
| 289 |
|
| 290 int ui_update_item_list(UiCocoaWindow *window, void *data) { |
|
| 291 UiMenuItemList *itemList = data; |
|
| 292 UiList *list = itemList->list; |
|
| 293 |
|
| 294 for(int r=0;r<itemList->oldcount;r++) { |
|
| 295 [itemList->menu removeItemAtIndex:itemList->index]; |
|
| 296 } |
|
| 297 |
|
| 298 char *str = ui_list_first(list); |
|
| 299 int i = itemList->index; |
|
| 300 [itemList->menu insertItem: [NSMenuItem separatorItem] atIndex: i]; |
|
| 301 i++; |
|
| 302 while(str) { |
|
| 303 EventWrapper *event = [[EventWrapper alloc]initWithData:itemList->data callback:itemList->callback]; |
|
| 304 [event setIntval: i - itemList->index - 1]; |
|
| 305 |
|
| 306 NSString *title = [[NSString alloc] initWithUTF8String:str]; |
|
| 307 NSMenuItem *item = [[NSMenuItem alloc]initWithTitle:title action:@selector(handleEvent:) keyEquivalent:@""]; |
|
| 308 [item setTarget:event]; |
|
| 309 |
|
| 310 [itemList->menu insertItem:item atIndex:i]; |
|
| 311 |
|
| 312 str = ui_list_next(list); |
|
| 313 i++; |
|
| 314 } |
|
| 315 |
|
| 316 itemList->oldcount = i - itemList->index; |
|
| 317 |
|
| 318 return 0; |
|
| 319 } |
|