# HG changeset patch # User Olaf Wintermann # Date 1734864599 -3600 # Node ID 28a5920bebe03d75df6fb082ab09cb5287d4368e # Parent 7d15cad351fc5ca7bfbe7e73da67e9a0c8ea7226 implement menu itemlist (Motif) diff -r 7d15cad351fc -r 28a5920bebe0 application/main.c --- a/application/main.c Sun Dec 15 22:53:51 2024 +0100 +++ b/application/main.c Sun Dec 22 11:49:59 2024 +0100 @@ -486,67 +486,39 @@ #if defined(UI_COCOA) || defined(UI_MOTIF) +static UiList *menulist; +int items = 4; + void action_button(UiEvent *event, void *data) { printf("action_button\n"); + + char *newitem = malloc(32); + snprintf(newitem, 32, "Item %d", ++items); + ui_list_append(menulist, newitem); + ui_list_notify(menulist); } typedef struct WData { UiString *path; } WData; + + void application_startup(UiEvent *event, void *data) { + + menulist = ui_list_new(ui_global_context(), "menulist"); + ui_list_append(menulist, "Item 1"); + ui_list_append(menulist, "Item 2"); + ui_list_append(menulist, "Item 3"); + ui_list_append(menulist, "Item 4"); + UiObject *obj = ui_window("Test", NULL); WData *wdata = ui_malloc(obj->ctx, sizeof(WData)); wdata->path = ui_string_new(obj->ctx, NULL); obj->window = wdata; - /* - ui_grid(obj, .margin = 10) { - ui_button(obj, .label = "Test Button", .onclick = action_button); - ui_newline(obj); - - ui_togglebutton(obj, .label = "Togglebutton"); - ui_togglebutton(obj, .label = "XY", .hfill = TRUE); - ui_togglebutton(obj, .label = "AB", .hfill = TRUE); - ui_togglebutton(obj, .label = "ZZ", .hexpand = TRUE, .hfill = TRUE); - ui_newline(obj); - - ui_hbox(obj, .colspan = 4, .hfill = TRUE, .hexpand = TRUE) { - ui_checkbox(obj, .label = "Checkbox", .enable_group = 123); - ui_checkbox(obj, .label = "Checkbox Disabled", .groups = UI_GROUPS(123)); - ui_button(obj, .label = "fill", .fill = UI_ON); - } - ui_newline(obj); - - - - ui_hbox(obj, .colspan = 4, .hfill = TRUE, .hexpand = TRUE) { - ui_radiobutton(obj, .label = "Radio 1", .varname = "radio"); - ui_radiobutton(obj, .label = "Radio 2", .varname = "radio"); - ui_button(obj, .label = "fill", .hexpand = TRUE, .hfill = TRUE); - } - ui_newline(obj); - - - ui_hbox(obj, .colspan = 4, .vexpand = TRUE, .vfill = TRUE) { - ui_button(obj, .label = "F1----------------------A"); - ui_button(obj, .label = "F2 test test test test test test test"); - ui_button(obj, .label = "F312343543"); - } - - - } - */ - - - - //ui_textfield(obj, .varname = "textfield"); - //ui_textfield(obj, .varname = "textfield2"); - ui_path_textfield(obj, .value = wdata->path, .hfill = TRUE, .hexpand = TRUE); - - ui_set(wdata->path, "/test/path/string"); - + ui_button(obj, .label = "Add Item", .onclick = action_button); ui_show(obj); } @@ -564,12 +536,18 @@ ui_menuitem(.label = "Test 1", .onclick = action_test); ui_menuitem(.label = "Test 2", .onclick = action_test); ui_menuitem(.label = "Test 3", .onclick = action_test); + ui_menuseparator(); ui_menu_toggleitem(.label = "Toggle 1"); ui_menu_toggleitem(.label = "Toggle 2"); + ui_menuseparator(); ui_menu_radioitem(.label = "Radio 1", .varname = "menu_radio"); ui_menu_radioitem(.label = "Radio 2", .varname = "menu_radio"); ui_menu_radioitem(.label = "Radio 3", .varname = "menu_radio"); ui_menu_radioitem(.label = "Radio 4", .varname = "menu_radio"); + ui_menuseparator(); + ui_menu_itemlist(.varname = "menulist"); + ui_menuseparator(); + ui_menuitem(.label = "Quit"); } ui_main(); diff -r 7d15cad351fc -r 28a5920bebe0 ui/common/context.c --- a/ui/common/context.c Sun Dec 15 22:53:51 2024 +0100 +++ b/ui/common/context.c Sun Dec 22 11:49:59 2024 +0100 @@ -100,6 +100,7 @@ if(var_ctx->vars_unbound && cxMapSize(var_ctx->vars_unbound) > 0) { CxIterator i = cxMapIterator(var_ctx->vars_unbound); cx_foreach(CxMapEntry*, entry, i) { + printf("attach %s\n", entry->key->data); UiVar *var = entry->value; UiVar *docvar = cxMapGet(doc_ctx->vars, *entry->key); if(docvar) { diff -r 7d15cad351fc -r 28a5920bebe0 ui/motif/menu.c --- a/ui/motif/menu.c Sun Dec 15 22:53:51 2024 +0100 +++ b/ui/motif/menu.c Sun Dec 22 11:49:59 2024 +0100 @@ -37,6 +37,7 @@ #include "container.h" #include "../common/context.h" #include "../common/menu.h" +#include "../common/types.h" #include "../ui/window.h" #include @@ -201,10 +202,109 @@ ui_bind_radiobutton(obj, button, NULL, it->varname, it->callback, it->userdata, 0); } -void add_checkitemnv_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) { +void add_menuitem_list_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) { + UiMenuItemList *il = (UiMenuItemList*)item; + const CxAllocator *a = obj->ctx->allocator; + UiActiveMenuItemList *ls = cxMalloc( + a, + sizeof(UiActiveMenuItemList)); + ls->object = obj; + ls->menu = p; + ls->index = i; + ls->oldcount = 0; + ls->getvalue = il->getvalue; + ls->callback = il->callback; + ls->userdata = il->userdata; + ls->addseparator = TRUE; + + ls->var = uic_create_var(ui_global_context(), il->varname, UI_VAR_LIST); //uic_widget_var(obj->ctx, obj->ctx, NULL, il->varname, UI_VAR_LIST); + UiList *list = ls->var->value; + + UiObserver *observer = ui_observer_new((ui_callback)ui_update_menuitem_list, ls); + list->observers = ui_obsvlist_add(list->observers, observer); + uic_list_register_observer_destructor(obj->ctx, list, observer); + + ui_update_menuitem_list(NULL, ls); } -void add_menuitem_list_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj) { +void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list) { + XmString s = NULL; + Arg args[4]; + int n; + + UiList *ls; + if(list->var && list->var->value) { + ls = list->var->value; + } else { + return; + } + + 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]); + } + } + + void* elm = ui_list_first(ls); + int i = 0; + if(elm && list->addseparator) { + Widget s = XmCreateSeparatorGadget(list->menu, "menuseparator", NULL, 0); + XtManageChild(s); + i++; + } + ui_getvaluefunc getvalue = list->getvalue; + while(elm) { + n = 0; + char *label = (char*) (getvalue ? getvalue(elm, 0) : elm); + if(label) { + s = XmStringCreateLocalized(label); + XtSetArg(args[n], XmNlabelString, s); n++; + } + + Widget mitem = XtCreateManagedWidget( + "menubutton", + xmPushButtonWidgetClass, + list->menu, + args, + n); + if(s) { + XmStringFree(s); + } + + if(list->callback) { + UiEventData *eventdata = malloc(sizeof(UiEventData)); + eventdata->callback = list->callback; + eventdata->userdata = list->userdata; + eventdata->obj = list->object; + eventdata->value = 0; + XtAddCallback( + mitem, + XmNactivateCallback, + (XtCallbackProc)ui_push_button_callback, + eventdata); + XtAddCallback( + mitem, + XmNdestroyCallback, + (XtCallbackProc)ui_destroy_eventdata, + eventdata); + } + + elm = ui_list_next(ls); + i++; + } + + list->oldcount = i; } diff -r 7d15cad351fc -r 28a5920bebe0 ui/motif/menu.h --- a/ui/motif/menu.h Sun Dec 15 22:53:51 2024 +0100 +++ b/ui/motif/menu.h Sun Dec 22 11:49:59 2024 +0100 @@ -31,11 +31,25 @@ #include "../ui/menu.h" #include "../common/menu.h" +#include "../common/context.h" #ifdef __cplusplus extern "C" { #endif +typedef struct UiActiveMenuItemList UiActiveMenuItemList; +struct UiActiveMenuItemList { + UiObject *object; + Widget menu; + int index; + int oldcount; + UiVar *var; + ui_getvaluefunc getvalue; + ui_callback callback; + void *userdata; + bool addseparator; +}; + typedef void(*ui_menu_add_f)(Widget, int, UiMenuItemI*, UiObject*); void ui_create_menubar(UiObject *obj, Widget window); @@ -50,6 +64,8 @@ void add_checkitemnv_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj); void add_menuitem_list_widget(Widget p, int i, UiMenuItemI *item, UiObject *obj); +void ui_update_menuitem_list(UiEvent *event, UiActiveMenuItemList *list); + #ifdef __cplusplus } #endif diff -r 7d15cad351fc -r 28a5920bebe0 ui/motif/toolkit.h --- a/ui/motif/toolkit.h Sun Dec 15 22:53:51 2024 +0100 +++ b/ui/motif/toolkit.h Sun Dec 22 11:49:59 2024 +0100 @@ -43,6 +43,7 @@ ui_callback callback; void *userdata; int value; + void *customdata; } UiEventData; typedef struct UiEventDataExt {