1/*
2 * Copyright (C) 2010 Openismus GmbH
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <gtk/gtk.h>
19
20enum {
21 SIMPLE_ITEMS = 0,
22 FOCUS_ITEMS,
23 WRAPPY_ITEMS,
24 IMAGE_ITEMS,
25 BUTTON_ITEMS
26};
27
28#define INITIAL_HALIGN GTK_ALIGN_FILL
29#define INITIAL_VALIGN GTK_ALIGN_START
30#define INITIAL_MINIMUM_LENGTH 3
31#define INITIAL_MAXIMUM_LENGTH 6
32#define INITIAL_CSPACING 2
33#define INITIAL_RSPACING 2
34#define N_ITEMS 1000
35
36static GtkFlowBox *the_flowbox = NULL;
37static int items_type = SIMPLE_ITEMS;
38
39static void
40populate_flowbox_simple (GtkFlowBox *flowbox)
41{
42 GtkWidget *widget, *frame;
43 int i;
44
45 for (i = 0; i < N_ITEMS; i++)
46 {
47 char *text = g_strdup_printf (format: "Item %02d", i);
48
49 widget = gtk_label_new (str: text);
50 frame = gtk_frame_new (NULL);
51
52 gtk_frame_set_child (GTK_FRAME (frame), child: widget);
53
54 g_object_set_data_full (G_OBJECT (frame), key: "id", data: (gpointer)g_strdup (str: text), destroy: g_free);
55 gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), widget: frame, position: -1);
56
57 g_free (mem: text);
58 }
59}
60
61static void
62populate_flowbox_focus (GtkFlowBox *flowbox)
63{
64 GtkWidget *widget, *frame, *box;
65 int i;
66 gboolean sensitive;
67
68 for (i = 0; i < 200; i++)
69 {
70 sensitive = TRUE;
71 frame = gtk_frame_new (NULL);
72
73 box = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 6);
74 gtk_frame_set_child (GTK_FRAME (frame), child: box);
75
76 widget = gtk_label_new (str: "Label");
77 gtk_box_append (GTK_BOX (box), child: widget);
78
79 switch (i % 4)
80 {
81 case 0:
82 widget = gtk_entry_new ();
83 break;
84 case 1:
85 widget = gtk_button_new_with_label (label: "Button");
86 break;
87 case 2:
88 widget = gtk_label_new (str: "bla");
89 break;
90 case 3:
91 widget = gtk_label_new (str: "bla");
92 sensitive = FALSE;
93 break;
94 default:
95 g_assert_not_reached ();
96 }
97
98 gtk_box_append (GTK_BOX (box), child: widget);
99
100 if (i % 5 == 0)
101 gtk_box_append (GTK_BOX (box), child: gtk_switch_new ());
102
103 gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), widget: frame, position: -1);
104 if (!sensitive)
105 gtk_widget_set_sensitive (widget: gtk_widget_get_parent (widget: frame), FALSE);
106 }
107}
108
109static void
110populate_flowbox_buttons (GtkFlowBox *flowbox)
111{
112 GtkWidget *widget;
113 int i;
114
115 for (i = 0; i < 50; i++)
116 {
117 widget = gtk_button_new_with_label (label: "Button");
118 gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), widget, position: -1);
119 widget = gtk_widget_get_parent (widget);
120 gtk_widget_set_can_focus (widget, FALSE);
121 }
122}
123
124static void
125populate_flowbox_wrappy (GtkFlowBox *flowbox)
126{
127 GtkWidget *widget, *frame;
128 int i;
129
130 const char *strings[] = {
131 "These are", "some wrappy label", "texts", "of various", "lengths.",
132 "They should always be", "shown", "consecutively. Except it's",
133 "hard to say", "where exactly the", "label", "will wrap", "and where exactly",
134 "the actual", "container", "will wrap.", "This label is really really really long !",
135 "Let's add some more", "labels to the",
136 "mix. Just to", "make sure we", "got something to work", "with here."
137 };
138
139 for (i = 0; i < G_N_ELEMENTS (strings); i++)
140 {
141 widget = gtk_label_new (str: strings[i]);
142 frame = gtk_frame_new (NULL);
143
144 gtk_frame_set_child (GTK_FRAME (frame), child: widget);
145
146 gtk_label_set_wrap (GTK_LABEL (widget), TRUE);
147 gtk_label_set_wrap_mode (GTK_LABEL (widget), wrap_mode: PANGO_WRAP_WORD);
148 gtk_label_set_width_chars (GTK_LABEL (widget), n_chars: 10);
149 g_object_set_data_full (G_OBJECT (frame), key: "id", data: (gpointer)g_strdup (str: strings[i]), destroy: g_free);
150
151 gtk_flow_box_insert (GTK_FLOW_BOX (flowbox), widget: frame, position: -1);
152 }
153}
154
155static void
156populate_flowbox_images (GtkFlowBox *flowbox)
157{
158 GtkWidget *widget, *image, *label;
159 int i;
160
161 for (i = 0; i < N_ITEMS; i++)
162 {
163 char *text = g_strdup_printf (format: "Item %02d", i);
164
165 widget = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 6);
166 gtk_widget_set_hexpand (widget, TRUE);
167
168 image = gtk_image_new_from_icon_name (icon_name: "face-wink");
169 gtk_image_set_icon_size (GTK_IMAGE (image), icon_size: GTK_ICON_SIZE_LARGE);
170 gtk_widget_set_hexpand (widget: image, TRUE);
171 gtk_image_set_pixel_size (GTK_IMAGE (image), pixel_size: 256);
172
173 label = gtk_label_new (str: text);
174
175 gtk_box_append (GTK_BOX (widget), child: image);
176 gtk_box_append (GTK_BOX (widget), child: label);
177
178 g_object_set_data_full (G_OBJECT (widget), key: "id", data: (gpointer)g_strdup (str: text), destroy: g_free);
179 gtk_box_append (GTK_BOX (flowbox), child: widget);
180
181 g_free (mem: text);
182 }
183}
184
185static void
186populate_items (GtkFlowBox *flowbox)
187{
188 GtkWidget *child;
189
190 while ((child = gtk_widget_get_first_child (GTK_WIDGET (flowbox))))
191 gtk_flow_box_remove (box: flowbox, widget: child);
192
193 if (items_type == SIMPLE_ITEMS)
194 populate_flowbox_simple (flowbox);
195 else if (items_type == FOCUS_ITEMS)
196 populate_flowbox_focus (flowbox);
197 else if (items_type == WRAPPY_ITEMS)
198 populate_flowbox_wrappy (flowbox);
199 else if (items_type == IMAGE_ITEMS)
200 populate_flowbox_images (flowbox);
201 else if (items_type == BUTTON_ITEMS)
202 populate_flowbox_buttons (flowbox);
203}
204
205static void
206horizontal_alignment_changed (GtkComboBox *box,
207 GtkFlowBox *flowbox)
208{
209 GtkAlign alignment = gtk_combo_box_get_active (combo_box: box);
210
211 gtk_widget_set_halign (GTK_WIDGET (flowbox), align: alignment);
212}
213
214static void
215vertical_alignment_changed (GtkComboBox *box,
216 GtkFlowBox *flowbox)
217{
218 GtkAlign alignment = gtk_combo_box_get_active (combo_box: box);
219
220 gtk_widget_set_valign (GTK_WIDGET (flowbox), align: alignment);
221}
222
223static void
224orientation_changed (GtkComboBox *box,
225 GtkFlowBox *flowbox)
226{
227 GtkOrientation orientation = gtk_combo_box_get_active (combo_box: box);
228
229 gtk_orientable_set_orientation (GTK_ORIENTABLE (flowbox), orientation);
230}
231
232static void
233selection_mode_changed (GtkComboBox *box,
234 GtkFlowBox *flowbox)
235{
236 GtkSelectionMode mode = gtk_combo_box_get_active (combo_box: box);
237
238 gtk_flow_box_set_selection_mode (box: flowbox, mode);
239}
240
241static void
242line_length_changed (GtkSpinButton *spin,
243 GtkFlowBox *flowbox)
244{
245 int length = gtk_spin_button_get_value_as_int (spin_button: spin);
246
247 gtk_flow_box_set_min_children_per_line (box: flowbox, n_children: length);
248}
249
250static void
251max_line_length_changed (GtkSpinButton *spin,
252 GtkFlowBox *flowbox)
253{
254 int length = gtk_spin_button_get_value_as_int (spin_button: spin);
255
256 gtk_flow_box_set_max_children_per_line (box: flowbox, n_children: length);
257}
258
259static void
260spacing_changed (GtkSpinButton *button,
261 gpointer data)
262{
263 GtkOrientation orientation = GPOINTER_TO_INT (data);
264 int state = gtk_spin_button_get_value_as_int (spin_button: button);
265
266 if (orientation == GTK_ORIENTATION_HORIZONTAL)
267 gtk_flow_box_set_column_spacing (box: the_flowbox, spacing: state);
268 else
269 gtk_flow_box_set_row_spacing (box: the_flowbox, spacing: state);
270}
271
272static void
273items_changed (GtkComboBox *box,
274 GtkFlowBox *flowbox)
275{
276 items_type = gtk_combo_box_get_active (combo_box: box);
277
278 populate_items (flowbox);
279}
280
281static void
282homogeneous_toggled (GtkCheckButton *button,
283 GtkFlowBox *flowbox)
284{
285 gboolean state = gtk_check_button_get_active (self: button);
286
287 gtk_flow_box_set_homogeneous (box: flowbox, homogeneous: state);
288}
289
290static void
291on_child_activated (GtkFlowBox *self,
292 GtkWidget *child)
293{
294 const char *id;
295 id = g_object_get_data (G_OBJECT (gtk_flow_box_child_get_child (GTK_FLOW_BOX_CHILD (child))), key: "id");
296 g_message ("Child activated %p: %s", child, id);
297}
298
299static G_GNUC_UNUSED void
300selection_foreach (GtkFlowBox *self,
301 GtkFlowBoxChild *child_info,
302 gpointer data)
303{
304 const char *id;
305 GtkWidget *child;
306
307 child = gtk_flow_box_child_get_child (self: child_info);
308 id = g_object_get_data (G_OBJECT (child), key: "id");
309 g_message ("Child selected %p: %s", child, id);
310}
311
312static void
313on_selected_children_changed (GtkFlowBox *self)
314{
315 g_message ("Selection changed");
316 //gtk_flow_box_selected_foreach (self, selection_foreach, NULL);
317}
318
319static gboolean
320filter_func (GtkFlowBoxChild *child, gpointer user_data)
321{
322 int index;
323
324 index = gtk_flow_box_child_get_index (child);
325
326 return (index % 3) == 0;
327}
328
329static void
330filter_toggled (GtkCheckButton *button,
331 GtkFlowBox *flowbox)
332{
333 gboolean state = gtk_check_button_get_active (self: button);
334
335 if (state)
336 gtk_flow_box_set_filter_func (box: flowbox, filter_func, NULL, NULL);
337 else
338 gtk_flow_box_set_filter_func (box: flowbox, NULL, NULL, NULL);
339}
340
341static int
342sort_func (GtkFlowBoxChild *a,
343 GtkFlowBoxChild *b,
344 gpointer data)
345{
346 char *ida, *idb;
347
348 ida = (char *)g_object_get_data (G_OBJECT (gtk_flow_box_child_get_child (a)), key: "id");
349 idb = (char *)g_object_get_data (G_OBJECT (gtk_flow_box_child_get_child (b)), key: "id");
350 return g_strcmp0 (str1: ida, str2: idb);
351}
352
353static void
354sort_toggled (GtkCheckButton *button,
355 GtkFlowBox *flowbox)
356{
357 gboolean state = gtk_check_button_get_active (self: button);
358
359 if (state)
360 gtk_flow_box_set_sort_func (box: flowbox, sort_func, NULL, NULL);
361 else
362 gtk_flow_box_set_sort_func (box: flowbox, NULL, NULL, NULL);
363}
364
365static GtkWidget *
366create_window (void)
367{
368 GtkWidget *window, *hbox, *vbox, *flowbox_cntl, *items_cntl;
369 GtkWidget *flowbox, *widget, *expander, *swindow;
370
371 window = gtk_window_new ();
372 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 6);
373 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 6);
374
375 gtk_window_set_child (GTK_WINDOW (window), child: hbox);
376 gtk_box_append (GTK_BOX (hbox), child: vbox);
377
378 swindow = gtk_scrolled_window_new ();
379 gtk_widget_set_hexpand (widget: swindow, TRUE);
380 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
381 hscrollbar_policy: GTK_POLICY_AUTOMATIC, vscrollbar_policy: GTK_POLICY_AUTOMATIC);
382
383 gtk_box_append (GTK_BOX (hbox), child: swindow);
384
385 flowbox = gtk_flow_box_new ();
386 gtk_widget_set_halign (widget: flowbox, align: GTK_ALIGN_END);
387 the_flowbox = (GtkFlowBox *)flowbox;
388 gtk_widget_set_halign (widget: flowbox, INITIAL_HALIGN);
389 gtk_widget_set_valign (widget: flowbox, INITIAL_VALIGN);
390 gtk_flow_box_set_column_spacing (GTK_FLOW_BOX (flowbox), INITIAL_CSPACING);
391 gtk_flow_box_set_row_spacing (GTK_FLOW_BOX (flowbox), INITIAL_RSPACING);
392 gtk_flow_box_set_min_children_per_line (GTK_FLOW_BOX (flowbox), INITIAL_MINIMUM_LENGTH);
393 gtk_flow_box_set_max_children_per_line (GTK_FLOW_BOX (flowbox), INITIAL_MAXIMUM_LENGTH);
394 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (swindow), child: flowbox);
395
396 gtk_flow_box_set_hadjustment (GTK_FLOW_BOX (flowbox),
397 adjustment: gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (swindow)));
398 gtk_flow_box_set_vadjustment (GTK_FLOW_BOX (flowbox),
399 adjustment: gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (swindow)));
400
401 g_signal_connect (flowbox, "child-activated", G_CALLBACK (on_child_activated), NULL);
402 g_signal_connect (flowbox, "selected-children-changed", G_CALLBACK (on_selected_children_changed), NULL);
403
404 /* Add Flowbox test control frame */
405 expander = gtk_expander_new (label: "Flow Box controls");
406 gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
407 flowbox_cntl = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 2);
408 gtk_expander_set_child (GTK_EXPANDER (expander), child: flowbox_cntl);
409 gtk_box_append (GTK_BOX (vbox), child: expander);
410
411 widget = gtk_check_button_new_with_label (label: "Homogeneous");
412 gtk_check_button_set_active (GTK_CHECK_BUTTON (widget), FALSE);
413
414 gtk_widget_set_tooltip_text (widget, text: "Set whether the items should be displayed at the same size");
415 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
416
417 g_signal_connect (G_OBJECT (widget), "toggled",
418 G_CALLBACK (homogeneous_toggled), flowbox);
419
420 widget = gtk_check_button_new_with_label (label: "Activate on single click");
421 gtk_check_button_set_active (GTK_CHECK_BUTTON (widget), FALSE);
422 g_object_bind_property (source: widget, source_property: "active",
423 target: flowbox, target_property: "activate-on-single-click",
424 flags: G_BINDING_SYNC_CREATE);
425 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
426
427 /* Add alignment controls */
428 widget = gtk_combo_box_text_new ();
429 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Fill");
430 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Start");
431 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "End");
432 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Center");
433 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), INITIAL_HALIGN);
434
435 gtk_widget_set_tooltip_text (widget, text: "Set the horizontal alignment policy");
436 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
437
438 g_signal_connect (G_OBJECT (widget), "changed",
439 G_CALLBACK (horizontal_alignment_changed), flowbox);
440
441 widget = gtk_combo_box_text_new ();
442 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Fill");
443 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Start");
444 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "End");
445 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Center");
446 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), INITIAL_VALIGN);
447
448 gtk_widget_set_tooltip_text (widget, text: "Set the vertical alignment policy");
449 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
450
451 g_signal_connect (G_OBJECT (widget), "changed",
452 G_CALLBACK (vertical_alignment_changed), flowbox);
453
454 /* Add Orientation control */
455 widget = gtk_combo_box_text_new ();
456 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Horizontal");
457 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Vertical");
458 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), index_: 0);
459
460 gtk_widget_set_tooltip_text (widget, text: "Set the flowbox orientation");
461 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
462
463 g_signal_connect (G_OBJECT (widget), "changed",
464 G_CALLBACK (orientation_changed), flowbox);
465
466 /* Add selection mode control */
467 widget = gtk_combo_box_text_new ();
468 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "None");
469 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Single");
470 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Browse");
471 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Multiple");
472 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), index_: 1);
473
474 gtk_widget_set_tooltip_text (widget, text: "Set the selection mode");
475 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
476
477 g_signal_connect (G_OBJECT (widget), "changed",
478 G_CALLBACK (selection_mode_changed), flowbox);
479
480 /* Add minimum line length in items control */
481 widget = gtk_spin_button_new_with_range (min: 1, max: 10, step: 1);
482 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_MINIMUM_LENGTH);
483
484 gtk_widget_set_tooltip_text (widget, text: "Set the minimum amount of items per line before wrapping");
485 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
486
487 g_signal_connect (G_OBJECT (widget), "changed",
488 G_CALLBACK (line_length_changed), flowbox);
489 g_signal_connect (G_OBJECT (widget), "value-changed",
490 G_CALLBACK (line_length_changed), flowbox);
491
492 /* Add natural line length in items control */
493 widget = gtk_spin_button_new_with_range (min: 1, max: 10, step: 1);
494 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_MAXIMUM_LENGTH);
495
496 gtk_widget_set_tooltip_text (widget, text: "Set the natural amount of items per line ");
497 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
498
499 g_signal_connect (G_OBJECT (widget), "changed",
500 G_CALLBACK (max_line_length_changed), flowbox);
501 g_signal_connect (G_OBJECT (widget), "value-changed",
502 G_CALLBACK (max_line_length_changed), flowbox);
503
504 /* Add horizontal/vertical spacing controls */
505 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
506
507 widget = gtk_label_new (str: "H Spacing");
508 gtk_box_append (GTK_BOX (hbox), child: widget);
509
510 widget = gtk_spin_button_new_with_range (min: 0, max: 30, step: 1);
511 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_CSPACING);
512
513 gtk_widget_set_tooltip_text (widget, text: "Set the horizontal spacing between children");
514 gtk_box_append (GTK_BOX (hbox), child: widget);
515
516 g_signal_connect (G_OBJECT (widget), "changed",
517 G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
518 g_signal_connect (G_OBJECT (widget), "value-changed",
519 G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_HORIZONTAL));
520
521 gtk_box_append (GTK_BOX (flowbox_cntl), child: hbox);
522
523 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
524
525 widget = gtk_label_new (str: "V Spacing");
526 gtk_box_append (GTK_BOX (hbox), child: widget);
527
528 widget = gtk_spin_button_new_with_range (min: 0, max: 30, step: 1);
529 gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), INITIAL_RSPACING);
530
531 gtk_widget_set_tooltip_text (widget, text: "Set the vertical spacing between children");
532 gtk_box_append (GTK_BOX (hbox), child: widget);
533
534 g_signal_connect (G_OBJECT (widget), "changed",
535 G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
536 g_signal_connect (G_OBJECT (widget), "value-changed",
537 G_CALLBACK (spacing_changed), GINT_TO_POINTER (GTK_ORIENTATION_VERTICAL));
538
539 gtk_box_append (GTK_BOX (flowbox_cntl), child: hbox);
540
541 /* filtering and sorting */
542
543 widget = gtk_check_button_new_with_label (label: "Filter");
544 gtk_check_button_set_active (GTK_CHECK_BUTTON (widget), FALSE);
545
546 gtk_widget_set_tooltip_text (widget, text: "Set whether some items should be filtered out");
547 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
548
549 g_signal_connect (G_OBJECT (widget), "toggled",
550 G_CALLBACK (filter_toggled), flowbox);
551
552 widget = gtk_check_button_new_with_label (label: "Sort");
553 gtk_check_button_set_active (GTK_CHECK_BUTTON (widget), FALSE);
554
555 gtk_widget_set_tooltip_text (widget, text: "Set whether items should be sorted");
556 gtk_box_append (GTK_BOX (flowbox_cntl), child: widget);
557
558 g_signal_connect (G_OBJECT (widget), "toggled",
559 G_CALLBACK (sort_toggled), flowbox);
560
561
562 /* Add test items control frame */
563 expander = gtk_expander_new (label: "Test item controls");
564 gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
565 items_cntl = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 2);
566 gtk_expander_set_child (GTK_EXPANDER (expander), child: items_cntl);
567 gtk_box_append (GTK_BOX (vbox), child: expander);
568
569 /* Add Items control */
570 widget = gtk_combo_box_text_new ();
571 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Simple");
572 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Focus");
573 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Wrappy");
574 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Images");
575 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Buttons");
576 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), index_: 0);
577
578 gtk_widget_set_tooltip_text (widget, text: "Set the item set to use");
579 gtk_box_append (GTK_BOX (items_cntl), child: widget);
580
581 g_signal_connect (G_OBJECT (widget), "changed",
582 G_CALLBACK (items_changed), flowbox);
583
584 populate_items (GTK_FLOW_BOX (flowbox));
585
586 /* This line was added only for the convenience of reproducing
587 * a height-for-width inside GtkScrolledWindow bug (bug 629778).
588 * -Tristan
589 */
590 gtk_window_set_default_size (GTK_WINDOW (window), width: 390, height: -1);
591
592 return window;
593}
594
595static void
596quit_cb (GtkWidget *widget,
597 gpointer data)
598{
599 gboolean *done = data;
600
601 *done = TRUE;
602
603 g_main_context_wakeup (NULL);
604}
605
606int
607main (int argc, char *argv[])
608{
609 GtkWidget *window;
610 gboolean done = FALSE;
611
612 gtk_init ();
613
614 window = create_window ();
615
616 g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
617
618 gtk_widget_show (widget: window);
619
620 while (!done)
621 g_main_context_iteration (NULL, TRUE);
622
623 return 0;
624}
625

source code of gtk/tests/testflowbox.c