add onchange event for toggle buttons (WinUI3) newapi

Sun, 01 Oct 2023 16:39:03 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 01 Oct 2023 16:39:03 +0200
branch
newapi
changeset 189
4daddc326877
parent 188
fbbae6738252
child 190
70fd1b24e395

add onchange event for toggle buttons (WinUI3)

make/vs/testapp/main.c file | annotate | diff | comparison | revisions
ui/ui/button.h file | annotate | diff | comparison | revisions
ui/winui/button.cpp file | annotate | diff | comparison | revisions
ui/winui/toolkit.cpp file | annotate | diff | comparison | revisions
ui/winui/toolkit.h file | annotate | diff | comparison | revisions
--- 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);
--- 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__ } )
--- 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
--- 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 <cx/allocator.h>
 #include <cx/mempool.h>
 
+#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;
--- 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

mercurial