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; }