# HG changeset patch # User Olaf Wintermann # Date 1396033381 -3600 # Node ID 6f263196f916133a1818c6610e3109d8e3e0e37a # Parent 84a541c6e093398b16bacc6dcb9d7926bbff6a26 added Cocoa implementation for menu check items (with bugs) diff -r 84a541c6e093 -r 6f263196f916 application/main.c --- a/application/main.c Wed Mar 26 15:53:43 2014 +0100 +++ b/application/main.c Fri Mar 28 20:03:01 2014 +0100 @@ -50,6 +50,7 @@ } void action_open(UiEvent *event, void *data) { + //printf("check1: %s\n", event->intval ? "true" : "false"); //printf("check1: %s\n", ui_getint(event->obj, "check1") ? "true" : "false"); TestDocument *doc = event->document; printf("check1: %s\n", ui_getval(doc->check1) ? "true" : "false"); @@ -82,13 +83,13 @@ void action_undo(UiEvent *event, void *data) { printf("undo\n"); TestWindowData *wd = event->window; - ui_text_undo(&wd->text); + //ui_text_undo(&wd->text); } void action_redo(UiEvent *event, void *data) { printf("redo\n"); TestWindowData *wd = event->window; - ui_text_redo(&wd->text); + //ui_text_redo(&wd->text); } @@ -104,6 +105,7 @@ ui_menuitem("Dokument 2", action_doc2, NULL); ui_menuseparator(); ui_checkitem_nv("Check", "check1"); + //ui_checkitem("Check", action_open, NULL); ui_menuitem("Close", action_close, NULL); diff -r 84a541c6e093 -r 6f263196f916 ui/cocoa/menu.h --- a/ui/cocoa/menu.h Wed Mar 26 15:53:43 2014 +0100 +++ b/ui/cocoa/menu.h Fri Mar 28 20:03:01 2014 +0100 @@ -26,7 +26,35 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "../ui/menu.h" +#import "../ui/menu.h" #import "toolkit.h" +#import "../../ucx/list.h" + +typedef struct UiMenuItem { + NSMenuItem *item; + int state; +} UiMenuItem; + +typedef struct UiStateItem { + NSMenuItem *item; + char *var; +} UiStateItem; + +@interface UiMenuDelegate : NSObject { + UcxList *items; +} + +- (void)menuNeedsUpdate:(NSMenu*) menu; + +- (void) addItem:(NSMenuItem*) item var: (char*)name; + +- (UcxList*) items; + +@end +void ui_menu_init(); +UiMenuDelegate* ui_menu_delegate(); + +int ui_menuitem_get(UiInteger *i); +void ui_menuitem_set(UiInteger *i, int value); diff -r 84a541c6e093 -r 6f263196f916 ui/cocoa/menu.m --- a/ui/cocoa/menu.m Wed Mar 26 15:53:43 2014 +0100 +++ b/ui/cocoa/menu.m Fri Mar 28 20:03:01 2014 +0100 @@ -31,9 +31,47 @@ #import #import "menu.h" +#import "window.h" + +@implementation UiMenuDelegate + +- (UiMenuDelegate*) init { + items = NULL; + return self; +} + +- (void) menuNeedsUpdate:(NSMenu *) menu { + NSWindow *activeWindow = [NSApp keyWindow]; + [(UiCocoaWindow*)activeWindow updateMenu: menu]; +} + +- (void) addItem:(NSMenuItem*) item var: (char*)name { + UiStateItem *i = malloc(sizeof(UiStateItem)); + i->item = item; + i->var = name; + items = ucx_list_append(items, i); +} + +- (UcxList*) items { + return items; +} + +@end + + static NSMenu *currentMenu = NULL; +static UiMenuDelegate *delegate; + +void ui_menu_init() { + delegate = [[UiMenuDelegate alloc]init]; +} + +UiMenuDelegate* ui_menu_delegate() { + return delegate; +} + void ui_menu(char *title) { NSString *str = [[NSString alloc] initWithUTF8String:title]; @@ -41,6 +79,7 @@ NSMenu *menu = [[NSMenu alloc] initWithTitle: str]; NSMenuItem *menuItem = [[NSApp mainMenu] addItemWithTitle:str action:nil keyEquivalent:@""]; + [menu setDelegate: delegate]; [[NSApp mainMenu] setSubmenu:menu forItem:menuItem]; currentMenu = menu; @@ -53,14 +92,30 @@ NSMenuItem *item = [currentMenu addItemWithTitle:str action:@selector(handleEvent:) keyEquivalent:@""]; [item setTarget:event]; + + //[delegate addItem: item]; } -void ui_checkitem(char *label, ui_callback f, void *userdata) { +void ui_checkitem(char *label, ui_callback f, void *data) { + EventWrapper *event = [[EventWrapper alloc]initWithData:data callback:f]; + NSString *str = [[NSString alloc] initWithUTF8String:label]; + NSMenuItem *item = [currentMenu addItemWithTitle:str + action:@selector(handleStateEvent:) keyEquivalent:@""]; + [item setTarget:event]; + + [delegate addItem: item var:NULL]; } void ui_checkitem_nv(char *label, char *vname) { + EventWrapper *event = [[EventWrapper alloc]initWithData:NULL callback:NULL]; + NSString *str = [[NSString alloc] initWithUTF8String:label]; + NSMenuItem *item = [currentMenu addItemWithTitle:str + action:@selector(handleStateEvent:) keyEquivalent:@""]; + [item setTarget:event]; + + [delegate addItem: item var:vname]; } void ui_menuseparator() { @@ -68,3 +123,15 @@ } + +int ui_menuitem_get(UiInteger *i) { + UiMenuItem *item = i->obj; + i->value = [item->item state]; + return i->value; +} + +void ui_menuitem_set(UiInteger *i, int value) { + UiMenuItem *item = i->obj; + [item->item setState: value]; + i->value = value; +} diff -r 84a541c6e093 -r 6f263196f916 ui/cocoa/toolkit.h --- a/ui/cocoa/toolkit.h Wed Mar 26 15:53:43 2014 +0100 +++ b/ui/cocoa/toolkit.h Fri Mar 28 20:03:01 2014 +0100 @@ -45,5 +45,8 @@ - (void) setCallback: (ui_callback)f; - (BOOL)handleEvent:(id)sender; +- (BOOL)handleStateEvent:(id)sender; @end + + diff -r 84a541c6e093 -r 6f263196f916 ui/cocoa/toolkit.m --- a/ui/cocoa/toolkit.m Wed Mar 26 15:53:43 2014 +0100 +++ b/ui/cocoa/toolkit.m Fri Mar 28 20:03:01 2014 +0100 @@ -36,6 +36,7 @@ #import "toolkit.h" #import "window.h" +#import "menu.h" #import "toolbar.h" @@ -53,6 +54,7 @@ uic_docmgr_init(); + ui_menu_init(); ui_toolbar_init(); // load item stock // ui_init_stock(); @@ -118,4 +120,32 @@ return true; } +- (BOOL)handleStateEvent:(id)sender { + NSWindow *activeWindow = [NSApp keyWindow]; + NSMenuItem *item = (NSMenuItem*)sender; + int state = [item state] ? NSOffState : NSOnState; + + UiEvent event; + event.intval = state; + if([activeWindow class] == [UiCocoaWindow class]) { + event.obj = [(UiCocoaWindow*)activeWindow object]; + event.window = event.obj->window; + event.document = event.obj->document; + // update state in window data + UiMenuItem *wmi = [(UiCocoaWindow*)activeWindow getMenuItem: sender]; + wmi->state = state; + } else { + event.window = NULL; + event.document = NULL; + } + if(callback) { + callback(&event, data); + } + [item setState: state]; + + return true; +} + @end + + diff -r 84a541c6e093 -r 6f263196f916 ui/cocoa/window.h --- a/ui/cocoa/window.h Wed Mar 26 15:53:43 2014 +0100 +++ b/ui/cocoa/window.h Fri Mar 28 20:03:01 2014 +0100 @@ -28,13 +28,21 @@ #import #import "../ui/window.h" +#import "../../ucx/list.h" +#import "../../ucx/map.h" +#import "menu.h" @interface UiCocoaWindow : NSWindow { UiObject *uiobj; + UcxMap *menus; // key: NSMenu value: UcxList of UiMenuItem + UcxMap *items; // key: NSMenuItem value: UiMenuItem } - (UiObject*) object; -- (void) setObject:(UiObject*)obj; +- (void) setObject:(UiObject*)obj; +- (void) setMenuItems:(UcxList*)menuItems; +- (UiMenuItem*) getMenuItem:(NSMenuItem*)item; +- (void) updateMenu:(NSMenu*)menu; @end diff -r 84a541c6e093 -r 6f263196f916 ui/cocoa/window.m --- a/ui/cocoa/window.m Wed Mar 26 15:53:43 2014 +0100 +++ b/ui/cocoa/window.m Fri Mar 28 20:03:01 2014 +0100 @@ -29,6 +29,7 @@ #include #import "window.h" +#import "menu.h" #import "toolbar.h" #import "container.h" #import "../../ucx/mempool.h" @@ -47,6 +48,55 @@ uiobj = obj; } +- (void) setMenuItems:(UcxList*)menuItems { + UcxAllocator *allocator = uiobj->ctx->mempool->allocator; + menus = ucx_map_new_a(allocator, 8); + items = ucx_map_new_a(allocator, 64); + + UCX_FOREACH(elm, menuItems) { + UiStateItem *item = elm->data; + NSMenu *menu = [item->item menu]; + + // create UiMenuItem which represents an NSMenuItem for a Window + UiMenuItem *windowItem = ucx_mempool_malloc(uiobj->ctx->mempool, sizeof(UiMenuItem)); + windowItem->item = item->item; + windowItem->state = 0; + if(item->var) { + // bind value + UiVar *var = uic_connect_var(uiobj->ctx, item->var, UI_VAR_INTEGER); + if(var) { + UiInteger *value = var->value; + value->obj = windowItem; + value->get = ui_menuitem_get; + value->set = ui_menuitem_set; + value = 0; + } else { + // TODO: error + } + } + + // add item + UcxList *itemList = ucx_map_get(menus, ucx_key(&menu, sizeof(void*))); + itemList = ucx_list_append_a(allocator, itemList, windowItem); + ucx_map_put(menus, ucx_key(&menu, sizeof(void*)), itemList); + + ucx_map_put(items, ucx_key(&windowItem->item, sizeof(void*)), windowItem); + } +} + +- (UiMenuItem*) getMenuItem:(NSMenuItem*)item { + return ucx_map_get(items, ucx_key(&item, sizeof(void*))); +} + +- (void) updateMenu:(NSMenu*)menu { + UcxList *itemList = ucx_map_get(menus, ucx_key(&menu, sizeof(void*))); + UCX_FOREACH(elm, itemList) { + UiMenuItem *item = elm->data; + + [item->item setState: item->state]; + } +} + @end @@ -74,6 +124,9 @@ NSString *titleStr = [[NSString alloc] initWithUTF8String:title]; [window setTitle:titleStr]; + UiMenuDelegate *menuDelegate = ui_menu_delegate(); + [window setMenuItems: [menuDelegate items]]; + NSToolbar *toolbar = ui_create_toolbar(); [window setToolbar: toolbar];