libui/unix/radiobuttons.c

122 lines
2.7 KiB
C
Raw Normal View History

2015-06-11 18:07:06 -05:00
// 11 june 2015
#include "uipriv_unix.h"
// on GTK+ a uiRadioButtons is a GtkBox with each of the GtkRadioButtons as children
struct uiRadioButtons {
2015-08-27 22:00:34 -05:00
uiUnixControl c;
GtkWidget *widget;
GtkContainer *container;
GtkBox *box;
2015-07-01 11:39:05 -05:00
GPtrArray *buttons;
void (*onSelected)(uiRadioButtons *, void *);
void *onSelectedData;
gboolean changing;
2015-06-11 18:07:06 -05:00
};
uiUnixControlAllDefaultsExceptDestroy(uiRadioButtons)
2015-06-11 18:07:06 -05:00
static void defaultOnSelected(uiRadioButtons *r, void *data)
{
// do nothing
}
static void onToggled(GtkToggleButton *tb, gpointer data)
{
uiRadioButtons *r = uiRadioButtons(data);
// only care if a button is selected
if (!gtk_toggle_button_get_active(tb))
return;
// ignore programmatic changes
if (r->changing)
return;
(*(r->onSelected))(r, r->onSelectedData);
}
static void uiRadioButtonsDestroy(uiControl *c)
2015-06-11 18:07:06 -05:00
{
uiRadioButtons *r = uiRadioButtons(c);
GtkWidget *b;
while (r->buttons->len != 0) {
b = GTK_WIDGET(g_ptr_array_remove_index(r->buttons, 0));
gtk_widget_destroy(b);
}
g_ptr_array_free(r->buttons, TRUE);
// and free ourselves
g_object_unref(r->widget);
uiFreeControl(uiControl(r));
2015-06-11 18:07:06 -05:00
}
void uiRadioButtonsAppend(uiRadioButtons *r, const char *text)
2015-06-11 18:07:06 -05:00
{
2015-07-01 11:39:05 -05:00
GtkWidget *rb;
GtkRadioButton *previous;
previous = NULL;
if (r->buttons->len > 0)
previous = GTK_RADIO_BUTTON(g_ptr_array_index(r->buttons, 0));
rb = gtk_radio_button_new_with_label_from_widget(previous, text);
g_signal_connect(rb, "toggled", G_CALLBACK(onToggled), r);
2015-08-27 22:00:34 -05:00
gtk_container_add(r->container, rb);
2015-07-01 11:39:05 -05:00
g_ptr_array_add(r->buttons, rb);
gtk_widget_show(rb);
2015-06-11 18:07:06 -05:00
}
intmax_t uiRadioButtonsSelected(uiRadioButtons *r)
{
GtkToggleButton *tb;
guint i;
for (i = 0; i < r->buttons->len; i++) {
tb = GTK_TOGGLE_BUTTON(g_ptr_array_index(r->buttons, i));
if (gtk_toggle_button_get_active(tb))
return i;
}
return -1;
}
void uiRadioButtonsSetSelected(uiRadioButtons *r, intmax_t n)
{
GtkToggleButton *tb;
gboolean active;
active = TRUE;
// TODO this doesn't work
if (n == -1) {
n = uiRadioButtonsSelected(r);
if (n == -1) // no selection; keep it that way
return;
active = FALSE;
}
tb = GTK_TOGGLE_BUTTON(g_ptr_array_index(r->buttons, n));
// this is easier than remembering all the signals
r->changing = TRUE;
gtk_toggle_button_set_active(tb, active);
r->changing = FALSE;
}
void uiRadioButtonsOnSelected(uiRadioButtons *r, void (*f)(uiRadioButtons *, void *), void *data)
{
r->onSelected = f;
r->onSelectedData = data;
}
2015-06-11 18:07:06 -05:00
uiRadioButtons *uiNewRadioButtons(void)
{
2015-08-27 22:00:34 -05:00
uiRadioButtons *r;
2015-06-11 18:07:06 -05:00
uiUnixNewControl(uiRadioButtons, r);
2015-06-11 18:07:06 -05:00
2015-08-27 22:00:34 -05:00
r->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
r->container = GTK_CONTAINER(r->widget);
r->box = GTK_BOX(r->widget);
2015-06-11 18:07:06 -05:00
2015-07-01 11:39:05 -05:00
r->buttons = g_ptr_array_new();
uiRadioButtonsOnSelected(r, defaultOnSelected, NULL);
2015-08-27 22:00:34 -05:00
return r;
2015-06-11 18:07:06 -05:00
}