Wed, 31 Dec 2025 12:37:09 +0100
implement menu radio items (GTK3)
| application/main.c | file | annotate | diff | comparison | revisions | |
| ui/gtk/menu.c | file | annotate | diff | comparison | revisions | |
| ui/gtk/menu.h | file | annotate | diff | comparison | revisions | |
| ui/gtk/toolkit.c | file | annotate | diff | comparison | revisions | |
| ui/gtk/toolkit.h | file | annotate | diff | comparison | revisions |
--- a/application/main.c Wed Dec 31 11:36:42 2025 +0100 +++ b/application/main.c Wed Dec 31 12:37:09 2025 +0100 @@ -627,6 +627,8 @@ } UiInteger *i = event->eventdata; printf("action_menu_toggle value: %d\n", ui_get(i)); + + ui_var_set_int(event->obj->ctx, "menu_radio", 5); } void application_startup(UiEvent *event, void *data) {
--- a/ui/gtk/menu.c Wed Dec 31 11:36:42 2025 +0100 +++ b/ui/gtk/menu.c Wed Dec 31 12:37:09 2025 +0100 @@ -181,8 +181,72 @@ event); } +static void ui_menu_event_radio_item_toggled(GtkRadioMenuItem *ri, UiVarEventData *event) { + UiInteger *i = event->var->value; + + UiEvent evt; + evt.obj = event->obj; + evt.window = event->obj->window; + evt.document = event->obj->ctx->document; + evt.eventdata = i; + evt.eventdatatype = i ? UI_EVENT_DATA_INTEGER_VALUE : 0; + evt.intval = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(ri)); + + if(event->callback) { + event->callback(&evt, event->userdata); + } + + if(evt.intval) { + evt.intval = ui_get(i); + ui_notify_evt(i->observers, &evt); + } +} + +static void ui_destroy_menu_radio_item(GtkWidget *unused, UiVarEventData *event) { + if(event->customint1) { + uic_unbind_var(event->var); + } + free(event); +} + void add_radioitem_widget(GtkWidget *p, int index, UiMenuItemI *item, UiObject *obj) { - // TODO + UiMenuRadioItem *ri = (UiMenuRadioItem*)item; + + UiVar *var = uic_widget_var(obj->ctx, obj->ctx, NULL, ri->varname, UI_VAR_INTEGER); + if(!var) { + fprintf(stderr, "Error: menu radioitem varname is null\n"); + return; + } + int first = 0; + UiInteger *i = var->value; + GSList *group = i->obj; + GtkWidget *widget = gtk_radio_menu_item_new_with_label(group, ri->label); + gtk_menu_shell_append(GTK_MENU_SHELL(p), widget); + if(!group) { + i->get = ui_radioitem_get; + i->set = ui_radioitem_set; + first = 1; + } + i->obj = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(widget)); + + UiVarEventData *event = malloc(sizeof(UiVarEventData)); + memset(event, 0, sizeof(UiVarEventData)); + event->obj = obj; + event->var = var; + event->callback = ri->callback; + event->userdata = ri->userdata; + event->customint1 = first; + + g_signal_connect( + widget, + "toggled", + G_CALLBACK(ui_menu_event_radio_item_toggled), + event); + g_signal_connect( + widget, + "destroy", + G_CALLBACK(ui_destroy_menu_radio_item), + event); } static void menuitem_list_remove_binding(void *obj) { @@ -360,6 +424,47 @@ gtk_check_menu_item_set_active(i->obj, (gboolean)value); } +int64_t ui_radioitem_get(UiInteger *value) { + int selection = 0; + GSList *ls = value->obj; + guint len = g_slist_length(ls); + int i = 0; + while(ls) { + if(gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(ls->data))) { + selection = len - i; + break; + } + ls = ls->next; + i++; + } + + value->value = selection; + return selection; +} + +void ui_radioitem_set(UiInteger *i, int64_t value) { + GSList *ls = i->obj; + + int len = g_slist_length(ls); + if(value > len) { + value = len; + } + int s = len - value; + int j = 0; + int unset = 1; + while(ls) { + if(j == s) { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(ls->data), TRUE); + unset = 0; + break; + } + ls = ls->next; + j++; + } + + i->value = value; +} + /* * widget menu functions
--- a/ui/gtk/menu.h Wed Dec 31 11:36:42 2025 +0100 +++ b/ui/gtk/menu.h Wed Dec 31 12:37:09 2025 +0100 @@ -78,6 +78,8 @@ void ui_menu_event_toggled(GtkCheckMenuItem *ci, UiVarEventData *event); int64_t ui_checkitem_get(UiInteger *i); void ui_checkitem_set(UiInteger *i, int64_t value); +int64_t ui_radioitem_get(UiInteger *i); +void ui_radioitem_set(UiInteger *i, int64_t value); #endif /* GTK_MAJOR_VERSION <= 3 */
--- a/ui/gtk/toolkit.c Wed Dec 31 11:36:42 2025 +0100 +++ b/ui/gtk/toolkit.c Wed Dec 31 12:37:09 2025 +0100 @@ -282,7 +282,7 @@ free(userdata); } -void ui_destroy_vardata(GtkWidget *object, UiVarEventData *data) { +void ui_destroy_vardata(GtkWidget *unused, UiVarEventData *data) { if(data->var) { ui_destroy_boundvar(data->obj->ctx, data->var); }
--- a/ui/gtk/toolkit.h Wed Dec 31 11:36:42 2025 +0100 +++ b/ui/gtk/toolkit.h Wed Dec 31 12:37:09 2025 +0100 @@ -190,7 +190,7 @@ void ui_set_widget_nvisibility_states(UiContext *ctx, GtkWidget *widget, const int *states, size_t ngroups); void ui_destroy_userdata(GtkWidget *object, void *userdata); -void ui_destroy_vardata(GtkWidget *object, UiVarEventData *data); +void ui_destroy_vardata(GtkWidget *unused, UiVarEventData *data); void ui_destroy_widget_var(GtkWidget *object, UiVar *var); void ui_destroy_boundvar(UiContext *ctx, UiVar *var);