]> Pileus Git - ~andy/gtk/blob - tests/testadjustsize.c
stylecontext: Do invalidation on first resize container
[~andy/gtk] / tests / testadjustsize.c
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_VERTICAL_LABEL,
28   TEST_WIDGET_WRAP_LABEL,
29   TEST_WIDGET_ALIGNMENT,
30   TEST_WIDGET_IMAGE,
31   TEST_WIDGET_BUTTON,
32   TEST_WIDGET_LAST
33 };
34
35 static GtkWidget *test_widgets[TEST_WIDGET_LAST];
36
37 static GtkWidget*
38 create_image (void)
39 {
40   return gtk_image_new_from_stock (GTK_STOCK_OPEN,
41                                    GTK_ICON_SIZE_BUTTON);
42 }
43
44 static GtkWidget*
45 create_label (gboolean vertical,
46               gboolean wrap)
47 {
48   GtkWidget *widget;
49
50   widget = gtk_label_new ("This is a label, label label label");
51
52   if (vertical)
53     gtk_label_set_angle (GTK_LABEL (widget), 90);
54
55   if (wrap)
56     gtk_label_set_line_wrap (GTK_LABEL (widget), TRUE);
57
58   return widget;
59 }
60
61 static GtkWidget*
62 create_button (void)
63 {
64   return gtk_button_new_with_label ("BUTTON!");
65 }
66
67 static gboolean
68 on_draw_alignment (GtkWidget      *widget,
69                    cairo_t        *cr,
70                    void           *data)
71 {
72   cairo_set_source_rgb (cr, 1.0, 0.0, 0.0);
73   cairo_paint (cr);
74
75   return FALSE;
76 }
77
78 static GtkWidget*
79 create_alignment (void)
80 {
81   GtkWidget *alignment;
82
83   alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
84
85   /* make the alignment visible */
86   gtk_widget_set_redraw_on_allocate (alignment, TRUE);
87   g_signal_connect (G_OBJECT (alignment),
88                     "draw",
89                     G_CALLBACK (on_draw_alignment),
90                     NULL);
91
92   return alignment;
93 }
94
95 static void
96 open_test_window (void)
97 {
98   GtkWidget *grid;
99   int i;
100
101   test_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
102   gtk_window_set_title (GTK_WINDOW (test_window), "Tests");
103
104   g_signal_connect (test_window, "delete-event",
105                     G_CALLBACK (gtk_main_quit), test_window);
106
107   gtk_window_set_resizable (GTK_WINDOW (test_window), FALSE);
108
109   test_widgets[TEST_WIDGET_IMAGE] = create_image ();
110   test_widgets[TEST_WIDGET_LABEL] = create_label (FALSE, FALSE);
111   test_widgets[TEST_WIDGET_VERTICAL_LABEL] = create_label (TRUE, FALSE);
112   test_widgets[TEST_WIDGET_WRAP_LABEL] = create_label (FALSE, TRUE);
113   test_widgets[TEST_WIDGET_BUTTON] = create_button ();
114   test_widgets[TEST_WIDGET_ALIGNMENT] = create_alignment ();
115
116   grid = gtk_grid_new ();
117
118   gtk_container_add (GTK_CONTAINER (test_window), grid);
119
120   for (i = 0; i < TEST_WIDGET_LAST; ++i)
121     {
122       gtk_grid_attach (GTK_GRID (grid), test_widgets[i], i % 3, i / 3, 1, 1);
123     }
124
125   gtk_widget_show_all (test_window);
126 }
127
128 static void
129 on_toggle_border_widths (GtkToggleButton *button,
130                          void            *data)
131 {
132   gboolean has_border;
133   int i;
134
135   has_border = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
136
137   for (i = 0; i < TEST_WIDGET_LAST; ++i)
138     {
139       if (GTK_IS_CONTAINER (test_widgets[i]))
140         {
141           gtk_container_set_border_width (GTK_CONTAINER (test_widgets[i]),
142                                           has_border ? 50 : 0);
143         }
144     }
145 }
146
147 static void
148 on_set_small_size_requests (GtkToggleButton *button,
149                             void            *data)
150 {
151   gboolean has_small_size_requests;
152   int i;
153
154   has_small_size_requests = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
155
156   for (i = 0; i < TEST_WIDGET_LAST; ++i)
157     {
158       gtk_widget_set_size_request (test_widgets[i],
159                                    has_small_size_requests ? 5 : -1,
160                                    has_small_size_requests ? 5 : -1);
161     }
162 }
163
164 static void
165 on_set_large_size_requests (GtkToggleButton *button,
166                             void            *data)
167 {
168   gboolean has_large_size_requests;
169   int i;
170
171   has_large_size_requests = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
172
173   for (i = 0; i < TEST_WIDGET_LAST; ++i)
174     {
175       gtk_widget_set_size_request (test_widgets[i],
176                                    has_large_size_requests ? 200 : -1,
177                                    has_large_size_requests ? 200 : -1);
178     }
179 }
180
181 static void
182 open_control_window (void)
183 {
184   GtkWidget *window;
185   GtkWidget *box;
186   GtkWidget *toggle;
187
188   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
189   gtk_window_set_title (GTK_WINDOW (window), "Controls");
190
191   g_signal_connect (window, "delete-event",
192                     G_CALLBACK (gtk_main_quit), window);
193
194   box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
195   gtk_container_add (GTK_CONTAINER (window), box);
196
197   toggle =
198     gtk_toggle_button_new_with_label ("Containers have borders");
199   g_signal_connect (G_OBJECT (toggle),
200                     "toggled", G_CALLBACK (on_toggle_border_widths),
201                     NULL);
202   gtk_container_add (GTK_CONTAINER (box), toggle);
203
204   toggle =
205     gtk_toggle_button_new_with_label ("Set small size requests");
206   g_signal_connect (G_OBJECT (toggle),
207                     "toggled", G_CALLBACK (on_set_small_size_requests),
208                     NULL);
209   gtk_container_add (GTK_CONTAINER (box), toggle);
210
211   toggle =
212     gtk_toggle_button_new_with_label ("Set large size requests");
213   g_signal_connect (G_OBJECT (toggle),
214                     "toggled", G_CALLBACK (on_set_large_size_requests),
215                     NULL);
216   gtk_container_add (GTK_CONTAINER (box), toggle);
217
218
219   gtk_widget_show_all (window);
220 }
221
222 #define TEST_WIDGET(outer) (gtk_bin_get_child (GTK_BIN (gtk_bin_get_child (GTK_BIN(outer)))))
223
224 static GtkWidget*
225 create_widget_visible_border (const char *text)
226 {
227   GtkWidget *outer_box;
228   GtkWidget *inner_box;
229   GtkWidget *test_widget;
230   GtkWidget *label;
231   GdkRGBA color;
232
233   outer_box = gtk_event_box_new ();
234   gdk_rgba_parse (&color, "black");
235   gtk_widget_override_background_color (outer_box, 0, &color);
236
237   inner_box = gtk_event_box_new ();
238   gtk_container_set_border_width (GTK_CONTAINER (inner_box), 5);
239   gdk_rgba_parse (&color, "blue");
240   gtk_widget_override_background_color (inner_box, 0, &color);
241
242   gtk_container_add (GTK_CONTAINER (outer_box), inner_box);
243
244
245   test_widget = gtk_event_box_new ();
246   gdk_rgba_parse (&color, "red");
247   gtk_widget_override_background_color (test_widget, 0, &color);
248
249   gtk_container_add (GTK_CONTAINER (inner_box), test_widget);
250
251   label = gtk_label_new (text);
252   gtk_container_add (GTK_CONTAINER (test_widget), label);
253
254   g_assert (TEST_WIDGET (outer_box) == test_widget);
255
256   gtk_widget_show_all (outer_box);
257
258   return outer_box;
259 }
260
261 static const char*
262 enum_to_string (GType enum_type,
263                 int   value)
264 {
265   GEnumValue *v;
266
267   v = g_enum_get_value (g_type_class_peek (enum_type), value);
268
269   return v->value_nick;
270 }
271
272 static GtkWidget*
273 create_aligned (GtkAlign halign,
274                 GtkAlign valign)
275 {
276   GtkWidget *widget;
277   char *label;
278
279   label = g_strdup_printf ("h=%s v=%s",
280                            enum_to_string (GTK_TYPE_ALIGN, halign),
281                            enum_to_string (GTK_TYPE_ALIGN, valign));
282
283   widget = create_widget_visible_border (label);
284
285   g_object_set (G_OBJECT (TEST_WIDGET (widget)),
286                 "halign", halign,
287                 "valign", valign,
288                 "hexpand", TRUE,
289                 "vexpand", TRUE,
290                 NULL);
291
292   return widget;
293 }
294
295 static void
296 open_alignment_window (void)
297 {
298   GtkWidget *grid;
299   int i;
300   GEnumClass *align_class;
301
302   test_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
303   gtk_window_set_title (GTK_WINDOW (test_window), "Alignment");
304
305   g_signal_connect (test_window, "delete-event",
306                     G_CALLBACK (gtk_main_quit), test_window);
307
308   gtk_window_set_resizable (GTK_WINDOW (test_window), TRUE);
309   gtk_window_set_default_size (GTK_WINDOW (test_window), 500, 500);
310
311   align_class = g_type_class_peek (GTK_TYPE_ALIGN);
312
313   grid = gtk_grid_new ();
314   gtk_grid_set_row_homogeneous (GTK_GRID (grid), TRUE);
315   gtk_grid_set_column_homogeneous (GTK_GRID (grid), TRUE);
316
317   gtk_container_add (GTK_CONTAINER (test_window), grid);
318
319   for (i = 0; i < align_class->n_values; ++i)
320     {
321       int j;
322       for (j = 0; j < align_class->n_values; ++j)
323         {
324           GtkWidget *child =
325             create_aligned(align_class->values[i].value,
326                            align_class->values[j].value);
327
328           gtk_grid_attach (GTK_GRID (grid), child, i, j, 1, 1);
329         }
330     }
331
332   gtk_widget_show_all (test_window);
333 }
334
335 static GtkWidget*
336 create_margined (const char *propname)
337 {
338   GtkWidget *widget;
339
340   widget = create_widget_visible_border (propname);
341
342   g_object_set (G_OBJECT (TEST_WIDGET (widget)),
343                 propname, 15,
344                 "hexpand", TRUE,
345                 "vexpand", TRUE,
346                 NULL);
347
348   return widget;
349 }
350
351 static void
352 open_margin_window (void)
353 {
354   GtkWidget *box;
355   int i;
356   const char * margins[] = {
357     "margin-left",
358     "margin-right",
359     "margin-top",
360     "margin-bottom",
361     "margin"
362   };
363
364   test_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
365   gtk_window_set_title (GTK_WINDOW (test_window), "Margin");
366
367   g_signal_connect (test_window, "delete-event",
368                     G_CALLBACK (gtk_main_quit), test_window);
369
370   gtk_window_set_resizable (GTK_WINDOW (test_window), TRUE);
371
372   box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
373
374   gtk_container_add (GTK_CONTAINER (test_window), box);
375
376   for (i = 0; i < (int) G_N_ELEMENTS (margins); ++i)
377     {
378       GtkWidget *child =
379         create_margined(margins[i]);
380
381       gtk_container_add (GTK_CONTAINER (box), child);
382     }
383
384   gtk_widget_show_all (test_window);
385 }
386
387 static void
388 open_valigned_label_window (void)
389 {
390   GtkWidget *window, *box, *label, *frame;
391
392   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
393
394   g_signal_connect (test_window, "delete-event",
395                     G_CALLBACK (gtk_main_quit), test_window);
396
397   box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
398   gtk_widget_show (box);
399   gtk_container_add (GTK_CONTAINER (window), box);
400
401   label = gtk_label_new ("Both labels expand");
402   gtk_widget_show (label);
403   gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0);
404
405   label = gtk_label_new ("Some wrapping text with width-chars = 15 and max-width-chars = 35");
406   gtk_label_set_line_wrap  (GTK_LABEL (label), TRUE);
407   gtk_label_set_width_chars  (GTK_LABEL (label), 15);
408   gtk_label_set_max_width_chars  (GTK_LABEL (label), 35);
409
410   gtk_widget_show (label);
411
412   frame  = gtk_frame_new (NULL);
413   gtk_widget_show (frame);
414   gtk_container_add (GTK_CONTAINER (frame), label);
415
416   gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
417   gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
418
419   gtk_box_pack_start (GTK_BOX (box), frame, TRUE, TRUE, 0);
420
421   gtk_window_present (GTK_WINDOW (window));
422 }
423
424 int
425 main (int argc, char *argv[])
426 {
427   gtk_init (&argc, &argv);
428
429   if (g_getenv ("RTL"))
430     gtk_widget_set_default_direction (GTK_TEXT_DIR_RTL);
431
432   open_test_window ();
433   open_control_window ();
434   open_alignment_window ();
435   open_margin_window ();
436   open_valigned_label_window ();
437
438   gtk_main ();
439
440   return 0;
441 }