1 | /* Theming/Animated Backgrounds |
2 | * |
3 | * This demo is in honour of a classic Pixbufs demo. |
4 | * |
5 | * It is done exclusively with CSS as the background of the window. |
6 | */ |
7 | |
8 | #include <gtk/gtk.h> |
9 | |
10 | static void |
11 | show_parsing_error (GtkCssProvider *provider, |
12 | GtkCssSection *section, |
13 | const GError *error, |
14 | GtkTextBuffer *buffer) |
15 | { |
16 | const GtkCssLocation *start_location, *end_location; |
17 | GtkTextIter start, end; |
18 | const char *tag_name; |
19 | |
20 | start_location = gtk_css_section_get_start_location (section); |
21 | gtk_text_buffer_get_iter_at_line_index (buffer, |
22 | iter: &start, |
23 | line_number: start_location->lines, |
24 | byte_index: start_location->line_bytes); |
25 | end_location = gtk_css_section_get_end_location (section); |
26 | gtk_text_buffer_get_iter_at_line_index (buffer, |
27 | iter: &end, |
28 | line_number: end_location->lines, |
29 | byte_index: end_location->line_bytes); |
30 | |
31 | |
32 | if (error->domain == GTK_CSS_PARSER_WARNING) |
33 | tag_name = "warning" ; |
34 | else |
35 | tag_name = "error" ; |
36 | |
37 | gtk_text_buffer_apply_tag_by_name (buffer, name: tag_name, start: &start, end: &end); |
38 | } |
39 | |
40 | static void |
41 | css_text_changed (GtkTextBuffer *buffer, |
42 | GtkCssProvider *provider) |
43 | { |
44 | GtkTextIter start, end; |
45 | char *text; |
46 | |
47 | gtk_text_buffer_get_start_iter (buffer, iter: &start); |
48 | gtk_text_buffer_get_end_iter (buffer, iter: &end); |
49 | gtk_text_buffer_remove_all_tags (buffer, start: &start, end: &end); |
50 | |
51 | text = gtk_text_buffer_get_text (buffer, start: &start, end: &end, FALSE); |
52 | gtk_css_provider_load_from_data (css_provider: provider, data: text, length: -1); |
53 | g_free (mem: text); |
54 | } |
55 | |
56 | static void |
57 | apply_css (GtkWidget *widget, GtkStyleProvider *provider) |
58 | { |
59 | GtkWidget *child; |
60 | |
61 | gtk_style_context_add_provider (context: gtk_widget_get_style_context (widget), provider, G_MAXUINT); |
62 | for (child = gtk_widget_get_first_child (widget); |
63 | child != NULL; |
64 | child = gtk_widget_get_next_sibling (widget: child)) |
65 | apply_css (widget: child, provider); |
66 | } |
67 | |
68 | GtkWidget * |
69 | do_css_pixbufs (GtkWidget *do_widget) |
70 | { |
71 | static GtkWidget *window = NULL; |
72 | |
73 | if (!window) |
74 | { |
75 | GtkWidget *paned, *container, *child; |
76 | GtkStyleProvider *provider; |
77 | GtkTextBuffer *text; |
78 | GBytes *bytes; |
79 | |
80 | window = gtk_window_new (); |
81 | gtk_window_set_title (GTK_WINDOW (window), title: "Animated Backgrounds" ); |
82 | gtk_window_set_transient_for (GTK_WINDOW (window), GTK_WINDOW (do_widget)); |
83 | gtk_window_set_default_size (GTK_WINDOW (window), width: 400, height: 300); |
84 | g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window); |
85 | |
86 | paned = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL); |
87 | gtk_window_set_child (GTK_WINDOW (window), child: paned); |
88 | |
89 | /* Need a filler so we get a handle */ |
90 | child = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0); |
91 | gtk_paned_set_start_child (GTK_PANED (paned), child); |
92 | |
93 | text = gtk_text_buffer_new (NULL); |
94 | gtk_text_buffer_create_tag (buffer: text, |
95 | tag_name: "warning" , |
96 | first_property_name: "underline" , PANGO_UNDERLINE_SINGLE, |
97 | NULL); |
98 | gtk_text_buffer_create_tag (buffer: text, |
99 | tag_name: "error" , |
100 | first_property_name: "underline" , PANGO_UNDERLINE_ERROR, |
101 | NULL); |
102 | |
103 | provider = GTK_STYLE_PROVIDER (gtk_css_provider_new ()); |
104 | |
105 | container = gtk_scrolled_window_new (); |
106 | gtk_paned_set_end_child (GTK_PANED (paned), child: container); |
107 | child = gtk_text_view_new_with_buffer (buffer: text); |
108 | gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (container), child); |
109 | g_signal_connect (text, "changed" , |
110 | G_CALLBACK (css_text_changed), provider); |
111 | |
112 | bytes = g_resources_lookup_data (path: "/css_pixbufs/gtk.css" , lookup_flags: 0, NULL); |
113 | gtk_text_buffer_set_text (buffer: text, text: g_bytes_get_data (bytes, NULL), len: g_bytes_get_size (bytes)); |
114 | g_bytes_unref (bytes); |
115 | |
116 | g_signal_connect (provider, |
117 | "parsing-error" , |
118 | G_CALLBACK (show_parsing_error), |
119 | gtk_text_view_get_buffer (GTK_TEXT_VIEW (child))); |
120 | |
121 | apply_css (widget: window, provider); |
122 | } |
123 | |
124 | if (!gtk_widget_get_visible (widget: window)) |
125 | gtk_widget_show (widget: window); |
126 | else |
127 | gtk_window_destroy (GTK_WINDOW (window)); |
128 | |
129 | return window; |
130 | } |
131 | |