# HG changeset patch # User Olaf Wintermann # Date 1696173737 -7200 # Node ID 6113ed66d2588ee371257421c9f93e098ace46a5 # Parent 70fd1b24e3951603acd154c4dd7d86afcf7c1d36 add toggle switch (WinUI3) diff -r 70fd1b24e395 -r 6113ed66d258 make/vs/testapp/main.c --- a/make/vs/testapp/main.c Sun Oct 01 16:53:02 2023 +0200 +++ b/make/vs/testapp/main.c Sun Oct 01 17:22:17 2023 +0200 @@ -61,6 +61,10 @@ printf("onchange: %d\n", event->intval); } +void action_switch(UiEvent* event, void* data) { + printf("onchange: %d\n", event->intval); +} + void application_startup(UiEvent* event, void* data) { UiObject* obj = ui_window("Test", NULL); WindowData* wdata = ui_malloc(obj->ctx, sizeof(WindowData)); @@ -93,6 +97,7 @@ } ui_newline(obj); ui_radiobutton(obj, .label = "Radio 4", .value = wdata->radio); + ui_switch(obj, .label = "test", .onchange=action_switch); } ui_show(obj); diff -r 70fd1b24e395 -r 6113ed66d258 ui/ui/button.h --- a/ui/ui/button.h Sun Oct 01 16:53:02 2023 +0200 +++ b/ui/ui/button.h Sun Oct 01 17:22:17 2023 +0200 @@ -66,11 +66,13 @@ #define ui_button(obj, ...) ui_button_create(obj, (UiButtonArgs){ __VA_ARGS__ } ) #define ui_togglebutton(obj, ...) ui_togglebutton_create(obj, (UiToggleArgs){ __VA_ARGS__ } ) #define ui_checkbox(obj, ...) ui_checkbox_create(obj, (UiToggleArgs){ __VA_ARGS__ } ) +#define ui_switch(obj, ...) ui_switch_create(obj, (UiToggleArgs){ __VA_ARGS__ } ) #define ui_radiobutton(obj, ...) ui_radiobutton_create(obj, (UiToggleArgs){ __VA_ARGS__ } ) UIWIDGET ui_button_create(UiObject* obj, UiButtonArgs args); UIWIDGET ui_togglebutton_create(UiObject* obj, UiToggleArgs args); UIWIDGET ui_checkbox_create(UiObject* obj, UiToggleArgs args); +UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args); UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args); diff -r 70fd1b24e395 -r 6113ed66d258 ui/winui/button.cpp --- a/ui/winui/button.cpp Sun Oct 01 16:53:02 2023 +0200 +++ b/ui/winui/button.cpp Sun Oct 01 17:22:17 2023 +0200 @@ -124,6 +124,28 @@ } } +// for some stupid reason the ToggleSwitch is not a ToggleButton and we need to write the same +// code again, because although everything is basically the same, it is named differently +static void switch_register_observers(ToggleSwitch button, UiObject* obj, UiVar* var) { + button.Toggled([button, obj, var](IInspectable const& sender, RoutedEventArgs) { + UiInteger* i = (UiInteger*)var->value; + UiEvent evt = ui_create_int_event(obj, i->get(i)); + ui_notify_evt(i->observers, &evt); + }); +} + +static void switch_register_callback(ToggleSwitch button, UiObject* obj, UiToggleArgs& args) { + ui_callback callback = args.onchange; + void* cbdata = args.onchangedata; + if (callback) { + button.Toggled([button, obj, callback, cbdata](IInspectable const& sender, RoutedEventArgs) { + UiEvent evt = ui_create_int_event(obj, button.IsOn()); + callback(&evt, cbdata); + }); + } +} + + static UIWIDGET create_togglebutton(UiObject *obj, ToggleButton button, UiToggleArgs args) { UiObject* current = uic_current_obj(obj); @@ -173,6 +195,48 @@ return create_togglebutton(obj, button, args); } +UIWIDGET ui_switch_create(UiObject* obj, UiToggleArgs args) { + ToggleSwitch button = ToggleSwitch(); + if (args.label) { + wchar_t* wlabel = str2wstr(args.label, nullptr); + button.Header(box_value(wlabel)); + free(wlabel); + } + switch_register_callback(button, obj, args); + + UiObject* current = uic_current_obj(obj); + + // create toolkit wrapper object and register destructor + UIElement elm = button; + UiWidget* widget = new UiWidget(elm); + ui_context_add_widget_destructor(current->ctx, widget); + + // bind variable + UiVar* var = nullptr; + if (args.value) { + var = uic_create_value_var(current->ctx, args.value); + } + else if (args.varname) { + var = uic_create_var(obj->ctx, args.varname, UI_VAR_INTEGER); + } + if (var) { + UiInteger* value = (UiInteger*)var->value; + value->obj = widget; + value->get = ui_toggle_button_get; + value->set = ui_toggle_button_set; + + // listener for notifying observers + switch_register_observers(button, obj, var); + } + + // add button to current container + UI_APPLY_LAYOUT1(current, args); + + current->container->Add(button, false); + + return widget; +} + UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) { RadioButton button = RadioButton(); @@ -248,6 +312,21 @@ integer->value = value; } +extern "C" int64_t ui_switch_get(UiInteger * integer) { + UiWidget* widget = (UiWidget*)integer->obj; + ToggleSwitch toggleButton = widget->uielement.as(); + int val = toggleButton.IsOn(); + integer->value = val; + return val; +} + +extern "C" 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) { CxList* list = (CxList*)integer->obj; CxIterator i = cxListIterator(list); diff -r 70fd1b24e395 -r 6113ed66d258 ui/winui/button.h --- a/ui/winui/button.h Sun Oct 01 16:53:02 2023 +0200 +++ b/ui/winui/button.h Sun Oct 01 17:22:17 2023 +0200 @@ -36,5 +36,8 @@ extern "C" int64_t ui_toggle_button_get(UiInteger * integer); extern "C" void ui_toggle_button_set(UiInteger * integer, int64_t value); +extern "C" int64_t ui_switch_get(UiInteger * integer); +extern "C" void ui_switch_set(UiInteger * integer, int64_t value); + extern "C" int64_t ui_radio_button_get(UiInteger * integer); extern "C" void ui_radio_button_set(UiInteger * integer, int64_t value);