1 | /* Error States |
2 | * |
3 | * GtkLabel and GtkEntry can indicate errors if you set the .error |
4 | * style class on them. |
5 | * |
6 | * This examples shows how this can be used in a dialog for input validation. |
7 | * |
8 | * It also shows how pass callbacks and objects to GtkBuilder with |
9 | * GtkBuilderScope and gtk_builder_expose_object(). |
10 | */ |
11 | |
12 | #include <glib/gi18n.h> |
13 | #include <gtk/gtk.h> |
14 | |
15 | static void |
16 | validate_more_details (GtkEntry *entry, |
17 | GParamSpec *pspec, |
18 | GtkEntry *details) |
19 | { |
20 | if (strlen (s: gtk_editable_get_text (GTK_EDITABLE (entry))) > 0 && |
21 | strlen (s: gtk_editable_get_text (GTK_EDITABLE (details))) == 0) |
22 | { |
23 | gtk_widget_set_tooltip_text (GTK_WIDGET (entry), text: "Must have details first" ); |
24 | gtk_widget_add_css_class (GTK_WIDGET (entry), css_class: "error" ); |
25 | } |
26 | else |
27 | { |
28 | gtk_widget_set_tooltip_text (GTK_WIDGET (entry), text: "" ); |
29 | gtk_widget_remove_css_class (GTK_WIDGET (entry), css_class: "error" ); |
30 | } |
31 | } |
32 | |
33 | static gboolean |
34 | mode_switch_state_set (GtkSwitch *sw, |
35 | gboolean state, |
36 | GtkWidget *scale) |
37 | { |
38 | GtkWidget *label; |
39 | |
40 | label = GTK_WIDGET (g_object_get_data (G_OBJECT (sw), "error_label" )); |
41 | |
42 | if (!state || |
43 | (gtk_range_get_value (GTK_RANGE (scale)) > 50)) |
44 | { |
45 | gtk_widget_hide (widget: label); |
46 | gtk_switch_set_state (self: sw, state); |
47 | } |
48 | else |
49 | { |
50 | gtk_widget_show (widget: label); |
51 | } |
52 | |
53 | return TRUE; |
54 | } |
55 | |
56 | static void |
57 | level_scale_value_changed (GtkRange *range, |
58 | GtkWidget *sw) |
59 | { |
60 | GtkWidget *label; |
61 | |
62 | label = GTK_WIDGET (g_object_get_data (G_OBJECT (sw), "error_label" )); |
63 | |
64 | if (gtk_switch_get_active (GTK_SWITCH (sw)) && |
65 | !gtk_switch_get_state (GTK_SWITCH (sw)) && |
66 | (gtk_range_get_value (range) > 50)) |
67 | { |
68 | gtk_widget_hide (widget: label); |
69 | gtk_switch_set_state (GTK_SWITCH (sw), TRUE); |
70 | } |
71 | else if (gtk_switch_get_state (GTK_SWITCH (sw)) && |
72 | (gtk_range_get_value (range) <= 50)) |
73 | { |
74 | gtk_switch_set_state (GTK_SWITCH (sw), FALSE); |
75 | } |
76 | } |
77 | |
78 | GtkWidget * |
79 | do_errorstates (GtkWidget *do_widget) |
80 | { |
81 | static GtkWidget *window = NULL; |
82 | |
83 | if (!window) |
84 | { |
85 | GtkWidget *toplevel; |
86 | GtkBuilder *builder; |
87 | GtkBuilderScope *scope; |
88 | GtkWidget *sw, *label; |
89 | |
90 | toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget)); |
91 | |
92 | scope = gtk_builder_cscope_new (); |
93 | gtk_builder_cscope_add_callback_symbols (self: GTK_BUILDER_CSCOPE (ptr: scope), |
94 | first_callback_name: "validate_more_details" , G_CALLBACK (validate_more_details), |
95 | "mode_switch_state_set" , G_CALLBACK (mode_switch_state_set), |
96 | "level_scale_value_changed" , G_CALLBACK (level_scale_value_changed), |
97 | NULL); |
98 | |
99 | builder = gtk_builder_new (); |
100 | gtk_builder_set_scope (builder, scope); |
101 | gtk_builder_expose_object (builder, name: "toplevel" , G_OBJECT (toplevel)); |
102 | gtk_builder_add_from_resource (builder, resource_path: "/errorstates/errorstates.ui" , NULL); |
103 | |
104 | window = GTK_WIDGET (gtk_builder_get_object (builder, "dialog" )); |
105 | |
106 | gtk_window_set_display (GTK_WINDOW (window), |
107 | display: gtk_widget_get_display (widget: do_widget)); |
108 | g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window); |
109 | |
110 | sw = GTK_WIDGET (gtk_builder_get_object (builder, "mode_switch" )); |
111 | label = GTK_WIDGET (gtk_builder_get_object (builder, "error_label" )); |
112 | g_object_set_data (G_OBJECT (sw), key: "error_label" , data: label); |
113 | |
114 | g_object_unref (object: builder); |
115 | g_object_unref (object: scope); |
116 | } |
117 | |
118 | if (!gtk_widget_get_visible (widget: window)) |
119 | gtk_widget_show (widget: window); |
120 | else |
121 | gtk_window_destroy (GTK_WINDOW (window)); |
122 | |
123 | return window; |
124 | } |
125 | |