# HG changeset patch # User Olaf Wintermann # Date 1697014464 -7200 # Node ID 7ebc5a747c6fe309280c9f0e10f2a675bb86b84f # Parent b1ac0dd1d38bb4b04b016a187a3a44c438b9bdb3 implement toolbar togglebutton diff -r b1ac0dd1d38b -r 7ebc5a747c6f ui/winui/button.cpp --- a/ui/winui/button.cpp Tue Oct 10 10:58:14 2023 +0200 +++ b/ui/winui/button.cpp Wed Oct 11 10:54:24 2023 +0200 @@ -91,7 +91,7 @@ } -static void togglebutton_register_checked_observers(ToggleButton button, UiObject* obj, UiVar* var) { +void togglebutton_register_checked_observers(ToggleButton button, UiObject* obj, UiVar* var) { button.Checked([button, obj, var](IInspectable const& sender, RoutedEventArgs) { UiInteger* i = (UiInteger*)var->value; UiEvent evt = ui_create_int_event(obj, i->get(i)); @@ -99,7 +99,7 @@ }); } -static void togglebutton_register_unchecked_observers(ToggleButton button, UiObject* obj, UiVar* var) { +void togglebutton_register_unchecked_observers(ToggleButton button, UiObject* obj, UiVar* var) { button.Unchecked([button, obj, var](IInspectable const& sender, RoutedEventArgs) { UiInteger* i = (UiInteger*)var->value; UiEvent evt = ui_create_int_event(obj, i->get(i)); @@ -107,7 +107,7 @@ }); } -static void togglebutton_register_callback(ToggleButton button, UiObject *obj, UiToggleArgs& args) { +void togglebutton_register_callback(ToggleButton button, UiObject *obj, UiToggleArgs& args) { ui_callback callback = args.onchange; void* cbdata = args.onchangedata; if (callback) { @@ -304,7 +304,7 @@ integer->value = value; } -extern "C" int64_t ui_switch_get(UiInteger * integer) { +int64_t ui_switch_get(UiInteger * integer) { UiWidget* widget = (UiWidget*)integer->obj; ToggleSwitch toggleButton = widget->uielement.as(); int val = toggleButton.IsOn(); @@ -312,14 +312,14 @@ return val; } -extern "C" void ui_switch_set(UiInteger * integer, int64_t value) { +void ui_switch_set(UiInteger * integer, int64_t value) { UiWidget* widget = (UiWidget*)integer->obj; ToggleSwitch toggleButton = widget->uielement.as(); toggleButton.IsOn((bool)value); integer->value = value; } -extern "C" int64_t ui_radio_button_get(UiInteger * integer) { +int64_t ui_radio_button_get(UiInteger * integer) { CxList* list = (CxList*)integer->obj; CxIterator i = cxListIterator(list); int selection = -1; @@ -334,7 +334,7 @@ return selection; } -extern "C" void ui_radio_button_set(UiInteger * integer, int64_t value) { +void ui_radio_button_set(UiInteger * integer, int64_t value) { CxList* list = (CxList*)integer->obj; UiWidget* widget = (UiWidget*)cxListAt(list, value); if (widget) { diff -r b1ac0dd1d38b -r 7ebc5a747c6f ui/winui/button.h --- a/ui/winui/button.h Tue Oct 10 10:58:14 2023 +0200 +++ b/ui/winui/button.h Wed Oct 11 10:54:24 2023 +0200 @@ -33,6 +33,13 @@ #include "../ui/button.h" +#include "../common/context.h" + + +void togglebutton_register_checked_observers(winrt::Microsoft::UI::Xaml::Controls::Primitives::ToggleButton button, UiObject* obj, UiVar* var); +void togglebutton_register_unchecked_observers(winrt::Microsoft::UI::Xaml::Controls::Primitives::ToggleButton button, UiObject* obj, UiVar* var); +void togglebutton_register_callback(winrt::Microsoft::UI::Xaml::Controls::Primitives::ToggleButton button, UiObject* obj, UiToggleArgs& args); + extern "C" int64_t ui_toggle_button_get(UiInteger * integer); extern "C" void ui_toggle_button_set(UiInteger * integer, int64_t value); diff -r b1ac0dd1d38b -r 7ebc5a747c6f ui/winui/commandbar.cpp --- a/ui/winui/commandbar.cpp Tue Oct 10 10:58:14 2023 +0200 +++ b/ui/winui/commandbar.cpp Wed Oct 11 10:54:24 2023 +0200 @@ -31,6 +31,10 @@ #include "commandbar.h" #include "util.h" +#include "../common/object.h" +#include "../common/context.h" + +#include "button.h" using namespace winrt; using namespace Microsoft::UI::Xaml; @@ -39,40 +43,42 @@ using namespace Microsoft::UI::Xaml::Markup; using namespace Windows::UI::Xaml::Interop; -static void create_item(CommandBar cb, UiToolbarItemI* i); -static void create_cmditem(CommandBar cb, UiToolbarItem* item); -static void create_toggleitem(CommandBar cb, UiToolbarToggleItem* item); +static void create_item(UiObject* obj, CommandBar cb, UiToolbarItemI* i); +static void create_cmditem(UiObject* obj, CommandBar cb, UiToolbarItem* item); +static void create_toggleitem(UiObject* obj, CommandBar cb, UiToolbarToggleItem* item); -CommandBar ui_create_toolbar() { +CommandBar ui_create_toolbar(UiObject *obj) { + + CommandBar cb = CommandBar(); + cb.DefaultLabelPosition(CommandBarDefaultLabelPosition::Right); + + // add pre-configured items CxList* defaults = uic_get_toolbar_defaults(); - CommandBar cb = CommandBar(); CxIterator i = cxListIterator(defaults); cx_foreach(char*, def, i) { UiToolbarItemI* item = uic_toolbar_get_item(def); if (!item) { - exit(-1); // TODO: maybe a error dialog? + exit(-1); // TODO: maybe an error dialog? } - - create_item(cb, item); + create_item(obj, cb, item); } - return cb; } -static void create_item(CommandBar cb, UiToolbarItemI* i) { +static void create_item(UiObject* obj, CommandBar cb, UiToolbarItemI* i) { switch (i->type) { case UI_TOOLBAR_ITEM: { - create_cmditem(cb, (UiToolbarItem*)i); + create_cmditem(obj, cb, (UiToolbarItem*)i); break; } case UI_TOOLBAR_TOGGLEITEM: { - create_toggleitem(cb, (UiToolbarToggleItem*)i); + create_toggleitem(obj, cb, (UiToolbarToggleItem*)i); break; } } } -static void create_cmditem(CommandBar cb, UiToolbarItem* item) { +static void create_cmditem(UiObject* obj, CommandBar cb, UiToolbarItem* item) { AppBarButton button = AppBarButton(); if (item->args.label) { wchar_t* wlabel = str2wstr(item->args.label, nullptr); @@ -80,9 +86,59 @@ free(wlabel); } + // register callback + if (item->args.onclick) { + ui_callback cbfunc = item->args.onclick; + void* cbdata = item->args.onclickdata; + button.Click([cbfunc, cbdata, obj](Windows::Foundation::IInspectable const& sender, RoutedEventArgs) { + UiEvent evt; + evt.obj = obj; + evt.window = obj->window; + evt.document = obj->ctx->document; + evt.eventdata = nullptr; + evt.intval = 0; + cbfunc(&evt, cbdata); + }); + } + cb.PrimaryCommands().Append(button); } -static void create_toggleitem(CommandBar cb, UiToolbarToggleItem* item) { + + +static void create_toggleitem(UiObject *obj, CommandBar cb, UiToolbarToggleItem* item) { + AppBarToggleButton button = AppBarToggleButton(); + if (item->args.label) { + wchar_t* wlabel = str2wstr(item->args.label, nullptr); + button.Content(box_value(wlabel)); + free(wlabel); + } + + UiVar* var = uic_widget_var(obj->ctx, obj->ctx, nullptr, item->args.varname, UI_VAR_INTEGER); + if (var) { + UIElement elm = button; + UiWidget* widget = new UiWidget(elm); + ui_context_add_widget_destructor(obj->ctx, widget); + UiInteger* value = (UiInteger*)var->value; + int64_t i = value->value; + value->get = ui_toggle_button_get; + value->set = ui_toggle_button_set; + value->obj = widget; + ui_toggle_button_set(value, i); // init togglebutton state + + // listener for notifying observers + togglebutton_register_checked_observers(button, obj, var); + togglebutton_register_unchecked_observers(button, obj, var); + } + + UiToggleArgs args = {}; + args.onchange = item->args.onchange; + args.onchangedata = item->args.onchangedata; + togglebutton_register_callback(button, obj, args); + + + cb.PrimaryCommands().Append(button); } + + diff -r b1ac0dd1d38b -r 7ebc5a747c6f ui/winui/commandbar.h --- a/ui/winui/commandbar.h Tue Oct 10 10:58:14 2023 +0200 +++ b/ui/winui/commandbar.h Wed Oct 11 10:54:24 2023 +0200 @@ -41,5 +41,7 @@ #include #include -winrt::Microsoft::UI::Xaml::Controls::CommandBar ui_create_toolbar(); +winrt::Microsoft::UI::Xaml::Controls::CommandBar ui_create_toolbar(UiObject *obj); +extern "C" int64_t ui_appbar_togglebutton_get(UiInteger * integer); +extern "C" void ui_appbar_togglebutton_set(UiInteger * integer, int64_t value); \ No newline at end of file diff -r b1ac0dd1d38b -r 7ebc5a747c6f ui/winui/window.cpp --- a/ui/winui/window.cpp Tue Oct 10 10:58:14 2023 +0200 +++ b/ui/winui/window.cpp Wed Oct 11 10:54:24 2023 +0200 @@ -93,10 +93,16 @@ } if (uic_toolbar_isenabled()) { - // create/add toolbar - CommandBar toolbar = ui_create_toolbar(); - toolbar.VerticalAlignment(VerticalAlignment::Top); - obj->container->Add(toolbar, false); + // create commandbar + CommandBar toolbar = ui_create_toolbar(obj); + // wrap the commandbar in a stackpanel, because we + // don't want to fill the horizontal space + StackPanel toolbar_panel = StackPanel(); + toolbar_panel.Orientation(Orientation::Horizontal); + toolbar_panel.Children().Append(toolbar); + + toolbar_panel.VerticalAlignment(VerticalAlignment::Top); + obj->container->Add(toolbar_panel, false); } obj->window = window_data; diff -r b1ac0dd1d38b -r 7ebc5a747c6f ui/winui/winui.vcxproj.filters --- a/ui/winui/winui.vcxproj.filters Tue Oct 10 10:58:14 2023 +0200 +++ b/ui/winui/winui.vcxproj.filters Wed Oct 11 10:54:24 2023 +0200 @@ -13,9 +13,29 @@ + + + + + + + + + + + + + + + + + + + + @@ -52,9 +72,9 @@ - + - + \ No newline at end of file