implement radio button (WinUI3) newapi

Sun, 01 Oct 2023 14:40:43 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sun, 01 Oct 2023 14:40:43 +0200
branch
newapi
changeset 188
fbbae6738252
parent 187
24ce2c326d85
child 189
4daddc326877

implement radio button (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
ui/winui/container.cpp file | annotate | diff | comparison | revisions
--- a/make/vs/testapp/main.c	Sun Oct 01 12:08:09 2023 +0200
+++ b/make/vs/testapp/main.c	Sun Oct 01 14:40:43 2023 +0200
@@ -37,6 +37,7 @@
 typedef struct WindowData {
     UiInteger* check;
     UiInteger* toggle;
+    UiInteger* radio;
 } WindowData;
 
 void action1(UiEvent* event, void* data) {
@@ -44,6 +45,7 @@
     
     WindowData* wdata = event->window;
     int64_t is_checked = wdata->check->get(wdata->check);
+    int64_t radio = wdata->radio->get(wdata->radio);
 
     printf("data: %s %d\n", data, is_checked);
 }
@@ -61,6 +63,7 @@
     obj->window = wdata;
     wdata->check = ui_int_new(obj->ctx, "check");
     wdata->toggle = ui_int_new(obj->ctx, "toggle");
+    wdata->radio = ui_int_new(obj->ctx, "radio");
 
     UI_GRID_SP(obj, 10, 5, 20) {
         ui_button(obj, .label="Button1", .onclick=action1, .onclickdata="action1");
@@ -77,6 +80,15 @@
 
         ui_checkbox(obj, .label = "Option 1", .value = wdata->check);
         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_show(obj);
--- a/ui/ui/button.h	Sun Oct 01 12:08:09 2023 +0200
+++ b/ui/ui/button.h	Sun Oct 01 14:40:43 2023 +0200
@@ -64,20 +64,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_radiobutton(obj, ...) ui_checkbox_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_radiobutton_create(UiObject* obj, UiToggleArgs);
-
-UIWIDGET deprecated_ui_button(UiObject *obj, char *label, ui_callback f, void *data);
+UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args);
 
-UIWIDGET deprecated_ui_checkbox(UiObject *obj, char *label, UiInteger *value);
-UIWIDGET deprecated_ui_checkbox_nv(UiObject *obj, char *label, char *varname);
-
-UIWIDGET deprecated_ui_radiobutton(UiObject *obj, char *label, UiInteger *rgroup);
-UIWIDGET deprecated_ui_radiobutton_nv(UiObject *obj, char *label, char *varname);
 
 
 #ifdef	__cplusplus
--- a/ui/winui/button.cpp	Sun Oct 01 12:08:09 2023 +0200
+++ b/ui/winui/button.cpp	Sun Oct 01 14:40:43 2023 +0200
@@ -136,8 +136,59 @@
 	return create_togglebutton(obj, button, args);
 }
 
-UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs) {
-	return nullptr;
+UIWIDGET ui_radiobutton_create(UiObject* obj, UiToggleArgs args) {
+	RadioButton button = RadioButton();
+
+	UiObject* current = uic_current_obj(obj);
+
+	// set label
+	set_button_label(button, args.label, args.stockid);
+
+	// create toolkit wrapper object and register destructor
+	UIElement elm = button;
+	UiWidget* widget = new UiWidget(elm);
+	ui_context_add_widget_destructor(current->ctx, widget);
+
+	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);
+	}
+
+	// bind radio button to the value
+	if (var) {
+		UiInteger* value = (UiInteger*)var->value;
+
+		// store a list of radio buttons in the value
+		CxList* radioButtons = (CxList*) (value->obj ? value->obj : cxLinkedListCreate(current->ctx->allocator, NULL, CX_STORE_POINTERS));
+		// get or create the group name
+		static int groupCount = 0;
+		winrt::hstring groupName;
+		if (radioButtons->size == 0) {
+			groupName = winrt::to_hstring(groupCount++);
+		} else {
+			UiWidget* firstButtonWidget = (UiWidget*)cxListAt(radioButtons, 0);
+			RadioButton firstRadioButton = firstButtonWidget->uielement.as<RadioButton>();
+			groupName = firstRadioButton.GroupName();
+		}
+
+		// set the group name for the new radiobutton
+		cxListAdd(radioButtons, widget);
+		button.GroupName(groupName);
+
+		value->obj = radioButtons;
+		value->get = ui_radio_button_get;
+		value->set = ui_radio_button_set;
+	}
+
+	// add button to current container
+	UI_APPLY_LAYOUT1(current, args);
+
+	current->container->Add(button, false);
+
+	return widget;
 }
 
 
@@ -155,3 +206,28 @@
 	toggleButton.IsChecked((bool)value);
 	integer->value = value;
 }
+
+extern "C" int64_t ui_radio_button_get(UiInteger * integer) {
+	CxList* list = (CxList*)integer->obj;
+	CxIterator i = cxListIterator(list);
+	int selection = -1;
+	cx_foreach(UiWidget*, widget, i) {
+		ToggleButton button = widget->uielement.as<ToggleButton>();
+		if (button.IsChecked().GetBoolean()) {
+			selection = i.index;
+			break;
+		}
+	}
+	integer->value = selection;
+	return selection;
+}
+
+extern "C" void ui_radio_button_set(UiInteger * integer, int64_t value) {
+	CxList* list = (CxList*)integer->obj;
+	UiWidget* widget = (UiWidget*)cxListAt(list, value);
+	if (widget) {
+		ToggleButton button = widget->uielement.as<ToggleButton>();
+		button.IsChecked(true);
+		integer->value = value;
+	}
+}
--- a/ui/winui/button.h	Sun Oct 01 12:08:09 2023 +0200
+++ b/ui/winui/button.h	Sun Oct 01 14:40:43 2023 +0200
@@ -34,5 +34,7 @@
 #include "../ui/button.h"
 
 extern "C" int64_t ui_toggle_button_get(UiInteger * integer);
+extern "C" void ui_toggle_button_set(UiInteger * integer, int64_t value);
 
-extern "C" void ui_toggle_button_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);
--- a/ui/winui/container.cpp	Sun Oct 01 12:08:09 2023 +0200
+++ b/ui/winui/container.cpp	Sun Oct 01 14:40:43 2023 +0200
@@ -49,6 +49,30 @@
 
 // --------------------- UiBoxContainer ---------------------
 
+static UIWIDGET ui_box(UiObject* obj, UiBoxContainerType type) {
+	UiContainer* ct = uic_get_current_container(obj);
+
+	Grid grid = Grid();
+	ct->Add(grid, true);
+
+	UIElement elm = grid;
+	UiWidget* widget = new UiWidget(elm);
+
+	UiObject* newobj = uic_object_new(obj, widget);
+	newobj->container = new UiBoxContainer(grid, type);
+	uic_obj_add(obj, newobj);
+
+	return widget;
+}
+
+UIWIDGET ui_vbox(UiObject* obj) {
+	return ui_box(obj, UI_CONTAINER_VBOX);
+}
+
+UIWIDGET ui_hbox(UiObject* obj) {
+	return ui_box(obj, UI_CONTAINER_HBOX);
+}
+
 UiBoxContainer::UiBoxContainer(Grid grid, enum UiBoxContainerType type) {
 	this->grid = grid;
 	this->type = type;
@@ -109,7 +133,8 @@
 	ui_reset_layout(layout);
 }
 
-// --------------------- UiBoxContainer ---------------------
+
+// --------------------- UiGridContainer ---------------------
 
 UIWIDGET ui_grid(UiObject* obj) {
 	return ui_grid_sp(obj, 0, 0, 0);

mercurial