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*
create_image(void)37 create_image (void)
38 {
39   return gtk_image_new_from_icon_name ("document-open");
40 }
41 
42 static GtkWidget*
create_label(gboolean wrap)43 create_label (gboolean wrap)
44 {
45   GtkWidget *widget;
46 
47   widget = gtk_label_new ("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*
create_button(void)56 create_button (void)
57 {
58   return gtk_button_new_with_label ("BUTTON!");
59 }
60 
61 static void
quit_cb(GtkWidget * widget,gpointer data)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
open_test_window(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), "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), grid);
93 
94   for (i = 0; i < TEST_WIDGET_LAST; ++i)
95     {
96       gtk_grid_attach (GTK_GRID (grid), test_widgets[i], i % 3, i / 3, 1, 1);
97     }
98 
99   gtk_widget_show (test_window);
100 }
101 
102 static void
on_set_small_size_requests(GtkToggleButton * button,void * data)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 (test_widgets[i],
114                                    has_small_size_requests ? 5 : -1,
115                                    has_small_size_requests ? 5 : -1);
116     }
117 }
118 
119 static void
on_set_large_size_requests(GtkToggleButton * button,void * data)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 (test_widgets[i],
131                                    has_large_size_requests ? 200 : -1,
132                                    has_large_size_requests ? 200 : -1);
133     }
134 }
135 
136 static void
open_control_window(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), "Controls");
145 
146   g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
147 
148   box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
149   gtk_window_set_child (GTK_WINDOW (window), box);
150 
151   toggle =
152     gtk_toggle_button_new_with_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), toggle);
157 
158   toggle =
159     gtk_toggle_button_new_with_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), toggle);
164 
165 
166   gtk_widget_show (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*
create_widget_visible_border(const char * text)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 (outer_box, "black-bg");
181 
182   inner_box = gtk_overlay_new ();
183   gtk_widget_add_css_class (inner_box, "blue-bg");
184 
185   gtk_overlay_set_child (GTK_OVERLAY (outer_box), inner_box);
186 
187 
188   test_widget = gtk_overlay_new ();
189   gtk_widget_add_css_class (test_widget, "red-bg");
190 
191   gtk_overlay_set_child (GTK_OVERLAY (inner_box), test_widget);
192 
193   label = gtk_label_new (text);
194   gtk_overlay_set_child (GTK_OVERLAY (test_widget), label);
195 
196   g_assert (TEST_WIDGET (outer_box) == test_widget);
197 
198   return outer_box;
199 }
200 
201 static const char*
enum_to_string(GType enum_type,int value)202 enum_to_string (GType enum_type,
203                 int   value)
204 {
205   GEnumValue *v;
206 
207   v = g_enum_get_value (g_type_class_peek (enum_type), value);
208 
209   return v->value_nick;
210 }
211 
212 static GtkWidget*
create_aligned(GtkAlign halign,GtkAlign valign)213 create_aligned (GtkAlign halign,
214                 GtkAlign valign)
215 {
216   GtkWidget *widget;
217   char *label;
218 
219   label = g_strdup_printf ("h=%s v=%s",
220                            enum_to_string (GTK_TYPE_ALIGN, halign),
221                            enum_to_string (GTK_TYPE_ALIGN, valign));
222 
223   widget = create_widget_visible_border (label);
224 
225   g_object_set (G_OBJECT (TEST_WIDGET (widget)),
226                 "halign", halign,
227                 "valign", valign,
228                 "hexpand", TRUE,
229                 "vexpand", TRUE,
230                 NULL);
231 
232   return widget;
233 }
234 
235 static void
open_alignment_window(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), "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), 500, 500);
249 
250   align_class = g_type_class_peek (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), 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(align_class->values[i].value,
265                            align_class->values[j].value);
266 
267           gtk_grid_attach (GTK_GRID (grid), child, i, j, 1, 1);
268         }
269     }
270 
271   gtk_widget_show (test_window);
272 }
273 
274 static GtkWidget*
create_margined(const char * propname)275 create_margined (const char *propname)
276 {
277   GtkWidget *widget;
278 
279   widget = create_widget_visible_border (propname);
280 
281   g_object_set (G_OBJECT (TEST_WIDGET (widget)),
282                 propname, 15,
283                 "hexpand", TRUE,
284                 "vexpand", TRUE,
285                 NULL);
286 
287   return widget;
288 }
289 
290 static void
open_margin_window(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), "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 (GTK_ORIENTATION_HORIZONTAL, 0);
310 
311   gtk_window_set_child (GTK_WINDOW (test_window), box);
312 
313   for (i = 0; i < (int) G_N_ELEMENTS (margins); ++i)
314     {
315       GtkWidget *child =
316         create_margined(margins[i]);
317 
318       gtk_box_append (GTK_BOX (box), child);
319     }
320 
321   gtk_widget_show (test_window);
322 }
323 
324 static void
open_valigned_label_window(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 (GTK_ORIENTATION_VERTICAL, 0);
334   gtk_window_set_child (GTK_WINDOW (window), box);
335 
336   label = gtk_label_new ("Both labels expand");
337   gtk_box_append (GTK_BOX (box), label);
338 
339   label = gtk_label_new ("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), 15);
342   gtk_label_set_max_width_chars  (GTK_LABEL (label), 35);
343 
344   frame  = gtk_frame_new (NULL);
345   gtk_frame_set_child (GTK_FRAME (frame), label);
346 
347   gtk_widget_set_valign (frame, GTK_ALIGN_CENTER);
348   gtk_widget_set_halign (frame, GTK_ALIGN_CENTER);
349 
350   gtk_box_append (GTK_BOX (box), frame);
351 
352   gtk_window_present (GTK_WINDOW (window));
353 }
354 
355 int
main(int argc,char * argv[])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 (provider,
364     ".black-bg { background-color: black; }"
365     ".red-bg { background-color: red; }"
366     ".blue-bg { background-color: blue; }", -1);
367   gtk_style_context_add_provider_for_display (gdk_display_get_default (),
368                                               GTK_STYLE_PROVIDER (provider),
369                                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
370   g_object_unref (provider);
371 
372   if (g_getenv ("RTL"))
373     gtk_widget_set_default_direction (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