Wed, 31 Dec 2025 10:34:29 +0100
implement check menu item (Win32)
| application/main.c | file | annotate | diff | comparison | revisions | |
| ui/win32/menu.c | file | annotate | diff | comparison | revisions | |
| ui/win32/menu.h | file | annotate | diff | comparison | revisions | |
| ui/win32/toolkit.c | file | annotate | diff | comparison | revisions | |
| ui/win32/toolkit.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Wed Dec 31 10:06:15 2025 +0100 +++ b/application/main.c Wed Dec 31 10:34:29 2025 +0100 @@ -1287,6 +1287,7 @@ ui_menu("File") { ui_menuitem("Open"); + ui_menu_toggleitem("Test"); ui_menuitem("Close"); }
--- a/ui/win32/menu.c Wed Dec 31 10:06:15 2025 +0100 +++ b/ui/win32/menu.c Wed Dec 31 10:34:29 2025 +0100 @@ -66,7 +66,7 @@ } } -static void menu_item_clicked(UiObject *obj, UiMenuItem *item) { +static void menu_item_clicked(UiObject *obj, uint64_t id, UiMenuItem *item) { UiEvent event; event.obj = obj; event.window = obj->window; @@ -92,8 +92,76 @@ cxMapPut(obj->ctx->command_map, id, &cmd); } +static void menu_stateitem_update(UiStateMenuItem *item) { + MENUITEMINFO mi = { 0 }; + mi.cbSize = sizeof(mi); + mi.fMask = MIIM_STATE; + mi.fState = item->state ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(item->menu, item->id, FALSE, &mi); +} + +static void menu_checkitem_clicked(UiObject *obj, uint64_t id, UiStateMenuItem *item) { + item->state = !item->state; + menu_stateitem_update(item); + + UiEvent event; + event.obj = obj; + event.window = obj->window; + event.document = obj->ctx->document; + event.eventdata = NULL; + event.eventdatatype = 0; + event.intval = 0; + event.set = 0; + if (item->onchange) { + item->onchange(&event, item->userdata); + } + + if (item->var) { + UiInteger *i = item->var->value; + ui_notify_evt(i->observers, &event); + } +} + void ui_add_menu_checkitem(HMENU parent, int pos, UiMenuItemI *item, UiObject *obj) { + uint64_t id = ++obj->ctx->command_id_counter; + UiMenuCheckItem *i = (UiMenuCheckItem*)item; + AppendMenu(parent, MF_STRING, id, i->label); + + // create an UiStateMenuItem with the same lifetime as the UiObject + UiStateMenuItem *sitem = ui_malloc(obj->ctx, sizeof(UiStateMenuItem)); + memset(sitem, 0, sizeof(UiStateMenuItem)); + sitem->obj = obj; + sitem->menu = parent; + sitem->id = id; + sitem->onchange = i->callback; + sitem->userdata = i->userdata; + sitem->var = uic_widget_var(obj->ctx, obj->ctx, NULL, i->varname, UI_VAR_INTEGER); + // bind to var + if (sitem->var) { + UiInteger *v = sitem->var->value; + sitem->state = v->value != 0; + v->obj = sitem; + v->get = ui_checkitem_get; + v->set = ui_checkitem_set; + } + + // register command id + UiCommand cmd; + cmd.callback = (ui_command_func)menu_checkitem_clicked; + cmd.userdata = sitem; + cxMapPut(obj->ctx->command_map, id, &cmd); + + menu_stateitem_update(sitem); +} + +int64_t ui_checkitem_get(UiInteger *i) { + return i->value; +} + +void ui_checkitem_set(UiInteger *i, int64_t value) { + i->value = value; + menu_stateitem_update(i->obj); } void ui_add_menu_radioitem(HMENU parent, int pos, UiMenuItemI *item, UiObject *obj) {
--- a/ui/win32/menu.h Wed Dec 31 10:06:15 2025 +0100 +++ b/ui/win32/menu.h Wed Dec 31 10:34:29 2025 +0100 @@ -37,6 +37,16 @@ extern "C" { #endif +typedef struct UiStateMenuItem { + UiObject *obj; + HMENU menu; + uint64_t id; + UiVar *var; + ui_callback onchange; + void *userdata; + UiBool state; +} UiStateMenuItem; + typedef void(*ui_menu_add_f)(HMENU, int, UiMenuItemI*, UiObject*); HMENU ui_create_main_menu(UiObject *obj); @@ -50,6 +60,9 @@ void ui_add_menu_radiolist(HMENU parent, int pos, UiMenuItemI *item, UiObject *obj); void ui_add_menu_separator(HMENU parent, int pos, UiMenuItemI *item, UiObject *obj); +int64_t ui_checkitem_get(UiInteger *i); +void ui_checkitem_set(UiInteger *i, int64_t value); + #ifdef __cplusplus } #endif
--- a/ui/win32/toolkit.c Wed Dec 31 10:06:15 2025 +0100 +++ b/ui/win32/toolkit.c Wed Dec 31 10:34:29 2025 +0100 @@ -122,7 +122,7 @@ uint64_t id = LOWORD(wParam); UiCommand *cmd = cxMapGet(win->obj->ctx->command_map, id); if (cmd) { - cmd->callback(win->obj, cmd->userdata); + cmd->callback(win->obj, id, cmd->userdata); break; } }
--- a/ui/win32/toolkit.h Wed Dec 31 10:06:15 2025 +0100 +++ b/ui/win32/toolkit.h Wed Dec 31 10:34:29 2025 +0100 @@ -55,7 +55,7 @@ LRESULT CALLBACK ui_default_eventproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); -typedef void(*ui_command_func)(UiObject *, void *userdata); +typedef void(*ui_command_func)(UiObject *, uint64_t id, void *userdata); typedef struct UiCommand { ui_command_func callback; void *userdata;