add toggle switch (WinUI3) newapi

Sun, 01 Oct 2023 17:22:17 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 01 Oct 2023 17:22:17 +0200
branch
newapi
changeset 191
6113ed66d258
parent 190
70fd1b24e395
child 192
bcacd00ea955

add toggle switch (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/button.h file | annotate | diff | comparison | revisions
--- 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);
--- 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);
 
 
--- 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<ToggleSwitch>();
+	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<ToggleSwitch>();
+	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);
--- 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);

mercurial