UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2012 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 #include <stdio.h> 30 #include <stdlib.h> 31 #include <string.h> 32 33 #import "window.h" 34 #import "menu.h" 35 #import "toolbar.h" 36 #import "container.h" 37 #import <ucx/mempool.h> 38 #import "../common/context.h" 39 40 static int window_default_width = 600; 41 static int window_default_height = 500; 42 43 @implementation UiCocoaWindow 44 45 - (UiCocoaWindow*) init: (NSRect)frame object: (UiObject*)obj { 46 self = [self initWithContentRect:frame 47 styleMask:NSTitledWindowMask | 48 NSResizableWindowMask | 49 NSClosableWindowMask | 50 NSMiniaturizableWindowMask 51 backing:NSBackingStoreBuffered 52 defer:false]; 53 54 uiobj = obj; 55 UcxAllocator *allocator = uiobj->ctx->mempool->allocator; 56 menus = ucx_map_new_a(allocator, 8); 57 items = ucx_map_new_a(allocator, 64); 58 59 return self; 60 } 61 62 - (UiObject*) object { 63 return uiobj; 64 } 65 66 - (void) setObject:(UiObject*)obj { 67 uiobj = obj; 68 } 69 70 - (void) setMenuItems:(UcxList*)menuItems { 71 UcxAllocator *allocator = uiobj->ctx->mempool->allocator; 72 73 UCX_FOREACH(elm, menuItems) { 74 UiStateItem *item = elm->data; 75 NSMenu *menu = [item->item menu]; 76 77 // create UiMenuItem which represents an NSMenuItem for a Window 78 UiMenuItem *windowItem = ucx_mempool_malloc(uiobj->ctx->mempool, sizeof(UiMenuItem)); 79 windowItem->item = item->item; 80 windowItem->state = 0; 81 if(item->var) { 82 // bind value 83 UiVar *var = uic_connect_var(uiobj->ctx, item->var, UI_VAR_INTEGER); 84 if(var) { 85 UiInteger *value = var->value; 86 value->obj = windowItem; 87 value->get = ui_menuitem_get; 88 value->set = ui_menuitem_set; 89 value = 0; 90 } else { 91 // TODO: error 92 } 93 } 94 95 // add item 96 UiAbstractMenuItem *abstractItem = malloc(sizeof(UiAbstractMenuItem)); 97 abstractItem->update = ui_update_item; 98 abstractItem->item_data = windowItem; 99 UcxList *itemList = ucx_map_get(menus, ucx_key(&menu, sizeof(void*))); 100 itemList = ucx_list_append_a(allocator, itemList, abstractItem); 101 ucx_map_put(menus, ucx_key(&menu, sizeof(void*)), itemList); 102 103 ucx_map_put(items, ucx_key(&windowItem->item, sizeof(void*)), windowItem); 104 } 105 } 106 107 - (void) setMenuItemLists:(UcxList*)itemLists { 108 UcxAllocator *allocator = uiobj->ctx->mempool->allocator; 109 110 UCX_FOREACH(elm, itemLists) { 111 UiMenuItemList *list = elm->data; 112 113 UiAbstractMenuItem *abstractItem = malloc(sizeof(UiAbstractMenuItem)); 114 abstractItem->update = ui_update_item_list; 115 abstractItem->item_data = list; 116 117 UcxList *itemList = ucx_map_get(menus, ucx_key(&list->menu, sizeof(void*))); 118 itemList = ucx_list_append_a(allocator, itemList, abstractItem); 119 ucx_map_put(menus, ucx_key(&list->menu, sizeof(void*)), itemList); 120 121 } 122 } 123 124 - (UiMenuItem*) getMenuItem:(NSMenuItem*)item { 125 return ucx_map_get(items, ucx_key(&item, sizeof(void*))); 126 } 127 128 - (void) updateMenu:(NSMenu*)menu { 129 UcxList *itemList = ucx_map_get(menus, ucx_key(&menu, sizeof(void*))); 130 UCX_FOREACH(elm, itemList) { 131 UiAbstractMenuItem *item = elm->data; 132 item->update(self, item->item_data); 133 } 134 135 // update group items 136 // TODO: use only one loop for all items 137 int ngroups = 0; 138 int *groups = ui_active_groups(uiobj->ctx, &ngroups); 139 140 NSArray *groupItems = [menu itemArray]; 141 int count = [groupItems count]; 142 for(int i=0;i<count;i++) { 143 id item = [groupItems objectAtIndex:i]; 144 if([item class] == [UiGroupMenuItem class]) { 145 [item checkGroups: groups count:ngroups]; 146 } 147 } 148 free(groups); 149 } 150 151 @end 152 153 154 /* ------------------------------ public API ------------------------------ */ 155 156 UiObject* ui_window(char *title, void *window_data) { 157 UcxMempool *mp = ucx_mempool_new(256); 158 UiObject *obj = ucx_mempool_calloc(mp, 1, sizeof(UiObject)); 159 obj->ctx = uic_context(obj, mp); 160 161 // create native window 162 NSRect frame = NSMakeRect( 163 300, 164 200, 165 window_default_width, 166 window_default_height); 167 168 /* 169 UiCocoaWindow *window = [[UiCocoaWindow alloc] initWithContentRect:frame 170 styleMask:NSTitledWindowMask | NSResizableWindowMask | 171 NSClosableWindowMask | NSMiniaturizableWindowMask 172 backing:NSBackingStoreBuffered 173 defer:false]; 174 */ 175 UiCocoaWindow *window = [[UiCocoaWindow alloc] init:frame object:obj]; 176 177 NSString *titleStr = [[NSString alloc] initWithUTF8String:title]; 178 [window setTitle:titleStr]; 179 180 UiMenuDelegate *menuDelegate = ui_menu_delegate(); 181 [window setMenuItems: [menuDelegate items]]; 182 [window setMenuItemLists: [menuDelegate lists]]; 183 184 NSToolbar *toolbar = ui_create_toolbar(obj); 185 [window setToolbar: toolbar]; 186 187 obj->widget = (NSView*)window; 188 obj->window = window_data; 189 obj->container = ui_window_container(obj, window); 190 191 192 return obj; 193 } 194 195 void ui_close(UiObject *obj) { 196 // TODO 197 } 198 199 char* ui_openfiledialog(UiObject *obj) { 200 NSOpenPanel* op = [NSOpenPanel openPanel]; 201 if ([op runModal] == NSOKButton) { 202 NSArray *urls = [op URLs]; 203 NSURL *url = [urls objectAtIndex:0]; 204 205 const char *str = [[url path] UTF8String]; 206 return (char*)strdup(str); 207 } 208 return NULL; 209 } 210 211 char* ui_savefiledialog(UiObject *obj) { 212 NSSavePanel* sp = [NSSavePanel savePanel]; 213 if ([sp runModal] == NSOKButton) { 214 NSURL *url = [sp URL]; 215 216 const char *str = [[url path] UTF8String]; 217 return (char*)strdup(str); 218 } 219 return NULL; 220 } 221