# HG changeset patch # User Olaf Wintermann # Date 1396290136 -7200 # Node ID e2fd132ab7814646c64bec8546b1ae8019c4b124 # Parent 2dbc56c2323b753dac55872a870aefb11ced5ac3 added menu item lists (Cocoa implementation) diff -r 2dbc56c2323b -r e2fd132ab781 application/main.c --- a/application/main.c Sat Mar 29 19:12:07 2014 +0100 +++ b/application/main.c Mon Mar 31 20:22:16 2014 +0200 @@ -43,6 +43,8 @@ UiInteger check1; +UiList *list; + void action_new(UiEvent *event, void *data) { UiObject *window = ui_window("Mod1", NULL); //ui_window_addint(window, "check1"); @@ -60,6 +62,8 @@ TestWindowData *wd = event->window; printf("Text: {%s}\n", ui_getval(wd->text)); ui_setval(wd->text, "--------"); + + ui_list_append(list, "abc"); } void action_close(UiEvent *event, void *data) { @@ -92,10 +96,18 @@ ui_text_redo(&wd->text); } +void action_document(UiEvent *event, void *data) { + UiList *documents = data; +} + int main(int argc, char** argv) { ui_init("app1", argc, argv); + list = ui_list_new(); + ui_list_append(list, "file1.txt"); + ui_list_append(list, "hello.txt"); + ui_list_append(list, "main.c"); ui_menu("File"); ui_menuitem("New", action_new, NULL); @@ -103,16 +115,19 @@ ui_menuseparator(); ui_menuitem("Dokument 1", action_doc1, NULL); ui_menuitem("Dokument 2", action_doc2, NULL); + void ui_menuseparator(); ui_menuseparator(); ui_checkitem_nv("Check", "check1"); //ui_checkitem("Check", action_open, NULL); ui_menuitem("Close", action_close, NULL); + void ui_menuseparator(); + ui_menuitem_list(list, action_document, list); ui_toolitem_st("new", UI_STOCK_NEW, action_new, NULL); - ui_toolitem_st("open", UI_STOCK_OPEN, action_open, NULL); - ui_toolitem_st("save", UI_STOCK_SAVE, action_save, NULL); + ui_toolitem_st("open", UI_STOCK_GO_BACK, action_open, NULL); + ui_toolitem_st("save", UI_STOCK_GO_FORWARD, action_save, NULL); ui_toolitem_st("close", UI_STOCK_CLOSE, action_close, NULL); ui_toolitem_st("undo", UI_STOCK_UNDO, action_undo, NULL); ui_toolitem_st("redo", UI_STOCK_REDO, action_redo, NULL); diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/menu.h --- a/ui/cocoa/menu.h Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/cocoa/menu.h Mon Mar 31 20:22:16 2014 +0200 @@ -30,26 +30,46 @@ #import "toolkit.h" #import "../../ucx/list.h" +typedef struct UiAbstractMenuItem { + int (*update)(id window, void *item); + void *item_data; +} UiAbstractMenuItem; + typedef struct UiMenuItem { - NSMenuItem *item; - int state; + NSMenuItem *item; + int state; } UiMenuItem; typedef struct UiStateItem { - NSMenuItem *item; - char *var; + NSMenuItem *item; + char *var; } UiStateItem; +typedef struct UiMenuItemList { + NSMenu *menu; + NSMenuItem *first; + UiList *list; + int index; + int oldcount; + ui_callback callback; + void *data; +} UiMenuItemList; + @interface UiMenuDelegate : NSObject { - UcxList *items; + UcxList *items; // UiStateItem* + UcxList *itemlists; // UiMenuItemList* } -- (void)menuNeedsUpdate:(NSMenu*) menu; +- (void) menuNeedsUpdate:(NSMenu*) menu; - (void) addItem:(NSMenuItem*) item var: (char*)name; +- (void) addList:(UiList*) list menu:(NSMenu*)menu index: (int)i callback: (ui_callback)f data:(void*) data; + - (UcxList*) items; +- (UcxList*) lists; + @end @@ -58,3 +78,6 @@ int ui_menuitem_get(UiInteger *i); void ui_menuitem_set(UiInteger *i, int value); + +int ui_update_item(id window, void *data); +int ui_update_item_list(id window, void *data); diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/menu.m --- a/ui/cocoa/menu.m Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/cocoa/menu.m Mon Mar 31 20:22:16 2014 +0200 @@ -37,6 +37,7 @@ - (UiMenuDelegate*) init { items = NULL; + itemlists = NULL; return self; } @@ -52,16 +53,34 @@ items = ucx_list_append(items, i); } +- (void) addList:(UiList*) list menu:(NSMenu*)menu index: (int)i callback: (ui_callback)f data:(void*) data { + UiMenuItemList *itemList = malloc(sizeof(UiMenuItemList)); + itemList->list = list; + itemList->menu = menu; + itemList->first = NULL; + itemList->index = i; + itemList->oldcount = 0; + itemList->callback = f; + itemList->data = data; + itemlists = ucx_list_append(itemlists, itemList); +} + - (UcxList*) items { return items; } +- (UcxList*) lists { + return itemlists; + +} + @end static NSMenu *currentMenu = NULL; +static int currentItemIndex = 0; static UiMenuDelegate *delegate; void ui_menu_init() { @@ -83,6 +102,7 @@ [[NSApp mainMenu] setSubmenu:menu forItem:menuItem]; currentMenu = menu; + currentItemIndex = 0; } void ui_menuitem(char *label, ui_callback f, void *data) { @@ -94,6 +114,7 @@ [item setTarget:event]; //[delegate addItem: item]; + currentItemIndex++; } void ui_checkitem(char *label, ui_callback f, void *data) { @@ -105,6 +126,7 @@ [item setTarget:event]; [delegate addItem: item var:NULL]; + currentItemIndex++; } void ui_checkitem_nv(char *label, char *vname) { @@ -116,10 +138,16 @@ [item setTarget:event]; [delegate addItem: item var:vname]; + currentItemIndex++; } void ui_menuseparator() { - + [currentMenu addItem: [NSMenuItem separatorItem]]; + currentItemIndex++; +} + +void ui_menuitem_list (UiList *items, ui_callback f, void *data) { + [delegate addList:items menu:currentMenu index:currentItemIndex callback:f data:data]; } @@ -136,3 +164,38 @@ i->value = value; item->state = value; } + + +int ui_update_item(UiCocoaWindow *window, void *data) { + UiMenuItem *item = data; + [item->item setState: item->state]; + return 0; +} + +int ui_update_item_list(UiCocoaWindow *window, void *data) { + printf("update list\n"); + + UiMenuItemList *itemList = data; + UiList *list = itemList->list; + + printf("oldcount: %d\n", itemList->oldcount); + for(int r=0;roldcount;r++) { + [itemList->menu removeItemAtIndex:itemList->index]; + } + + char *str = ui_list_first(list); + int i = itemList->index; + [itemList->menu insertItem: [NSMenuItem separatorItem] atIndex: i]; + i++; + do { + NSString *title = [[NSString alloc] initWithUTF8String:str]; + NSMenuItem *item = [[NSMenuItem alloc]initWithTitle:title action:@selector(handleStateEvent:) keyEquivalent:@""]; + + [itemList->menu insertItem:item atIndex:i]; + i++; + } while ((str = ui_list_next(list))); + + itemList->oldcount = i - itemList->index; + + return 0; +} diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/objs.mk --- a/ui/cocoa/objs.mk Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/cocoa/objs.mk Mon Mar 31 20:22:16 2014 +0200 @@ -32,6 +32,7 @@ COCOAOBJ = toolkit.o COCOAOBJ += window.o COCOAOBJ += menu.o +COCOAOBJ += stock.o COCOAOBJ += toolbar.o COCOAOBJ += container.o COCOAOBJ += text.o diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/stock.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/stock.h Mon Mar 31 20:22:16 2014 +0200 @@ -0,0 +1,42 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import "toolkit.h" +#import "../ui/stock.h" +#import "../../ucx/map.h" + +typedef struct UiStockItem { + NSString *label; + NSImage *image; +} UiStockItem; + +void ui_stock_init(); + +void ui_add_stock_item(char *stock_id, NSString *label, NSImage *image); + +UiStockItem* ui_get_stock_item(char *stock_id); diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/stock.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/cocoa/stock.m Mon Mar 31 20:22:16 2014 +0200 @@ -0,0 +1,61 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2012 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#import +#import + +#import "stock.h" + +static UcxMap *stock_items; + +void ui_stock_init() { + stock_items = ucx_map_new(64); + + ui_add_stock_item(UI_STOCK_NEW, @"New", nil); + ui_add_stock_item(UI_STOCK_OPEN, @"Open", nil); + ui_add_stock_item(UI_STOCK_SAVE, @"Save", nil); + ui_add_stock_item(UI_STOCK_SAVE_AS, @"Save as ...", nil); + ui_add_stock_item(UI_STOCK_CLOSE, @"Close", nil); + ui_add_stock_item(UI_STOCK_UNDO, @"Undo", nil); + ui_add_stock_item(UI_STOCK_REDO, @"Redo", nil); + + ui_add_stock_item(UI_STOCK_GO_BACK, @"Back", [NSImage imageNamed: NSImageNameGoLeftTemplate]); + ui_add_stock_item(UI_STOCK_GO_FORWARD, @"Forward", [NSImage imageNamed: NSImageNameGoRightTemplate]); +} + +void ui_add_stock_item(char *stock_id, NSString *label, NSImage *image) { + UiStockItem *i = malloc(sizeof(UiStockItem)); + i->label = label; + i->image = image; + + ucx_map_cstr_put(stock_items, stock_id, i); +} + +UiStockItem* ui_get_stock_item(char *stock_id) { + return ucx_map_cstr_get(stock_items, stock_id); +} diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/toolbar.m --- a/ui/cocoa/toolbar.m Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/cocoa/toolbar.m Mon Mar 31 20:22:16 2014 +0200 @@ -31,6 +31,7 @@ #import #import "toolbar.h" +#import "stock.h" static UiToolbarDelegate* toolbar_delegate; @@ -55,22 +56,17 @@ - (NSToolbarItem *) createItem:(NSToolbar*)toolbar identifier:(NSString*)identifier { - /* UiStockItem *s = ui_get_stock_item(stockid); if(s == nil) { printf("cannot find stock item\n"); return nil; } - if([s buttonImage] == nil && [s itemImage] == nil) { - return nil; - } - */ NSToolbarItem *item = [[[NSToolbarItem alloc] initWithItemIdentifier: identifier] autorelease]; //[item setLabel:[s label]]; //[item setPaletteLabel:[s label]]; - [item setLabel:@"Add"]; + [item setLabel:s->label]; [item setPaletteLabel:@"Operation"]; // create button ... @@ -78,7 +74,12 @@ //NSSearchField *sf = [[NSSearchField alloc]initWithFrame:frame]; NSButton *button = [[NSButton alloc]initWithFrame:frame]; //[button setImage:[s buttonImage]]; - [button setImage:[NSImage imageNamed: NSImageNameAddTemplate]]; + //[button setImage:[NSImage imageNamed: NSImageNameAddTemplate]]; + if(s->image) { + [button setImage:s->image]; + } else { + [button setImage:[NSImage imageNamed: NSImageNameRemoveTemplate]]; + } [button setBezelStyle: NSTexturedRoundedBezelStyle]; [item setView:button]; diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/toolkit.m --- a/ui/cocoa/toolkit.m Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/cocoa/toolkit.m Mon Mar 31 20:22:16 2014 +0200 @@ -38,7 +38,7 @@ #import "window.h" #import "menu.h" #import "toolbar.h" - +#import "stock.h" NSAutoreleasePool *pool; @@ -56,8 +56,7 @@ uic_docmgr_init(); ui_menu_init(); ui_toolbar_init(); - // load item stock - // ui_init_stock(); + ui_stock_init(); } void ui_show(UiObject *obj) { diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/window.h --- a/ui/cocoa/window.h Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/cocoa/window.h Mon Mar 31 20:22:16 2014 +0200 @@ -30,18 +30,22 @@ #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 *menus; // key: NSMenu value: UcxList of UiMenuItem UcxMap *items; // key: NSMenuItem value: UiMenuItem } +- (UiCocoaWindow*) init: (NSRect)frame object: (UiObject*)obj; - (UiObject*) object; - (void) setObject:(UiObject*)obj; - (void) setMenuItems:(UcxList*)menuItems; +- (void) setMenuItemLists:(UcxList*)itemLists; - (UiMenuItem*) getMenuItem:(NSMenuItem*)item; - (void) updateMenu:(NSMenu*)menu; diff -r 2dbc56c2323b -r e2fd132ab781 ui/cocoa/window.m --- a/ui/cocoa/window.m Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/cocoa/window.m Mon Mar 31 20:22:16 2014 +0200 @@ -40,6 +40,23 @@ @implementation UiCocoaWindow +- (UiCocoaWindow*) init: (NSRect)frame object: (UiObject*)obj { + self = [self initWithContentRect:frame + styleMask:NSTitledWindowMask | + NSResizableWindowMask | + NSClosableWindowMask | + NSMiniaturizableWindowMask + backing:NSBackingStoreBuffered + defer:false]; + + uiobj = obj; + UcxAllocator *allocator = uiobj->ctx->mempool->allocator; + menus = ucx_map_new_a(allocator, 8); + items = ucx_map_new_a(allocator, 64); + + return self; +} + - (UiObject*) object { return uiobj; } @@ -50,8 +67,6 @@ - (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; @@ -76,14 +91,34 @@ } // add item + UiAbstractMenuItem *abstractItem = malloc(sizeof(UiAbstractMenuItem)); + abstractItem->update = ui_update_item; + abstractItem->item_data = windowItem; UcxList *itemList = ucx_map_get(menus, ucx_key(&menu, sizeof(void*))); - itemList = ucx_list_append_a(allocator, itemList, windowItem); + itemList = ucx_list_append_a(allocator, itemList, abstractItem); ucx_map_put(menus, ucx_key(&menu, sizeof(void*)), itemList); ucx_map_put(items, ucx_key(&windowItem->item, sizeof(void*)), windowItem); } } +- (void) setMenuItemLists:(UcxList*)itemLists { + UcxAllocator *allocator = uiobj->ctx->mempool->allocator; + + UCX_FOREACH(elm, itemLists) { + UiMenuItemList *list = elm->data; + + UiAbstractMenuItem *abstractItem = malloc(sizeof(UiAbstractMenuItem)); + abstractItem->update = ui_update_item_list; + abstractItem->item_data = list; + + UcxList *itemList = ucx_map_get(menus, ucx_key(&list->menu, sizeof(void*))); + itemList = ucx_list_append_a(allocator, itemList, abstractItem); + ucx_map_put(menus, ucx_key(&list->menu, sizeof(void*)), itemList); + + } +} + - (UiMenuItem*) getMenuItem:(NSMenuItem*)item { return ucx_map_get(items, ucx_key(&item, sizeof(void*))); } @@ -91,9 +126,8 @@ - (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]; + UiAbstractMenuItem *item = elm->data; + item->update(self, item->item_data); } } @@ -114,18 +148,21 @@ window_default_width, window_default_height); + /* UiCocoaWindow *window = [[UiCocoaWindow alloc] initWithContentRect:frame styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask backing:NSBackingStoreBuffered defer:false]; + */ + UiCocoaWindow *window = [[UiCocoaWindow alloc] init:frame object:obj]; - [window setObject: obj]; NSString *titleStr = [[NSString alloc] initWithUTF8String:title]; [window setTitle:titleStr]; UiMenuDelegate *menuDelegate = ui_menu_delegate(); [window setMenuItems: [menuDelegate items]]; + [window setMenuItemLists: [menuDelegate lists]]; NSToolbar *toolbar = ui_create_toolbar(); [window setToolbar: toolbar]; diff -r 2dbc56c2323b -r e2fd132ab781 ui/common/context.h --- a/ui/common/context.h Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/common/context.h Mon Mar 31 20:22:16 2014 +0200 @@ -26,8 +26,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef VALUE_H -#define VALUE_H +#ifndef UIC_CONTEXT_H +#define UIC_CONTEXT_H #include "../ui/toolkit.h" #include "../../ucx/map.h" @@ -67,5 +67,5 @@ } #endif -#endif /* VALUE_H */ +#endif /* UIC_CONTEXT_H */ diff -r 2dbc56c2323b -r e2fd132ab781 ui/common/objs.mk --- a/ui/common/objs.mk Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/common/objs.mk Mon Mar 31 20:22:16 2014 +0200 @@ -32,8 +32,10 @@ COMMON_OBJ = context.o COMMON_OBJ += document.o COMMON_OBJ += object.o +COMMON_OBJ += types.o #COMMON_OBJ = observer.o #COMMON_OBJ += list.o + TOOLKITOBJS += $(COMMON_OBJ:%=$(COMMON_OBJPRE)%) TOOLKITSOURCE += $(COMMON_OBJ:%.o=common/%.c) diff -r 2dbc56c2323b -r e2fd132ab781 ui/common/types.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/common/types.c Mon Mar 31 20:22:16 2014 +0200 @@ -0,0 +1,142 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "../../ucx/list.h" +#include "types.h" + +UiObserver* ui_observer_new(ui_callback f, void *data) { + UiObserver *observer = malloc(sizeof(UiObserver)); + observer->callback = f; + observer->data = data; + observer->next = NULL; + return observer; +} + +UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer) { + if(!list) { + return observer; + } else { + UiObserver *l = list; + while(l->next) { + l = l->next; + } + l->next = observer; + return list; + } +} + +UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data) { + UiObserver *observer = ui_observer_new(f, data); + return ui_obsvlist_add(list, observer); +} + +void ui_notify(UiObserver *observer, void *data) { + ui_notify_except(observer, NULL, data); +} + +void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data) { + while(observer) { + if(observer != exc) { + observer->callback(data, observer->data); + } + observer = observer->next; + } +} + +/* --------------------------- UiList --------------------------- */ + +UiList* ui_list_new() { + UiList *list = malloc(sizeof(UiList)); + list->first = ui_list_first; + list->next = ui_list_next; + list->get = ui_list_get; + list->count = ui_list_count; + list->observers = NULL; + + list->data = NULL; + list->iter = NULL; + + return list; +} + +void ui_list_free(UiList *list) { + ucx_list_free(list->data); + free(list); +} + +void* ui_list_first(UiList *list) { + UcxList *elm = list->data; + list->iter = elm; + return elm ? elm->data : NULL; +} + +void* ui_list_next(UiList *list) { + UcxList *elm = list->iter; + if(elm) { + elm = elm->next; + if(elm) { + list->iter = elm; + return elm->data; + } + } + return NULL; +} + +void* ui_list_get(UiList *list, int i) { + UcxList *elm = ucx_list_get(list->data, i); + if(elm) { + list->iter = elm; + return elm->data; + } else { + return NULL; + } +} + +int ui_list_count(UiList *list) { + UcxList *elm = list->data; + return (int)ucx_list_size(elm); +} + +void ui_list_append(UiList *list, void *data) { + list->data = ucx_list_append(list->data, data); +} + +void ui_list_prepend(UiList *list, void *data) { + list->data = ucx_list_prepend(list->data, data); +} + +void ui_list_addobsv(UiList *list, ui_callback f, void *data) { + list->observers = ui_add_observer(list->observers, f, data); +} + +void ui_list_notify(UiList *list) { + ui_notify(list->observers, list); +} diff -r 2dbc56c2323b -r e2fd132ab781 ui/common/types.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ui/common/types.h Mon Mar 31 20:22:16 2014 +0200 @@ -0,0 +1,62 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2014 Olaf Wintermann. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UIC_TYPES_H +#define UIC_TYPES_H + +#include "../ui/toolkit.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +UiObserver* ui_observer_new(ui_callback f, void *data); +UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer); +UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data); +void ui_notify(UiObserver *observer, void *data); +void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data); + + +UiList* ui_list_new(); +void* ui_list_first(UiList *list); +void* ui_list_next(UiList *list); +void* ui_list_get(UiList *list, int i); +int ui_list_count(UiList *list); +void ui_list_append(UiList *list, void *data); +void ui_list_prepend(UiList *list, void *data); +void ui_list_addobsv(UiList *list, ui_callback f, void *data); +void ui_list_notify(UiList *list); +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* UIC_TYPES_H */ + diff -r 2dbc56c2323b -r e2fd132ab781 ui/ui/menu.h --- a/ui/ui/menu.h Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/ui/menu.h Mon Mar 31 20:22:16 2014 +0200 @@ -46,6 +46,8 @@ void ui_checkitem(char *label, ui_callback f, void *userdata); void ui_checkitem_nv(char *label, char *vname); +void ui_menuitem_list(UiList *items, ui_callback f, void *userdata); + #ifdef __cplusplus } #endif diff -r 2dbc56c2323b -r e2fd132ab781 ui/ui/toolkit.h --- a/ui/ui/toolkit.h Sat Mar 29 19:12:07 2014 +0100 +++ b/ui/ui/toolkit.h Mon Mar 31 20:22:16 2014 +0200 @@ -55,12 +55,14 @@ #endif /* public types */ -typedef struct UiObject UiObject; -typedef struct UiEvent UiEvent; +typedef struct UiObject UiObject; +typedef struct UiEvent UiEvent; +typedef struct UiObserver UiObserver; typedef struct UiInteger UiInteger; typedef struct UiString UiString; typedef struct UiText UiText; +typedef struct UiList UiList; /* private types */ typedef struct UiContext UiContext; @@ -73,7 +75,7 @@ #define ui_insert(text, begin, str) (text).insert(&(text), begin, str) -typedef void(*ui_callback)(UiEvent*, void*); // event, user data +typedef void(*ui_callback)(UiEvent*, void*); /* event, user data */ struct UiObject { /* @@ -109,6 +111,12 @@ int intval; }; +struct UiObserver { + ui_callback callback; + void *data; + UiObserver *next; +}; + struct UiInteger { int (*get)(UiInteger*); void (*set)(UiInteger*, int); @@ -128,11 +136,32 @@ char* (*get)(UiText*); char* (*getsubstr)(UiText*, int, int); // text, begin, end void (*insert)(UiText*, int, char*); - char* value; + char *value; void *obj; void *undomgr; // TODO: selection, undo, replace, ... }; + +/* + * abstract list + */ +struct UiList { + /* get the first element */ + void*(*first)(UiList *list); + /* get the next element */ + void*(*next)(UiList *list); + /* get the nth element */ + void*(*get)(UiList *list, int i); + /* get the number of elements */ + int(*count)(UiList *list); + /* list of observers */ + UiObserver *observers; + /* iterator changes after first() next() and get() */ + void *iter; + /* private - implementation dependent */ + void *data; + +}; void ui_init(char *appname, int argc, char **argv); void ui_exitfunc(ui_callback f, void *udata); @@ -163,6 +192,27 @@ // new: int ui_getint(UiObject *obj, char *name); + + + + +// types +UiObserver* ui_observer_new(ui_callback f, void *data); +UiObserver* ui_obsvlist_add(UiObserver *list, UiObserver *observer); +UiObserver* ui_add_observer(UiObserver *list, ui_callback f, void *data); +void ui_notify(UiObserver *observer, void *data); +void ui_notify_except(UiObserver *observer, UiObserver *exc, void *data); + + +UiList* ui_list_new(); +void* ui_list_first(UiList *list); +void* ui_list_next(UiList *list); +void* ui_list_get(UiList *list, int i); +int ui_list_count(UiList *list); +void ui_list_append(UiList *list, void *data); +void ui_list_prepend(UiList *list, void *data); +void ui_list_addobsv(UiList *list, ui_callback f, void *data); +void ui_list_notify(UiList *list); #ifdef __cplusplus