# HG changeset patch # User Olaf Wintermann # Date 1706285834 -3600 # Node ID a952760955b420fb1be1846a6b50e5787952ed2b # Parent b4d7686b30dc5625866213901eebf5b71c97699a add menu item list (WinUI3) diff -r b4d7686b30dc -r a952760955b4 make/vs/testapp/main.c --- a/make/vs/testapp/main.c Fri Jan 26 15:31:47 2024 +0100 +++ b/make/vs/testapp/main.c Fri Jan 26 17:17:14 2024 +0100 @@ -53,6 +53,9 @@ static UiIcon* folder_icon; +UiList* menuList; + + void action1(UiEvent* event, void* data) { char* action = data; @@ -67,6 +70,10 @@ int spinner_active = wdata->spinner->get(wdata->spinner); wdata->spinner->set(wdata->spinner, !spinner_active); + + ui_list_append(menuList, "List Item X"); + ui_list_append(menuList, "List Item X"); + ui_notify(menuList->observers, NULL); } void action_set_checkbox(UiEvent* event, void* data) { @@ -162,7 +169,17 @@ } + void application_startup(UiEvent* event, void* data) { + UiContext* gctx = ui_global_context(); + menuList = ui_list_new(gctx, "menulist"); + ui_list_append(menuList, "List Item 1"); + ui_list_append(menuList, "List Item 2"); + ui_list_append(menuList, "List Item 3"); + ui_list_append(menuList, "List Item 4"); + ui_list_append(menuList, "List Item 5"); + ui_list_append(menuList, "List Item 6"); + UiObject* obj = ui_window("Test", NULL); WindowData* wdata = ui_malloc(obj->ctx, sizeof(WindowData)); obj->window = wdata; @@ -351,6 +368,7 @@ ui_menuitem(.label = "x", NULL, NULL); ui_menuitem(.label = "x", NULL, NULL); + ui_menu_itemlist(.varname = "menulist"); ui_menuitem(.label = "x", NULL, NULL); ui_menuitem(.label = "x", NULL, NULL); ui_menuitem(.label = "x", NULL, NULL); diff -r b4d7686b30dc -r a952760955b4 ui/common/menu.c --- a/ui/common/menu.c Fri Jan 26 15:31:47 2024 +0100 +++ b/ui/common/menu.c Fri Jan 26 17:17:14 2024 +0100 @@ -211,7 +211,7 @@ UiMenuItemList* item = malloc(sizeof(UiMenuItemList)); item->item.prev = NULL; item->item.next = NULL; - item->item.type = UI_MENU_ITEM_LIST; + item->item.type = UI_MENU_CHECKITEM_LIST; item->callback = args.onselect; item->userdata = args.onselectdata; item->varname = nl_strdup(args.varname); @@ -227,7 +227,7 @@ UiMenuItemList* item = malloc(sizeof(UiMenuItemList)); item->item.prev = NULL; item->item.next = NULL; - item->item.type = UI_MENU_ITEM_LIST; + item->item.type = UI_MENU_RADIOITEM_LIST; item->callback = args.onselect; item->userdata = args.onselectdata; item->varname = nl_strdup(args.varname); diff -r b4d7686b30dc -r a952760955b4 ui/common/menu.h --- a/ui/common/menu.h Fri Jan 26 15:31:47 2024 +0100 +++ b/ui/common/menu.h Fri Jan 26 17:17:14 2024 +0100 @@ -110,7 +110,7 @@ UiMenuItemI item; ui_callback callback; void *userdata; - const char* varname; + const char *varname; }; diff -r b4d7686b30dc -r a952760955b4 ui/ui/menu.h --- a/ui/ui/menu.h Fri Jan 26 15:31:47 2024 +0100 +++ b/ui/ui/menu.h Fri Jan 26 17:17:14 2024 +0100 @@ -70,6 +70,9 @@ #define ui_menuitem(...) ui_menuitem_create((UiMenuItemArgs){ __VA_ARGS__ }) #define ui_menu_toggleitem(...) ui_menu_toggleitem_create((UiMenuToggleItemArgs){ __VA_ARGS__ }) #define ui_menu_radioitem(...) ui_menu_radioitem_create((UiMenuToggleItemArgs){ __VA_ARGS__ }) +#define ui_menu_itemlist(...) ui_menu_itemlist_create((UiMenuItemListArgs) { __VA_ARGS__ } ) +#define ui_menu_togglelist(...) ui_menu_itemlist_create((UiMenuItemListArgs) { __VA_ARGS} ) +#define ui_menu_radiolist(...) ui_menu_itemlist_create((UiMenuItemListArgs) { __VA_ARGS} ) UIEXPORT void ui_menu_create(const char* label); UIEXPORT void ui_menuitem_create(UiMenuItemArgs args); @@ -97,7 +100,7 @@ UIEXPORT void ui_menuitem_list_deprecated(UiList *items, ui_callback f, void *userdata); -UIEXPORT void ui_menu_end(void); +UIEXPORT void ui_menu_end(void); // TODO: private /* * widget menu functions diff -r b4d7686b30dc -r a952760955b4 ui/winui/appmenu.cpp --- a/ui/winui/appmenu.cpp Fri Jan 26 15:31:47 2024 +0100 +++ b/ui/winui/appmenu.cpp Fri Jan 26 17:17:14 2024 +0100 @@ -33,6 +33,9 @@ #include #include +#include "../common/context.h" +#include "../common/object.h" + #include "util.h" @@ -51,17 +54,15 @@ static void add_checkitem_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj); static void add_radioitem_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj); static void add_menuitem_list_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj); -static void add_menucheckitem_list_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj); -static void add_menuradioitem_list_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj); static ui_menu_add_f createMenuItem[] = { /* UI_MENU */ add_menu_widget, /* UI_MENU_ITEM */ add_menuitem_widget, /* UI_MENU_CHECK_ITEM */ add_checkitem_widget, - /* UI_MENU_RADIO_ITEM */ NULL, // TODO + /* UI_MENU_RADIO_ITEM */ add_radioitem_widget, /* UI_MENU_ITEM_LIST */ add_menuitem_list_widget, - /* UI_MENU_CHECKITEM_LIST */ NULL, // TODO - /* UI_MENU_RADIOITEM_LIST */ NULL, // TODO + /* UI_MENU_CHECKITEM_LIST */ add_menuitem_list_widget, + /* UI_MENU_RADIOITEM_LIST */ add_menuitem_list_widget, /* UI_MENU_SEPARATOR */ add_menuseparator_widget }; @@ -134,28 +135,124 @@ parent.Append(mi); } -static void add_menuitem_st_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj) { +static void add_menuseparator_widget( + winrt::Windows::Foundation::Collections::IVector parent, + int i, + UiMenuItemI* item, + UiObject* obj) +{ } -static void add_menuseparator_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj) { +static void add_checkitem_widget( + winrt::Windows::Foundation::Collections::IVector parent, + int i, + UiMenuItemI* item, + UiObject* obj) +{ + +} + +static void add_radioitem_widget( + winrt::Windows::Foundation::Collections::IVector parent, + int i, + UiMenuItemI* item, + UiObject* obj) +{ } -static void add_checkitem_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj) { + +class UiMenuList { +public: + winrt::Windows::Foundation::Collections::IVector parent = { nullptr }; + UiMenuItemType type; + int prevSize = 0; + int insertPos = 0; + UiVar* var = nullptr; + ui_callback callback = nullptr; + void* userdata = nullptr; + + UiMenuList() { + + } + + void updateItems() { + UiList* list = (UiList*)var->value; + // delete previous items + for (int i = 0; i < prevSize; i++) { + parent.RemoveAt(insertPos); + } + + // insert new items + int count = 0; + void* elm = list->first(list); + while (elm) { + + MenuFlyoutItem mi = MenuFlyoutItem(); + wchar_t* wlabel = str2wstr((char*)elm, NULL); + mi.Text(wlabel); + free(wlabel); + + parent.InsertAt(insertPos + count, mi); + + elm = list->next(list); + count++; + } + + prevSize = count; + } +}; + +extern "C" void destroy_ui_menu_list(void* ptr) { + UiMenuList* ls = (UiMenuList*)ptr; + delete ls; } -static void add_checkitemnv_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj) { +static void ui_context_add_menu_list_destructor(UiContext* ctx, UiMenuList* list) { + cxMempoolRegister(ctx->mp, list, destroy_ui_menu_list); +} +static void ui_menulist_update(UiEvent* event, void* userdata) { + UiMenuList* mlist = (UiMenuList*)userdata; + mlist->updateItems(); } -static void add_menuitem_list_widget(winrt::Windows::Foundation::Collections::IVector parent, int i, UiMenuItemI* item, UiObject* obj) { +static void add_menuitem_list_widget( + winrt::Windows::Foundation::Collections::IVector parent, + int i, + UiMenuItemI* item, + UiObject* obj) +{ + UiMenuItemList* it = (UiMenuItemList*)item; + if (!it->varname) { + return; + } + + uint32_t size = parent.Size(); + + UiVar* var = uic_create_var(ui_global_context(), it->varname, UI_VAR_LIST); + UiMenuList* mlist = new UiMenuList(); + mlist->parent = parent; + mlist->callback = it->callback; + mlist->userdata = it->userdata; + mlist->prevSize = 0; + mlist->insertPos = size; + mlist->type = item->type; + mlist->var = var; + ui_context_add_menu_list_destructor(obj->ctx, mlist); + + UiList* list = (UiList*)var->value; + list->observers = ui_add_observer(list->observers, ui_menulist_update, mlist); + + mlist->updateItems(); } + winrt::Microsoft::UI::Xaml::Controls::MenuFlyout ui_create_menu_flyout(UiObject* obj, UiMenu* menudef) { MenuFlyout flyout = MenuFlyout(); diff -r b4d7686b30dc -r a952760955b4 ui/winui/toolkit.cpp --- a/ui/winui/toolkit.cpp Fri Jan 26 15:31:47 2024 +0100 +++ b/ui/winui/toolkit.cpp Fri Jan 26 17:17:14 2024 +0100 @@ -157,6 +157,7 @@ //ui_appsdk_bootstrap(); + uic_init_global_context(); uic_toolbar_init(); }