diff -r fbdfaacc4182 -r f154867f54dc ui/winui/appmenu.cpp --- a/ui/winui/appmenu.cpp Sat Jan 27 17:50:19 2024 +0100 +++ b/ui/winui/appmenu.cpp Sun Jan 28 16:31:34 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();