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