]> Pileus Git - ~andy/gtk/blob - demos/gtk-demo/css_basics.c
gtk-demo: Use explicit resource:// urls in CSS
[~andy/gtk] / demos / gtk-demo / css_basics.c
1 /* CSS Theming/CSS Basics :: css_basics.css
2  *
3  * Gtk themes are written using CSS. Every widget is build of multiple items
4  * that you can style very similarly to a regular website.
5  *
6  */
7
8 #include <gtk/gtk.h>
9
10 static GtkWidget *window = NULL;
11
12 static void
13 show_parsing_error (GtkCssProvider *provider,
14                     GtkCssSection  *section,
15                     const GError   *error,
16                     GtkTextBuffer  *buffer)
17 {
18   GtkTextIter start, end;
19   const char *tag_name;
20
21   gtk_text_buffer_get_iter_at_line_index (buffer,
22                                           &start,
23                                           gtk_css_section_get_start_line (section),
24                                           gtk_css_section_get_start_position (section));
25   gtk_text_buffer_get_iter_at_line_index (buffer,
26                                           &end,
27                                           gtk_css_section_get_end_line (section),
28                                           gtk_css_section_get_end_position (section));
29
30   if (g_error_matches (error, GTK_CSS_PROVIDER_ERROR, GTK_CSS_PROVIDER_ERROR_DEPRECATED))
31     tag_name = "warning";
32   else
33     tag_name = "error";
34
35   gtk_text_buffer_apply_tag_by_name (buffer, tag_name, &start, &end);
36 }
37                     
38 static void
39 css_text_changed (GtkTextBuffer  *buffer,
40                   GtkCssProvider *provider)
41 {
42   GtkTextIter start, end;
43   char *text;
44
45   gtk_text_buffer_get_start_iter (buffer, &start);
46   gtk_text_buffer_get_end_iter (buffer, &end);
47   gtk_text_buffer_remove_all_tags (buffer, &start, &end);
48
49   text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
50   gtk_css_provider_load_from_data (provider, text, -1, NULL);
51   g_free (text);
52
53   gtk_style_context_reset_widgets (gdk_screen_get_default ());
54 }
55
56 static void
57 apply_css (GtkWidget *widget, GtkStyleProvider *provider)
58 {
59   gtk_style_context_add_provider (gtk_widget_get_style_context (widget), provider, G_MAXUINT);
60   if (GTK_IS_CONTAINER (widget))
61     gtk_container_forall (GTK_CONTAINER (widget), (GtkCallback) apply_css, provider);
62 }
63
64 GtkWidget *
65 do_css_basics (GtkWidget *do_widget)
66 {
67   if (!window)
68     {
69       GtkWidget *container, *child;
70       GtkStyleProvider *provider;
71       GtkTextBuffer *text;
72       GBytes *bytes;
73       
74       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
75       gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget));
76       gtk_window_set_default_size (GTK_WINDOW (window), 400, 300);
77       g_signal_connect (window, "destroy",
78                         G_CALLBACK (gtk_widget_destroyed), &window);
79
80       text = gtk_text_buffer_new (NULL);
81       gtk_text_buffer_create_tag (text,
82                                   "warning",
83                                   "underline", PANGO_UNDERLINE_SINGLE,
84                                   NULL);
85       gtk_text_buffer_create_tag (text,
86                                   "error",
87                                   "underline", PANGO_UNDERLINE_ERROR,
88                                   NULL);
89
90       provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ());
91       
92       container = gtk_scrolled_window_new (NULL, NULL);
93       gtk_container_add (GTK_CONTAINER (window), container);
94       child = gtk_text_view_new_with_buffer (text);
95       gtk_container_add (GTK_CONTAINER (container), child);
96       g_signal_connect (text,
97                         "changed",
98                         G_CALLBACK (css_text_changed),
99                         provider);
100
101       bytes = g_resources_lookup_data ("/css_basics/gtk.css", 0, NULL);
102       gtk_text_buffer_set_text (text, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes));
103       g_bytes_unref (bytes);
104
105       g_signal_connect (provider,
106                         "parsing-error",
107                         G_CALLBACK (show_parsing_error),
108                         gtk_text_view_get_buffer (GTK_TEXT_VIEW (child)));
109
110       apply_css (window, provider);
111     }
112
113   if (!gtk_widget_get_visible (window))
114     gtk_widget_show_all (window);
115   else
116     {
117       gtk_widget_destroy (window);
118       window = NULL;
119     }
120
121   return window;
122 }