[gtk/matthiasc/for-master] gtk-demo: Add another demo



commit a90801e696379f8328536c0c83d3917565faea51
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Sep 13 10:37:32 2020 -0400

    gtk-demo: Add another demo
    
    This one is a more or less direct copy of the
    settings dialog from widget-factory, demonstrating
    error states and builder scopes.

 demos/gtk-demo/demo.gresource.xml |   4 +
 demos/gtk-demo/errorstates.c      | 124 ++++++++++++++++++++++++++++++
 demos/gtk-demo/errorstates.ui     | 158 ++++++++++++++++++++++++++++++++++++++
 demos/gtk-demo/meson.build        |   1 +
 4 files changed, 287 insertions(+)
---
diff --git a/demos/gtk-demo/demo.gresource.xml b/demos/gtk-demo/demo.gresource.xml
index 22db1bad21..238503c0d2 100644
--- a/demos/gtk-demo/demo.gresource.xml
+++ b/demos/gtk-demo/demo.gresource.xml
@@ -112,6 +112,9 @@
   <gresource prefix="/dnd">
     <file>dnd.css</file>
   </gresource>
+  <gresource prefix="/errorstates">
+    <file>errorstates.ui</file>
+  </gresource>
   <gresource prefix="/fishbowl">
     <file>fishbowl.ui</file>
     <file>gtkfishbowl.c</file>
@@ -222,6 +225,7 @@
     <file>editable_cells.c</file>
     <file>entry_completion.c</file>
     <file>entry_undo.c</file>
+    <file>errorstates.c</file>
     <file>expander.c</file>
     <file>filtermodel.c</file>
     <file>fishbowl.c</file>
diff --git a/demos/gtk-demo/errorstates.c b/demos/gtk-demo/errorstates.c
new file mode 100644
index 0000000000..3dc3b50f3b
--- /dev/null
+++ b/demos/gtk-demo/errorstates.c
@@ -0,0 +1,124 @@
+/* Error states
+ *
+ * GtkLabel and GtkEntry can indicate errors if you set the .error
+ * style class on them.
+ *
+ * This examples shows how this can be used in a dialog for input validation.
+ *
+ * It also shows how pass callbacks and objects to GtkBuilder with
+ * GtkBuilderScope and gtk_builder_expose_object().
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+static void
+validate_more_details (GtkEntry   *entry,
+                       GParamSpec *pspec,
+                       GtkEntry   *details)
+{
+  if (strlen (gtk_editable_get_text (GTK_EDITABLE (entry))) > 0 &&
+      strlen (gtk_editable_get_text (GTK_EDITABLE (details))) == 0)
+    {
+      gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "Must have details first");
+      gtk_widget_add_css_class (GTK_WIDGET (entry), "error");
+    }
+  else
+    {
+      gtk_widget_set_tooltip_text (GTK_WIDGET (entry), "");
+      gtk_widget_remove_css_class (GTK_WIDGET (entry), "error");
+    }
+}
+
+static gboolean
+mode_switch_state_set (GtkSwitch *sw,
+                       gboolean   state,
+                       GtkWidget *scale)
+{
+  GtkWidget *label;
+
+  label = GTK_WIDGET (g_object_get_data (G_OBJECT (sw), "error_label"));
+
+  if (!state ||
+      (gtk_range_get_value (GTK_RANGE (scale)) > 50))
+    {
+      gtk_widget_hide (label);
+      gtk_switch_set_state (sw, state);
+    }
+  else
+    {
+      gtk_widget_show (label);
+    }
+
+  return TRUE;
+}
+
+static void
+level_scale_value_changed (GtkRange *range,
+                           GtkWidget *sw)
+{
+  GtkWidget *label;
+
+  label = GTK_WIDGET (g_object_get_data (G_OBJECT (sw), "error_label"));
+
+  if (gtk_switch_get_active (GTK_SWITCH (sw)) &&
+      !gtk_switch_get_state (GTK_SWITCH (sw)) &&
+      (gtk_range_get_value (range) > 50))
+    {
+      gtk_widget_hide (label);
+      gtk_switch_set_state (GTK_SWITCH (sw), TRUE);
+    }
+  else if (gtk_switch_get_state (GTK_SWITCH (sw)) &&
+          (gtk_range_get_value (range) <= 50))
+    {
+      gtk_switch_set_state (GTK_SWITCH (sw), FALSE);
+    }
+}
+
+GtkWidget *
+do_errorstates (GtkWidget *do_widget)
+{
+  static GtkWidget *window = NULL;
+
+  if (!window)
+    {
+      GtkWidget *toplevel;
+      GtkBuilder *builder;
+      GtkBuilderScope *scope;
+      GtkWidget *sw, *label;
+
+      toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget));
+
+      scope = gtk_builder_cscope_new ();
+      gtk_builder_cscope_add_callback_symbols (GTK_BUILDER_CSCOPE (scope),
+              "validate_more_details", G_CALLBACK (validate_more_details),
+              "mode_switch_state_set", G_CALLBACK (mode_switch_state_set),
+              "level_scale_value_changed", G_CALLBACK (level_scale_value_changed),
+              NULL);
+
+      builder = gtk_builder_new ();
+      gtk_builder_set_scope (builder, scope);
+      gtk_builder_expose_object (builder, "toplevel", G_OBJECT (toplevel));
+      gtk_builder_add_from_resource (builder, "/errorstates/errorstates.ui", NULL);
+
+      window = GTK_WIDGET (gtk_builder_get_object (builder, "dialog"));
+
+      gtk_window_set_display (GTK_WINDOW (window),
+                              gtk_widget_get_display (do_widget));
+      g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
+
+      sw = GTK_WIDGET (gtk_builder_get_object (builder, "mode_switch"));
+      label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label"));
+      g_object_set_data (G_OBJECT (sw), "error_label", label);
+
+      g_object_unref (builder);
+      g_object_unref (scope);
+    }
+
+  if (!gtk_widget_get_visible (window))
+    gtk_widget_show (window);
+  else
+    gtk_window_destroy (GTK_WINDOW (window));
+
+  return window;
+}
diff --git a/demos/gtk-demo/errorstates.ui b/demos/gtk-demo/errorstates.ui
new file mode 100644
index 0000000000..dd4a95b8fc
--- /dev/null
+++ b/demos/gtk-demo/errorstates.ui
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GtkDialog" id="dialog">
+    <property name="transient-for">toplevel</property>
+    <property name="modal">1</property>
+    <property name="resizable">0</property>
+    <property name="use-header-bar">1</property>
+    <property name="title" translatable="yes">Settings</property>
+    <property name="hide-on-close">1</property>
+    <child internal-child="content_area">
+      <object class="GtkBox">
+        <child>
+          <object class="GtkGrid">
+            <property name="row-spacing">10</property>
+            <property name="column-spacing">10</property>
+            <property name="margin-start">20</property>
+            <property name="margin-end">20</property>
+            <property name="margin-top">20</property>
+            <property name="margin-bottom">20</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">end</property>
+                <property name="valign">baseline</property>
+                <property name="label">_Details</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">details_entry</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">0</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkEntry" id="details_entry">
+                <property name="valign">baseline</property>
+                <signal name="notify::text" handler="validate_more_details" object="more_details_entry" 
swapped="yes"/>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">0</property>
+                  <property name="column-span">2</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">end</property>
+                <property name="valign">baseline</property>
+                <property name="label">More D_etails</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">more_details_entry</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">1</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkEntry" id="more_details_entry">
+                <property name="valign">baseline</property>
+                <signal name="notify::text" handler="validate_more_details" object="details_entry" 
swapped="no"/>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">1</property>
+                  <property name="column-span">2</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">end</property>
+                <property name="valign">baseline</property>
+                <property name="label">_Level</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">level_scale</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">2</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkScale" id="level_scale">
+                <property name="valign">baseline</property>
+                <property name="draw-value">0</property>
+                <property name="adjustment">
+                  <object class="GtkAdjustment">
+                    <property name="upper">100</property>
+                    <property name="lower">0</property>
+                    <property name="value">50</property>
+                    <property name="step-increment">1</property>
+                    <property name="page-increment">10</property>
+                  </object>
+                </property>
+                <signal name="value-changed" handler="level_scale_value_changed" object="mode_switch" 
swapped="no"/>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">2</property>
+                  <property name="column-span">2</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">end</property>
+                <property name="valign">baseline</property>
+                <property name="label">_Mode</property>
+                <property name="use-underline">1</property>
+                <property name="mnemonic-widget">mode_switch</property>
+                <style>
+                  <class name="dim-label"/>
+                </style>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">3</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkSwitch" id="mode_switch">
+                <property name="halign">start</property>
+                <property name="valign">baseline</property>
+                <signal name="state-set" handler="mode_switch_state_set" object="level_scale" swapped="no"/>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">3</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel" id="error_label">
+                <property name="visible">0</property>
+                <property name="halign">start</property>
+                <property name="valign">baseline</property>
+                <property name="label">Level too low</property>
+                <style>
+                  <class name="error"/>
+                </style>
+                <layout>
+                  <property name="column">2</property>
+                  <property name="row">3</property>
+                </layout>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/demos/gtk-demo/meson.build b/demos/gtk-demo/meson.build
index 07fd1b2330..a60f121896 100644
--- a/demos/gtk-demo/meson.build
+++ b/demos/gtk-demo/meson.build
@@ -23,6 +23,7 @@ demos = files([
   'editable_cells.c',
   'entry_completion.c',
   'entry_undo.c',
+  'errorstates.c',
   'expander.c',
   'filtermodel.c',
   'fishbowl.c',


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