From be4a25231d0554f4be241b498969151331bd675d Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 28 Jun 2015 10:11:54 -0400 Subject: [PATCH] gtk-demo: Add a spin button example More or less copied from the spin button example in testgtk. --- demos/gtk-demo/Makefile.am | 1 + demos/gtk-demo/demo.gresource.xml | 4 + demos/gtk-demo/spinbutton.c | 253 ++++++++++++++++++++++++++++++ demos/gtk-demo/spinbutton.ui | 205 ++++++++++++++++++++++++ 4 files changed, 463 insertions(+) create mode 100644 demos/gtk-demo/spinbutton.c create mode 100644 demos/gtk-demo/spinbutton.ui diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am index 91a59d71cd..c6791ae28e 100644 --- a/demos/gtk-demo/Makefile.am +++ b/demos/gtk-demo/Makefile.am @@ -53,6 +53,7 @@ demos_base = \ search_entry2.c \ sidebar.c \ sizegroup.c \ + spinbutton.c \ spinner.c \ stack.c \ textview.c \ diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml index 657442e9dc..5f84bfb27f 100644 --- a/demos/gtk-demo/demo.gresource.xml +++ b/demos/gtk-demo/demo.gresource.xml @@ -161,6 +161,7 @@ sizegroup.c sidebar.c stack.c + spinbutton.c spinner.c textview.c textscroll.c @@ -187,4 +188,7 @@ font-features.ui + + spinbutton.ui + diff --git a/demos/gtk-demo/spinbutton.c b/demos/gtk-demo/spinbutton.c new file mode 100644 index 0000000000..f504ba5474 --- /dev/null +++ b/demos/gtk-demo/spinbutton.c @@ -0,0 +1,253 @@ +/* Spin Button + * + * GtkSpinButton provides convenient ways to input data + * that can be seen as a value in a range. The examples + * here show that this does not necessarily mean numeric + * values, and it can include custom formatting. + */ + +#include +#include +#include +#include + +static gint +hex_spin_input (GtkSpinButton *spin_button, + gdouble *new_val) +{ + const gchar *buf; + gchar *err; + gdouble res; + + buf = gtk_entry_get_text (GTK_ENTRY (spin_button)); + res = strtol (buf, &err, 16); + *new_val = res; + if (*err) + return GTK_INPUT_ERROR; + else + return TRUE; +} + +static gint +hex_spin_output (GtkSpinButton *spin_button) +{ + GtkAdjustment *adjustment; + gchar *buf; + gint val; + + adjustment = gtk_spin_button_get_adjustment (spin_button); + val = (gint) gtk_adjustment_get_value (adjustment); + if (fabs (val) < 1e-5) + buf = g_strdup ("0x00"); + else + buf = g_strdup_printf ("0x%.2X", val); + if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button)))) + gtk_entry_set_text (GTK_ENTRY (spin_button), buf); + g_free (buf); + + return TRUE; +} + +static gint +time_spin_input (GtkSpinButton *spin_button, + gdouble *new_val) +{ + const gchar *text; + gchar **str; + gboolean found = FALSE; + gint hours; + gint minutes; + gchar *endh; + gchar *endm; + + text = gtk_entry_get_text (GTK_ENTRY (spin_button)); + str = g_strsplit (text, ":", 2); + + if (g_strv_length (str) == 2) + { + hours = strtol (str[0], &endh, 10); + minutes = strtol (str[1], &endm, 10); + if (!*endh && !*endm && + 0 <= hours && hours < 24 && + 0 <= minutes && minutes < 60) + { + *new_val = hours * 60 + minutes; + found = TRUE; + } + } + + g_strfreev (str); + + if (!found) + { + *new_val = 0.0; + return GTK_INPUT_ERROR; + } + + return TRUE; +} + +static gint +time_spin_output (GtkSpinButton *spin_button) +{ + GtkAdjustment *adjustment; + gchar *buf; + gdouble hours; + gdouble minutes; + + adjustment = gtk_spin_button_get_adjustment (spin_button); + hours = gtk_adjustment_get_value (adjustment) / 60.0; + minutes = (hours - floor (hours)) * 60.0; + buf = g_strdup_printf ("%02.0f:%02.0f", floor (hours), floor (minutes + 0.5)); + if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button)))) + gtk_entry_set_text (GTK_ENTRY (spin_button), buf); + g_free (buf); + + return TRUE; +} + +static gchar *month[12] = { + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" +}; + +static gint +month_spin_input (GtkSpinButton *spin_button, + gdouble *new_val) +{ + gint i; + gchar *tmp1, *tmp2; + gboolean found = FALSE; + + for (i = 1; i <= 12; i++) + { + tmp1 = g_ascii_strup (month[i - 1], -1); + tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1); + if (strstr (tmp1, tmp2) == tmp1) + found = TRUE; + g_free (tmp1); + g_free (tmp2); + if (found) + break; + } + if (!found) + { + *new_val = 0.0; + return GTK_INPUT_ERROR; + } + *new_val = (gdouble) i; + + return TRUE; +} + +static gint +month_spin_output (GtkSpinButton *spin_button) +{ + GtkAdjustment *adjustment; + gdouble value; + gint i; + + adjustment = gtk_spin_button_get_adjustment (spin_button); + value = gtk_adjustment_get_value (adjustment); + for (i = 1; i <= 12; i++) + if (fabs (value - (double)i) < 1e-5) + { + if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button)))) + gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]); + } + + return TRUE; +} + +static gboolean +value_to_label (GBinding *binding, + const GValue *from, + GValue *to, + gpointer user_data) +{ + g_value_take_string (to, g_strdup_printf ("%g", g_value_get_double (from))); + return TRUE; +} + +GtkWidget * +do_spinbutton (GtkWidget *do_widget) +{ + static GtkWidget *window; + + if (!window) + { + GtkBuilder *builder; + GtkAdjustment *adj; + GtkWidget *label; + + builder = gtk_builder_new_from_resource ("/spinbutton/spinbutton.ui"); + gtk_builder_add_callback_symbols (builder, + "hex_spin_input", G_CALLBACK (hex_spin_input), + "hex_spin_output", G_CALLBACK (hex_spin_output), + "time_spin_input", G_CALLBACK (time_spin_input), + "time_spin_output", G_CALLBACK (time_spin_output), + "month_spin_input", G_CALLBACK (month_spin_input), + "month_spin_output", G_CALLBACK (month_spin_output), + NULL); + gtk_builder_connect_signals (builder, NULL); + window = GTK_WIDGET (gtk_builder_get_object (builder, "window")); + gtk_window_set_screen (GTK_WINDOW (window), + gtk_widget_get_screen (do_widget)); + gtk_window_set_title (GTK_WINDOW (window), "Spin Buttons"); + gtk_window_set_resizable (GTK_WINDOW (window), FALSE); + g_signal_connect (window, "destroy", + G_CALLBACK (gtk_widget_destroyed), &window); + + adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "basic_adjustment")); + label = GTK_WIDGET (gtk_builder_get_object (builder, "basic_label")); + g_object_bind_property_full (adj, "value", + label, "label", + G_BINDING_SYNC_CREATE, + value_to_label, + NULL, + NULL, NULL); + adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "hex_adjustment")); + label = GTK_WIDGET (gtk_builder_get_object (builder, "hex_label")); + g_object_bind_property_full (adj, "value", + label, "label", + G_BINDING_SYNC_CREATE, + value_to_label, + NULL, + NULL, NULL); + adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "time_adjustment")); + label = GTK_WIDGET (gtk_builder_get_object (builder, "time_label")); + g_object_bind_property_full (adj, "value", + label, "label", + G_BINDING_SYNC_CREATE, + value_to_label, + NULL, + NULL, NULL); + adj = GTK_ADJUSTMENT (gtk_builder_get_object (builder, "month_adjustment")); + label = GTK_WIDGET (gtk_builder_get_object (builder, "month_label")); + g_object_bind_property_full (adj, "value", + label, "label", + G_BINDING_SYNC_CREATE, + value_to_label, + NULL, + NULL, NULL); + + g_object_unref (builder); + } + + if (!gtk_widget_get_visible (window)) + gtk_widget_show_all (window); + else + gtk_widget_destroy (window); + + return window; +} diff --git a/demos/gtk-demo/spinbutton.ui b/demos/gtk-demo/spinbutton.ui new file mode 100644 index 0000000000..bd1e08cce2 --- /dev/null +++ b/demos/gtk-demo/spinbutton.ui @@ -0,0 +1,205 @@ + + + + -10000 + 10000 + 0 + 0.5 + 100 + 0 + + + 0 + 255 + 0 + 1 + 16 + 0 + + + 0 + 1410 + 0 + 30 + 60 + 0 + + + 1 + 12 + 1 + 1 + 5 + 0 + + + False + Spin Button + + + True + False + 20 + 10 + 10 + + + True + _Numeric + True + basic_spin + 1 + + + 0 + 0 + + + + + True + start + 5 + basic_adjustment + 1 + 2 + True + + + 1 + 0 + + + + + True + 10 + 1 + + + 2 + 0 + + + + + True + _Hexadecimal + True + hex_spin + 1 + + + 0 + 1 + + + + + True + start + 4 + hex_adjustment + + + True + + + 1 + 1 + + + + + True + 10 + 1 + + + 2 + 1 + + + + + True + _Time + True + time_spin + 1 + + + 0 + 2 + + + + + True + start + 5 + time_adjustment + + + True + + + 1 + 2 + + + + + True + 10 + 1 + + + 2 + 2 + + + + + True + _Month + True + month_spin + 1 + + + 0 + 3 + + + + + True + start + 9 + + + month_adjustment + True + if-valid + + + 1 + 3 + + + + + True + 10 + 1 + + + 2 + 3 + + + + + +