1 | /* testadjustsize.c |
2 | * Copyright (C) 2010 Havoc Pennington |
3 | * |
4 | * Author: |
5 | * Havoc Pennington <hp@pobox.com> |
6 | * |
7 | * This library is free software; you can redistribute it and/or |
8 | * modify it under the terms of the GNU Library General Public |
9 | * License as published by the Free Software Foundation; either |
10 | * version 2 of the License, or (at your option) any later version. |
11 | * |
12 | * This library is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | * Library General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU Library General Public |
18 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
19 | */ |
20 | |
21 | #include <gtk/gtk.h> |
22 | |
23 | static GtkWidget *test_window; |
24 | |
25 | enum { |
26 | TEST_WIDGET_LABEL, |
27 | TEST_WIDGET_WRAP_LABEL, |
28 | TEST_WIDGET_IMAGE, |
29 | TEST_WIDGET_BUTTON, |
30 | TEST_WIDGET_LAST |
31 | }; |
32 | |
33 | static gboolean done = FALSE; |
34 | static GtkWidget *test_widgets[TEST_WIDGET_LAST]; |
35 | |
36 | static GtkWidget* |
37 | create_image (void) |
38 | { |
39 | return gtk_image_new_from_icon_name (icon_name: "document-open" ); |
40 | } |
41 | |
42 | static GtkWidget* |
43 | create_label (gboolean wrap) |
44 | { |
45 | GtkWidget *widget; |
46 | |
47 | widget = gtk_label_new (str: "This is a label, label label label" ); |
48 | |
49 | if (wrap) |
50 | gtk_label_set_wrap (GTK_LABEL (widget), TRUE); |
51 | |
52 | return widget; |
53 | } |
54 | |
55 | static GtkWidget* |
56 | create_button (void) |
57 | { |
58 | return gtk_button_new_with_label (label: "BUTTON!" ); |
59 | } |
60 | |
61 | static void |
62 | quit_cb (GtkWidget *widget, |
63 | gpointer data) |
64 | { |
65 | gboolean *is_done = data; |
66 | |
67 | *is_done = TRUE; |
68 | |
69 | g_main_context_wakeup (NULL); |
70 | } |
71 | |
72 | static void |
73 | open_test_window (void) |
74 | { |
75 | GtkWidget *grid; |
76 | int i; |
77 | |
78 | test_window = gtk_window_new (); |
79 | gtk_window_set_title (GTK_WINDOW (test_window), title: "Tests" ); |
80 | |
81 | g_signal_connect (test_window, "destroy" , G_CALLBACK (quit_cb), &done); |
82 | |
83 | gtk_window_set_resizable (GTK_WINDOW (test_window), FALSE); |
84 | |
85 | test_widgets[TEST_WIDGET_IMAGE] = create_image (); |
86 | test_widgets[TEST_WIDGET_LABEL] = create_label (FALSE); |
87 | test_widgets[TEST_WIDGET_WRAP_LABEL] = create_label (TRUE); |
88 | test_widgets[TEST_WIDGET_BUTTON] = create_button (); |
89 | |
90 | grid = gtk_grid_new (); |
91 | |
92 | gtk_window_set_child (GTK_WINDOW (test_window), child: grid); |
93 | |
94 | for (i = 0; i < TEST_WIDGET_LAST; ++i) |
95 | { |
96 | gtk_grid_attach (GTK_GRID (grid), child: test_widgets[i], column: i % 3, row: i / 3, width: 1, height: 1); |
97 | } |
98 | |
99 | gtk_widget_show (widget: test_window); |
100 | } |
101 | |
102 | static void |
103 | on_set_small_size_requests (GtkToggleButton *button, |
104 | void *data) |
105 | { |
106 | gboolean has_small_size_requests; |
107 | int i; |
108 | |
109 | has_small_size_requests = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); |
110 | |
111 | for (i = 0; i < TEST_WIDGET_LAST; ++i) |
112 | { |
113 | gtk_widget_set_size_request (widget: test_widgets[i], |
114 | width: has_small_size_requests ? 5 : -1, |
115 | height: has_small_size_requests ? 5 : -1); |
116 | } |
117 | } |
118 | |
119 | static void |
120 | on_set_large_size_requests (GtkToggleButton *button, |
121 | void *data) |
122 | { |
123 | gboolean has_large_size_requests; |
124 | int i; |
125 | |
126 | has_large_size_requests = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)); |
127 | |
128 | for (i = 0; i < TEST_WIDGET_LAST; ++i) |
129 | { |
130 | gtk_widget_set_size_request (widget: test_widgets[i], |
131 | width: has_large_size_requests ? 200 : -1, |
132 | height: has_large_size_requests ? 200 : -1); |
133 | } |
134 | } |
135 | |
136 | static void |
137 | open_control_window (void) |
138 | { |
139 | GtkWidget *window; |
140 | GtkWidget *box; |
141 | GtkWidget *toggle; |
142 | |
143 | window = gtk_window_new (); |
144 | gtk_window_set_title (GTK_WINDOW (window), title: "Controls" ); |
145 | |
146 | g_signal_connect (window, "destroy" , G_CALLBACK (quit_cb), &done); |
147 | |
148 | box = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0); |
149 | gtk_window_set_child (GTK_WINDOW (window), child: box); |
150 | |
151 | toggle = |
152 | gtk_toggle_button_new_with_label (label: "Set small size requests" ); |
153 | g_signal_connect (G_OBJECT (toggle), |
154 | "toggled" , G_CALLBACK (on_set_small_size_requests), |
155 | NULL); |
156 | gtk_box_append (GTK_BOX (box), child: toggle); |
157 | |
158 | toggle = |
159 | gtk_toggle_button_new_with_label (label: "Set large size requests" ); |
160 | g_signal_connect (G_OBJECT (toggle), |
161 | "toggled" , G_CALLBACK (on_set_large_size_requests), |
162 | NULL); |
163 | gtk_box_append (GTK_BOX (box), child: toggle); |
164 | |
165 | |
166 | gtk_widget_show (widget: window); |
167 | } |
168 | |
169 | #define TEST_WIDGET(outer) (gtk_overlay_get_child (GTK_OVERLAY (gtk_overlay_get_child (GTK_OVERLAY (outer))))) |
170 | |
171 | static GtkWidget* |
172 | create_widget_visible_border (const char *text) |
173 | { |
174 | GtkWidget *outer_box; |
175 | GtkWidget *inner_box; |
176 | GtkWidget *test_widget; |
177 | GtkWidget *label; |
178 | |
179 | outer_box = gtk_overlay_new (); |
180 | gtk_widget_add_css_class (widget: outer_box, css_class: "black-bg" ); |
181 | |
182 | inner_box = gtk_overlay_new (); |
183 | gtk_widget_add_css_class (widget: inner_box, css_class: "blue-bg" ); |
184 | |
185 | gtk_overlay_set_child (GTK_OVERLAY (outer_box), child: inner_box); |
186 | |
187 | |
188 | test_widget = gtk_overlay_new (); |
189 | gtk_widget_add_css_class (widget: test_widget, css_class: "red-bg" ); |
190 | |
191 | gtk_overlay_set_child (GTK_OVERLAY (inner_box), child: test_widget); |
192 | |
193 | label = gtk_label_new (str: text); |
194 | gtk_overlay_set_child (GTK_OVERLAY (test_widget), child: label); |
195 | |
196 | g_assert (TEST_WIDGET (outer_box) == test_widget); |
197 | |
198 | return outer_box; |
199 | } |
200 | |
201 | static const char* |
202 | enum_to_string (GType enum_type, |
203 | int value) |
204 | { |
205 | GEnumValue *v; |
206 | |
207 | v = g_enum_get_value (enum_class: g_type_class_peek (type: enum_type), value); |
208 | |
209 | return v->value_nick; |
210 | } |
211 | |
212 | static GtkWidget* |
213 | create_aligned (GtkAlign halign, |
214 | GtkAlign valign) |
215 | { |
216 | GtkWidget *widget; |
217 | char *label; |
218 | |
219 | label = g_strdup_printf (format: "h=%s v=%s" , |
220 | enum_to_string (enum_type: GTK_TYPE_ALIGN, value: halign), |
221 | enum_to_string (enum_type: GTK_TYPE_ALIGN, value: valign)); |
222 | |
223 | widget = create_widget_visible_border (text: label); |
224 | |
225 | g_object_set (G_OBJECT (TEST_WIDGET (widget)), |
226 | first_property_name: "halign" , halign, |
227 | "valign" , valign, |
228 | "hexpand" , TRUE, |
229 | "vexpand" , TRUE, |
230 | NULL); |
231 | |
232 | return widget; |
233 | } |
234 | |
235 | static void |
236 | open_alignment_window (void) |
237 | { |
238 | GtkWidget *grid; |
239 | int i; |
240 | GEnumClass *align_class; |
241 | |
242 | test_window = gtk_window_new (); |
243 | gtk_window_set_title (GTK_WINDOW (test_window), title: "Alignment" ); |
244 | |
245 | g_signal_connect (test_window, "destroy" , G_CALLBACK (quit_cb), &done); |
246 | |
247 | gtk_window_set_resizable (GTK_WINDOW (test_window), TRUE); |
248 | gtk_window_set_default_size (GTK_WINDOW (test_window), width: 500, height: 500); |
249 | |
250 | align_class = g_type_class_peek (type: GTK_TYPE_ALIGN); |
251 | |
252 | grid = gtk_grid_new (); |
253 | gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE); |
254 | gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE); |
255 | |
256 | gtk_window_set_child (GTK_WINDOW (test_window), child: grid); |
257 | |
258 | for (i = 0; i < align_class->n_values; ++i) |
259 | { |
260 | int j; |
261 | for (j = 0; j < align_class->n_values; ++j) |
262 | { |
263 | GtkWidget *child = |
264 | create_aligned(halign: align_class->values[i].value, |
265 | valign: align_class->values[j].value); |
266 | |
267 | gtk_grid_attach (GTK_GRID (grid), child, column: i, row: j, width: 1, height: 1); |
268 | } |
269 | } |
270 | |
271 | gtk_widget_show (widget: test_window); |
272 | } |
273 | |
274 | static GtkWidget* |
275 | create_margined (const char *propname) |
276 | { |
277 | GtkWidget *widget; |
278 | |
279 | widget = create_widget_visible_border (text: propname); |
280 | |
281 | g_object_set (G_OBJECT (TEST_WIDGET (widget)), |
282 | first_property_name: propname, 15, |
283 | "hexpand" , TRUE, |
284 | "vexpand" , TRUE, |
285 | NULL); |
286 | |
287 | return widget; |
288 | } |
289 | |
290 | static void |
291 | open_margin_window (void) |
292 | { |
293 | GtkWidget *box; |
294 | int i; |
295 | const char *margins[] = { |
296 | "margin-start" , |
297 | "margin-end" , |
298 | "margin-top" , |
299 | "margin-bottom" |
300 | }; |
301 | |
302 | test_window = gtk_window_new (); |
303 | gtk_window_set_title (GTK_WINDOW (test_window), title: "Margin" ); |
304 | |
305 | g_signal_connect (test_window, "destroy" , G_CALLBACK (quit_cb), &done); |
306 | |
307 | gtk_window_set_resizable (GTK_WINDOW (test_window), TRUE); |
308 | |
309 | box = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0); |
310 | |
311 | gtk_window_set_child (GTK_WINDOW (test_window), child: box); |
312 | |
313 | for (i = 0; i < (int) G_N_ELEMENTS (margins); ++i) |
314 | { |
315 | GtkWidget *child = |
316 | create_margined(propname: margins[i]); |
317 | |
318 | gtk_box_append (GTK_BOX (box), child); |
319 | } |
320 | |
321 | gtk_widget_show (widget: test_window); |
322 | } |
323 | |
324 | static void |
325 | open_valigned_label_window (void) |
326 | { |
327 | GtkWidget *window, *box, *label, *frame; |
328 | |
329 | window = gtk_window_new (); |
330 | |
331 | g_signal_connect (test_window, "destroy" , G_CALLBACK (quit_cb), &done); |
332 | |
333 | box = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0); |
334 | gtk_window_set_child (GTK_WINDOW (window), child: box); |
335 | |
336 | label = gtk_label_new (str: "Both labels expand" ); |
337 | gtk_box_append (GTK_BOX (box), child: label); |
338 | |
339 | label = gtk_label_new (str: "Some wrapping text with width-chars = 15 and max-width-chars = 35" ); |
340 | gtk_label_set_wrap (GTK_LABEL (label), TRUE); |
341 | gtk_label_set_width_chars (GTK_LABEL (label), n_chars: 15); |
342 | gtk_label_set_max_width_chars (GTK_LABEL (label), n_chars: 35); |
343 | |
344 | frame = gtk_frame_new (NULL); |
345 | gtk_frame_set_child (GTK_FRAME (frame), child: label); |
346 | |
347 | gtk_widget_set_valign (widget: frame, align: GTK_ALIGN_CENTER); |
348 | gtk_widget_set_halign (widget: frame, align: GTK_ALIGN_CENTER); |
349 | |
350 | gtk_box_append (GTK_BOX (box), child: frame); |
351 | |
352 | gtk_window_present (GTK_WINDOW (window)); |
353 | } |
354 | |
355 | int |
356 | main (int argc, char *argv[]) |
357 | { |
358 | GtkCssProvider *provider; |
359 | |
360 | gtk_init (); |
361 | |
362 | provider = gtk_css_provider_new (); |
363 | gtk_css_provider_load_from_data (css_provider: provider, |
364 | data: ".black-bg { background-color: black; }" |
365 | ".red-bg { background-color: red; }" |
366 | ".blue-bg { background-color: blue; }" , length: -1); |
367 | gtk_style_context_add_provider_for_display (display: gdk_display_get_default (), |
368 | GTK_STYLE_PROVIDER (provider), |
369 | GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); |
370 | g_object_unref (object: provider); |
371 | |
372 | if (g_getenv (variable: "RTL" )) |
373 | gtk_widget_set_default_direction (dir: GTK_TEXT_DIR_RTL); |
374 | |
375 | open_test_window (); |
376 | open_control_window (); |
377 | open_alignment_window (); |
378 | open_margin_window (); |
379 | open_valigned_label_window (); |
380 | |
381 | while (!done) |
382 | g_main_context_iteration (NULL, TRUE); |
383 | |
384 | return 0; |
385 | } |
386 | |