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 
21 /* This is exactly the style information you've been looking for */
22 #define GTK_STYLE_PROVIDER_PRIORITY_FORCE G_MAXUINT
23 
24 #define DEFAULT_CSS \
25   ".play {\n" \
26   "  engine: none;\n" \
27   "  background-image: none;\n" \
28   "  background-color: red;\n" \
29   "  border-color: black;\n" \
30   "  border-radius: 0;\n" \
31   "}\n" \
32   "\n" \
33   ".play:nth-child(even) {\n" \
34   "  background-color: yellow;\n" \
35   "  color: green;\n" \
36   "}\n" \
37   "\n" \
38   ".play:nth-child(first) {\n" \
39   "  border-radius: 5 0 0 5;\n" \
40   "}\n" \
41   "\n" \
42   ".play:nth-child(last) {\n" \
43   "  border-radius: 0 5 5 0;\n" \
44   "}\n" \
45   "\n"
46 
47 static void
show_parsing_error(GtkCssProvider * provider,GtkCssSection * section,const GError * error,GtkTextBuffer * buffer)48 show_parsing_error (GtkCssProvider *provider,
49                     GtkCssSection  *section,
50                     const GError   *error,
51                     GtkTextBuffer  *buffer)
52 {
53   GtkTextIter start, end;
54   const char *tag_name;
55 
56   gtk_text_buffer_get_iter_at_line_index (buffer,
57                                           &start,
58                                           gtk_css_section_get_start_line (section),
59                                           gtk_css_section_get_start_position (section));
60   gtk_text_buffer_get_iter_at_line_index (buffer,
61                                           &end,
62                                           gtk_css_section_get_end_line (section),
63                                           gtk_css_section_get_end_position (section));
64 
65   if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
66     tag_name = "warning";
67   else
68     tag_name = "error";
69 
70   gtk_text_buffer_apply_tag_by_name (buffer, tag_name, &start, &end);
71 }
72 
73 static void
css_text_changed(GtkTextBuffer * buffer,GtkCssProvider * provider)74 css_text_changed (GtkTextBuffer  *buffer,
75                   GtkCssProvider *provider)
76 {
77   GtkTextIter start, end;
78   char *text;
79 
80   gtk_text_buffer_get_start_iter (buffer, &start);
81   gtk_text_buffer_get_end_iter (buffer, &end);
82   gtk_text_buffer_remove_all_tags (buffer, &start, &end);
83 
84   text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
85   gtk_css_provider_load_from_data (provider, text, -1, NULL);
86   g_free (text);
87 
88   gtk_style_context_reset_widgets (gdk_screen_get_default ());
89 }
90 
91 static void
remove_widget(GtkWidget * widget)92 remove_widget (GtkWidget *widget)
93 {
94   gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (widget)), widget);
95 }
96 
97 static int count = 0;
98 
99 static void
add_button(GtkBox * box)100 add_button (GtkBox *box)
101 {
102   GtkWidget* button;
103   char *text;
104 
105   text = g_strdup_printf ("Remove %d", ++count);
106   button = (GtkWidget *)gtk_button_new_with_label (text);
107   g_free (text);
108   gtk_style_context_add_class (gtk_widget_get_style_context (button), "play");
109   g_signal_connect_swapped (button,
110                             "clicked",
111                             G_CALLBACK (remove_widget),
112                             button);
113   gtk_widget_show (button);
114   gtk_container_add (GTK_CONTAINER (box), button);
115 }
116 
117 static void
add_toolbutton(GtkToolbar * toolbar)118 add_toolbutton (GtkToolbar *toolbar)
119 {
120   GtkWidget* button;
121   char *text;
122 
123   text = g_strdup_printf ("Remove %d", ++count);
124   button = (GtkWidget *)gtk_tool_button_new (NULL, text);
125   g_free (text);
126   gtk_style_context_add_class (gtk_widget_get_style_context (button), "play");
127   g_signal_connect_swapped (button,
128                             "clicked",
129                             G_CALLBACK (remove_widget),
130                             button);
131   gtk_widget_show (button);
132   gtk_container_add (GTK_CONTAINER (toolbar), button);
133 }
134 
135 static void
set_orientation(GtkSwitch * switch_)136 set_orientation (GtkSwitch *switch_)
137 {
138   gtk_widget_set_default_direction (gtk_switch_get_active (switch_) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL);
139 }
140 
141 gint
main(gint argc,gchar ** argv)142 main (gint argc, gchar **argv)
143 {
144   GtkWidget *window, *main_box, *container, *child;
145   GtkWidget *box, *toolbar;
146   GtkStyleProvider *provider;
147   GtkTextBuffer *css;
148 
149   gtk_init (&argc, &argv);
150 
151   css = gtk_text_buffer_new (NULL);
152   gtk_text_buffer_create_tag (css,
153                               "warning",
154                               "background", "rgba(255,255,0,0.3)",
155                               NULL);
156   gtk_text_buffer_create_tag (css,
157                               "error",
158                               "background", "rgba(255,0,0,0.3)",
159                               NULL);
160 
161   provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
162   gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
163                                              provider,
164                                              GTK_STYLE_PROVIDER_PRIORITY_FORCE);
165 
166   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
167 
168   g_signal_connect (window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
169   g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
170 
171   main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
172   gtk_container_add (GTK_CONTAINER (window), main_box);
173 
174   toolbar = gtk_toolbar_new ();
175   gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_TEXT);
176   gtk_box_pack_start (GTK_BOX (main_box), toolbar, FALSE, TRUE, 0);
177 
178   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
179   gtk_box_pack_start (GTK_BOX (main_box), box, FALSE, TRUE, 0);
180 
181   container = gtk_scrolled_window_new (NULL, NULL);
182   gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (container), 200);
183   gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (container), 200);
184   gtk_box_pack_start (GTK_BOX (main_box), container, TRUE, TRUE, 0);
185   child = gtk_text_view_new_with_buffer (css);
186   gtk_container_add (GTK_CONTAINER (container), child);
187   g_signal_connect (css,
188                     "changed",
189                     G_CALLBACK (css_text_changed),
190                     provider);
191   gtk_text_buffer_set_text (css,
192                             DEFAULT_CSS,
193                             -1);
194   g_signal_connect (provider,
195                     "parsing-error",
196                     G_CALLBACK (show_parsing_error),
197                     gtk_text_view_get_buffer (GTK_TEXT_VIEW (child)));
198 
199   container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
200   gtk_box_pack_start (GTK_BOX (main_box), container, FALSE, TRUE, 0);
201   child = gtk_switch_new ();
202   gtk_switch_set_active (GTK_SWITCH (child), gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR);
203   g_signal_connect (child,
204                     "notify::active",
205                     G_CALLBACK (set_orientation),
206                     NULL);
207   gtk_box_pack_start (GTK_BOX (container), child, FALSE, FALSE, 0);
208   child = gtk_label_new ("left-to-right");
209   gtk_box_pack_start (GTK_BOX (container), child, FALSE, FALSE, 0);
210   child = gtk_button_new_with_label ("Add button");
211   g_signal_connect_swapped (child,
212                             "clicked",
213                             G_CALLBACK (add_button),
214                             box);
215   gtk_box_pack_end (GTK_BOX (container), child, FALSE, FALSE, 0);
216   child = gtk_button_new_with_label ("Add toolbutton");
217   g_signal_connect_swapped (child,
218                             "clicked",
219                             G_CALLBACK (add_toolbutton),
220                             toolbar);
221   gtk_box_pack_end (GTK_BOX (container), child, FALSE, FALSE, 0);
222 
223   add_toolbutton (GTK_TOOLBAR (toolbar));
224   add_toolbutton (GTK_TOOLBAR (toolbar));
225   add_toolbutton (GTK_TOOLBAR (toolbar));
226   add_toolbutton (GTK_TOOLBAR (toolbar));
227 
228   add_button (GTK_BOX (box));
229   add_button (GTK_BOX (box));
230   add_button (GTK_BOX (box));
231   add_button (GTK_BOX (box));
232 
233   gtk_widget_show_all (window);
234 
235   gtk_main ();
236 
237   return 0;
238 }
239