[gtk+] gtk-demo: Add a spin button example



commit be4a25231d0554f4be241b498969151331bd675d
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jun 28 10:11:54 2015 -0400

    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(+), 0 deletions(-)
---
diff --git a/demos/gtk-demo/Makefile.am b/demos/gtk-demo/Makefile.am
index 91a59d7..c6791ae 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 657442e..5f84bfb 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 0000000..f504ba5
--- /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 0000000..bd1e08c
--- /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>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]