]> Pileus Git - ~andy/gtk/blob - tests/testboxcss.c
tests: Add a cute demo and test app for the new box css
[~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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 #include "config.h"
21 #include <gtk/gtk.h>
22 #include "prop-editor.h"
23
24 /* This is exactly the style information you've been looking for */
25 #define GTK_STYLE_PROVIDER_PRIORITY_FORCE G_MAXUINT
26
27 #define DEFAULT_CSS \
28   ".play {\n" \
29   "  engine: none;\n" \
30   "  background-image: none;\n" \
31   "  background-color: red;\n" \
32   "  border-color: black;\n" \
33   "  border-radius: 0;\n" \
34   "}\n" \
35   "\n" \
36   ".play:nth-child(even) {\n" \
37   "  background-color: yellow\n" \
38   "}\n" \
39   "\n" \
40   ".play:nth-child(first) {\n" \
41   "  border-radius: 5 0 0 5;\n" \
42   "}\n" \
43   "\n" \
44   ".play:nth-child(last) {\n" \
45   "  border-radius: 0 5 5 0;\n" \
46   "}\n" \
47   "\n"
48
49 static void
50 show_parsing_error (GtkCssProvider *provider,
51                     const gchar    *path,
52                     guint           line,
53                     guint           position,
54                     const GError   *error,
55                     GtkTextBuffer  *buffer)
56 {
57   GtkTextIter start, end;
58   const char *tag_name;
59
60   gtk_text_buffer_get_iter_at_line (buffer, &start, line - 1);
61   if (gtk_text_buffer_get_line_count (buffer) <= line)
62     gtk_text_buffer_get_end_iter (buffer, &end);
63   else
64     gtk_text_buffer_get_iter_at_line (buffer, &end, line);
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 void
99 add_widget (GtkBox *box)
100 {
101   static int count = 0;
102   GtkWidget* button;
103   char *text;
104
105   text = g_strdup_printf ("Remove %d", ++count);
106   button = gtk_button_new_from_stock (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
118 set_orientation (GtkSwitch *switch_)
119 {
120   gtk_widget_set_default_direction (gtk_switch_get_active (switch_) ? GTK_TEXT_DIR_LTR : GTK_TEXT_DIR_RTL);
121 }
122
123 gint
124 main (gint argc, gchar **argv)
125 {
126   GtkWidget *window, *main_box, *box, *container, *child;
127   GtkStyleProvider *provider;
128   GtkTextBuffer *css;
129   
130   gtk_init (&argc, &argv);
131
132   css = gtk_text_buffer_new (NULL);
133   gtk_text_buffer_create_tag (css,
134                               "warning",
135                               "background", "rgba(255,255,0,0.3)",
136                               NULL);
137   gtk_text_buffer_create_tag (css,
138                               "error",
139                               "background", "rgba(255,0,0,0.3)",
140                               NULL);
141
142   provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
143   gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
144                                              provider,
145                                              GTK_STYLE_PROVIDER_PRIORITY_FORCE);
146   
147   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
148
149   g_signal_connect (window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
150   g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
151
152   main_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
153   gtk_container_add (GTK_CONTAINER (window), main_box);
154
155   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
156   gtk_box_pack_start (GTK_BOX (main_box), box, FALSE, TRUE, 0);
157
158   container = gtk_scrolled_window_new (NULL, NULL);
159   gtk_scrolled_window_set_min_content_width (GTK_SCROLLED_WINDOW (container), 200);
160   gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (container), 200);
161   gtk_box_pack_start (GTK_BOX (main_box), container, TRUE, TRUE, 0);
162   child = gtk_text_view_new_with_buffer (css);
163   gtk_container_add (GTK_CONTAINER (container), child);
164   g_signal_connect (css,
165                     "changed",
166                     G_CALLBACK (css_text_changed),
167                     provider);
168   gtk_text_buffer_set_text (css,
169                             DEFAULT_CSS,
170                             -1);
171   g_signal_connect (provider,
172                     "parsing-error",
173                     G_CALLBACK (show_parsing_error),
174                     gtk_text_view_get_buffer (GTK_TEXT_VIEW (child)));
175
176   container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
177   gtk_box_pack_start (GTK_BOX (main_box), container, FALSE, TRUE, 0);
178   child = gtk_switch_new ();
179   gtk_switch_set_active (GTK_SWITCH (child), gtk_widget_get_default_direction () == GTK_TEXT_DIR_LTR);
180   g_signal_connect (child,
181                     "notify::active",
182                     G_CALLBACK (set_orientation),
183                     NULL);
184   gtk_box_pack_start (GTK_BOX (container), child, FALSE, FALSE, 0);
185   child = gtk_label_new ("left-to-right");
186   gtk_box_pack_start (GTK_BOX (container), child, FALSE, FALSE, 0);
187   child = gtk_button_new_with_label ("Add widget");
188   g_signal_connect_swapped (child,
189                             "clicked",
190                             G_CALLBACK (add_widget),
191                             box);
192   gtk_box_pack_end (GTK_BOX (container), child, FALSE, FALSE, 0);
193
194   add_widget (GTK_BOX (box));
195   add_widget (GTK_BOX (box));
196   add_widget (GTK_BOX (box));
197   add_widget (GTK_BOX (box));
198
199   gtk_widget_show_all (window);
200
201   gtk_main ();
202   
203   return 0;
204 }