]> Pileus Git - ~andy/gtk/blob - tests/testboxcss.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / tests / testboxcss.c
1 /* testbox.c
2  *
3  * Copyright (C) 2010 Benjamin Otte <otte@gnome.ogr>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
17  */
18 #include "config.h"
19 #include <gtk/gtk.h>
20 #include "prop-editor.h"
21
22 /* This is exactly the style information you've been looking for */
23 #define GTK_STYLE_PROVIDER_PRIORITY_FORCE G_MAXUINT
24
25 #define DEFAULT_CSS \
26   ".play {\n" \
27   "  engine: none;\n" \
28   "  background-image: none;\n" \
29   "  background-color: red;\n" \
30   "  border-color: black;\n" \
31   "  border-radius: 0;\n" \
32   "}\n" \
33   "\n" \
34   ".play:nth-child(even) {\n" \
35   "  background-color: yellow;\n" \
36   "  color: green;\n" \
37   "}\n" \
38   "\n" \
39   ".play:nth-child(first) {\n" \
40   "  border-radius: 5 0 0 5;\n" \
41   "}\n" \
42   "\n" \
43   ".play:nth-child(last) {\n" \
44   "  border-radius: 0 5 5 0;\n" \
45   "}\n" \
46   "\n"
47
48 static void
49 show_parsing_error (GtkCssProvider *provider,
50                     GtkCssSection  *section,
51                     const GError   *error,
52                     GtkTextBuffer  *buffer)
53 {
54   GtkTextIter start, end;
55   const char *tag_name;
56
57   gtk_text_buffer_get_iter_at_line_index (buffer,
58                                           &start,
59                                           gtk_css_section_get_start_line (section),
60                                           gtk_css_section_get_start_position (section));
61   gtk_text_buffer_get_iter_at_line_index (buffer,
62                                           &end,
63                                           gtk_css_section_get_end_line (section),
64                                           gtk_css_section_get_end_position (section));
65
66   if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
67     tag_name = "warning";
68   else
69     tag_name = "error";
70
71   gtk_text_buffer_apply_tag_by_name (buffer, tag_name, &start, &end);
72 }
73                     
74 static void
75 css_text_changed (GtkTextBuffer  *buffer,
76                   GtkCssProvider *provider)
77 {
78   GtkTextIter start, end;
79   char *text;
80
81   gtk_text_buffer_get_start_iter (buffer, &start);
82   gtk_text_buffer_get_end_iter (buffer, &end);
83   gtk_text_buffer_remove_all_tags (buffer, &start, &end);
84
85   text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
86   gtk_css_provider_load_from_data (provider, text, -1, NULL);
87   g_free (text);
88
89   gtk_style_context_reset_widgets (gdk_screen_get_default ());
90 }
91
92 static void
93 remove_widget (GtkWidget *widget)
94 {
95   gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (widget)), widget);
96 }
97
98 static int count = 0;
99
100 static void
101 add_button (GtkBox *box)
102 {
103   GtkWidget* button;
104   char *text;
105
106   text = g_strdup_printf ("Remove %d", ++count);
107   button = (GtkWidget *)gtk_button_new_from_stock (text);
108   g_free (text);
109   gtk_style_context_add_class (gtk_widget_get_style_context (button), "play");
110   g_signal_connect_swapped (button,
111                             "clicked",
112                             G_CALLBACK (remove_widget),
113                             button);
114   gtk_widget_show (button);
115   gtk_container_add (GTK_CONTAINER (box), button);
116 }
117
118 static void
119 add_toolbutton (GtkToolbar *toolbar)
120 {
121   GtkWidget* button;
122   char *text;
123
124   text = g_strdup_printf ("Remove %d", ++count);
125   button = (GtkWidget *)gtk_tool_button_new (NULL, text);
126   g_free (text);
127   gtk_style_context_add_class (gtk_widget_get_style_context (button), "play");
128   g_signal_connect_swapped (button,
129                             "clicked",
130                             G_CALLBACK (remove_widget),
131                             button);
132   gtk_widget_show (button);
133   gtk_container_add (GTK_CONTAINER (toolbar), button);
134 }
135
136 static void
137 set_orientation (GtkSwitch *switch_)
138 {
139   gtk_widget_set_default_direction (gtk_switch_get_active (switch_) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL);
140 }
141
142 gint
143 main (gint argc, gchar **argv)
144 {
145   GtkWidget *window, *main_box, *container, *child;
146   GtkWidget *box, *toolbar;
147   GtkStyleProvider *provider;
148   GtkTextBuffer *css;
149   
150   gtk_init (&argc, &argv);
151
152   css = gtk_text_buffer_new (NULL);
153   gtk_text_buffer_create_tag (css,
154                               "warning",
155                               "background", "rgba(255,255,0,0.3)",
156                               NULL);
157   gtk_text_buffer_create_tag (css,
158                               "error",
159                               "background", "rgba(255,0,0,0.3)",
160                               NULL);
161
162   provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
163   gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
164                                              provider,
165                                              GTK_STYLE_PROVIDER_PRIORITY_FORCE);
166   
167   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
168
169   g_signal_connect (window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
170   g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
171
172   main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
173   gtk_container_add (GTK_CONTAINER (window), main_box);
174
175   toolbar = gtk_toolbar_new ();
176   gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
177   gtk_box_pack_start (GTK_BOX (main_box), toolbar, FALSE, TRUE, 0);
178
179   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
180   gtk_box_pack_start (GTK_BOX (main_box), box, FALSE, TRUE, 0);
181
182   container = gtk_scrolled_window_new (NULL, NULL);
183   gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (container), 200);
184   gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (container), 200);
185   gtk_box_pack_start (GTK_BOX (main_box), container, TRUE, TRUE, 0);
186   child = gtk_text_view_new_with_buffer (css);
187   gtk_container_add (GTK_CONTAINER (container), child);
188   g_signal_connect (css,
189                     "changed",
190                     G_CALLBACK (css_text_changed),
191                     provider);
192   gtk_text_buffer_set_text (css,
193                             DEFAULT_CSS,
194                             -1);
195   g_signal_connect (provider,
196                     "parsing-error",
197                     G_CALLBACK (show_parsing_error),
198                     gtk_text_view_get_buffer (GTK_TEXT_VIEW (child)));
199
200   container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
201   gtk_box_pack_start (GTK_BOX (main_box), container, FALSE, TRUE, 0);
202   child = gtk_switch_new ();
203   gtk_switch_set_active (GTK_SWITCH (child), gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR);
204   g_signal_connect (child,
205                     "notify::active",
206                     G_CALLBACK (set_orientation),
207                     NULL);
208   gtk_box_pack_start (GTK_BOX (container), child, FALSE, FALSE, 0);
209   child = gtk_label_new ("left-to-right");
210   gtk_box_pack_start (GTK_BOX (container), child, FALSE, FALSE, 0);
211   child = gtk_button_new_with_label ("Add button");
212   g_signal_connect_swapped (child,
213                             "clicked",
214                             G_CALLBACK (add_button),
215                             box);
216   gtk_box_pack_end (GTK_BOX (container), child, FALSE, FALSE, 0);
217   child = gtk_button_new_with_label ("Add toolbutton");
218   g_signal_connect_swapped (child,
219                             "clicked",
220                             G_CALLBACK (add_toolbutton),
221                             toolbar);
222   gtk_box_pack_end (GTK_BOX (container), child, FALSE, FALSE, 0);
223
224   add_toolbutton (GTK_TOOLBAR (toolbar));
225   add_toolbutton (GTK_TOOLBAR (toolbar));
226   add_toolbutton (GTK_TOOLBAR (toolbar));
227   add_toolbutton (GTK_TOOLBAR (toolbar));
228
229   add_button (GTK_BOX (box));
230   add_button (GTK_BOX (box));
231   add_button (GTK_BOX (box));
232   add_button (GTK_BOX (box));
233
234   gtk_widget_show_all (window);
235
236   gtk_main ();
237   
238   return 0;
239 }