diff options
author | Matthias Clasen <mclasen@redhat.com> | 2015-06-28 10:11:54 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2015-06-28 17:40:58 -0400 |
commit | be4a25231d0554f4be241b498969151331bd675d (patch) | |
tree | 203971012e05756f09a98b9d5ebfbb8988264f34 /demos/gtk-demo | |
parent | cd3f24d5793e038ee29d780b24747707c73ad00c (diff) | |
download | gtk+-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')
-rw-r--r-- | demos/gtk-demo/Makefile.am | 1 | ||||
-rw-r--r-- | demos/gtk-demo/demo.gresource.xml | 4 | ||||
-rw-r--r-- | demos/gtk-demo/spinbutton.c | 253 | ||||
-rw-r--r-- | demos/gtk-demo/spinbutton.ui | 205 |
4 files changed, 463 insertions, 0 deletions
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 @@ <file>sizegroup.c</file> <file>sidebar.c</file> <file>stack.c</file> + <file>spinbutton.c</file> <file>spinner.c</file> <file>textview.c</file> <file>textscroll.c</file> @@ -187,4 +188,7 @@ <gresource prefix="/font-features"> <file>font-features.ui</file> </gresource> + <gresource prefix="/spinbutton"> + <file>spinbutton.ui</file> + </gresource> </gresources> 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; +} 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 @@ +<?xml version="1.0" encoding="UTF-8"?> +<interface> + <object class="GtkAdjustment" id="basic_adjustment"> + <property name="lower">-10000</property> + <property name="upper">10000</property> + <property name="value">0</property> + <property name="step_increment">0.5</property> + <property name="page_increment">100</property> + <property name="page_size">0</property> + </object> + <object class="GtkAdjustment" id="hex_adjustment"> + <property name="lower">0</property> + <property name="upper">255</property> + <property name="value">0</property> + <property name="step_increment">1</property> + <property name="page_increment">16</property> + <property name="page_size">0</property> + </object> + <object class="GtkAdjustment" id="time_adjustment"> + <property name="lower">0</property> + <property name="upper">1410</property> + <property name="value">0</property> + <property name="step_increment">30</property> + <property name="page_increment">60</property> + <property name="page_size">0</property> + </object> + <object class="GtkAdjustment" id="month_adjustment"> + <property name="lower">1</property> + <property name="upper">12</property> + <property name="value">1</property> + <property name="step_increment">1</property> + <property name="page_increment">5</property> + <property name="page_size">0</property> + </object> + <object class="GtkWindow" id="window"> + <property name="can_focus">False</property> + <property name="title" translatable="yes">Spin Button</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="margin">20</property> + <property name="row-spacing">10</property> + <property name="column-spacing">10</property> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="label">_Numeric</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">basic_spin</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="basic_spin"> + <property name="visible">True</property> + <property name="halign">start</property> + <property name="width_chars">5</property> + <property name="adjustment">basic_adjustment</property> + <property name="climb_rate">1</property> + <property name="digits">2</property> + <property name="numeric">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="basic_label"> + <property name="visible">True</property> + <property name="width_chars">10</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="label">_Hexadecimal</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">hex_spin</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="hex_spin"> + <property name="visible">True</property> + <property name="halign">start</property> + <property name="width_chars">4</property> + <property name="adjustment">hex_adjustment</property> + <signal name="input" handler="hex_spin_input"/> + <signal name="output" handler="hex_spin_output"/> + <property name="wrap">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="hex_label"> + <property name="visible">True</property> + <property name="width_chars">10</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">1</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="label">_Time</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">time_spin</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="time_spin"> + <property name="visible">True</property> + <property name="halign">start</property> + <property name="width_chars">5</property> + <property name="adjustment">time_adjustment</property> + <signal name="input" handler="time_spin_input"/> + <signal name="output" handler="time_spin_output"/> + <property name="wrap">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="time_label"> + <property name="visible">True</property> + <property name="width_chars">10</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">2</property> + </packing> + </child> + <child> + <object class="GtkLabel"> + <property name="visible">True</property> + <property name="label">_Month</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">month_spin</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkSpinButton" id="month_spin"> + <property name="visible">True</property> + <property name="halign">start</property> + <property name="width_chars">9</property> + <signal name="input" handler="month_spin_input"/> + <signal name="output" handler="month_spin_output"/> + <property name="adjustment">month_adjustment</property> + <property name="wrap">True</property> + <property name="update_policy">if-valid</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="top_attach">3</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="month_label"> + <property name="visible">True</property> + <property name="width_chars">10</property> + <property name="xalign">1</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="top_attach">3</property> + </packing> + </child> + </object> + </child> + </object> +</interface> |