aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/unix/radiobuttons.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libui_sdl/libui/unix/radiobuttons.c')
-rw-r--r--src/libui_sdl/libui/unix/radiobuttons.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/unix/radiobuttons.c b/src/libui_sdl/libui/unix/radiobuttons.c
new file mode 100644
index 0000000..da41107
--- /dev/null
+++ b/src/libui_sdl/libui/unix/radiobuttons.c
@@ -0,0 +1,121 @@
+// 11 june 2015
+#include "uipriv_unix.h"
+
+// on GTK+ a uiRadioButtons is a GtkBox with each of the GtkRadioButtons as children
+
+struct uiRadioButtons {
+ uiUnixControl c;
+ GtkWidget *widget;
+ GtkContainer *container;
+ GtkBox *box;
+ GPtrArray *buttons;
+ void (*onSelected)(uiRadioButtons *, void *);
+ void *onSelectedData;
+ gboolean changing;
+};
+
+uiUnixControlAllDefaultsExceptDestroy(uiRadioButtons)
+
+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)
+{
+ 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));
+}
+
+void uiRadioButtonsAppend(uiRadioButtons *r, const char *text)
+{
+ 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);
+ gtk_container_add(r->container, rb);
+ g_ptr_array_add(r->buttons, rb);
+ gtk_widget_show(rb);
+}
+
+int 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, int 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;
+}
+
+uiRadioButtons *uiNewRadioButtons(void)
+{
+ uiRadioButtons *r;
+
+ uiUnixNewControl(uiRadioButtons, r);
+
+ r->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
+ r->container = GTK_CONTAINER(r->widget);
+ r->box = GTK_BOX(r->widget);
+
+ r->buttons = g_ptr_array_new();
+
+ uiRadioButtonsOnSelected(r, defaultOnSelected, NULL);
+
+ return r;
+}