# HG changeset patch # User Olaf Wintermann # Date 1696164043 -7200 # Node ID fbbae673825266211d385edf5ae930adb33f273a # Parent 24ce2c326d851264a4aaf67ffcff1bbf14ff3833 implement radio button (WinUI3) diff -r 24ce2c326d85 -r fbbae6738252 make/vs/testapp/main.c --- 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); diff -r 24ce2c326d85 -r fbbae6738252 ui/ui/button.h --- 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 diff -r 24ce2c326d85 -r fbbae6738252 ui/winui/button.cpp --- 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(); + 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(); + 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(); + button.IsChecked(true); + integer->value = value; + } +} diff -r 24ce2c326d85 -r fbbae6738252 ui/winui/button.h --- 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); diff -r 24ce2c326d85 -r fbbae6738252 ui/winui/container.cpp --- 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);