# HG changeset patch # User Olaf Wintermann # Date 1396352849 -7200 # Node ID db95c0104937a9761843a1d856bfe74382645720 # Parent a499c8a72c15141c6d402246f5e08270c20eafcd added menu item lists (Motif) diff -r a499c8a72c15 -r db95c0104937 ui/motif/button.c --- a/ui/motif/button.c Tue Apr 01 11:53:10 2014 +0200 +++ b/ui/motif/button.c Tue Apr 01 13:47:29 2014 +0200 @@ -54,6 +54,7 @@ event->obj = obj; event->user_data = data; event->callback = f; + event->value = 0; XtAddCallback( button, XmNactivateCallback, @@ -99,6 +100,6 @@ e.obj = event->obj; e.window = event->obj->window; e.document = event->obj->document; - e.intval = 0; + e.intval = event->value; event->callback(&e, event->user_data); } diff -r a499c8a72c15 -r db95c0104937 ui/motif/menu.c --- a/ui/motif/menu.c Tue Apr 01 11:53:10 2014 +0200 +++ b/ui/motif/menu.c Tue Apr 01 13:47:29 2014 +0200 @@ -136,6 +136,21 @@ cm->items = ucx_list_append(cm->items, item); } +void ui_menuitem_list(UiList *items, ui_callback f, void *userdata) { + if(!current) { + return; + } + + UiMenuItemList *item = malloc(sizeof(UiMenuItemList)); + item->item.add_to = (ui_menu_add_f)add_menuitem_list_widget; + item->callback = f; + item->userdata = userdata; + item->list = items; + + UiMenu *cm = current->data; + cm->items = ucx_list_append(cm->items, item); +} + // private menu functions void ui_create_menubar(UiObject *obj) { @@ -204,6 +219,7 @@ event->obj = obj; event->user_data = mi->userdata; event->callback = mi->callback; + event->value = 0; XtAddCallback( mitem, XmNactivateCallback, @@ -292,8 +308,104 @@ } else { // TODO: error } + + return 1; +} + +int add_menuitem_list_widget( + Widget parent, + int i, + UiMenuItemI *item, + UiObject *obj) +{ + UiMenuItemList *il = (UiMenuItemList*)item; + UcxMempool *mp = obj->ctx->mempool; + + UiActiveMenuItemList *ls = ucx_mempool_malloc( + mp, + sizeof(UiActiveMenuItemList)); + + ls->object = obj; + ls->menu = parent; + ls->index = i; + ls->oldcount = 0; + ls->list = il->list; + ls->callback = il->callback; + ls->userdata = il->userdata; + + ls->list->observers = ui_add_observer( + ls->list->observers, + (ui_callback)ui_update_menuitem_list, + ls); + + ui_update_menuitem_list(NULL, ls); + + return 0; } +void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list) { + Arg args[4]; + + // remove old items + if(list->oldcount > 0) { + Widget *children; + int nc; + + XtVaGetValues( + list->menu, + XmNchildren, + &children, + XmNnumChildren, + &nc, + NULL); + + for(int i=0;ioldcount;i++) { + XtDestroyWidget(children[list->index + i]); + } + } + + char *str = ui_list_first(list->list); + if(str) { + // add separator + XtSetArg(args[0], XmNpositionIndex, list->index); + Widget s = XmCreateSeparatorGadget (list->menu, "menu_separator", args, 1); + XtManageChild(s); + } + int i = 1; + while(str) { + XmString label = XmStringCreateLocalized(str); + XtSetArg(args[0], XmNlabelString, label); + XtSetArg(args[1], XmNpositionIndex, list->index + i); + + Widget mitem = XtCreateManagedWidget( + "menubutton", + xmPushButtonWidgetClass, + list->menu, + args, + 2); + XmStringFree(label); + + if(list->callback) { + // TODO: use mempool + UiEventData *event = malloc(sizeof(UiEventData)); + event->obj = list->object; + event->user_data = list->userdata; + event->callback = list->callback; + event->value = i - 1; + + XtAddCallback( + mitem, + XmNactivateCallback, + (XtCallbackProc)ui_push_button_callback, + event); + } + + str = ui_list_next(list->list); + i++; + } + + list->oldcount = i; +} void ui_menu_event_wrapper(Widget widget, XtPointer udata, XtPointer cdata) { UiEventData *event = udata; diff -r a499c8a72c15 -r db95c0104937 ui/motif/menu.h --- a/ui/motif/menu.h Tue Apr 01 11:53:10 2014 +0200 +++ b/ui/motif/menu.h Tue Apr 01 13:47:29 2014 +0200 @@ -42,6 +42,9 @@ typedef struct UiStMenuItem UiStMenuItem; typedef struct UiCheckItem UiCheckItem; typedef struct UiCheckItemNV UiCheckItemNV; +typedef struct UiMenuItemList UiMenuItemList; + +typedef struct UiActiveMenuItemList UiActiveMenuItemList; typedef int(*ui_menu_add_f)(Widget, int, UiMenuItemI*, UiObject*); @@ -83,6 +86,23 @@ char *varname; }; +struct UiMenuItemList { + UiMenuItemI item; + ui_callback callback; + void *userdata; + UiList *list; +}; + +struct UiActiveMenuItemList { + UiObject *object; + Widget menu; + int index; + int oldcount; + UiList *list; + ui_callback callback; + void *userdata; +}; + void ui_create_menubar(UiObject *obj); int add_menu_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj); @@ -91,8 +111,9 @@ int add_menuseparator_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj); int add_checkitem_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj); int add_checkitemnv_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj); +int add_menuitem_list_widget(Widget parent, int i, UiMenuItemI *item, UiObject *obj); - +void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list); void ui_menu_event_wrapper(Widget widget, XtPointer udata, XtPointer cdata); diff -r a499c8a72c15 -r db95c0104937 ui/motif/stock.c --- a/ui/motif/stock.c Tue Apr 01 11:53:10 2014 +0200 +++ b/ui/motif/stock.c Tue Apr 01 13:47:29 2014 +0200 @@ -44,6 +44,8 @@ ui_add_stock_item(UI_STOCK_CLOSE, "Close", NULL); ui_add_stock_item(UI_STOCK_UNDO, "Undo", NULL); ui_add_stock_item(UI_STOCK_REDO, "Redo", NULL); + ui_add_stock_item(UI_STOCK_GO_BACK, "Back", NULL); + ui_add_stock_item(UI_STOCK_GO_FORWARD, "Forward", NULL); } void ui_add_stock_item(char *id, char *label, void *icon) { diff -r a499c8a72c15 -r db95c0104937 ui/motif/toolkit.h --- a/ui/motif/toolkit.h Tue Apr 01 11:53:10 2014 +0200 +++ b/ui/motif/toolkit.h Tue Apr 01 13:47:29 2014 +0200 @@ -43,6 +43,7 @@ UiObject *obj; ui_callback callback; void *user_data; + int value; } UiEventData; #ifdef __cplusplus