UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2014 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #import <stdio.h> 30 #import <stdlib.h> 31 #import <string.h> 32 #import <stdarg.h> 33 34 #import "menu.h" 35 #import "window.h" 36 #import "stock.h" 37 38 @implementation UiMenuDelegate 39 40 - (UiMenuDelegate*) init { 41 items = NULL; 42 itemlists = NULL; 43 return self; 44 } 45 46 - (void) menuNeedsUpdate:(NSMenu *) menu { 47 NSWindow *activeWindow = [NSApp keyWindow]; 48 [(UiCocoaWindow*)activeWindow updateMenu: menu]; 49 } 50 51 - (void) addItem:(NSMenuItem*) item var: (char*)name { 52 UiStateItem *i = malloc(sizeof(UiStateItem)); 53 i->item = item; 54 i->var = name; 55 items = ucx_list_append(items, i); 56 } 57 58 - (void) addList:(UiList*) list menu:(NSMenu*)menu index: (int)i callback: (ui_callback)f data:(void*) data { 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 77 } 78 79 @end 80 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 } 89 90 - (void) addGroup:(int)group { 91 NSNumber *groupNumber = [NSNumber numberWithInteger:group]; 92 [groups addObject:groupNumber]; 93 } 94 95 - (void) checkGroups:(int*)g count:(int)n { 96 int c = [groups count]; 97 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 } 117 118 @end 119 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 } 135 136 137 void ui_menu(char *title) { 138 NSString *str = [[NSString alloc] initWithUTF8String:title]; 139 140 NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; 141 NSMenuItem *menuItem = [[NSApp mainMenu] addItemWithTitle:str 142 action:nil keyEquivalent:@""]; 143 [menu setDelegate: delegate]; 144 [menu setAutoenablesItems:NO]; 145 146 [[NSApp mainMenu] setSubmenu:menu forItem:menuItem]; 147 //currentMenu = menu; 148 currentItemIndex = 0; 149 150 current = ucx_list_prepend(NULL, menu); 151 } 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 } 320