# HG changeset patch # User Olaf Wintermann # Date 1696171143 -7200 # Node ID 4daddc326877fbcf2486082a3315ffd3a6b4a075 # Parent fbbae673825266211d385edf5ae930adb33f273a add onchange event for toggle buttons (WinUI3) diff -r fbbae6738252 -r 4daddc326877 make/vs/testapp/main.c --- a/make/vs/testapp/main.c Sun Oct 01 14:40:43 2023 +0200 +++ b/make/vs/testapp/main.c Sun Oct 01 16:39:03 2023 +0200 @@ -57,6 +57,10 @@ wdata->check->set(wdata->check, 1); } +void action_onchange(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)); @@ -78,17 +82,18 @@ ui_button(obj, .label="Very Long Button Label Text ____________ Test", .onclick=action_set_checkbox); ui_newline(obj); - ui_checkbox(obj, .label = "Option 1", .value = wdata->check); + ui_checkbox(obj, .label = "Option 1", .value = wdata->check, .onchange=action_onchange); ui_togglebutton(obj, .label = "Option 2", .value = wdata->toggle); ui_newline(obj); ui_layout_colspan(obj, 3); - ui_layout_fill(obj, FALSE); UI_HBOX(obj) { ui_radiobutton(obj, .label = "Radio 1", .value = wdata->radio); ui_radiobutton(obj, .label = "Radio 2", .value = wdata->radio); ui_radiobutton(obj, .label = "Radio 3", .value = wdata->radio); } + ui_newline(obj); + ui_radiobutton(obj, .label = "Radio 4", .value = wdata->radio); } ui_show(obj); diff -r fbbae6738252 -r 4daddc326877 ui/ui/button.h --- a/ui/ui/button.h Sun Oct 01 14:40:43 2023 +0200 +++ b/ui/ui/button.h Sun Oct 01 16:39:03 2023 +0200 @@ -59,6 +59,8 @@ const char* stockid; UiInteger* value; const char* varname; + ui_callback onchange; + void* onchangedata; } UiToggleArgs; #define ui_button(obj, ...) ui_button_create(obj, (UiButtonArgs){ __VA_ARGS__ } ) diff -r fbbae6738252 -r 4daddc326877 ui/winui/button.cpp --- a/ui/winui/button.cpp Sun Oct 01 14:40:43 2023 +0200 +++ b/ui/winui/button.cpp Sun Oct 01 16:39:03 2023 +0200 @@ -92,11 +92,44 @@ return widget; } + +static 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)); + ui_notify_evt(i->observers, &evt); + }); +} + +static 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)); + ui_notify_evt(i->observers, &evt); + }); +} + +static void togglebutton_register_callback(ToggleButton button, UiObject *obj, UiToggleArgs& args) { + ui_callback callback = args.onchange; + void* cbdata = args.onchangedata; + if (callback) { + button.Checked([button, obj, callback, cbdata](IInspectable const& sender, RoutedEventArgs) { + UiEvent evt = ui_create_int_event(obj, true); + callback(&evt, cbdata); + }); + button.Unchecked([button, obj, callback, cbdata](IInspectable const& sender, RoutedEventArgs) { + UiEvent evt = ui_create_int_event(obj, false); + callback(&evt, cbdata); + }); + } +} + static UIWIDGET create_togglebutton(UiObject *obj, ToggleButton button, UiToggleArgs args) { UiObject* current = uic_current_obj(obj); // set label set_button_label(button, args.label, args.stockid); + togglebutton_register_callback(button, obj, args); // create toolkit wrapper object and register destructor UIElement elm = button; @@ -116,6 +149,10 @@ value->obj = widget; value->get = ui_toggle_button_get; value->set = ui_toggle_button_set; + + // listener for notifying observers + togglebutton_register_checked_observers(button, obj, var); + togglebutton_register_unchecked_observers(button, obj, var); } // add button to current container @@ -143,6 +180,7 @@ // set label set_button_label(button, args.label, args.stockid); + togglebutton_register_callback(button, obj, args); // create toolkit wrapper object and register destructor UIElement elm = button; @@ -181,6 +219,9 @@ value->obj = radioButtons; value->get = ui_radio_button_get; value->set = ui_radio_button_set; + + // listener for notifying observers (only checked, not unchecked) + togglebutton_register_checked_observers(button, obj, var); } // add button to current container diff -r fbbae6738252 -r 4daddc326877 ui/winui/toolkit.cpp --- a/ui/winui/toolkit.cpp Sun Oct 01 14:40:43 2023 +0200 +++ b/ui/winui/toolkit.cpp Sun Oct 01 16:39:03 2023 +0200 @@ -40,6 +40,8 @@ #include #include +#include "../common/context.h" + using namespace winrt; using namespace Microsoft::UI::Xaml; @@ -110,6 +112,17 @@ } +UiEvent ui_create_int_event(UiObject* obj, int64_t i) { + UiEvent evt; + evt.obj = obj; + evt.window = obj->window; + evt.document = obj->ctx->document; + evt.eventdata = nullptr; + evt.intval = i; + return evt; +} + + void ui_init(const char* appname, int argc, char** argv) { application_name = appname; diff -r fbbae6738252 -r 4daddc326877 ui/winui/toolkit.h --- a/ui/winui/toolkit.h Sun Oct 01 14:40:43 2023 +0200 +++ b/ui/winui/toolkit.h Sun Oct 01 16:39:03 2023 +0200 @@ -38,3 +38,5 @@ void ui_context_add_window_destructor(UiContext* ctx, UiWindow *win); void ui_context_add_widget_destructor(UiContext* ctx, UiWidget* widget); + +UiEvent ui_create_int_event(UiObject* obj, int64_t i); \ No newline at end of file