[gtk/matthiasc/for-master] gtk-demo: Add another demo
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/matthiasc/for-master] gtk-demo: Add another demo
- Date: Sun, 13 Sep 2020 16:37:05 +0000 (UTC)
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]