summaryrefslogtreecommitdiff
path: root/demos/gtk-demo/spinbutton.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2015-06-28 10:11:54 -0400
committerMatthias Clasen <mclasen@redhat.com>2015-06-28 17:40:58 -0400
commitbe4a25231d0554f4be241b498969151331bd675d (patch)
tree203971012e05756f09a98b9d5ebfbb8988264f34 /demos/gtk-demo/spinbutton.c
parentcd3f24d5793e038ee29d780b24747707c73ad00c (diff)
downloadgtk+-be4a25231d0554f4be241b498969151331bd675d.tar.gz
gtk-demo: Add a spin button example
More or less copied from the spin button example in testgtk.
Diffstat (limited to 'demos/gtk-demo/spinbutton.c')
-rw-r--r--demos/gtk-demo/spinbutton.c253
1 files changed, 253 insertions, 0 deletions
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 <glib/gi18n.h>
+#include <gtk/gtk.h>
+#include <math.h>
+#include <stdlib.h>
+
+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;
+}