SameBoy/gtk3/check_menu_radio_group.c

81 lines
2.6 KiB
C
Raw Permalink Normal View History

#include "check_menu_radio_group.h"
2020-05-16 14:56:09 +00:00
static void check_menu_item_group_handler(GtkCheckMenuItem *item, CheckMenuItemGroupHandlerData *data) {
bool cancel = false;
if (data->handler) {
cancel = data->handler(data->group->parent, GTK_WIDGET(item), (gpointer) data->arg);
}
GValue value = G_VALUE_INIT;
g_value_init(&value, G_TYPE_BOOLEAN);
if (cancel) {
g_value_set_boolean(&value, false);
g_object_set_property(G_OBJECT(item), "active", &value);
}
else {
for (unsigned i = 0; i < data->group->count; i++) {
GtkCheckMenuItem *cur = GTK_CHECK_MENU_ITEM(data->group->items[i]);
g_value_set_boolean(&value, cur == item);
g_object_set_property(G_OBJECT(cur), "active", &value);
}
}
}
CheckMenuItemGroup *check_menu_item_group_new(GtkWidget *parent, char **names, char **args) {
unsigned name_count = 0;
if (names != NULL) {
for (char **ptr = names; *ptr != NULL; ptr++, name_count++);
}
CheckMenuItemGroup *group = g_malloc0(sizeof(CheckMenuItemGroup));
group->parent = parent;
group->count = name_count;
group->items = g_malloc0(sizeof(GtkWidget*) * name_count);
group->handlers = g_malloc0(sizeof(CheckMenuItemGroupHandlerData*) * name_count);
for (unsigned i = 0; i < name_count; i++) {
group->items[i] = gtk_check_menu_item_new_with_label(names[i]);
group->handlers[i] = g_malloc0(sizeof(CheckMenuItemGroupHandlerData));
group->handlers[i]->group = group;
group->handlers[i]->arg = args[i];
g_signal_connect(group->items[i], "toggled", G_CALLBACK(check_menu_item_group_handler), group->handlers[i]);
gtk_check_menu_item_set_draw_as_radio(GTK_CHECK_MENU_ITEM(group->items[i]), true);
}
return group;
}
void check_menu_item_group_activate(CheckMenuItemGroup *group, char *arg) {
GValue value = G_VALUE_INIT;
g_value_init(&value, G_TYPE_BOOLEAN);
g_value_set_boolean(&value, false);
for (unsigned i = 0; i < group->count; i++) {
GtkCheckMenuItem *cur = GTK_CHECK_MENU_ITEM(group->items[i]);
if (g_strcmp0(arg, group->handlers[i]->arg) == 0) {
gtk_check_menu_item_set_active(cur, true);
}
else {
g_object_set_property(G_OBJECT(cur), "active", &value);
}
}
}
void check_menu_item_group_connect_toggle_signal(CheckMenuItemGroup *group, bool (*handler)(GtkWidget *, GtkWidget *, gpointer)) {
for (unsigned i = 0; i < group->count; i++) {
group->handlers[i]->handler = handler;
}
}
void check_menu_item_group_insert_into_menu_shell(CheckMenuItemGroup *group, GtkMenuShell *menu_shell, gint position) {
for (unsigned i = 0; i < group->count; i++) {
gtk_menu_shell_insert(menu_shell, group->items[i], position + i);
}
}