1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser 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 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18/*
19 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
20 * file for a list of people on the GTK+ Team. See the ChangeLog
21 * files for a list of changes. These files are distributed with
22 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
23 */
24
25
26#include "config.h"
27
28#undef G_LOG_DOMAIN
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <sys/stat.h>
34#include <math.h>
35#include <time.h>
36#ifdef HAVE_UNISTD_H
37#include <unistd.h>
38#endif
39
40#include <glib/gstdio.h>
41
42#include "gtk/gtk.h"
43#include "gdk/gdk.h"
44#include "gdk/gdkkeysyms.h"
45
46#ifdef G_OS_WIN32
47#define sleep(n) _sleep(n)
48#endif
49
50#include "test.xpm"
51
52static gboolean done = FALSE;
53
54static gboolean
55file_exists (const char *filename)
56{
57 struct stat statbuf;
58
59 return stat (file: filename, buf: &statbuf) == 0;
60}
61
62static GtkWidget *
63build_option_menu (const char *items[],
64 int num_items,
65 int history,
66 void (*func) (GtkWidget *widget, gpointer data),
67 gpointer data);
68
69/* macro, structure and variables used by tree window demos */
70#define DEFAULT_NUMBER_OF_ITEM 3
71#define DEFAULT_RECURSION_LEVEL 3
72
73struct {
74 GSList* selection_mode_group;
75 GtkWidget* single_button;
76 GtkWidget* browse_button;
77 GtkWidget* multiple_button;
78 GtkWidget* draw_line_button;
79 GtkWidget* view_line_button;
80 GtkWidget* no_root_item_button;
81 GtkWidget* nb_item_spinner;
82 GtkWidget* recursion_spinner;
83} sTreeSampleSelection;
84
85typedef struct sTreeButtons {
86 guint nb_item_add;
87 GtkWidget* add_button;
88 GtkWidget* remove_button;
89 GtkWidget* subtree_button;
90} sTreeButtons;
91/* end of tree section */
92
93static GtkWidget *
94build_option_menu (const char *items[],
95 int num_items,
96 int history,
97 void (*func)(GtkWidget *widget, gpointer data),
98 gpointer data)
99{
100 GtkWidget *omenu;
101 int i;
102
103 omenu = gtk_combo_box_text_new ();
104 g_signal_connect (omenu, "changed",
105 G_CALLBACK (func), data);
106
107 for (i = 0; i < num_items; i++)
108 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (omenu), text: items[i]);
109
110 gtk_combo_box_set_active (GTK_COMBO_BOX (omenu), index_: history);
111
112 return omenu;
113}
114
115/*
116 * Windows with an alpha channel
117 */
118static GtkWidget *
119build_alpha_widgets (void)
120{
121 GtkWidget *grid;
122 GtkWidget *radio_button;
123 GtkWidget *check_button;
124 GtkWidget *hbox;
125 GtkWidget *label;
126 GtkWidget *entry;
127 GtkWidget *group;
128
129 grid = gtk_grid_new ();
130 gtk_widget_set_vexpand (widget: grid, TRUE);
131
132 radio_button = gtk_check_button_new_with_label (label: "Red");
133 gtk_widget_set_hexpand (widget: radio_button, TRUE);
134 gtk_grid_attach (GTK_GRID (grid), child: radio_button, column: 0, row: 0, width: 1, height: 1);
135 group = radio_button;
136
137 radio_button = gtk_check_button_new_with_label (label: "Green");
138 gtk_widget_set_hexpand (widget: radio_button, TRUE);
139 gtk_grid_attach (GTK_GRID (grid), child: radio_button, column: 0, row: 1, width: 1, height: 1);
140 gtk_check_button_set_group (GTK_CHECK_BUTTON (radio_button), GTK_CHECK_BUTTON (group));
141
142 radio_button = gtk_check_button_new_with_label (label: "Blue"),
143 gtk_widget_set_hexpand (widget: radio_button, TRUE);
144 gtk_grid_attach (GTK_GRID (grid), child: radio_button, column: 0, row: 2, width: 1, height: 1);
145 gtk_check_button_set_group (GTK_CHECK_BUTTON (radio_button), GTK_CHECK_BUTTON (group));
146 gtk_check_button_set_active (GTK_CHECK_BUTTON (group), TRUE);
147
148 check_button = gtk_check_button_new_with_label (label: "Sedentary"),
149 gtk_widget_set_hexpand (widget: check_button, TRUE);
150 gtk_grid_attach (GTK_GRID (grid), child: check_button, column: 1, row: 0, width: 1, height: 1);
151
152 check_button = gtk_check_button_new_with_label (label: "Nocturnal"),
153 gtk_widget_set_hexpand (widget: check_button, TRUE);
154 gtk_grid_attach (GTK_GRID (grid), child: check_button, column: 1, row: 1, width: 1, height: 1);
155
156 check_button = gtk_check_button_new_with_label (label: "Compulsive"),
157 gtk_widget_set_hexpand (widget: check_button, TRUE);
158 gtk_grid_attach (GTK_GRID (grid), child: check_button, column: 1, row: 2, width: 1, height: 1);
159
160 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
161 label = gtk_label_new (NULL);
162 gtk_label_set_markup (GTK_LABEL (label), str: "<i>Entry: </i>");
163 gtk_box_append (GTK_BOX (hbox), child: label);
164 entry = gtk_entry_new ();
165 gtk_widget_set_hexpand (widget: entry, TRUE);
166 gtk_box_append (GTK_BOX (hbox), child: entry);
167 gtk_widget_set_hexpand (widget: hbox, TRUE);
168 gtk_grid_attach (GTK_GRID (grid), child: hbox, column: 0, row: 3, width: 2, height: 1);
169
170 return grid;
171}
172
173static void
174on_composited_changed (GdkDisplay *display,
175 GParamSpec *pspec,
176 GtkLabel *label)
177{
178 gboolean is_composited = gdk_display_is_composited (display);
179
180 if (is_composited)
181 gtk_label_set_text (self: label, str: "Composited");
182 else
183 gtk_label_set_text (self: label, str: "Not composited");
184
185 /* We draw a different background on the GdkSurface */
186 gtk_widget_queue_draw (GTK_WIDGET (gtk_widget_get_root (GTK_WIDGET (label))));
187}
188
189static void
190create_alpha_window (GtkWidget *widget)
191{
192 static GtkWidget *window;
193
194 if (!window)
195 {
196 GtkWidget *content_area;
197 GtkWidget *vbox;
198 GtkWidget *label;
199 GdkDisplay *display;
200 GtkCssProvider *provider;
201
202 window = gtk_dialog_new_with_buttons (title: "Alpha Window",
203 GTK_WINDOW (gtk_widget_get_root (widget)), flags: 0,
204 first_button_text: "_Close", 0,
205 NULL);
206 provider = gtk_css_provider_new ();
207 gtk_css_provider_load_from_data (css_provider: provider,
208 data: "dialog {\n"
209 " background: radial-gradient(ellipse at center, #FFBF00, #FFBF0000);\n"
210 "}\n",
211 length: -1);
212 gtk_style_context_add_provider (context: gtk_widget_get_style_context (widget: window),
213 GTK_STYLE_PROVIDER (provider),
214 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
215 g_object_unref (object: provider);
216
217 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
218
219 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 8);
220 gtk_widget_set_margin_top (widget: vbox, margin: 12);
221 gtk_widget_set_margin_bottom (widget: vbox, margin: 12);
222 gtk_widget_set_margin_start (widget: vbox, margin: 12);
223 gtk_widget_set_margin_end (widget: vbox, margin: 12);
224 gtk_widget_set_vexpand (widget: vbox, TRUE);
225 label = gtk_label_new (NULL);
226 gtk_box_append (GTK_BOX (content_area), child: vbox);
227 gtk_box_append (GTK_BOX (vbox), child: label);
228 display = gtk_widget_get_display (widget: window);
229 on_composited_changed (display, NULL, GTK_LABEL (label));
230 g_signal_connect (display, "notify::composited", G_CALLBACK (on_composited_changed), label);
231
232 gtk_box_append (GTK_BOX (vbox), child: build_alpha_widgets ());
233 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
234
235 g_signal_connect (window, "response",
236 G_CALLBACK (gtk_window_destroy),
237 NULL);
238 }
239
240 if (!gtk_widget_get_visible (widget: window))
241 gtk_widget_show (widget: window);
242 else
243 gtk_window_destroy (GTK_WINDOW (window));
244}
245
246/*
247 * GtkButton
248 */
249
250static void
251button_window (GtkWidget *widget,
252 GtkWidget *button)
253{
254 if (!gtk_widget_get_visible (widget: button))
255 gtk_widget_show (widget: button);
256 else
257 gtk_widget_hide (widget: button);
258}
259
260static void
261create_buttons (GtkWidget *widget)
262{
263 static GtkWidget *window = NULL;
264 GtkWidget *box1;
265 GtkWidget *box2;
266 GtkWidget *grid;
267 GtkWidget *separator;
268 GtkWidget *button[10];
269 int button_x[9] = { 0, 1, 2, 0, 2, 1, 1, 2, 0 };
270 int button_y[9] = { 0, 1, 2, 2, 0, 2, 0, 1, 1 };
271 guint i;
272
273 if (!window)
274 {
275 window = gtk_window_new ();
276 gtk_window_set_display (GTK_WINDOW (window),
277 display: gtk_widget_get_display (widget));
278 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
279
280 gtk_window_set_title (GTK_WINDOW (window), title: "GtkButton");
281
282 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
283 gtk_window_set_child (GTK_WINDOW (window), child: box1);
284
285 grid = gtk_grid_new ();
286 gtk_grid_set_row_spacing (GTK_GRID (grid), spacing: 5);
287 gtk_grid_set_column_spacing (GTK_GRID (grid), spacing: 5);
288
289 gtk_widget_set_margin_top (widget: grid, margin: 10);
290 gtk_widget_set_margin_bottom (widget: grid, margin: 10);
291 gtk_widget_set_margin_start (widget: grid, margin: 10);
292 gtk_widget_set_margin_end (widget: grid, margin: 10);
293 gtk_box_append (GTK_BOX (box1), child: grid);
294
295 button[0] = gtk_button_new_with_label (label: "button1");
296 button[1] = gtk_button_new_with_mnemonic (label: "_button2");
297 button[2] = gtk_button_new_with_mnemonic (label: "_button3");
298 button[3] = gtk_button_new_with_mnemonic (label: "_button4");
299 button[4] = gtk_button_new_with_label (label: "button5");
300 button[5] = gtk_button_new_with_label (label: "button6");
301 button[6] = gtk_button_new_with_label (label: "button7");
302 button[7] = gtk_button_new_with_label (label: "button8");
303 button[8] = gtk_button_new_with_label (label: "button9");
304
305 for (i = 0; i < 9; i++)
306 {
307 g_signal_connect (button[i], "clicked",
308 G_CALLBACK (button_window),
309 button[(i + 1) % 9]);
310 gtk_widget_set_hexpand (widget: button[i], TRUE);
311 gtk_widget_set_vexpand (widget: button[i], TRUE);
312
313 gtk_grid_attach (GTK_GRID (grid), child: button[i],
314 column: button_x[i], row: button_y[i] + 1, width: 1, height: 1);
315 }
316
317 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
318 gtk_box_append (GTK_BOX (box1), child: separator);
319
320 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
321 gtk_box_append (GTK_BOX (box1), child: box2);
322
323 button[9] = gtk_button_new_with_label (label: "close");
324 gtk_widget_set_margin_top (widget: button[9], margin: 10);
325 gtk_widget_set_margin_bottom (widget: button[9], margin: 10);
326 gtk_widget_set_margin_start (widget: button[9], margin: 10);
327 gtk_widget_set_margin_end (widget: button[9], margin: 10);
328 g_signal_connect_swapped (button[9], "clicked",
329 G_CALLBACK (gtk_window_destroy),
330 window);
331 gtk_box_append (GTK_BOX (box2), child: button[9]);
332 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button[9]);
333 }
334
335 if (!gtk_widget_get_visible (widget: window))
336 gtk_widget_show (widget: window);
337 else
338 gtk_window_destroy (GTK_WINDOW (window));
339}
340
341/*
342 * GtkToggleButton
343 */
344
345static void
346create_toggle_buttons (GtkWidget *widget)
347{
348 static GtkWidget *window = NULL;
349 GtkWidget *box1;
350 GtkWidget *box2;
351 GtkWidget *button;
352 GtkWidget *separator;
353
354 if (!window)
355 {
356 window = gtk_window_new ();
357 gtk_window_set_display (GTK_WINDOW (window),
358 display: gtk_widget_get_display (widget));
359 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
360
361 gtk_window_set_title (GTK_WINDOW (window), title: "GtkToggleButton");
362
363 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
364 gtk_window_set_child (GTK_WINDOW (window), child: box1);
365
366 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
367 gtk_box_append (GTK_BOX (box1), child: box2);
368
369 button = gtk_toggle_button_new_with_label (label: "button1");
370 gtk_box_append (GTK_BOX (box2), child: button);
371
372 button = gtk_toggle_button_new_with_label (label: "button2");
373 gtk_box_append (GTK_BOX (box2), child: button);
374
375 button = gtk_toggle_button_new_with_label (label: "button3");
376 gtk_box_append (GTK_BOX (box2), child: button);
377
378 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
379 gtk_box_append (GTK_BOX (box1), child: separator);
380
381 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
382 gtk_box_append (GTK_BOX (box1), child: box2);
383
384 button = gtk_button_new_with_label (label: "close");
385 g_signal_connect_swapped (button, "clicked",
386 G_CALLBACK (gtk_window_destroy),
387 window);
388 gtk_box_append (GTK_BOX (box2), child: button);
389 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
390 }
391
392 if (!gtk_widget_get_visible (widget: window))
393 gtk_widget_show (widget: window);
394 else
395 gtk_window_destroy (GTK_WINDOW (window));
396}
397
398static GtkWidget *
399create_widget_grid (gboolean group)
400{
401 GtkWidget *grid;
402 GtkWidget *group_widget = NULL;
403 int i, j;
404
405 grid = gtk_grid_new ();
406
407 for (i = 0; i < 5; i++)
408 {
409 for (j = 0; j < 5; j++)
410 {
411 GtkWidget *widget;
412 char *tmp;
413
414 if (i == 0 && j == 0)
415 {
416 widget = NULL;
417 }
418 else if (i == 0)
419 {
420 tmp = g_strdup_printf (format: "%d", j);
421 widget = gtk_label_new (str: tmp);
422 g_free (mem: tmp);
423 }
424 else if (j == 0)
425 {
426 tmp = g_strdup_printf (format: "%c", 'A' + i - 1);
427 widget = gtk_label_new (str: tmp);
428 g_free (mem: tmp);
429 }
430 else
431 {
432 widget = gtk_check_button_new ();
433 if (group)
434 {
435 if (!group_widget)
436 group_widget = widget;
437 else
438 gtk_check_button_set_group (GTK_CHECK_BUTTON (widget), GTK_CHECK_BUTTON (group_widget));
439 }
440 }
441
442 if (widget)
443 gtk_grid_attach (GTK_GRID (grid), child: widget, column: i, row: j, width: 1, height: 1);
444 }
445 }
446
447 return grid;
448}
449
450/*
451 * GtkCheckButton
452 */
453
454static void
455create_check_buttons (GtkWidget *widget)
456{
457 static GtkWidget *window = NULL;
458 GtkWidget *box1;
459 GtkWidget *box2;
460 GtkWidget *button;
461 GtkWidget *separator;
462 GtkWidget *table;
463
464 if (!window)
465 {
466 window = gtk_dialog_new_with_buttons (title: "Check Buttons",
467 NULL, flags: 0,
468 first_button_text: "_Close",
469 GTK_RESPONSE_NONE,
470 NULL);
471
472 gtk_window_set_display (GTK_WINDOW (window),
473 display: gtk_widget_get_display (widget));
474 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
475 g_signal_connect (window, "response",
476 G_CALLBACK (gtk_window_destroy),
477 NULL);
478
479 box1 = gtk_dialog_get_content_area (GTK_DIALOG (window));
480
481 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
482 gtk_widget_set_hexpand (widget: box2, TRUE);
483 gtk_widget_set_margin_start (widget: box2, margin: 10);
484 gtk_widget_set_margin_end (widget: box2, margin: 10);
485 gtk_widget_set_margin_top (widget: box2, margin: 10);
486 gtk_widget_set_margin_bottom (widget: box2, margin: 10);
487 gtk_box_append (GTK_BOX (box1), child: box2);
488
489 button = gtk_check_button_new_with_mnemonic (label: "_button1");
490 gtk_box_append (GTK_BOX (box2), child: button);
491
492 button = gtk_check_button_new_with_label (label: "button2");
493 gtk_box_append (GTK_BOX (box2), child: button);
494
495 button = gtk_check_button_new_with_label (label: "button3");
496 gtk_box_append (GTK_BOX (box2), child: button);
497
498 button = gtk_check_button_new_with_label (label: "inconsistent");
499 gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (button), TRUE);
500 gtk_box_append (GTK_BOX (box2), child: button);
501
502 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
503 gtk_box_append (GTK_BOX (box1), child: separator);
504
505 table = create_widget_grid (FALSE);
506 gtk_widget_set_vexpand (widget: table, TRUE);
507 gtk_box_append (GTK_BOX (box2), child: table);
508 }
509
510 if (!gtk_widget_get_visible (widget: window))
511 gtk_widget_show (widget: window);
512 else
513 gtk_window_destroy (GTK_WINDOW (window));
514}
515
516static void
517create_radio_buttons (GtkWidget *widget)
518{
519 static GtkWidget *window = NULL;
520 GtkWidget *box1;
521 GtkWidget *box2;
522 GtkWidget *button;
523 GtkWidget *separator;
524 GtkWidget *table;
525 GtkWidget *group;
526
527 if (!window)
528 {
529 window = gtk_dialog_new_with_buttons (title: "Radio Buttons",
530 NULL, flags: 0,
531 first_button_text: "_Close",
532 GTK_RESPONSE_NONE,
533 NULL);
534
535 gtk_window_set_display (GTK_WINDOW (window),
536 display: gtk_widget_get_display (widget));
537 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
538 g_signal_connect (window, "response",
539 G_CALLBACK (gtk_window_destroy),
540 NULL);
541
542 box1 = gtk_dialog_get_content_area (GTK_DIALOG (window));
543
544 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
545 gtk_box_append (GTK_BOX (box1), child: box2);
546
547 button = gtk_check_button_new_with_label (label: "button1");
548 gtk_box_append (GTK_BOX (box2), child: button);
549 group = button;
550
551 button = gtk_check_button_new_with_label (label: "button2");
552 gtk_check_button_set_active (GTK_CHECK_BUTTON (button), TRUE);
553 gtk_check_button_set_group (GTK_CHECK_BUTTON (button), GTK_CHECK_BUTTON (group));
554 gtk_box_append (GTK_BOX (box2), child: button);
555
556 button = gtk_check_button_new_with_label (label: "button3");
557 gtk_check_button_set_group (GTK_CHECK_BUTTON (button), GTK_CHECK_BUTTON (group));
558 gtk_box_append (GTK_BOX (box2), child: button);
559
560 button = gtk_check_button_new_with_label (label: "inconsistent");
561 gtk_check_button_set_group (GTK_CHECK_BUTTON (button), GTK_CHECK_BUTTON (group));
562 gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (button), TRUE);
563 gtk_box_append (GTK_BOX (box2), child: button);
564
565 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
566 gtk_box_append (GTK_BOX (box1), child: separator);
567
568 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
569 gtk_box_append (GTK_BOX (box1), child: box2);
570
571 button = gtk_check_button_new_with_label (label: "button4");
572 gtk_box_append (GTK_BOX (box2), child: button);
573 group = button;
574
575 button = gtk_check_button_new_with_label (label: "button5");
576 gtk_check_button_set_active (GTK_CHECK_BUTTON (button), TRUE);
577 gtk_check_button_set_group (GTK_CHECK_BUTTON (button), GTK_CHECK_BUTTON (group));
578 gtk_box_append (GTK_BOX (box2), child: button);
579
580 button = gtk_check_button_new_with_label (label: "button6");
581 gtk_check_button_set_group (GTK_CHECK_BUTTON (button), GTK_CHECK_BUTTON (group));
582 gtk_box_append (GTK_BOX (box2), child: button);
583
584 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
585 gtk_box_append (GTK_BOX (box1), child: separator);
586
587 table = create_widget_grid (TRUE);
588 gtk_box_append (GTK_BOX (box1), child: table);
589 }
590
591 if (!gtk_widget_get_visible (widget: window))
592 gtk_widget_show (widget: window);
593 else
594 gtk_window_destroy (GTK_WINDOW (window));
595}
596
597/*
598 * GtkToolBar
599 */
600
601static GtkWidget*
602new_pixbuf (const char *filename,
603 GdkSurface *window)
604{
605 GtkWidget *widget;
606 GdkPixbuf *pixbuf;
607
608 if (strcmp (s1: filename, s2: "test.xpm") == 0)
609 pixbuf = NULL;
610 else
611 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
612
613 if (pixbuf == NULL)
614 pixbuf = gdk_pixbuf_new_from_xpm_data (data: (const char **) openfile);
615
616 widget = gtk_image_new_from_pixbuf (pixbuf);
617
618 g_object_unref (object: pixbuf);
619
620 return widget;
621}
622
623/*
624 * GtkStatusBar
625 */
626
627static guint statusbar_counter = 1;
628
629static void
630statusbar_push (GtkWidget *button,
631 GtkStatusbar *statusbar)
632{
633 char text[1024];
634
635 sprintf (s: text, format: "something %d", statusbar_counter++);
636
637 gtk_statusbar_push (statusbar, context_id: 1, text);
638}
639
640static void
641statusbar_push_long (GtkWidget *button,
642 GtkStatusbar *statusbar)
643{
644 char text[1024];
645
646 sprintf (s: text, format: "Just because a system has menu choices written with English words, phrases or sentences, that is no guarantee, that it is comprehensible. Individual words may not be familiar to some users (for example, \"repaginate\"), and two menu items may appear to satisfy the users's needs, whereas only one does (for example, \"put away\" or \"eject\").");
647
648 gtk_statusbar_push (statusbar, context_id: 1, text);
649}
650
651static void
652statusbar_pop (GtkWidget *button,
653 GtkStatusbar *statusbar)
654{
655 gtk_statusbar_pop (statusbar, context_id: 1);
656}
657
658static void
659statusbar_steal (GtkWidget *button,
660 GtkStatusbar *statusbar)
661{
662 gtk_statusbar_remove (statusbar, context_id: 1, message_id: 4);
663}
664
665static void
666statusbar_popped (GtkStatusbar *statusbar,
667 guint context_id,
668 const char *text)
669{
670 if (!text)
671 statusbar_counter = 1;
672}
673
674static void
675statusbar_contexts (GtkStatusbar *statusbar)
676{
677 const char *string;
678
679 string = "any context";
680 g_print (format: "GtkStatusBar: context=\"%s\", context_id=%d\n",
681 string,
682 gtk_statusbar_get_context_id (statusbar, context_description: string));
683
684 string = "idle messages";
685 g_print (format: "GtkStatusBar: context=\"%s\", context_id=%d\n",
686 string,
687 gtk_statusbar_get_context_id (statusbar, context_description: string));
688
689 string = "some text";
690 g_print (format: "GtkStatusBar: context=\"%s\", context_id=%d\n",
691 string,
692 gtk_statusbar_get_context_id (statusbar, context_description: string));
693
694 string = "hit the mouse";
695 g_print (format: "GtkStatusBar: context=\"%s\", context_id=%d\n",
696 string,
697 gtk_statusbar_get_context_id (statusbar, context_description: string));
698
699 string = "hit the mouse2";
700 g_print (format: "GtkStatusBar: context=\"%s\", context_id=%d\n",
701 string,
702 gtk_statusbar_get_context_id (statusbar, context_description: string));
703}
704
705static void
706create_statusbar (GtkWidget *widget)
707{
708 static GtkWidget *window = NULL;
709 GtkWidget *box1;
710 GtkWidget *box2;
711 GtkWidget *button;
712 GtkWidget *separator;
713 GtkWidget *statusbar;
714
715 if (!window)
716 {
717 window = gtk_window_new ();
718 gtk_window_set_display (GTK_WINDOW (window),
719 display: gtk_widget_get_display (widget));
720 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
721
722 gtk_window_set_title (GTK_WINDOW (window), title: "statusbar");
723
724 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
725 gtk_window_set_child (GTK_WINDOW (window), child: box1);
726
727 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
728 gtk_box_append (GTK_BOX (box1), child: box2);
729
730 statusbar = gtk_statusbar_new ();
731 g_signal_connect (statusbar,
732 "text_popped",
733 G_CALLBACK (statusbar_popped),
734 NULL);
735
736 button = g_object_new (object_type: gtk_button_get_type (),
737 first_property_name: "label", "push something",
738 NULL);
739 gtk_box_append (GTK_BOX (box2), child: button);
740 g_object_connect (object: button,
741 signal_spec: "signal::clicked", statusbar_push, statusbar,
742 NULL);
743
744 button = g_object_connect (object: g_object_new (object_type: gtk_button_get_type (),
745 first_property_name: "label", "pop",
746 NULL),
747 signal_spec: "signal_after::clicked", statusbar_pop, statusbar,
748 NULL);
749 gtk_box_append (GTK_BOX (box2), child: button);
750
751 button = g_object_connect (object: g_object_new (object_type: gtk_button_get_type (),
752 first_property_name: "label", "steal #4",
753 NULL),
754 signal_spec: "signal_after::clicked", statusbar_steal, statusbar,
755 NULL);
756 gtk_box_append (GTK_BOX (box2), child: button);
757
758 button = g_object_connect (object: g_object_new (object_type: gtk_button_get_type (),
759 first_property_name: "label", "test contexts",
760 NULL),
761 signal_spec: "swapped_signal_after::clicked", statusbar_contexts, statusbar,
762 NULL);
763 gtk_box_append (GTK_BOX (box2), child: button);
764
765 button = g_object_connect (object: g_object_new (object_type: gtk_button_get_type (),
766 first_property_name: "label", "push something long",
767 NULL),
768 signal_spec: "signal_after::clicked", statusbar_push_long, statusbar,
769 NULL);
770 gtk_box_append (GTK_BOX (box2), child: button);
771
772 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
773 gtk_box_append (GTK_BOX (box1), child: separator);
774
775 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
776 gtk_box_append (GTK_BOX (box1), child: box2);
777 gtk_box_append (GTK_BOX (box1), child: statusbar);
778
779 button = gtk_button_new_with_label (label: "close");
780 g_signal_connect_swapped (button, "clicked",
781 G_CALLBACK (gtk_window_destroy),
782 window);
783 gtk_box_append (GTK_BOX (box2), child: button);
784 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
785 }
786
787 if (!gtk_widget_get_visible (widget: window))
788 gtk_widget_show (widget: window);
789 else
790 gtk_window_destroy (GTK_WINDOW (window));
791}
792
793/*
794 * Label Demo
795 */
796static void
797sensitivity_toggled (GtkWidget *toggle,
798 GtkWidget *widget)
799{
800 gtk_widget_set_sensitive (widget,
801 sensitive: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
802}
803
804static GtkWidget*
805create_sensitivity_control (GtkWidget *widget)
806{
807 GtkWidget *button;
808
809 button = gtk_toggle_button_new_with_label (label: "Sensitive");
810
811 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
812 is_active: gtk_widget_is_sensitive (widget));
813
814 g_signal_connect (button,
815 "toggled",
816 G_CALLBACK (sensitivity_toggled),
817 widget);
818
819 return button;
820}
821
822static void
823set_selectable_recursive (GtkWidget *widget,
824 gboolean setting)
825{
826 if (GTK_IS_LABEL (widget))
827 gtk_label_set_selectable (GTK_LABEL (widget), setting);
828 else
829 {
830 GtkWidget *child;
831
832 for (child = gtk_widget_get_first_child (widget);
833 child != NULL;
834 child = gtk_widget_get_next_sibling (widget: child))
835 set_selectable_recursive (widget: child, setting);
836 }
837}
838
839static void
840selectable_toggled (GtkWidget *toggle,
841 GtkWidget *widget)
842{
843 set_selectable_recursive (widget,
844 setting: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
845}
846
847static GtkWidget*
848create_selectable_control (GtkWidget *widget)
849{
850 GtkWidget *button;
851
852 button = gtk_toggle_button_new_with_label (label: "Selectable");
853
854 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
855 FALSE);
856
857 g_signal_connect (button,
858 "toggled",
859 G_CALLBACK (selectable_toggled),
860 widget);
861
862 return button;
863}
864
865static void
866dialog_response (GtkWidget *dialog, int response_id, GtkLabel *label)
867{
868 const char *text;
869
870 gtk_window_destroy (GTK_WINDOW (dialog));
871
872 text = "Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
873 "as hyperlinks, which can be clicked\n"
874 "or activated via <a href=\"keynav\">keynav</a>.\n"
875 "The links remain the same.";
876 gtk_label_set_markup (self: label, str: text);
877}
878
879static gboolean
880activate_link (GtkWidget *label, const char *uri, gpointer data)
881{
882 if (g_strcmp0 (str1: uri, str2: "keynav") == 0)
883 {
884 GtkWidget *dialog;
885
886 dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_root (label)),
887 flags: GTK_DIALOG_DESTROY_WITH_PARENT,
888 type: GTK_MESSAGE_INFO,
889 buttons: GTK_BUTTONS_OK,
890 message_format: "The term <i>keynav</i> is a shorthand for "
891 "keyboard navigation and refers to the process of using a program "
892 "(exclusively) via keyboard input.");
893
894 gtk_window_present (GTK_WINDOW (dialog));
895
896 g_signal_connect (dialog, "response", G_CALLBACK (dialog_response), label);
897
898 return TRUE;
899 }
900
901 return FALSE;
902}
903
904static void create_labels (GtkWidget *widget)
905{
906 static GtkWidget *window = NULL;
907 GtkWidget *hbox;
908 GtkWidget *vbox;
909 GtkWidget *frame;
910 GtkWidget *label;
911 GtkWidget *button;
912
913 if (!window)
914 {
915 window = gtk_window_new ();
916
917 gtk_window_set_display (GTK_WINDOW (window),
918 display: gtk_widget_get_display (widget));
919 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
920
921 gtk_window_set_title (GTK_WINDOW (window), title: "Label");
922
923 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
924
925 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 5);
926 gtk_window_set_child (GTK_WINDOW (window), child: vbox);
927
928
929 button = create_sensitivity_control (widget: hbox);
930
931 gtk_box_append (GTK_BOX (vbox), child: button);
932
933 button = create_selectable_control (widget: hbox);
934
935 gtk_box_append (GTK_BOX (vbox), child: button);
936 gtk_box_append (GTK_BOX (vbox), child: hbox);
937
938 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
939
940 gtk_box_append (GTK_BOX (hbox), child: vbox);
941
942 frame = gtk_frame_new (label: "Normal Label");
943 label = gtk_label_new (str: "This is a Normal label");
944 gtk_label_set_ellipsize (GTK_LABEL (label), mode: PANGO_ELLIPSIZE_START);
945 gtk_frame_set_child (GTK_FRAME (frame), child: label);
946 gtk_box_append (GTK_BOX (vbox), child: frame);
947
948 frame = gtk_frame_new (label: "Multi-line Label");
949 label = gtk_label_new (str: "This is a Multi-line label.\nSecond line\nThird line");
950 gtk_label_set_ellipsize (GTK_LABEL (label), mode: PANGO_ELLIPSIZE_END);
951 gtk_frame_set_child (GTK_FRAME (frame), child: label);
952 gtk_box_append (GTK_BOX (vbox), child: frame);
953
954 frame = gtk_frame_new (label: "Left Justified Label");
955 label = gtk_label_new (str: "This is a Left-Justified\nMulti-line label.\nThird line");
956 gtk_label_set_ellipsize (GTK_LABEL (label), mode: PANGO_ELLIPSIZE_MIDDLE);
957 gtk_label_set_justify (GTK_LABEL (label), jtype: GTK_JUSTIFY_LEFT);
958 gtk_frame_set_child (GTK_FRAME (frame), child: label);
959 gtk_box_append (GTK_BOX (vbox), child: frame);
960
961 frame = gtk_frame_new (label: "Right Justified Label");
962 gtk_label_set_ellipsize (GTK_LABEL (label), mode: PANGO_ELLIPSIZE_START);
963 label = gtk_label_new (str: "This is a Right-Justified\nMulti-line label.\nFourth line, (j/k)");
964 gtk_label_set_justify (GTK_LABEL (label), jtype: GTK_JUSTIFY_RIGHT);
965 gtk_frame_set_child (GTK_FRAME (frame), child: label);
966 gtk_box_append (GTK_BOX (vbox), child: frame);
967
968 frame = gtk_frame_new (label: "Internationalized Label");
969 label = gtk_label_new (NULL);
970 gtk_label_set_markup (GTK_LABEL (label),
971 str: "French (Fran\303\247ais) Bonjour, Salut\n"
972 "Korean (\355\225\234\352\270\200) \354\225\210\353\205\225\355\225\230\354\204\270\354\232\224, \354\225\210\353\205\225\355\225\230\354\213\255\353\213\210\352\271\214\n"
973 "Russian (\320\240\321\203\321\201\321\201\320\272\320\270\320\271) \320\227\320\264\321\200\320\260\320\262\321\201\321\202\320\262\321\203\320\271\321\202\320\265!\n"
974 "Chinese (Simplified) <span lang=\"zh-cn\">\345\205\203\346\260\224 \345\274\200\345\217\221</span>\n"
975 "Chinese (Traditional) <span lang=\"zh-tw\">\345\205\203\346\260\243 \351\226\213\347\231\274</span>\n"
976 "Japanese <span lang=\"ja\">\345\205\203\346\260\227 \351\226\213\347\231\272</span>");
977 gtk_label_set_justify (GTK_LABEL (label), jtype: GTK_JUSTIFY_LEFT);
978 gtk_frame_set_child (GTK_FRAME (frame), child: label);
979 gtk_box_append (GTK_BOX (vbox), child: frame);
980
981 frame = gtk_frame_new (label: "Bidirection Label");
982 label = gtk_label_new (str: "\342\200\217Arabic \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205\n"
983 "\342\200\217Hebrew \327\251\327\234\327\225\327\235");
984 gtk_frame_set_child (GTK_FRAME (frame), child: label);
985 gtk_box_append (GTK_BOX (vbox), child: frame);
986
987 frame = gtk_frame_new (label: "Links in a label");
988 label = gtk_label_new (str: "Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
989 "as hyperlinks, which can be clicked\n"
990 "or activated via <a href=\"keynav\">keynav</a>");
991 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
992 gtk_frame_set_child (GTK_FRAME (frame), child: label);
993 gtk_box_append (GTK_BOX (vbox), child: frame);
994 g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
995
996 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
997 gtk_box_append (GTK_BOX (hbox), child: vbox);
998 frame = gtk_frame_new (label: "Line wrapped label");
999 label = gtk_label_new (str: "This is an example of a line-wrapped label. It should not be taking "\
1000 "up the entire "/* big space to test spacing */\
1001 "width allocated to it, but automatically wraps the words to fit. "\
1002 "The time has come, for all good men, to come to the aid of their party. "\
1003 "The sixth sheik's six sheep's sick.\n"\
1004 " It supports multiple paragraphs correctly, and correctly adds "\
1005 "many extra spaces. ");
1006
1007 gtk_label_set_wrap (GTK_LABEL (label), TRUE);
1008 gtk_frame_set_child (GTK_FRAME (frame), child: label);
1009 gtk_box_append (GTK_BOX (vbox), child: frame);
1010
1011 frame = gtk_frame_new (label: "Filled, wrapped label");
1012 label = gtk_label_new (str: "This is an example of a line-wrapped, filled label. It should be taking "\
1013 "up the entire width allocated to it. Here is a seneance to prove "\
1014 "my point. Here is another sentence. "\
1015 "Here comes the sun, do de do de do.\n"\
1016 " This is a new paragraph.\n"\
1017 " This is another newer, longer, better paragraph. It is coming to an end, "\
1018 "unfortunately.");
1019 gtk_label_set_justify (GTK_LABEL (label), jtype: GTK_JUSTIFY_FILL);
1020 gtk_label_set_wrap (GTK_LABEL (label), TRUE);
1021 gtk_frame_set_child (GTK_FRAME (frame), child: label);
1022 gtk_box_append (GTK_BOX (vbox), child: frame);
1023
1024 frame = gtk_frame_new (label: "Underlined label");
1025 label = gtk_label_new (str: "This label is underlined!\n"
1026 "This one is underlined (\343\201\223\343\202\223\343\201\253\343\201\241\343\201\257) in quite a funky fashion");
1027 gtk_label_set_justify (GTK_LABEL (label), jtype: GTK_JUSTIFY_LEFT);
1028 gtk_frame_set_child (GTK_FRAME (frame), child: label);
1029 gtk_box_append (GTK_BOX (vbox), child: frame);
1030
1031 frame = gtk_frame_new (label: "Markup label");
1032 label = gtk_label_new (NULL);
1033
1034 /* There's also a gtk_label_set_markup() without accel if you
1035 * don't have an accelerator key
1036 */
1037 gtk_label_set_markup_with_mnemonic (GTK_LABEL (label),
1038 str: "This <span foreground=\"blue\" background=\"orange\">label</span> has "
1039 "<b>markup</b> _such as "
1040 "<big><i>Big Italics</i></big>\n"
1041 "<tt>Monospace font</tt>\n"
1042 "<u>Underline!</u>\n"
1043 "foo\n"
1044 "<span foreground=\"green\" background=\"red\">Ugly colors</span>\n"
1045 "and nothing on this line,\n"
1046 "or this.\n"
1047 "or this either\n"
1048 "or even on this one\n"
1049 "la <big>la <big>la <big>la <big>la</big></big></big></big>\n"
1050 "but this _word is <span foreground=\"purple\"><big>purple</big></span>\n"
1051 "<span underline=\"double\">We like <sup>superscript</sup> and <sub>subscript</sub> too</span>");
1052
1053 g_assert (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)) == GDK_KEY_s);
1054
1055 gtk_frame_set_child (GTK_FRAME (frame), child: label);
1056 gtk_box_append (GTK_BOX (vbox), child: frame);
1057 }
1058
1059 if (!gtk_widget_get_visible (widget: window))
1060 gtk_widget_show (widget: window);
1061 else
1062 gtk_window_destroy (GTK_WINDOW (window));
1063}
1064
1065#define DEFAULT_TEXT_RADIUS 200
1066
1067static void
1068on_rotated_text_unrealize (GtkWidget *widget)
1069{
1070 g_object_set_data (G_OBJECT (widget), key: "text-gc", NULL);
1071}
1072
1073static void
1074on_rotated_text_draw (GtkDrawingArea *drawing_area,
1075 cairo_t *cr,
1076 int width,
1077 int height,
1078 gpointer tile_pixbuf)
1079{
1080 static const char *words[] = { "The", "grand", "old", "Duke", "of", "York",
1081 "had", "10,000", "men" };
1082 int n_words;
1083 int i;
1084 double radius;
1085 PangoLayout *layout;
1086 PangoContext *context;
1087 PangoFontDescription *desc;
1088
1089 cairo_set_source_rgb (cr, red: 1, green: 1, blue: 1);
1090 cairo_paint (cr);
1091
1092 if (tile_pixbuf)
1093 {
1094 gdk_cairo_set_source_pixbuf (cr, pixbuf: tile_pixbuf, pixbuf_x: 0, pixbuf_y: 0);
1095 cairo_pattern_set_extend (pattern: cairo_get_source (cr), extend: CAIRO_EXTEND_REPEAT);
1096 }
1097 else
1098 cairo_set_source_rgb (cr, red: 0, green: 0, blue: 0);
1099
1100 radius = MIN (width, height) / 2.;
1101
1102 cairo_translate (cr,
1103 tx: radius + (width - 2 * radius) / 2,
1104 ty: radius + (height - 2 * radius) / 2);
1105 cairo_scale (cr, sx: radius / DEFAULT_TEXT_RADIUS, sy: radius / DEFAULT_TEXT_RADIUS);
1106
1107 context = gtk_widget_get_pango_context (GTK_WIDGET (drawing_area));
1108 layout = pango_layout_new (context);
1109 desc = pango_font_description_from_string (str: "Sans Bold 30");
1110 pango_layout_set_font_description (layout, desc);
1111 pango_font_description_free (desc);
1112
1113 n_words = G_N_ELEMENTS (words);
1114 for (i = 0; i < n_words; i++)
1115 {
1116 int layout_width, layout_height;
1117
1118 cairo_save (cr);
1119
1120 cairo_rotate (cr, angle: 2 * G_PI * i / n_words);
1121 pango_cairo_update_layout (cr, layout);
1122
1123 pango_layout_set_text (layout, text: words[i], length: -1);
1124 pango_layout_get_size (layout, width: &layout_width, height: &layout_height);
1125
1126 cairo_move_to (cr, x: - layout_width / 2 / PANGO_SCALE, y: - DEFAULT_TEXT_RADIUS);
1127 pango_cairo_show_layout (cr, layout);
1128
1129 cairo_restore (cr);
1130 }
1131
1132 g_object_unref (object: layout);
1133}
1134
1135static void
1136create_rotated_text (GtkWidget *widget)
1137{
1138 static GtkWidget *window = NULL;
1139
1140 if (!window)
1141 {
1142 GtkWidget *content_area;
1143 GtkWidget *drawing_area;
1144 GdkPixbuf *tile_pixbuf;
1145
1146 window = gtk_dialog_new_with_buttons (title: "Rotated Text",
1147 GTK_WINDOW (gtk_widget_get_root (widget)), flags: 0,
1148 first_button_text: "_Close", GTK_RESPONSE_CLOSE,
1149 NULL);
1150
1151 gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
1152
1153 gtk_window_set_display (GTK_WINDOW (window),
1154 display: gtk_widget_get_display (widget));
1155
1156 g_signal_connect (window, "response",
1157 G_CALLBACK (gtk_window_destroy), NULL);
1158 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
1159
1160 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
1161
1162 drawing_area = gtk_drawing_area_new ();
1163 gtk_widget_set_hexpand (widget: drawing_area, TRUE);
1164 gtk_widget_set_vexpand (widget: drawing_area, TRUE);
1165 gtk_box_append (GTK_BOX (content_area), child: drawing_area);
1166
1167 tile_pixbuf = gdk_pixbuf_new_from_file (filename: "marble.xpm", NULL);
1168
1169 gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (drawing_area),
1170 draw_func: on_rotated_text_draw,
1171 user_data: tile_pixbuf,
1172 destroy: g_object_unref);
1173 g_signal_connect (drawing_area, "unrealize",
1174 G_CALLBACK (on_rotated_text_unrealize), NULL);
1175
1176 gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (drawing_area), DEFAULT_TEXT_RADIUS * 2);
1177 gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (drawing_area), DEFAULT_TEXT_RADIUS * 2);
1178 }
1179
1180 if (!gtk_widget_get_visible (widget: window))
1181 gtk_widget_show (widget: window);
1182 else
1183 gtk_window_destroy (GTK_WINDOW (window));
1184}
1185
1186
1187/*
1188 * GtkPixmap
1189 */
1190
1191static void
1192create_pixbuf (GtkWidget *widget)
1193{
1194 static GtkWidget *window = NULL;
1195 GtkWidget *box1;
1196 GtkWidget *box2;
1197 GtkWidget *box3;
1198 GtkWidget *button;
1199 GtkWidget *label;
1200 GtkWidget *separator;
1201 GtkWidget *pixbufwid;
1202 GdkSurface *gdk_surface;
1203
1204 if (!window)
1205 {
1206 window = gtk_window_new ();
1207
1208 gtk_window_set_display (GTK_WINDOW (window),
1209 display: gtk_widget_get_display (widget));
1210 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
1211
1212 gtk_window_set_title (GTK_WINDOW (window), title: "GtkPixmap");
1213 gtk_widget_realize(widget: window);
1214
1215 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
1216 gtk_window_set_child (GTK_WINDOW (window), child: box1);
1217
1218 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
1219 gtk_box_append (GTK_BOX (box1), child: box2);
1220
1221 button = gtk_button_new ();
1222 gtk_box_append (GTK_BOX (box2), child: button);
1223
1224 gdk_surface = gtk_native_get_surface (self: GTK_NATIVE (ptr: window));
1225
1226 pixbufwid = new_pixbuf (filename: "test.xpm", window: gdk_surface);
1227
1228 label = gtk_label_new (str: "Pixbuf\ntest");
1229 box3 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
1230 gtk_box_append (GTK_BOX (box3), child: pixbufwid);
1231 gtk_box_append (GTK_BOX (box3), child: label);
1232 gtk_button_set_child (GTK_BUTTON (button), child: box3);
1233
1234 button = gtk_button_new ();
1235 gtk_box_append (GTK_BOX (box2), child: button);
1236
1237 pixbufwid = new_pixbuf (filename: "test.xpm", window: gdk_surface);
1238
1239 label = gtk_label_new (str: "Pixbuf\ntest");
1240 box3 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
1241 gtk_box_append (GTK_BOX (box3), child: pixbufwid);
1242 gtk_box_append (GTK_BOX (box3), child: label);
1243 gtk_button_set_child (GTK_BUTTON (button), child: box3);
1244
1245 gtk_widget_set_sensitive (widget: button, FALSE);
1246
1247 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
1248 gtk_box_append (GTK_BOX (box1), child: separator);
1249
1250 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
1251 gtk_box_append (GTK_BOX (box1), child: box2);
1252
1253 button = gtk_button_new_with_label (label: "close");
1254 g_signal_connect_swapped (button, "clicked",
1255 G_CALLBACK (gtk_window_destroy),
1256 window);
1257 gtk_box_append (GTK_BOX (box2), child: button);
1258 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
1259 }
1260
1261 if (!gtk_widget_get_visible (widget: window))
1262 gtk_widget_show (widget: window);
1263 else
1264 gtk_window_destroy (GTK_WINDOW (window));
1265}
1266
1267static void
1268create_tooltips (GtkWidget *widget)
1269{
1270 static GtkWidget *window = NULL;
1271 GtkWidget *box1;
1272 GtkWidget *box2;
1273 GtkWidget *box3;
1274 GtkWidget *button;
1275 GtkWidget *toggle;
1276 GtkWidget *frame;
1277 GtkWidget *separator;
1278
1279 if (!window)
1280 {
1281 window =
1282 g_object_new (object_type: gtk_window_get_type (),
1283 first_property_name: "GtkWindow::title", "Tooltips",
1284 "GtkWindow::resizable", FALSE,
1285 NULL);
1286
1287 gtk_window_set_display (GTK_WINDOW (window),
1288 display: gtk_widget_get_display (widget));
1289
1290 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
1291 gtk_window_set_child (GTK_WINDOW (window), child: box1);
1292
1293 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
1294 gtk_box_append (GTK_BOX (box1), child: box2);
1295
1296 button = gtk_toggle_button_new_with_label (label: "button1");
1297 gtk_box_append (GTK_BOX (box2), child: button);
1298
1299 gtk_widget_set_tooltip_text (widget: button, text: "This is button 1");
1300
1301 button = gtk_toggle_button_new_with_label (label: "button2");
1302 gtk_box_append (GTK_BOX (box2), child: button);
1303
1304 gtk_widget_set_tooltip_text (widget: button,
1305 text: "This is button 2. This is also a really long tooltip which probably "
1306 "won't fit on a single line and will therefore need to be wrapped. "
1307 "Hopefully the wrapping will work correctly.");
1308
1309 toggle = gtk_toggle_button_new_with_label (label: "Override TipsQuery Label");
1310 gtk_box_append (GTK_BOX (box2), child: toggle);
1311
1312 gtk_widget_set_tooltip_text (widget: toggle, text: "Toggle TipsQuery view.");
1313
1314 box3 =
1315 g_object_new (GTK_TYPE_BOX,
1316 first_property_name: "orientation", GTK_ORIENTATION_VERTICAL,
1317 "homogeneous", FALSE,
1318 "spacing", 5,
1319 NULL);
1320
1321 button =
1322 g_object_new (object_type: gtk_button_get_type (),
1323 first_property_name: "label", "[?]",
1324 NULL);
1325 gtk_box_append (GTK_BOX (box3), child: button);
1326 gtk_widget_set_tooltip_text (widget: button, text: "Start the Tooltips Inspector");
1327
1328 frame = g_object_new (object_type: gtk_frame_get_type (),
1329 first_property_name: "label", "ToolTips Inspector",
1330 "label_xalign", (double) 0.5,
1331 NULL);
1332 gtk_box_append (GTK_BOX (box2), child: frame);
1333 gtk_frame_set_child (GTK_FRAME (frame), child: box3);
1334
1335 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
1336 gtk_box_append (GTK_BOX (box1), child: separator);
1337
1338 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
1339 gtk_box_append (GTK_BOX (box1), child: box2);
1340
1341 button = gtk_button_new_with_label (label: "close");
1342 g_signal_connect_swapped (button, "clicked",
1343 G_CALLBACK (gtk_window_destroy),
1344 window);
1345 gtk_box_append (GTK_BOX (box2), child: button);
1346 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
1347
1348 gtk_widget_set_tooltip_text (widget: button, text: "Push this button to close window");
1349 }
1350
1351 if (!gtk_widget_get_visible (widget: window))
1352 gtk_widget_show (widget: window);
1353 else
1354 gtk_window_destroy (GTK_WINDOW (window));
1355}
1356
1357/*
1358 * GtkImage
1359 */
1360
1361static void
1362pack_image (GtkWidget *box,
1363 const char *text,
1364 GtkWidget *image)
1365{
1366 gtk_box_append (GTK_BOX (box),
1367 child: gtk_label_new (str: text));
1368
1369 gtk_box_append (GTK_BOX (box),
1370 child: image);
1371}
1372
1373static void
1374create_image (GtkWidget *widget)
1375{
1376 static GtkWidget *window = NULL;
1377
1378 if (window == NULL)
1379 {
1380 GtkWidget *vbox;
1381 GdkPixbuf *pixbuf;
1382
1383 window = gtk_window_new ();
1384
1385 gtk_window_set_display (GTK_WINDOW (window),
1386 display: gtk_widget_get_display (widget));
1387
1388 /* this is bogus for testing drawing when allocation < request,
1389 * don't copy into real code
1390 */
1391 gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
1392
1393 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
1394
1395 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
1396
1397 gtk_window_set_child (GTK_WINDOW (window), child: vbox);
1398
1399 pack_image (box: vbox, text: "Stock Warning Dialog", image: gtk_image_new_from_icon_name (icon_name: "dialog-warning"));
1400
1401 pixbuf = gdk_pixbuf_new_from_xpm_data (data: (const char **) openfile);
1402
1403 pack_image (box: vbox, text: "Pixbuf",
1404 image: gtk_image_new_from_pixbuf (pixbuf));
1405
1406 g_object_unref (object: pixbuf);
1407 }
1408
1409 if (!gtk_widget_get_visible (widget: window))
1410 gtk_widget_show (widget: window);
1411 else
1412 gtk_window_destroy (GTK_WINDOW (window));
1413}
1414
1415/*
1416 * ListBox demo
1417 */
1418
1419static int
1420list_sort_cb (GtkListBoxRow *a, GtkListBoxRow *b, gpointer data)
1421{
1422 int aa = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "value"));
1423 int bb = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "value"));
1424 return aa - bb;
1425}
1426
1427static gboolean
1428list_filter_all_cb (GtkListBoxRow *row, gpointer data)
1429{
1430 return FALSE;
1431}
1432
1433static gboolean
1434list_filter_odd_cb (GtkListBoxRow *row, gpointer data)
1435{
1436 int value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "value"));
1437
1438 return value % 2 == 0;
1439}
1440
1441static void
1442list_sort_clicked_cb (GtkButton *button,
1443 gpointer data)
1444{
1445 GtkListBox *list = data;
1446
1447 gtk_list_box_set_sort_func (box: list, sort_func: list_sort_cb, NULL, NULL);
1448}
1449
1450static void
1451list_filter_odd_clicked_cb (GtkButton *button,
1452 gpointer data)
1453{
1454 GtkListBox *list = data;
1455
1456 gtk_list_box_set_filter_func (box: list, filter_func: list_filter_odd_cb, NULL, NULL);
1457}
1458
1459static void
1460list_filter_all_clicked_cb (GtkButton *button,
1461 gpointer data)
1462{
1463 GtkListBox *list = data;
1464
1465 gtk_list_box_set_filter_func (box: list, filter_func: list_filter_all_cb, NULL, NULL);
1466}
1467
1468
1469static void
1470list_unfilter_clicked_cb (GtkButton *button,
1471 gpointer data)
1472{
1473 GtkListBox *list = data;
1474
1475 gtk_list_box_set_filter_func (box: list, NULL, NULL, NULL);
1476}
1477
1478static void
1479add_placeholder_clicked_cb (GtkButton *button,
1480 gpointer data)
1481{
1482 GtkListBox *list = data;
1483 GtkWidget *label;
1484
1485 label = gtk_label_new (str: "You filtered everything!!!");
1486 gtk_list_box_set_placeholder (GTK_LIST_BOX (list), placeholder: label);
1487}
1488
1489static void
1490remove_placeholder_clicked_cb (GtkButton *button,
1491 gpointer data)
1492{
1493 GtkListBox *list = data;
1494
1495 gtk_list_box_set_placeholder (GTK_LIST_BOX (list), NULL);
1496}
1497
1498
1499static void
1500create_listbox (GtkWidget *widget)
1501{
1502 static GtkWidget *window = NULL;
1503
1504 if (!window)
1505 {
1506 GtkWidget *hbox, *vbox, *scrolled, *scrolled_box, *list, *label, *button;
1507 GdkDisplay *display = gtk_widget_get_display (widget);
1508 int i;
1509
1510 window = gtk_window_new ();
1511 gtk_window_set_hide_on_close (GTK_WINDOW (window), TRUE);
1512 gtk_window_set_display (GTK_WINDOW (window), display);
1513
1514 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
1515
1516 gtk_window_set_title (GTK_WINDOW (window), title: "listbox");
1517
1518 hbox = gtk_box_new(orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
1519 gtk_window_set_child (GTK_WINDOW (window), child: hbox);
1520
1521 scrolled = gtk_scrolled_window_new ();
1522 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), hscrollbar_policy: GTK_POLICY_NEVER, vscrollbar_policy: GTK_POLICY_AUTOMATIC);
1523 gtk_box_append (GTK_BOX (hbox), child: scrolled);
1524
1525 scrolled_box = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
1526 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled), child: scrolled_box);
1527
1528 label = gtk_label_new (str: "This is \na LABEL\nwith rows");
1529 gtk_box_append (GTK_BOX (scrolled_box), child: label);
1530
1531 list = gtk_list_box_new();
1532 gtk_list_box_set_adjustment (GTK_LIST_BOX (list), adjustment: gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled)));
1533 gtk_box_append (GTK_BOX (scrolled_box), child: list);
1534
1535 for (i = 0; i < 1000; i++)
1536 {
1537 int value = g_random_int_range (begin: 0, end: 10000);
1538 label = gtk_label_new (str: g_strdup_printf (format: "Value %u", value));
1539 gtk_list_box_insert (GTK_LIST_BOX (list), child: label, position: -1);
1540 g_object_set_data (G_OBJECT (gtk_widget_get_parent (label)), key: "value", GINT_TO_POINTER (value));
1541 }
1542
1543 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
1544 gtk_box_append (GTK_BOX (hbox), child: vbox);
1545
1546 button = gtk_button_new_with_label (label: "sort");
1547 gtk_box_append (GTK_BOX (vbox), child: button);
1548 g_signal_connect (button, "clicked", G_CALLBACK (list_sort_clicked_cb), list);
1549
1550 button = gtk_button_new_with_label (label: "filter odd");
1551 gtk_box_append (GTK_BOX (vbox), child: button);
1552 g_signal_connect (button, "clicked", G_CALLBACK (list_filter_odd_clicked_cb), list);
1553
1554 button = gtk_button_new_with_label (label: "filter all");
1555 gtk_box_append (GTK_BOX (vbox), child: button);
1556 g_signal_connect (button, "clicked", G_CALLBACK (list_filter_all_clicked_cb), list);
1557
1558 button = gtk_button_new_with_label (label: "unfilter");
1559 gtk_box_append (GTK_BOX (vbox), child: button);
1560 g_signal_connect (button, "clicked", G_CALLBACK (list_unfilter_clicked_cb), list);
1561
1562 button = gtk_button_new_with_label (label: "add placeholder");
1563 gtk_box_append (GTK_BOX (vbox), child: button);
1564 g_signal_connect (button, "clicked", G_CALLBACK (add_placeholder_clicked_cb), list);
1565
1566 button = gtk_button_new_with_label (label: "remove placeholder");
1567 gtk_box_append (GTK_BOX (vbox), child: button);
1568 g_signal_connect (button, "clicked", G_CALLBACK (remove_placeholder_clicked_cb), list);
1569 }
1570
1571 if (!gtk_widget_get_visible (widget: window))
1572 gtk_widget_show (widget: window);
1573 else
1574 gtk_window_destroy (GTK_WINDOW (window));
1575}
1576
1577/*
1578 create_modal_window
1579 */
1580
1581static gboolean
1582cmw_destroy_cb(GtkWidget *widget)
1583{
1584 done = TRUE;
1585 g_main_context_wakeup (NULL);
1586
1587 return FALSE;
1588}
1589
1590static void
1591cmw_color (GtkWidget *widget, GtkWidget *parent)
1592{
1593 GtkWidget *csd;
1594
1595 csd = gtk_color_chooser_dialog_new (title: "This is a modal color selection dialog", GTK_WINDOW (parent));
1596
1597 /* Set as modal */
1598 gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
1599
1600 g_signal_connect (csd, "destroy",
1601 G_CALLBACK (cmw_destroy_cb), NULL);
1602 g_signal_connect (csd, "response",
1603 G_CALLBACK (gtk_window_destroy), NULL);
1604
1605 /* wait until destroy calls gtk_main_quit */
1606 gtk_widget_show (widget: csd);
1607 while (!done)
1608 g_main_context_iteration (NULL, TRUE);
1609}
1610
1611static void
1612cmw_file (GtkWidget *widget, GtkWidget *parent)
1613{
1614 GtkWidget *fs;
1615
1616 fs = gtk_file_chooser_dialog_new (title: "This is a modal file selection dialog",
1617 GTK_WINDOW (parent),
1618 action: GTK_FILE_CHOOSER_ACTION_OPEN,
1619 first_button_text: "_Open", GTK_RESPONSE_ACCEPT,
1620 "_Cancel", GTK_RESPONSE_CANCEL,
1621 NULL);
1622 gtk_window_set_display (GTK_WINDOW (fs), display: gtk_widget_get_display (widget: parent));
1623 gtk_window_set_modal (GTK_WINDOW (fs), TRUE);
1624
1625 g_signal_connect (fs, "destroy",
1626 G_CALLBACK (cmw_destroy_cb), NULL);
1627 g_signal_connect_swapped (fs, "response",
1628 G_CALLBACK (gtk_window_destroy), fs);
1629
1630 /* wait until destroy calls gtk_main_quit */
1631 gtk_widget_show (widget: fs);
1632 while (!done)
1633 g_main_context_iteration (NULL, TRUE);
1634}
1635
1636
1637static void
1638create_modal_window (GtkWidget *widget)
1639{
1640 GtkWidget *window = NULL;
1641 GtkWidget *box1,*box2;
1642 GtkWidget *frame1;
1643 GtkWidget *btnColor,*btnFile,*btnClose;
1644
1645 /* Create modal window (Here you can use any window descendent )*/
1646 window = gtk_window_new ();
1647 gtk_window_set_display (GTK_WINDOW (window),
1648 display: gtk_widget_get_display (widget));
1649
1650 gtk_window_set_title (GTK_WINDOW(window),title: "This window is modal");
1651
1652 /* Set window as modal */
1653 gtk_window_set_modal (GTK_WINDOW(window),TRUE);
1654
1655 /* Create widgets */
1656 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
1657 frame1 = gtk_frame_new (label: "Standard dialogs in modal form");
1658 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
1659 gtk_box_set_homogeneous (GTK_BOX (box2), TRUE);
1660 btnColor = gtk_button_new_with_label (label: "Color");
1661 btnFile = gtk_button_new_with_label (label: "File Selection");
1662 btnClose = gtk_button_new_with_label (label: "Close");
1663
1664 /* Pack widgets */
1665 gtk_window_set_child (GTK_WINDOW (window), child: box1);
1666 gtk_box_append (GTK_BOX (box1), child: frame1);
1667 gtk_frame_set_child (GTK_FRAME (frame1), child: box2);
1668 gtk_box_append (GTK_BOX (box2), child: btnColor);
1669 gtk_box_append (GTK_BOX (box2), child: btnFile);
1670 gtk_box_append (GTK_BOX (box1), child: gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL));
1671 gtk_box_append (GTK_BOX (box1), child: btnClose);
1672
1673 /* connect signals */
1674 g_signal_connect_swapped (btnClose, "clicked",
1675 G_CALLBACK (gtk_window_destroy), window);
1676
1677 g_signal_connect (window, "destroy",
1678 G_CALLBACK (cmw_destroy_cb), NULL);
1679
1680 g_signal_connect (btnColor, "clicked",
1681 G_CALLBACK (cmw_color), window);
1682 g_signal_connect (btnFile, "clicked",
1683 G_CALLBACK (cmw_file), window);
1684
1685 /* Show widgets */
1686 gtk_widget_show (widget: window);
1687
1688 /* wait until dialog get destroyed */
1689 while (!done)
1690 g_main_context_iteration (NULL, TRUE);
1691}
1692
1693/*
1694 * GtkMessageDialog
1695 */
1696
1697static void
1698make_message_dialog (GdkDisplay *display,
1699 GtkWidget **dialog,
1700 GtkMessageType type,
1701 GtkButtonsType buttons,
1702 guint default_response)
1703{
1704 if (*dialog)
1705 {
1706 gtk_window_destroy (GTK_WINDOW (*dialog));
1707
1708 return;
1709 }
1710
1711 *dialog = gtk_message_dialog_new (NULL, flags: 0, type, buttons,
1712 message_format: "This is a message dialog; it can wrap long lines. This is a long line. La la la. Look this line is wrapped. Blah blah blah blah blah blah. (Note: testgtk has a nonstandard gtkrc that changes some of the message dialog icons.)");
1713
1714 gtk_window_set_display (GTK_WINDOW (*dialog), display);
1715
1716 g_signal_connect_swapped (*dialog,
1717 "response",
1718 G_CALLBACK (gtk_window_destroy),
1719 *dialog);
1720
1721 g_object_add_weak_pointer (G_OBJECT (*dialog), weak_pointer_location: (gpointer)dialog);
1722
1723 gtk_dialog_set_default_response (GTK_DIALOG (*dialog), response_id: default_response);
1724
1725 gtk_widget_show (widget: *dialog);
1726}
1727
1728static void
1729create_message_dialog (GtkWidget *widget)
1730{
1731 static GtkWidget *info = NULL;
1732 static GtkWidget *warning = NULL;
1733 static GtkWidget *error = NULL;
1734 static GtkWidget *question = NULL;
1735 GdkDisplay *display = gtk_widget_get_display (widget);
1736
1737 make_message_dialog (display, dialog: &info, type: GTK_MESSAGE_INFO, buttons: GTK_BUTTONS_OK, default_response: GTK_RESPONSE_OK);
1738 make_message_dialog (display, dialog: &warning, type: GTK_MESSAGE_WARNING, buttons: GTK_BUTTONS_CLOSE, default_response: GTK_RESPONSE_CLOSE);
1739 make_message_dialog (display, dialog: &error, type: GTK_MESSAGE_ERROR, buttons: GTK_BUTTONS_OK_CANCEL, default_response: GTK_RESPONSE_OK);
1740 make_message_dialog (display, dialog: &question, type: GTK_MESSAGE_QUESTION, buttons: GTK_BUTTONS_YES_NO, default_response: GTK_RESPONSE_NO);
1741}
1742
1743/*
1744 * GtkScrolledWindow
1745 */
1746
1747static GtkWidget *sw_parent = NULL;
1748static GtkWidget *sw_float_parent;
1749static gulong sw_destroyed_handler = 0;
1750
1751static gboolean
1752scrolled_windows_delete_cb (GtkWidget *widget,
1753 GtkWidget *scrollwin)
1754{
1755 g_object_ref (scrollwin);
1756 gtk_box_remove (GTK_BOX (gtk_widget_get_parent (scrollwin)), child: scrollwin);
1757 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw_parent), child: scrollwin);
1758 g_object_unref (object: scrollwin);
1759
1760 g_signal_handler_disconnect (instance: sw_parent, handler_id: sw_destroyed_handler);
1761 sw_float_parent = NULL;
1762 sw_parent = NULL;
1763 sw_destroyed_handler = 0;
1764
1765 return FALSE;
1766}
1767
1768static void
1769scrolled_windows_destroy_cb (GtkWidget *widget, GtkWidget *scrollwin)
1770{
1771 gtk_window_destroy (GTK_WINDOW (sw_float_parent));
1772
1773 sw_float_parent = NULL;
1774 sw_parent = NULL;
1775 sw_destroyed_handler = 0;
1776}
1777
1778static void
1779scrolled_windows_remove (GtkWidget *dialog, int response, GtkWidget *scrollwin)
1780{
1781 if (response != GTK_RESPONSE_APPLY)
1782 {
1783 gtk_window_destroy (GTK_WINDOW (dialog));
1784 return;
1785 }
1786
1787 if (sw_parent)
1788 {
1789 g_object_ref (scrollwin);
1790 gtk_box_remove (GTK_BOX (gtk_widget_get_parent (scrollwin)), child: scrollwin);
1791 gtk_window_set_child (GTK_WINDOW (sw_float_parent), child: scrollwin);
1792 g_object_unref (object: scrollwin);
1793
1794
1795 gtk_window_destroy (GTK_WINDOW (sw_float_parent));
1796
1797 g_signal_handler_disconnect (instance: sw_parent, handler_id: sw_destroyed_handler);
1798 sw_float_parent = NULL;
1799 sw_parent = NULL;
1800 sw_destroyed_handler = 0;
1801 }
1802 else
1803 {
1804 sw_parent = gtk_widget_get_parent (widget: scrollwin);
1805 sw_float_parent = gtk_window_new ();
1806 gtk_window_set_display (GTK_WINDOW (sw_float_parent),
1807 display: gtk_widget_get_display (widget: dialog));
1808
1809 gtk_window_set_default_size (GTK_WINDOW (sw_float_parent), width: 200, height: 200);
1810
1811 g_object_ref (scrollwin);
1812 gtk_box_remove (GTK_BOX (gtk_widget_get_parent (scrollwin)), child: scrollwin);
1813 gtk_window_set_child (GTK_WINDOW (sw_float_parent), child: scrollwin);
1814 g_object_unref (object: scrollwin);
1815
1816
1817 gtk_widget_show (widget: sw_float_parent);
1818
1819 sw_destroyed_handler =
1820 g_signal_connect (sw_parent, "destroy",
1821 G_CALLBACK (scrolled_windows_destroy_cb), scrollwin);
1822 g_signal_connect (sw_float_parent, "close-request",
1823 G_CALLBACK (scrolled_windows_delete_cb), scrollwin);
1824 }
1825}
1826
1827static void
1828create_scrolled_windows (GtkWidget *widget)
1829{
1830 static GtkWidget *window;
1831 GtkWidget *content_area;
1832 GtkWidget *scrolled_window;
1833 GtkWidget *button;
1834 GtkWidget *grid;
1835 char buffer[32];
1836 int i, j;
1837
1838 if (!window)
1839 {
1840 window = gtk_dialog_new ();
1841
1842 gtk_window_set_display (GTK_WINDOW (window),
1843 display: gtk_widget_get_display (widget));
1844 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
1845
1846 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
1847
1848 gtk_window_set_title (GTK_WINDOW (window), title: "dialog");
1849
1850 scrolled_window = gtk_scrolled_window_new ();
1851 gtk_widget_set_hexpand (widget: scrolled_window, TRUE);
1852 gtk_widget_set_vexpand (widget: scrolled_window, TRUE);
1853 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
1854 hscrollbar_policy: GTK_POLICY_AUTOMATIC,
1855 vscrollbar_policy: GTK_POLICY_AUTOMATIC);
1856 gtk_box_append (GTK_BOX (content_area), child: scrolled_window);
1857
1858 grid = gtk_grid_new ();
1859 gtk_grid_set_row_spacing (GTK_GRID (grid), spacing: 10);
1860 gtk_grid_set_column_spacing (GTK_GRID (grid), spacing: 10);
1861 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled_window), child: grid);
1862 gtk_viewport_set_scroll_to_focus (GTK_VIEWPORT (gtk_widget_get_parent (grid)), TRUE);
1863
1864 for (i = 0; i < 20; i++)
1865 for (j = 0; j < 20; j++)
1866 {
1867 sprintf (s: buffer, format: "button (%d,%d)\n", i, j);
1868 button = gtk_toggle_button_new_with_label (label: buffer);
1869 gtk_grid_attach (GTK_GRID (grid), child: button, column: i, row: j, width: 1, height: 1);
1870 }
1871
1872 gtk_dialog_add_button (GTK_DIALOG (window),
1873 button_text: "Close",
1874 response_id: GTK_RESPONSE_CLOSE);
1875
1876 gtk_dialog_add_button (GTK_DIALOG (window),
1877 button_text: "Reparent Out",
1878 response_id: GTK_RESPONSE_APPLY);
1879
1880 g_signal_connect (window, "response",
1881 G_CALLBACK (scrolled_windows_remove),
1882 scrolled_window);
1883
1884 gtk_window_set_default_size (GTK_WINDOW (window), width: 300, height: 300);
1885 }
1886
1887 if (!gtk_widget_get_visible (widget: window))
1888 gtk_widget_show (widget: window);
1889 else
1890 gtk_window_destroy (GTK_WINDOW (window));
1891}
1892
1893/*
1894 * GtkEntry
1895 */
1896
1897static void
1898entry_toggle_frame (GtkWidget *checkbutton,
1899 GtkWidget *entry)
1900{
1901 gtk_entry_set_has_frame (GTK_ENTRY(entry),
1902 setting: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)));
1903}
1904
1905static void
1906entry_toggle_sensitive (GtkWidget *checkbutton,
1907 GtkWidget *entry)
1908{
1909 gtk_widget_set_sensitive (widget: entry,
1910 sensitive: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
1911}
1912
1913static gboolean
1914entry_progress_timeout (gpointer data)
1915{
1916 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data), "progress-pulse")))
1917 {
1918 gtk_entry_progress_pulse (GTK_ENTRY (data));
1919 }
1920 else
1921 {
1922 double fraction;
1923
1924 fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (data));
1925
1926 fraction += 0.05;
1927 if (fraction > 1.0001)
1928 fraction = 0.0;
1929
1930 gtk_entry_set_progress_fraction (GTK_ENTRY (data), fraction);
1931 }
1932
1933 return G_SOURCE_CONTINUE;
1934}
1935
1936static void
1937entry_remove_timeout (gpointer data)
1938{
1939 g_source_remove (GPOINTER_TO_UINT (data));
1940}
1941
1942static void
1943entry_toggle_progress (GtkWidget *checkbutton,
1944 GtkWidget *entry)
1945{
1946 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)))
1947 {
1948 guint timeout = g_timeout_add (interval: 100, function: entry_progress_timeout, data: entry);
1949 g_object_set_data_full (G_OBJECT (entry), key: "timeout-id",
1950 GUINT_TO_POINTER (timeout),
1951 destroy: entry_remove_timeout);
1952 }
1953 else
1954 {
1955 g_object_set_data (G_OBJECT (entry), key: "timeout-id",
1956 GUINT_TO_POINTER (0));
1957
1958 gtk_entry_set_progress_fraction (GTK_ENTRY (entry), fraction: 0.0);
1959 }
1960}
1961
1962static void
1963entry_toggle_pulse (GtkWidget *checkbutton,
1964 GtkWidget *entry)
1965{
1966 g_object_set_data (G_OBJECT (entry), key: "progress-pulse",
1967 GUINT_TO_POINTER ((guint) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))));
1968}
1969
1970static void
1971create_entry (GtkWidget *widget)
1972{
1973 static GtkWidget *window = NULL;
1974 GtkWidget *box1;
1975 GtkWidget *box2;
1976 GtkWidget *hbox;
1977 GtkWidget *has_frame_check;
1978 GtkWidget *sensitive_check;
1979 GtkWidget *progress_check;
1980 GtkWidget *entry;
1981 GtkComboBoxText *cb;
1982 GtkWidget *cb_entry;
1983 GtkWidget *button;
1984 GtkWidget *separator;
1985
1986 if (!window)
1987 {
1988 window = gtk_window_new ();
1989 gtk_window_set_display (GTK_WINDOW (window),
1990 display: gtk_widget_get_display (widget));
1991 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
1992
1993 gtk_window_set_title (GTK_WINDOW (window), title: "entry");
1994
1995
1996 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
1997 gtk_window_set_child (GTK_WINDOW (window), child: box1);
1998
1999
2000 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
2001 gtk_widget_set_margin_top (widget: box2, margin: 10);
2002 gtk_widget_set_margin_bottom (widget: box2, margin: 10);
2003 gtk_widget_set_margin_start (widget: box2, margin: 10);
2004 gtk_widget_set_margin_end (widget: box2, margin: 10);
2005 gtk_box_append (GTK_BOX (box1), child: box2);
2006
2007 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 5);
2008 gtk_box_append (GTK_BOX (box2), child: hbox);
2009
2010 entry = gtk_entry_new ();
2011 gtk_editable_set_text (GTK_EDITABLE (entry), text: "hello world \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205");
2012 gtk_editable_select_region (GTK_EDITABLE (entry), start_pos: 0, end_pos: 5);
2013 gtk_widget_set_hexpand (widget: entry, TRUE);
2014 gtk_box_append (GTK_BOX (hbox), child: entry);
2015
2016 cb = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new_with_entry ());
2017
2018 gtk_combo_box_text_append_text (combo_box: cb, text: "item0");
2019 gtk_combo_box_text_append_text (combo_box: cb, text: "item0");
2020 gtk_combo_box_text_append_text (combo_box: cb, text: "item1 item1");
2021 gtk_combo_box_text_append_text (combo_box: cb, text: "item2 item2 item2");
2022 gtk_combo_box_text_append_text (combo_box: cb, text: "item3 item3 item3 item3");
2023 gtk_combo_box_text_append_text (combo_box: cb, text: "item4 item4 item4 item4 item4");
2024 gtk_combo_box_text_append_text (combo_box: cb, text: "item5 item5 item5 item5 item5 item5");
2025 gtk_combo_box_text_append_text (combo_box: cb, text: "item6 item6 item6 item6 item6");
2026 gtk_combo_box_text_append_text (combo_box: cb, text: "item7 item7 item7 item7");
2027 gtk_combo_box_text_append_text (combo_box: cb, text: "item8 item8 item8");
2028 gtk_combo_box_text_append_text (combo_box: cb, text: "item9 item9");
2029
2030 cb_entry = gtk_combo_box_get_child (GTK_COMBO_BOX (cb));
2031 gtk_editable_set_text (GTK_EDITABLE (cb_entry), text: "hello world \n\n\n foo");
2032 gtk_editable_select_region (GTK_EDITABLE (cb_entry), start_pos: 0, end_pos: -1);
2033 gtk_box_append (GTK_BOX (box2), GTK_WIDGET (cb));
2034
2035 sensitive_check = gtk_check_button_new_with_label (label: "Sensitive");
2036 gtk_box_append (GTK_BOX (box2), child: sensitive_check);
2037 g_signal_connect (sensitive_check, "toggled",
2038 G_CALLBACK (entry_toggle_sensitive), entry);
2039 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
2040
2041 has_frame_check = gtk_check_button_new_with_label(label: "Has Frame");
2042 gtk_box_append (GTK_BOX (box2), child: has_frame_check);
2043 g_signal_connect (has_frame_check, "toggled",
2044 G_CALLBACK (entry_toggle_frame), entry);
2045 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
2046
2047 progress_check = gtk_check_button_new_with_label(label: "Show Progress");
2048 gtk_box_append (GTK_BOX (box2), child: progress_check);
2049 g_signal_connect (progress_check, "toggled",
2050 G_CALLBACK (entry_toggle_progress), entry);
2051
2052 progress_check = gtk_check_button_new_with_label(label: "Pulse Progress");
2053 gtk_box_append (GTK_BOX (box2), child: progress_check);
2054 g_signal_connect (progress_check, "toggled",
2055 G_CALLBACK (entry_toggle_pulse), entry);
2056
2057 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
2058 gtk_box_append (GTK_BOX (box1), child: separator);
2059
2060 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
2061 gtk_widget_set_margin_top (widget: box2, margin: 10);
2062 gtk_widget_set_margin_bottom (widget: box2, margin: 10);
2063 gtk_widget_set_margin_start (widget: box2, margin: 10);
2064 gtk_widget_set_margin_end (widget: box2, margin: 10);
2065 gtk_box_append (GTK_BOX (box1), child: box2);
2066
2067 button = gtk_button_new_with_label (label: "close");
2068 g_signal_connect_swapped (button, "clicked",
2069 G_CALLBACK (gtk_window_destroy),
2070 window);
2071 gtk_box_append (GTK_BOX (box2), child: button);
2072 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
2073 }
2074
2075 if (!gtk_widget_get_visible (widget: window))
2076 gtk_widget_show (widget: window);
2077 else
2078 gtk_window_destroy (GTK_WINDOW (window));
2079}
2080
2081static void
2082create_expander (GtkWidget *widget)
2083{
2084 GtkWidget *box1;
2085 GtkWidget *expander;
2086 GtkWidget *hidden;
2087 static GtkWidget *window = NULL;
2088
2089 if (!window)
2090 {
2091 window = gtk_window_new ();
2092 gtk_window_set_display (GTK_WINDOW (window),
2093 display: gtk_widget_get_display (widget));
2094 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
2095
2096 gtk_window_set_title (GTK_WINDOW (window), title: "expander");
2097
2098 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2099 gtk_window_set_child (GTK_WINDOW (window), child: box1);
2100
2101 expander = gtk_expander_new (label: "The Hidden");
2102
2103 gtk_box_append (GTK_BOX (box1), child: expander);
2104
2105 hidden = gtk_label_new (str: "Revealed!");
2106
2107 gtk_expander_set_child (GTK_EXPANDER (expander), child: hidden);
2108 }
2109
2110 if (!gtk_widget_get_visible (widget: window))
2111 gtk_widget_show (widget: window);
2112 else
2113 gtk_window_destroy (GTK_WINDOW (window));
2114}
2115
2116
2117/*
2118 * GtkSizeGroup
2119 */
2120
2121#define SIZE_GROUP_INITIAL_SIZE 50
2122
2123static void
2124size_group_hsize_changed (GtkSpinButton *spin_button,
2125 GtkWidget *button)
2126{
2127 gtk_widget_set_size_request (widget: gtk_button_get_child (GTK_BUTTON (button)),
2128 width: gtk_spin_button_get_value_as_int (spin_button),
2129 height: -1);
2130}
2131
2132static void
2133size_group_vsize_changed (GtkSpinButton *spin_button,
2134 GtkWidget *button)
2135{
2136 gtk_widget_set_size_request (widget: gtk_button_get_child (GTK_BUTTON (button)),
2137 width: -1,
2138 height: gtk_spin_button_get_value_as_int (spin_button));
2139}
2140
2141static GtkWidget *
2142create_size_group_window (GdkDisplay *display,
2143 GtkSizeGroup *master_size_group)
2144{
2145 GtkWidget *content_area;
2146 GtkWidget *window;
2147 GtkWidget *vbox;
2148 GtkWidget *grid;
2149 GtkWidget *main_button;
2150 GtkWidget *button;
2151 GtkWidget *spin_button;
2152 GtkWidget *hbox;
2153 GtkSizeGroup *hgroup1;
2154 GtkSizeGroup *hgroup2;
2155 GtkSizeGroup *vgroup1;
2156 GtkSizeGroup *vgroup2;
2157
2158 window = gtk_dialog_new_with_buttons (title: "GtkSizeGroup",
2159 NULL, flags: 0,
2160 first_button_text: "_Close",
2161 GTK_RESPONSE_NONE,
2162 NULL);
2163
2164 gtk_window_set_display (GTK_WINDOW (window), display);
2165
2166 gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
2167
2168 g_signal_connect (window, "response",
2169 G_CALLBACK (gtk_window_destroy),
2170 NULL);
2171
2172 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
2173
2174 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2175 gtk_box_append (GTK_BOX (content_area), child: vbox);
2176
2177 grid = gtk_grid_new ();
2178 gtk_box_append (GTK_BOX (content_area), child: grid);
2179
2180 gtk_grid_set_row_spacing (GTK_GRID (grid), spacing: 5);
2181 gtk_grid_set_column_spacing (GTK_GRID (grid), spacing: 5);
2182 gtk_widget_set_size_request (widget: grid, width: 250, height: 250);
2183
2184 hgroup1 = gtk_size_group_new (mode: GTK_SIZE_GROUP_HORIZONTAL);
2185 hgroup2 = gtk_size_group_new (mode: GTK_SIZE_GROUP_HORIZONTAL);
2186 vgroup1 = gtk_size_group_new (mode: GTK_SIZE_GROUP_VERTICAL);
2187 vgroup2 = gtk_size_group_new (mode: GTK_SIZE_GROUP_VERTICAL);
2188
2189 main_button = gtk_button_new_with_label (label: "X");
2190 gtk_widget_set_hexpand (widget: main_button, TRUE);
2191 gtk_widget_set_vexpand (widget: main_button, TRUE);
2192 gtk_widget_set_halign (widget: main_button, align: GTK_ALIGN_CENTER);
2193 gtk_widget_set_valign (widget: main_button, align: GTK_ALIGN_CENTER);
2194 gtk_grid_attach (GTK_GRID (grid), child: main_button, column: 0, row: 0, width: 1, height: 1);
2195
2196 gtk_size_group_add_widget (size_group: master_size_group, widget: main_button);
2197 gtk_size_group_add_widget (size_group: hgroup1, widget: main_button);
2198 gtk_size_group_add_widget (size_group: vgroup1, widget: main_button);
2199 gtk_widget_set_size_request (widget: gtk_button_get_child (GTK_BUTTON (main_button)),
2200 SIZE_GROUP_INITIAL_SIZE,
2201 SIZE_GROUP_INITIAL_SIZE);
2202
2203 button = gtk_button_new ();
2204 gtk_widget_set_hexpand (widget: button, TRUE);
2205 gtk_widget_set_vexpand (widget: button, TRUE);
2206 gtk_widget_set_halign (widget: button, align: GTK_ALIGN_CENTER);
2207 gtk_widget_set_valign (widget: button, align: GTK_ALIGN_CENTER);
2208 gtk_grid_attach (GTK_GRID (grid), child: button, column: 1, row: 0, width: 1, height: 1);
2209
2210 gtk_size_group_add_widget (size_group: vgroup1, widget: button);
2211 gtk_size_group_add_widget (size_group: vgroup2, widget: button);
2212
2213 button = gtk_button_new ();
2214 gtk_widget_set_hexpand (widget: button, TRUE);
2215 gtk_widget_set_vexpand (widget: button, TRUE);
2216 gtk_widget_set_halign (widget: button, align: GTK_ALIGN_CENTER);
2217 gtk_widget_set_valign (widget: button, align: GTK_ALIGN_CENTER);
2218 gtk_grid_attach (GTK_GRID (grid), child: button, column: 0, row: 1, width: 1, height: 1);
2219
2220 gtk_size_group_add_widget (size_group: hgroup1, widget: button);
2221 gtk_size_group_add_widget (size_group: hgroup2, widget: button);
2222
2223 button = gtk_button_new ();
2224 gtk_widget_set_hexpand (widget: button, TRUE);
2225 gtk_widget_set_vexpand (widget: button, TRUE);
2226 gtk_widget_set_halign (widget: button, align: GTK_ALIGN_CENTER);
2227 gtk_widget_set_valign (widget: button, align: GTK_ALIGN_CENTER);
2228 gtk_grid_attach (GTK_GRID (grid), child: button, column: 1, row: 1, width: 1, height: 1);
2229
2230 gtk_size_group_add_widget (size_group: hgroup2, widget: button);
2231 gtk_size_group_add_widget (size_group: vgroup2, widget: button);
2232
2233 g_object_unref (object: hgroup1);
2234 g_object_unref (object: hgroup2);
2235 g_object_unref (object: vgroup1);
2236 g_object_unref (object: vgroup2);
2237
2238 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 5);
2239 gtk_box_append (GTK_BOX (content_area), child: hbox);
2240
2241 spin_button = gtk_spin_button_new_with_range (min: 1, max: 100, step: 1);
2242 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
2243 gtk_widget_set_hexpand (widget: spin_button, TRUE);
2244 gtk_box_append (GTK_BOX (hbox), child: spin_button);
2245 g_signal_connect (spin_button, "value_changed",
2246 G_CALLBACK (size_group_hsize_changed), main_button);
2247
2248 spin_button = gtk_spin_button_new_with_range (min: 1, max: 100, step: 1);
2249 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
2250 gtk_widget_set_hexpand (widget: spin_button, TRUE);
2251 gtk_box_append (GTK_BOX (hbox), child: spin_button);
2252 g_signal_connect (spin_button, "value_changed",
2253 G_CALLBACK (size_group_vsize_changed), main_button);
2254
2255 return window;
2256}
2257
2258static void
2259create_size_groups (GtkWidget *widget)
2260{
2261 static GtkWidget *window1 = NULL;
2262 static GtkWidget *window2 = NULL;
2263 static GtkSizeGroup *master_size_group;
2264
2265 if (!master_size_group)
2266 master_size_group = gtk_size_group_new (mode: GTK_SIZE_GROUP_BOTH);
2267
2268 if (!window1)
2269 {
2270 window1 = create_size_group_window (display: gtk_widget_get_display (widget),
2271 master_size_group);
2272 g_object_add_weak_pointer (G_OBJECT (window1), weak_pointer_location: (gpointer *)&window1);
2273 }
2274
2275 if (!window2)
2276 {
2277 window2 = create_size_group_window (display: gtk_widget_get_display (widget),
2278 master_size_group);
2279 g_object_add_weak_pointer (G_OBJECT (window2), weak_pointer_location: (gpointer *)&window2);
2280 }
2281
2282 if (gtk_widget_get_visible (widget: window1) && gtk_widget_get_visible (widget: window2))
2283 {
2284 gtk_window_destroy (GTK_WINDOW (window1));
2285 gtk_window_destroy (GTK_WINDOW (window2));
2286 }
2287 else
2288 {
2289 if (!gtk_widget_get_visible (widget: window1))
2290 gtk_widget_show (widget: window1);
2291 if (!gtk_widget_get_visible (widget: window2))
2292 gtk_widget_show (widget: window2);
2293 }
2294}
2295
2296/*
2297 * GtkSpinButton
2298 */
2299
2300static GtkWidget *spinner1;
2301
2302static void
2303toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
2304{
2305 gtk_spin_button_set_snap_to_ticks (spin_button: spin,
2306 snap_to_ticks: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
2307}
2308
2309static void
2310toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
2311{
2312 gtk_spin_button_set_numeric (spin_button: spin,
2313 numeric: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
2314}
2315
2316static void
2317change_digits (GtkWidget *widget, GtkSpinButton *spin)
2318{
2319 gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
2320 digits: gtk_spin_button_get_value_as_int (spin_button: spin));
2321}
2322
2323static void
2324get_value (GtkWidget *widget, gpointer data)
2325{
2326 char buf[32];
2327 GtkLabel *label;
2328 GtkSpinButton *spin;
2329
2330 spin = GTK_SPIN_BUTTON (spinner1);
2331 label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
2332 if (GPOINTER_TO_INT (data) == 1)
2333 sprintf (s: buf, format: "%d", gtk_spin_button_get_value_as_int (spin_button: spin));
2334 else
2335 sprintf (s: buf, format: "%0.*f",
2336 gtk_spin_button_get_digits (spin_button: spin),
2337 gtk_spin_button_get_value (spin_button: spin));
2338
2339 gtk_label_set_text (self: label, str: buf);
2340}
2341
2342static void
2343get_spin_value (GtkWidget *widget, gpointer data)
2344{
2345 char *buffer;
2346 GtkLabel *label;
2347 GtkSpinButton *spin;
2348
2349 spin = GTK_SPIN_BUTTON (widget);
2350 label = GTK_LABEL (data);
2351
2352 buffer = g_strdup_printf (format: "%0.*f",
2353 gtk_spin_button_get_digits (spin_button: spin),
2354 gtk_spin_button_get_value (spin_button: spin));
2355 gtk_label_set_text (self: label, str: buffer);
2356
2357 g_free (mem: buffer);
2358}
2359
2360static int
2361spin_button_time_output_func (GtkSpinButton *spin_button)
2362{
2363 GtkAdjustment *adjustment;
2364 static char buf[6];
2365 double hours;
2366 double minutes;
2367
2368 adjustment = gtk_spin_button_get_adjustment (spin_button);
2369 hours = gtk_adjustment_get_value (adjustment) / 60.0;
2370 minutes = (fabs(x: floor (x: hours) - hours) < 1e-5) ? 0.0 : 30;
2371 sprintf (s: buf, format: "%02.0f:%02.0f", floor (x: hours), minutes);
2372 if (strcmp (s1: buf, s2: gtk_editable_get_text (GTK_EDITABLE (spin_button))))
2373 gtk_editable_set_text (GTK_EDITABLE (spin_button), text: buf);
2374 return TRUE;
2375}
2376
2377static int
2378spin_button_month_input_func (GtkSpinButton *spin_button,
2379 double *new_val)
2380{
2381 int i;
2382 static const char *month[12] = { "January", "February", "March", "April",
2383 "May", "June", "July", "August",
2384 "September", "October", "November", "December" };
2385 char *tmp1, *tmp2;
2386 gboolean found = FALSE;
2387
2388 for (i = 1; i <= 12; i++)
2389 {
2390 tmp1 = g_ascii_strup (str: month[i - 1], len: -1);
2391 tmp2 = g_ascii_strup (str: gtk_editable_get_text (GTK_EDITABLE (spin_button)), len: -1);
2392 if (strstr (haystack: tmp1, needle: tmp2) == tmp1)
2393 found = TRUE;
2394 g_free (mem: tmp1);
2395 g_free (mem: tmp2);
2396 if (found)
2397 break;
2398 }
2399 if (!found)
2400 {
2401 *new_val = 0.0;
2402 return GTK_INPUT_ERROR;
2403 }
2404 *new_val = (double) i;
2405 return TRUE;
2406}
2407
2408static int
2409spin_button_month_output_func (GtkSpinButton *spin_button)
2410{
2411 GtkAdjustment *adjustment;
2412 double value;
2413 int i;
2414 static const char *month[12] = { "January", "February", "March", "April",
2415 "May", "June", "July", "August", "September",
2416 "October", "November", "December" };
2417
2418 adjustment = gtk_spin_button_get_adjustment (spin_button);
2419 value = gtk_adjustment_get_value (adjustment);
2420 for (i = 1; i <= 12; i++)
2421 if (fabs (x: value - (double)i) < 1e-5)
2422 {
2423 if (strcmp (s1: month[i-1], s2: gtk_editable_get_text (GTK_EDITABLE (spin_button))))
2424 gtk_editable_set_text (GTK_EDITABLE (spin_button), text: month[i-1]);
2425 }
2426 return TRUE;
2427}
2428
2429static int
2430spin_button_hex_input_func (GtkSpinButton *spin_button,
2431 double *new_val)
2432{
2433 const char *buf;
2434 char *err;
2435 double res;
2436
2437 buf = gtk_editable_get_text (GTK_EDITABLE (spin_button));
2438 res = strtol(nptr: buf, endptr: &err, base: 16);
2439 *new_val = res;
2440 if (*err)
2441 return GTK_INPUT_ERROR;
2442 else
2443 return TRUE;
2444}
2445
2446static int
2447spin_button_hex_output_func (GtkSpinButton *spin_button)
2448{
2449 GtkAdjustment *adjustment;
2450 static char buf[7];
2451 double val;
2452
2453 adjustment = gtk_spin_button_get_adjustment (spin_button);
2454 val = gtk_adjustment_get_value (adjustment);
2455 if (fabs (x: val) < 1e-5)
2456 sprintf (s: buf, format: "0x00");
2457 else
2458 sprintf (s: buf, format: "0x%.2X", (int) val);
2459 if (strcmp (s1: buf, s2: gtk_editable_get_text (GTK_EDITABLE (spin_button))))
2460 gtk_editable_set_text (GTK_EDITABLE (spin_button), text: buf);
2461
2462 return TRUE;
2463}
2464
2465static void
2466create_spins (GtkWidget *widget)
2467{
2468 static GtkWidget *window = NULL;
2469 GtkWidget *frame;
2470 GtkWidget *hbox;
2471 GtkWidget *main_vbox;
2472 GtkWidget *vbox;
2473 GtkWidget *vbox2;
2474 GtkWidget *spinner2;
2475 GtkWidget *spinner;
2476 GtkWidget *button;
2477 GtkWidget *label;
2478 GtkWidget *val_label;
2479 GtkAdjustment *adjustment;
2480
2481 if (!window)
2482 {
2483 window = gtk_window_new ();
2484 gtk_window_set_display (GTK_WINDOW (window),
2485 display: gtk_widget_get_display (widget));
2486 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
2487
2488 gtk_window_set_title (GTK_WINDOW (window), title: "GtkSpinButton");
2489
2490 main_vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
2491 gtk_window_set_child (GTK_WINDOW (window), child: main_vbox);
2492
2493 frame = gtk_frame_new (label: "Not accelerated");
2494 gtk_box_append (GTK_BOX (main_vbox), child: frame);
2495
2496 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2497 gtk_frame_set_child (GTK_FRAME (frame), child: vbox);
2498
2499 /* Time, month, hex spinners */
2500
2501 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
2502 gtk_box_append (GTK_BOX (vbox), child: hbox);
2503
2504 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2505 gtk_widget_set_hexpand (widget: vbox2, TRUE);
2506 gtk_box_append (GTK_BOX (hbox), child: vbox2);
2507
2508 label = gtk_label_new (str: "Time :");
2509 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
2510 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
2511 gtk_box_append (GTK_BOX (vbox2), child: label);
2512
2513 adjustment = gtk_adjustment_new (value: 0, lower: 0, upper: 1410, step_increment: 30, page_increment: 60, page_size: 0);
2514 spinner = gtk_spin_button_new (adjustment, climb_rate: 0, digits: 0);
2515 gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
2516 g_signal_connect (spinner,
2517 "output",
2518 G_CALLBACK (spin_button_time_output_func),
2519 NULL);
2520 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
2521 gtk_editable_set_width_chars (GTK_EDITABLE (spinner), n_chars: 5);
2522 gtk_box_append (GTK_BOX (vbox2), child: spinner);
2523
2524 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2525 gtk_widget_set_hexpand (widget: vbox2, TRUE);
2526 gtk_box_append (GTK_BOX (hbox), child: vbox2);
2527
2528 label = gtk_label_new (str: "Month :");
2529 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
2530 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
2531 gtk_box_append (GTK_BOX (vbox2), child: label);
2532
2533 adjustment = gtk_adjustment_new (value: 1.0, lower: 1.0, upper: 12.0, step_increment: 1.0,
2534 page_increment: 5.0, page_size: 0.0);
2535 spinner = gtk_spin_button_new (adjustment, climb_rate: 0, digits: 0);
2536 gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
2537 policy: GTK_UPDATE_IF_VALID);
2538 g_signal_connect (spinner,
2539 "input",
2540 G_CALLBACK (spin_button_month_input_func),
2541 NULL);
2542 g_signal_connect (spinner,
2543 "output",
2544 G_CALLBACK (spin_button_month_output_func),
2545 NULL);
2546 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
2547 gtk_editable_set_width_chars (GTK_EDITABLE (spinner), n_chars: 9);
2548 gtk_box_append (GTK_BOX (vbox2), child: spinner);
2549
2550 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2551 gtk_widget_set_hexpand (widget: vbox2, TRUE);
2552 gtk_box_append (GTK_BOX (hbox), child: vbox2);
2553
2554 label = gtk_label_new (str: "Hex :");
2555 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
2556 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
2557 gtk_box_append (GTK_BOX (vbox2), child: label);
2558
2559 adjustment = gtk_adjustment_new (value: 0, lower: 0, upper: 255, step_increment: 1, page_increment: 16, page_size: 0);
2560 spinner = gtk_spin_button_new (adjustment, climb_rate: 0, digits: 0);
2561 gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
2562 g_signal_connect (spinner,
2563 "input",
2564 G_CALLBACK (spin_button_hex_input_func),
2565 NULL);
2566 g_signal_connect (spinner,
2567 "output",
2568 G_CALLBACK (spin_button_hex_output_func),
2569 NULL);
2570 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
2571 gtk_editable_set_width_chars (GTK_EDITABLE (spinner), n_chars: 4);
2572 gtk_box_append (GTK_BOX (vbox2), child: spinner);
2573
2574 frame = gtk_frame_new (label: "Accelerated");
2575 gtk_box_append (GTK_BOX (main_vbox), child: frame);
2576
2577 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2578 gtk_frame_set_child (GTK_FRAME (frame), child: vbox);
2579
2580 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
2581 gtk_box_append (GTK_BOX (vbox), child: hbox);
2582
2583 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2584 gtk_box_append (GTK_BOX (hbox), child: vbox2);
2585
2586 label = gtk_label_new (str: "Value :");
2587 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
2588 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
2589 gtk_box_append (GTK_BOX (vbox2), child: label);
2590
2591 adjustment = gtk_adjustment_new (value: 0.0, lower: -10000.0, upper: 10000.0,
2592 step_increment: 0.5, page_increment: 100.0, page_size: 0.0);
2593 spinner1 = gtk_spin_button_new (adjustment, climb_rate: 1.0, digits: 2);
2594 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
2595 gtk_box_append (GTK_BOX (vbox2), child: spinner1);
2596
2597 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
2598 gtk_box_append (GTK_BOX (hbox), child: vbox2);
2599
2600 label = gtk_label_new (str: "Digits :");
2601 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
2602 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
2603 gtk_box_append (GTK_BOX (vbox2), child: label);
2604
2605 adjustment = gtk_adjustment_new (value: 2, lower: 1, upper: 15, step_increment: 1, page_increment: 1, page_size: 0);
2606 spinner2 = gtk_spin_button_new (adjustment, climb_rate: 0.0, digits: 0);
2607 g_signal_connect (adjustment, "value_changed",
2608 G_CALLBACK (change_digits),
2609 spinner2);
2610 gtk_box_append (GTK_BOX (vbox2), child: spinner2);
2611
2612 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
2613 gtk_box_append (GTK_BOX (vbox), child: hbox);
2614
2615 button = gtk_check_button_new_with_label (label: "Snap to 0.5-ticks");
2616 g_signal_connect (button, "clicked",
2617 G_CALLBACK (toggle_snap),
2618 spinner1);
2619 gtk_box_append (GTK_BOX (vbox), child: button);
2620 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2621
2622 button = gtk_check_button_new_with_label (label: "Numeric only input mode");
2623 g_signal_connect (button, "clicked",
2624 G_CALLBACK (toggle_numeric),
2625 spinner1);
2626 gtk_box_append (GTK_BOX (vbox), child: button);
2627 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
2628
2629 val_label = gtk_label_new (str: "");
2630
2631 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
2632 gtk_box_append (GTK_BOX (vbox), child: hbox);
2633
2634 button = gtk_button_new_with_label (label: "Value as Int");
2635 gtk_widget_set_hexpand (widget: button, TRUE);
2636 g_object_set_data (G_OBJECT (button), key: "user_data", data: val_label);
2637 g_signal_connect (button, "clicked",
2638 G_CALLBACK (get_value),
2639 GINT_TO_POINTER (1));
2640 gtk_box_append (GTK_BOX (hbox), child: button);
2641
2642 button = gtk_button_new_with_label (label: "Value as Float");
2643 gtk_widget_set_hexpand (widget: button, TRUE);
2644 g_object_set_data (G_OBJECT (button), key: "user_data", data: val_label);
2645 g_signal_connect (button, "clicked",
2646 G_CALLBACK (get_value),
2647 GINT_TO_POINTER (2));
2648 gtk_box_append (GTK_BOX (hbox), child: button);
2649
2650 gtk_box_append (GTK_BOX (vbox), child: val_label);
2651 gtk_label_set_text (GTK_LABEL (val_label), str: "0");
2652
2653 frame = gtk_frame_new (label: "Using Convenience Constructor");
2654 gtk_box_append (GTK_BOX (main_vbox), child: frame);
2655
2656 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
2657 gtk_frame_set_child (GTK_FRAME (frame), child: hbox);
2658
2659 val_label = gtk_label_new (str: "0.0");
2660 gtk_widget_set_hexpand (widget: val_label, TRUE);
2661
2662 spinner = gtk_spin_button_new_with_range (min: 0.0, max: 10.0, step: 0.009);
2663 gtk_widget_set_hexpand (widget: spinner, TRUE);
2664 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), value: 0.0);
2665 g_signal_connect (spinner, "value_changed",
2666 G_CALLBACK (get_spin_value), val_label);
2667 gtk_box_append (GTK_BOX (hbox), child: spinner);
2668 gtk_box_append (GTK_BOX (hbox), child: val_label);
2669
2670 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
2671 gtk_box_append (GTK_BOX (main_vbox), child: hbox);
2672
2673 button = gtk_button_new_with_label (label: "Close");
2674 gtk_widget_set_hexpand (widget: button, TRUE);
2675 g_signal_connect_swapped (button, "clicked",
2676 G_CALLBACK (gtk_window_destroy),
2677 window);
2678 gtk_box_append (GTK_BOX (hbox), child: button);
2679 }
2680
2681 if (!gtk_widget_get_visible (widget: window))
2682 gtk_widget_show (widget: window);
2683 else
2684 gtk_window_destroy (GTK_WINDOW (window));
2685}
2686
2687
2688/*
2689 * Cursors
2690 */
2691
2692static void
2693cursor_draw (GtkDrawingArea *darea,
2694 cairo_t *cr,
2695 int width,
2696 int height,
2697 gpointer user_data)
2698{
2699 cairo_set_fill_rule (cr, fill_rule: CAIRO_FILL_RULE_EVEN_ODD);
2700 cairo_rectangle (cr, x: 0, y: 0, width, height);
2701 cairo_rectangle (cr, x: width / 3, y: height / 3, width: width / 3, height: height / 3);
2702 cairo_clip (cr);
2703
2704 cairo_set_source_rgb (cr, red: 1, green: 1, blue: 1);
2705 cairo_rectangle (cr, x: 0, y: 0, width, height: height / 2);
2706 cairo_fill (cr);
2707
2708 cairo_set_source_rgb (cr, red: 0, green: 0, blue: 0);
2709 cairo_rectangle (cr, x: 0, y: height / 2, width, height: height / 2);
2710 cairo_fill (cr);
2711}
2712
2713static const char *cursor_names[] = {
2714 "none",
2715 "default",
2716 "help",
2717 "pointer",
2718 "context-menu",
2719 "progress",
2720 "wait",
2721 "cell",
2722 "crosshair",
2723 "text",
2724 "vertical-text",
2725 "alias",
2726 "copy",
2727 "no-drop",
2728 "move",
2729 "not-allowed",
2730 "grab",
2731 "grabbing",
2732 "all-scroll",
2733 "col-resize",
2734 "row-resize",
2735 "n-resize",
2736 "e-resize",
2737 "s-resize",
2738 "w-resize",
2739 "ne-resize",
2740 "nw-resize",
2741 "sw-resize",
2742 "se-resize",
2743 "ew-resize",
2744 "ns-resize",
2745 "nesw-resize",
2746 "nwse-resize",
2747 "zoom-in",
2748 "zoom-out",
2749 NULL
2750};
2751
2752static GtkTreeModel *
2753cursor_model (void)
2754{
2755 GtkListStore *store;
2756 int i;
2757 store = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
2758
2759 for (i = 0; i < G_N_ELEMENTS (cursor_names); i++)
2760 gtk_list_store_insert_with_values (list_store: store, NULL, position: -1, 0, cursor_names[i], -1);
2761
2762 return (GtkTreeModel *)store;
2763}
2764
2765static void
2766cursor_pressed_cb (GtkGesture *gesture,
2767 int n_pressed,
2768 double x,
2769 double y,
2770 GtkWidget *entry)
2771{
2772 GtkWidget *widget;
2773 const char *name;
2774 int i;
2775 const int n = G_N_ELEMENTS (cursor_names);
2776 int button;
2777
2778 widget = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
2779
2780 name = (const char *)g_object_get_data (G_OBJECT (widget), key: "name");
2781 if (name != NULL)
2782 {
2783 for (i = 0; i < n; i++)
2784 if (strcmp (s1: name, s2: cursor_names[i]) == 0)
2785 break;
2786 }
2787 else
2788 i = 0;
2789
2790 button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
2791 if (button == GDK_BUTTON_PRIMARY)
2792 i = (i + 1) % n;
2793 else
2794 i = (i + n - 1) % n;
2795
2796 gtk_editable_set_text (GTK_EDITABLE (entry), text: cursor_names[i]);
2797}
2798
2799static void
2800set_cursor_from_name (GtkWidget *entry,
2801 GtkWidget *widget)
2802{
2803 const char *name;
2804
2805 name = gtk_editable_get_text (GTK_EDITABLE (entry));
2806 gtk_widget_set_cursor_from_name (widget, name);
2807
2808 g_object_set_data_full (G_OBJECT (widget), key: "name", data: g_strdup (str: name), destroy: g_free);
2809}
2810
2811#ifdef GDK_WINDOWING_X11
2812#include "x11/gdkx.h"
2813#endif
2814#ifdef GDK_WINDOWING_WAYLAND
2815#include "wayland/gdkwayland.h"
2816#endif
2817
2818static void
2819change_cursor_theme (GtkWidget *widget,
2820 gpointer data)
2821{
2822#if defined(GDK_WINDOWING_X11) || defined (GDK_WINDOWING_WAYLAND)
2823 const char *theme;
2824 int size;
2825 GdkDisplay *display;
2826 GtkWidget *entry;
2827 GtkWidget *spin;
2828
2829 entry = gtk_widget_get_next_sibling (widget: gtk_widget_get_first_child (GTK_WIDGET (data)));
2830 spin = gtk_widget_get_next_sibling (widget: entry);
2831
2832 theme = gtk_editable_get_text (GTK_EDITABLE (entry));
2833 size = (int) gtk_spin_button_get_value (GTK_SPIN_BUTTON (spin));
2834
2835 display = gtk_widget_get_display (widget);
2836#ifdef GDK_WINDOWING_X11
2837 if (GDK_IS_X11_DISPLAY (display))
2838 gdk_x11_display_set_cursor_theme (display, theme, size);
2839#endif
2840#ifdef GDK_WINDOWING_WAYLAND
2841 if (GDK_IS_WAYLAND_DISPLAY (display))
2842 gdk_wayland_display_set_cursor_theme (display, name: theme, size);
2843#endif
2844#endif
2845}
2846
2847
2848static void
2849create_cursors (GtkWidget *widget)
2850{
2851 static GtkWidget *window = NULL;
2852 GtkWidget *frame;
2853 GtkWidget *hbox;
2854 GtkWidget *main_vbox;
2855 GtkWidget *vbox;
2856 GtkWidget *darea;
2857 GtkWidget *button;
2858 GtkWidget *label;
2859 GtkWidget *any;
2860 GtkWidget *entry;
2861 GtkWidget *size;
2862 GtkEntryCompletion *completion;
2863 GtkTreeModel *model;
2864 gboolean cursor_demo = FALSE;
2865 GtkGesture *gesture;
2866
2867 if (!window)
2868 {
2869 window = gtk_window_new ();
2870 gtk_window_set_display (GTK_WINDOW (window),
2871 display: gtk_widget_get_display (widget));
2872 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
2873
2874 gtk_window_set_title (GTK_WINDOW (window), title: "Cursors");
2875
2876 main_vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
2877 gtk_window_set_child (GTK_WINDOW (window), child: main_vbox);
2878
2879 vbox = g_object_new (GTK_TYPE_BOX,
2880 first_property_name: "orientation", GTK_ORIENTATION_VERTICAL,
2881 "homogeneous", FALSE,
2882 "spacing", 5,
2883 NULL);
2884 gtk_box_append (GTK_BOX (main_vbox), child: vbox);
2885
2886#ifdef GDK_WINDOWING_X11
2887 if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (vbox)))
2888 cursor_demo = TRUE;
2889#endif
2890#ifdef GDK_WINDOWING_WAYLAND
2891 if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (vbox)))
2892 cursor_demo = TRUE;
2893#endif
2894
2895 if (cursor_demo)
2896 {
2897 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 6);
2898 gtk_widget_set_margin_top (widget: hbox, margin: 5);
2899 gtk_widget_set_margin_bottom (widget: hbox, margin: 5);
2900 gtk_widget_set_margin_start (widget: hbox, margin: 5);
2901 gtk_widget_set_margin_end (widget: hbox, margin: 5);
2902 gtk_box_append (GTK_BOX (vbox), child: hbox);
2903
2904 label = gtk_label_new (str: "Cursor Theme:");
2905 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
2906 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
2907 gtk_box_append (GTK_BOX (hbox), child: label);
2908
2909 entry = gtk_entry_new ();
2910 gtk_editable_set_text (GTK_EDITABLE (entry), text: "default");
2911 gtk_box_append (GTK_BOX (hbox), child: entry);
2912
2913 size = gtk_spin_button_new_with_range (min: 1.0, max: 128.0, step: 1.0);
2914 gtk_spin_button_set_value (GTK_SPIN_BUTTON (size), value: 24.0);
2915 gtk_widget_set_hexpand (widget: size, TRUE);
2916 gtk_box_append (GTK_BOX (hbox), child: size);
2917
2918 g_signal_connect (entry, "changed",
2919 G_CALLBACK (change_cursor_theme), hbox);
2920 g_signal_connect (size, "value-changed",
2921 G_CALLBACK (change_cursor_theme), hbox);
2922 }
2923
2924 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 6);
2925 gtk_widget_set_margin_top (widget: hbox, margin: 5);
2926 gtk_widget_set_margin_bottom (widget: hbox, margin: 5);
2927 gtk_widget_set_margin_start (widget: hbox, margin: 5);
2928 gtk_widget_set_margin_end (widget: hbox, margin: 5);
2929 gtk_box_append (GTK_BOX (vbox), child: hbox);
2930
2931 label = gtk_label_new (str: "Cursor Name:");
2932 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
2933 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
2934 gtk_box_append (GTK_BOX (hbox), child: label);
2935
2936 entry = gtk_entry_new ();
2937 completion = gtk_entry_completion_new ();
2938 model = cursor_model ();
2939 gtk_entry_completion_set_model (completion, model);
2940 gtk_entry_completion_set_text_column (completion, column: 0);
2941 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
2942 g_object_unref (object: model);
2943 gtk_widget_set_hexpand (widget: entry, TRUE);
2944 gtk_box_append (GTK_BOX (hbox), child: entry);
2945
2946 frame =
2947 g_object_new (object_type: gtk_frame_get_type (),
2948 first_property_name: "label_xalign", 0.5,
2949 "label", "Cursor Area",
2950 NULL);
2951 gtk_box_append (GTK_BOX (vbox), child: frame);
2952
2953 darea = gtk_drawing_area_new ();
2954 gtk_drawing_area_set_content_width (GTK_DRAWING_AREA (darea), width: 80);
2955 gtk_drawing_area_set_content_height (GTK_DRAWING_AREA (darea), height: 80);
2956 gtk_drawing_area_set_draw_func (GTK_DRAWING_AREA (darea), draw_func: cursor_draw, NULL, NULL);
2957 gtk_frame_set_child (GTK_FRAME (frame), child: darea);
2958 gesture = gtk_gesture_click_new ();
2959 gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), button: 0);
2960 g_signal_connect (gesture, "pressed", G_CALLBACK (cursor_pressed_cb), entry);
2961 gtk_widget_add_controller (widget: darea, GTK_EVENT_CONTROLLER (gesture));
2962
2963 g_signal_connect (entry, "changed",
2964 G_CALLBACK (set_cursor_from_name), darea);
2965
2966
2967 any = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
2968 gtk_box_append (GTK_BOX (main_vbox), child: any);
2969
2970 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
2971 gtk_widget_set_margin_top (widget: hbox, margin: 10);
2972 gtk_widget_set_margin_bottom (widget: hbox, margin: 10);
2973 gtk_widget_set_margin_start (widget: hbox, margin: 10);
2974 gtk_widget_set_margin_end (widget: hbox, margin: 10);
2975 gtk_box_append (GTK_BOX (main_vbox), child: hbox);
2976
2977 button = gtk_button_new_with_label (label: "Close");
2978 gtk_widget_set_hexpand (widget: button, TRUE);
2979 g_signal_connect_swapped (button, "clicked",
2980 G_CALLBACK (gtk_window_destroy),
2981 window);
2982 gtk_box_append (GTK_BOX (hbox), child: button);
2983
2984 gtk_widget_show (widget: window);
2985
2986 gtk_editable_set_text (GTK_EDITABLE (entry), text: "arrow");
2987 }
2988 else
2989 gtk_window_destroy (GTK_WINDOW (window));
2990}
2991
2992/*
2993 * GtkColorSelection
2994 */
2995
2996static void
2997create_color_selection (GtkWidget *widget)
2998{
2999 static GtkWidget *window = NULL;
3000
3001 if (!window)
3002 {
3003 GtkWidget *picker;
3004 GtkWidget *hbox;
3005 GtkWidget *label;
3006
3007 window = gtk_window_new ();
3008 gtk_window_set_display (GTK_WINDOW (window),
3009 display: gtk_widget_get_display (widget));
3010 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
3011
3012 gtk_window_set_title (GTK_WINDOW (window), title: "GtkColorButton");
3013
3014 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 8);
3015 gtk_widget_set_margin_top (widget: hbox, margin: 5);
3016 gtk_widget_set_margin_bottom (widget: hbox, margin: 5);
3017 gtk_widget_set_margin_start (widget: hbox, margin: 5);
3018 gtk_widget_set_margin_end (widget: hbox, margin: 5);
3019 gtk_window_set_child (GTK_WINDOW (window), child: hbox);
3020
3021 label = gtk_label_new (str: "Pick a color");
3022 gtk_box_append (GTK_BOX (hbox), child: label);
3023
3024 picker = gtk_color_button_new ();
3025 gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (picker), TRUE);
3026 gtk_box_append (GTK_BOX (hbox), child: picker);
3027 }
3028
3029 if (!gtk_widget_get_visible (widget: window))
3030 gtk_widget_show (widget: window);
3031 else
3032 gtk_window_destroy (GTK_WINDOW (window));
3033}
3034
3035static void
3036flipping_toggled_cb (GtkWidget *widget, gpointer data)
3037{
3038 int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
3039 int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
3040
3041 gtk_widget_set_default_direction (dir: new_direction);
3042}
3043
3044static void
3045orientable_toggle_orientation (GtkOrientable *orientable)
3046{
3047 GtkOrientation orientation;
3048 GtkWidget *child;
3049
3050 orientation = gtk_orientable_get_orientation (orientable);
3051 gtk_orientable_set_orientation (orientable,
3052 orientation: orientation == GTK_ORIENTATION_HORIZONTAL ?
3053 GTK_ORIENTATION_VERTICAL :
3054 GTK_ORIENTATION_HORIZONTAL);
3055
3056
3057 for (child = gtk_widget_get_first_child (GTK_WIDGET (orientable));
3058 child != NULL;
3059 child = gtk_widget_get_next_sibling (widget: child))
3060 {
3061 if (GTK_IS_ORIENTABLE (child))
3062 orientable_toggle_orientation (GTK_ORIENTABLE (child));
3063 }
3064}
3065
3066static void
3067flipping_orientation_toggled_cb (GtkWidget *widget, gpointer data)
3068{
3069 GtkWidget *content_area;
3070 GtkWidget *toplevel;
3071
3072 toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
3073 content_area = gtk_dialog_get_content_area (GTK_DIALOG (toplevel));
3074 orientable_toggle_orientation (GTK_ORIENTABLE (content_area));
3075}
3076
3077static void
3078set_direction_recurse (GtkWidget *widget,
3079 gpointer data)
3080{
3081 GtkTextDirection *dir = data;
3082 GtkWidget *child;
3083
3084 gtk_widget_set_direction (widget, dir: *dir);
3085 for (child = gtk_widget_get_first_child (widget);
3086 child != NULL;
3087 child = gtk_widget_get_next_sibling (widget: child))
3088 set_direction_recurse (widget: child, data);
3089}
3090
3091static GtkWidget *
3092create_forward_back (const char *title,
3093 GtkTextDirection text_dir)
3094{
3095 GtkWidget *frame = gtk_frame_new (label: title);
3096 GtkWidget *bbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
3097 GtkWidget *back_button = gtk_button_new_with_label (label: "Back");
3098 GtkWidget *forward_button = gtk_button_new_with_label (label: "Forward");
3099
3100 gtk_frame_set_child (GTK_FRAME (frame), child: bbox);
3101 gtk_box_append (GTK_BOX (bbox), child: back_button);
3102 gtk_box_append (GTK_BOX (bbox), child: forward_button);
3103
3104 set_direction_recurse (widget: frame, data: &text_dir);
3105
3106 return frame;
3107}
3108
3109static void
3110create_flipping (GtkWidget *widget)
3111{
3112 static GtkWidget *window = NULL;
3113 GtkWidget *check_button;
3114 GtkWidget *content_area;
3115
3116 if (!window)
3117 {
3118 window = gtk_dialog_new ();
3119
3120 gtk_window_set_display (GTK_WINDOW (window),
3121 display: gtk_widget_get_display (widget));
3122 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
3123
3124 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
3125
3126 gtk_window_set_title (GTK_WINDOW (window), title: "Bidirectional Flipping");
3127
3128 check_button = gtk_check_button_new_with_label (label: "Right-to-left global direction");
3129 gtk_box_append (GTK_BOX (content_area), child: check_button);
3130
3131 if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
3132 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
3133
3134 g_signal_connect (check_button, "toggled",
3135 G_CALLBACK (flipping_toggled_cb), NULL);
3136
3137 check_button = gtk_check_button_new_with_label (label: "Toggle orientation of all boxes");
3138 gtk_box_append (GTK_BOX (content_area), child: check_button);
3139
3140 g_signal_connect (check_button, "toggled",
3141 G_CALLBACK (flipping_orientation_toggled_cb), NULL);
3142
3143 gtk_box_append (GTK_BOX (content_area),
3144 child: create_forward_back (title: "Default", text_dir: GTK_TEXT_DIR_NONE));
3145
3146 gtk_box_append (GTK_BOX (content_area),
3147 child: create_forward_back (title: "Left-to-Right", text_dir: GTK_TEXT_DIR_LTR));
3148
3149 gtk_box_append (GTK_BOX (content_area),
3150 child: create_forward_back (title: "Right-to-Left", text_dir: GTK_TEXT_DIR_RTL));
3151
3152 gtk_dialog_add_button (GTK_DIALOG (window), button_text: "Close", response_id: GTK_RESPONSE_CLOSE);
3153 g_signal_connect (window, "response", G_CALLBACK (gtk_window_destroy), NULL);
3154 }
3155
3156 if (!gtk_widget_get_visible (widget: window))
3157 gtk_widget_show (widget: window);
3158 else
3159 gtk_window_destroy (GTK_WINDOW (window));
3160}
3161
3162/*
3163 * GtkFontSelection
3164 */
3165
3166static void
3167create_font_selection (GtkWidget *widget)
3168{
3169 static GtkWidget *window = NULL;
3170
3171 if (!window)
3172 {
3173 GtkWidget *picker;
3174 GtkWidget *hbox;
3175 GtkWidget *label;
3176
3177 window = gtk_window_new ();
3178 gtk_window_set_display (GTK_WINDOW (window),
3179 display: gtk_widget_get_display (widget));
3180 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
3181
3182 gtk_window_set_title (GTK_WINDOW (window), title: "GtkFontButton");
3183
3184 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 8);
3185 gtk_widget_set_margin_top (widget: hbox, margin: 8);
3186 gtk_widget_set_margin_bottom (widget: hbox, margin: 8);
3187 gtk_widget_set_margin_start (widget: hbox, margin: 8);
3188 gtk_widget_set_margin_end (widget: hbox, margin: 8);
3189 gtk_window_set_child (GTK_WINDOW (window), child: hbox);
3190
3191 label = gtk_label_new (str: "Pick a font");
3192 gtk_box_append (GTK_BOX (hbox), child: label);
3193
3194 picker = gtk_font_button_new ();
3195 gtk_font_button_set_use_font (GTK_FONT_BUTTON (picker), TRUE);
3196 gtk_box_append (GTK_BOX (hbox), child: picker);
3197 }
3198
3199 if (!gtk_widget_get_visible (widget: window))
3200 gtk_widget_show (widget: window);
3201 else
3202 gtk_window_destroy (GTK_WINDOW (window));
3203}
3204
3205/*
3206 * GtkDialog
3207 */
3208
3209static GtkWidget *dialog_window = NULL;
3210
3211static void
3212dialog_response_cb (GtkWidget *widget, int response, gpointer unused)
3213{
3214 GtkWidget *content_area;
3215 GtkWidget *child;
3216
3217 if (response == GTK_RESPONSE_APPLY)
3218 {
3219 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog_window));
3220
3221 for (child = gtk_widget_get_first_child (widget: content_area);
3222 child != NULL;
3223 child = gtk_widget_get_next_sibling (widget: child))
3224 {
3225 if (GTK_IS_LABEL (child))
3226 {
3227 gtk_box_remove (GTK_BOX (content_area), child);
3228 break;
3229 }
3230 }
3231
3232 /* no label removed, so add one */
3233 if (child == NULL)
3234 {
3235 GtkWidget *label;
3236
3237 label = gtk_label_new (str: "Dialog Test");
3238 gtk_widget_set_margin_start (widget: label, margin: 10);
3239 gtk_widget_set_margin_end (widget: label, margin: 10);
3240 gtk_widget_set_margin_top (widget: label, margin: 10);
3241 gtk_widget_set_margin_bottom (widget: label, margin: 10);
3242 gtk_box_append (GTK_BOX (content_area), child: label);
3243 }
3244 }
3245}
3246
3247static void
3248create_dialog (GtkWidget *widget)
3249{
3250 if (!dialog_window)
3251 {
3252 /* This is a terrible example; it's much simpler to create
3253 * dialogs than this. Don't use testgtk for example code,
3254 * use gtk-demo ;-)
3255 */
3256
3257 dialog_window = gtk_dialog_new ();
3258 gtk_window_set_display (GTK_WINDOW (dialog_window),
3259 display: gtk_widget_get_display (widget));
3260 g_object_add_weak_pointer (G_OBJECT (dialog_window), weak_pointer_location: (gpointer *)&dialog_window);
3261
3262 gtk_window_set_title (GTK_WINDOW (dialog_window), title: "GtkDialog");
3263
3264 gtk_dialog_add_button (GTK_DIALOG (dialog_window),
3265 button_text: "OK",
3266 response_id: GTK_RESPONSE_OK);
3267
3268 gtk_dialog_add_button (GTK_DIALOG (dialog_window),
3269 button_text: "Toggle",
3270 response_id: GTK_RESPONSE_APPLY);
3271
3272 g_signal_connect (dialog_window, "response",
3273 G_CALLBACK (dialog_response_cb),
3274 NULL);
3275 }
3276
3277 if (!gtk_widget_get_visible (widget: dialog_window))
3278 gtk_widget_show (widget: dialog_window);
3279 else
3280 gtk_window_destroy (GTK_WINDOW (dialog_window));
3281}
3282
3283/* Display & Screen test
3284 */
3285
3286typedef struct
3287{
3288 GtkWidget *combo;
3289 GtkWidget *entry;
3290 GtkWidget *toplevel;
3291 GtkWidget *dialog_window;
3292} ScreenDisplaySelection;
3293
3294static void
3295screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
3296{
3297 const char *display_name;
3298 GdkDisplay *display;
3299 GtkWidget *dialog;
3300 GdkDisplay *new_display = NULL;
3301 GdkDisplay *current_display = gtk_widget_get_display (widget);
3302
3303 display_name = gtk_editable_get_text (GTK_EDITABLE (data->entry));
3304 display = gdk_display_open (display_name);
3305
3306 if (!display)
3307 {
3308 dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_root (widget)),
3309 flags: GTK_DIALOG_DESTROY_WITH_PARENT,
3310 type: GTK_MESSAGE_ERROR,
3311 buttons: GTK_BUTTONS_OK,
3312 message_format: "The display :\n%s\ncannot be opened",
3313 display_name);
3314 gtk_window_set_display (GTK_WINDOW (dialog), display: current_display);
3315 gtk_widget_show (widget: dialog);
3316 g_signal_connect (dialog, "response",
3317 G_CALLBACK (gtk_window_destroy),
3318 NULL);
3319 }
3320 else
3321 {
3322 GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (data->combo));
3323 int i = 0;
3324 GtkTreeIter iter;
3325 gboolean found = FALSE;
3326 while (gtk_tree_model_iter_nth_child (tree_model: model, iter: &iter, NULL, n: i++))
3327 {
3328 char *name;
3329 gtk_tree_model_get (tree_model: model, iter: &iter, 0, &name, -1);
3330 found = !g_ascii_strcasecmp (s1: display_name, s2: name);
3331 g_free (mem: name);
3332
3333 if (found)
3334 break;
3335 }
3336 if (!found)
3337 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (data->combo), text: display_name);
3338 new_display = display;
3339
3340 gtk_window_set_display (GTK_WINDOW (data->toplevel), display: new_display);
3341 gtk_window_destroy (GTK_WINDOW (data->dialog_window));
3342 }
3343}
3344
3345static void
3346screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
3347{
3348 gtk_window_destroy (GTK_WINDOW (data));
3349}
3350
3351static void
3352create_display_screen (GtkWidget *widget)
3353{
3354 GtkWidget *grid, *frame, *window, *combo_dpy, *vbox;
3355 GtkWidget *label_dpy, *applyb, *cancelb;
3356 GtkWidget *bbox;
3357 ScreenDisplaySelection *scr_dpy_data;
3358 GdkDisplay *display = gtk_widget_get_display (widget);
3359
3360 window = g_object_new (object_type: gtk_window_get_type (),
3361 first_property_name: "display", display,
3362 "title", "Screen or Display selection",
3363 NULL);
3364 g_signal_connect (window, "destroy",
3365 G_CALLBACK (gtk_window_destroy), NULL);
3366
3367 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 3);
3368 gtk_window_set_child (GTK_WINDOW (window), child: vbox);
3369
3370 frame = gtk_frame_new (label: "Select display");
3371 gtk_box_append (GTK_BOX (vbox), child: frame);
3372
3373 grid = gtk_grid_new ();
3374 gtk_grid_set_row_spacing (GTK_GRID (grid), spacing: 3);
3375 gtk_grid_set_column_spacing (GTK_GRID (grid), spacing: 3);
3376
3377 gtk_frame_set_child (GTK_FRAME (frame), child: grid);
3378
3379 label_dpy = gtk_label_new (str: "move to another X display");
3380 combo_dpy = gtk_combo_box_text_new_with_entry ();
3381 gtk_widget_set_hexpand (widget: combo_dpy, TRUE);
3382 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_dpy), text: "diabolo:0.0");
3383 gtk_editable_set_text (GTK_EDITABLE (gtk_combo_box_get_child (GTK_COMBO_BOX (combo_dpy))),
3384 text: "<hostname>:<X Server Num>.<Screen Num>");
3385
3386 gtk_grid_attach (GTK_GRID (grid), child: label_dpy, column: 0, row: 0, width: 1, height: 1);
3387 gtk_grid_attach (GTK_GRID (grid), child: combo_dpy, column: 0, row: 1, width: 1, height: 1);
3388
3389 bbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
3390 gtk_widget_set_halign (widget: bbox, align: GTK_ALIGN_END);
3391 applyb = gtk_button_new_with_mnemonic (label: "_Apply");
3392 cancelb = gtk_button_new_with_mnemonic (label: "_Cancel");
3393
3394 gtk_box_append (GTK_BOX (vbox), child: bbox);
3395
3396 gtk_box_append (GTK_BOX (bbox), child: applyb);
3397 gtk_box_append (GTK_BOX (bbox), child: cancelb);
3398
3399 scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
3400
3401 scr_dpy_data->entry = gtk_combo_box_get_child (GTK_COMBO_BOX (combo_dpy));
3402 scr_dpy_data->toplevel = GTK_WIDGET (gtk_widget_get_root (widget));
3403 scr_dpy_data->dialog_window = window;
3404
3405 g_signal_connect (cancelb, "clicked",
3406 G_CALLBACK (screen_display_destroy_diag), window);
3407 g_signal_connect (applyb, "clicked",
3408 G_CALLBACK (screen_display_check), scr_dpy_data);
3409 gtk_widget_show (widget: window);
3410}
3411
3412/*
3413 * GtkRange
3414 */
3415
3416static char *
3417reformat_value (GtkScale *scale,
3418 double value)
3419{
3420 return g_strdup_printf (format: "-->%0.*g<--",
3421 gtk_scale_get_digits (scale), value);
3422}
3423
3424static void
3425create_range_controls (GtkWidget *widget)
3426{
3427 static GtkWidget *window = NULL;
3428 GtkWidget *box1;
3429 GtkWidget *box2;
3430 GtkWidget *button;
3431 GtkWidget *scrollbar;
3432 GtkWidget *scale;
3433 GtkWidget *separator;
3434 GtkAdjustment *adjustment;
3435 GtkWidget *hbox;
3436
3437 if (!window)
3438 {
3439 window = gtk_window_new ();
3440
3441 gtk_window_set_display (GTK_WINDOW (window),
3442 display: gtk_widget_get_display (widget));
3443 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
3444
3445 gtk_window_set_title (GTK_WINDOW (window), title: "range controls");
3446
3447
3448 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
3449 gtk_window_set_child (GTK_WINDOW (window), child: box1);
3450
3451
3452 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
3453 gtk_box_append (GTK_BOX (box1), child: box2);
3454
3455
3456 adjustment = gtk_adjustment_new (value: 0.0, lower: 0.0, upper: 101.0, step_increment: 0.1, page_increment: 1.0, page_size: 1.0);
3457
3458 scale = gtk_scale_new (orientation: GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
3459 gtk_widget_set_size_request (GTK_WIDGET (scale), width: 150, height: -1);
3460 gtk_scale_set_digits (GTK_SCALE (scale), digits: 1);
3461 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
3462 gtk_box_append (GTK_BOX (box2), child: scale);
3463
3464 scrollbar = gtk_scrollbar_new (orientation: GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
3465 gtk_box_append (GTK_BOX (box2), child: scrollbar);
3466
3467 scale = gtk_scale_new (orientation: GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
3468 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
3469 gtk_scale_set_format_value_func (GTK_SCALE (scale),
3470 func: (GtkScaleFormatValueFunc) reformat_value,
3471 NULL, NULL);
3472 gtk_box_append (GTK_BOX (box2), child: scale);
3473
3474 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
3475
3476 scale = gtk_scale_new (orientation: GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
3477 gtk_widget_set_size_request (widget: scale, width: -1, height: 200);
3478 gtk_scale_set_digits (GTK_SCALE (scale), digits: 2);
3479 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
3480 gtk_box_append (GTK_BOX (hbox), child: scale);
3481
3482 scale = gtk_scale_new (orientation: GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
3483 gtk_widget_set_size_request (widget: scale, width: -1, height: 200);
3484 gtk_scale_set_digits (GTK_SCALE (scale), digits: 2);
3485 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
3486 gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
3487 gtk_box_append (GTK_BOX (hbox), child: scale);
3488
3489 scale = gtk_scale_new (orientation: GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
3490 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
3491 gtk_scale_set_format_value_func (GTK_SCALE (scale),
3492 func: (GtkScaleFormatValueFunc) reformat_value,
3493 NULL, NULL);
3494 gtk_box_append (GTK_BOX (hbox), child: scale);
3495
3496
3497 gtk_box_append (GTK_BOX (box2), child: hbox);
3498
3499 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
3500 gtk_box_append (GTK_BOX (box1), child: separator);
3501
3502
3503 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
3504 gtk_box_append (GTK_BOX (box1), child: box2);
3505
3506
3507 button = gtk_button_new_with_label (label: "close");
3508 g_signal_connect_swapped (button, "clicked",
3509 G_CALLBACK (gtk_window_destroy),
3510 window);
3511 gtk_box_append (GTK_BOX (box2), child: button);
3512 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
3513 }
3514
3515 if (!gtk_widget_get_visible (widget: window))
3516 gtk_widget_show (widget: window);
3517 else
3518 gtk_window_destroy (GTK_WINDOW (window));
3519}
3520
3521/*
3522 * GtkNotebook
3523 */
3524
3525static const char * book_open_xpm[] = {
3526"16 16 4 1",
3527" c None s None",
3528". c black",
3529"X c #808080",
3530"o c white",
3531" ",
3532" .. ",
3533" .Xo. ... ",
3534" .Xoo. ..oo. ",
3535" .Xooo.Xooo... ",
3536" .Xooo.oooo.X. ",
3537" .Xooo.Xooo.X. ",
3538" .Xooo.oooo.X. ",
3539" .Xooo.Xooo.X. ",
3540" .Xooo.oooo.X. ",
3541" .Xoo.Xoo..X. ",
3542" .Xo.o..ooX. ",
3543" .X..XXXXX. ",
3544" ..X....... ",
3545" .. ",
3546" "};
3547
3548static const char * book_closed_xpm[] = {
3549"16 16 6 1",
3550" c None s None",
3551". c black",
3552"X c red",
3553"o c yellow",
3554"O c #808080",
3555"# c white",
3556" ",
3557" .. ",
3558" ..XX. ",
3559" ..XXXXX. ",
3560" ..XXXXXXXX. ",
3561".ooXXXXXXXXX. ",
3562"..ooXXXXXXXXX. ",
3563".X.ooXXXXXXXXX. ",
3564".XX.ooXXXXXX.. ",
3565" .XX.ooXXX..#O ",
3566" .XX.oo..##OO. ",
3567" .XX..##OO.. ",
3568" .X.#OO.. ",
3569" ..O.. ",
3570" .. ",
3571" "};
3572
3573GdkPixbuf *book_open;
3574GdkPixbuf *book_closed;
3575GtkWidget *sample_notebook;
3576
3577static void
3578set_page_image (GtkNotebook *notebook, int page_num, GdkPixbuf *pixbuf)
3579{
3580 GtkWidget *page_widget;
3581 GtkWidget *pixwid;
3582
3583 page_widget = gtk_notebook_get_nth_page (notebook, page_num);
3584
3585 pixwid = g_object_get_data (G_OBJECT (page_widget), key: "tab_pixmap");
3586 gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
3587
3588 pixwid = g_object_get_data (G_OBJECT (page_widget), key: "menu_pixmap");
3589 gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
3590}
3591
3592static void
3593page_switch (GtkWidget *widget, gpointer *page, int page_num)
3594{
3595 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
3596 int old_page_num = gtk_notebook_get_current_page (notebook);
3597
3598 if (page_num == old_page_num)
3599 return;
3600
3601 set_page_image (notebook, page_num, pixbuf: book_open);
3602
3603 if (old_page_num != -1)
3604 set_page_image (notebook, page_num: old_page_num, pixbuf: book_closed);
3605}
3606
3607static void
3608tab_fill (GtkToggleButton *button, GtkWidget *child)
3609{
3610 GtkNotebookPage *page = gtk_notebook_get_page (GTK_NOTEBOOK (sample_notebook), child);
3611 g_object_set (object: page, first_property_name: "tab-fill", gtk_toggle_button_get_active (toggle_button: button), NULL);
3612}
3613
3614static void
3615tab_expand (GtkToggleButton *button, GtkWidget *child)
3616{
3617 GtkNotebookPage *page = gtk_notebook_get_page (GTK_NOTEBOOK (sample_notebook), child);
3618 g_object_set (object: page, first_property_name: "tab-expand", gtk_toggle_button_get_active (toggle_button: button), NULL);
3619}
3620
3621static void
3622create_pages (GtkNotebook *notebook, int start, int end)
3623{
3624 GtkWidget *child = NULL;
3625 GtkWidget *button;
3626 GtkWidget *label;
3627 GtkWidget *hbox;
3628 GtkWidget *vbox;
3629 GtkWidget *label_box;
3630 GtkWidget *menu_box;
3631 GtkWidget *pixwid;
3632 int i;
3633 char buffer[32];
3634 char accel_buffer[32];
3635
3636 for (i = start; i <= end; i++)
3637 {
3638 sprintf (s: buffer, format: "Page %d", i);
3639 sprintf (s: accel_buffer, format: "Page _%d", i);
3640
3641 child = gtk_frame_new (label: buffer);
3642
3643 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
3644 gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
3645 gtk_frame_set_child (GTK_FRAME (child), child: vbox);
3646
3647 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
3648 gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
3649 gtk_box_append (GTK_BOX (vbox), child: hbox);
3650
3651 button = gtk_check_button_new_with_label (label: "Fill Tab");
3652 gtk_box_append (GTK_BOX (hbox), child: button);
3653 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
3654 g_signal_connect (button, "toggled",
3655 G_CALLBACK (tab_fill), child);
3656
3657 button = gtk_check_button_new_with_label (label: "Expand Tab");
3658 gtk_box_append (GTK_BOX (hbox), child: button);
3659 g_signal_connect (button, "toggled",
3660 G_CALLBACK (tab_expand), child);
3661
3662 button = gtk_button_new_with_label (label: "Hide Page");
3663 g_signal_connect_swapped (button, "clicked",
3664 G_CALLBACK (gtk_widget_hide),
3665 child);
3666
3667 label_box = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
3668 pixwid = gtk_image_new_from_pixbuf (pixbuf: book_closed);
3669 g_object_set_data (G_OBJECT (child), key: "tab_pixmap", data: pixwid);
3670
3671 gtk_box_append (GTK_BOX (label_box), child: pixwid);
3672 gtk_widget_set_margin_start (widget: pixwid, margin: 3);
3673 gtk_widget_set_margin_end (widget: pixwid, margin: 3);
3674 gtk_widget_set_margin_bottom (widget: pixwid, margin: 1);
3675 gtk_widget_set_margin_top (widget: pixwid, margin: 1);
3676 label = gtk_label_new_with_mnemonic (str: accel_buffer);
3677 gtk_box_append (GTK_BOX (label_box), child: label);
3678
3679
3680 menu_box = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
3681 pixwid = gtk_image_new_from_pixbuf (pixbuf: book_closed);
3682 g_object_set_data (G_OBJECT (child), key: "menu_pixmap", data: pixwid);
3683
3684 gtk_box_append (GTK_BOX (menu_box), child: pixwid);
3685 gtk_widget_set_margin_start (widget: pixwid, margin: 3);
3686 gtk_widget_set_margin_end (widget: pixwid, margin: 3);
3687 gtk_widget_set_margin_bottom (widget: pixwid, margin: 1);
3688 gtk_widget_set_margin_top (widget: pixwid, margin: 1);
3689 label = gtk_label_new (str: buffer);
3690 gtk_box_append (GTK_BOX (menu_box), child: label);
3691
3692 gtk_notebook_append_page_menu (notebook, child, tab_label: label_box, menu_label: menu_box);
3693 }
3694}
3695
3696static void
3697rotate_notebook (GtkButton *button,
3698 GtkNotebook *notebook)
3699{
3700 gtk_notebook_set_tab_pos (notebook, pos: (gtk_notebook_get_tab_pos (notebook) + 1) % 4);
3701}
3702
3703static void
3704show_all_pages (GtkButton *button,
3705 GtkNotebook *notebook)
3706{
3707 int i;
3708
3709 for (i = 0; i < gtk_notebook_get_n_pages (notebook); i++)
3710 gtk_widget_show (widget: gtk_notebook_get_nth_page (notebook, page_num: i));
3711}
3712
3713static void
3714notebook_type_changed (GtkWidget *optionmenu,
3715 gpointer data)
3716{
3717 GtkNotebook *notebook;
3718 int i, c;
3719
3720 enum {
3721 STANDARD,
3722 NOTABS,
3723 BORDERLESS,
3724 SCROLLABLE
3725 };
3726
3727 notebook = GTK_NOTEBOOK (data);
3728
3729 c = gtk_combo_box_get_active (GTK_COMBO_BOX (optionmenu));
3730
3731 switch (c)
3732 {
3733 case STANDARD:
3734 /* standard notebook */
3735 gtk_notebook_set_show_tabs (notebook, TRUE);
3736 gtk_notebook_set_show_border (notebook, TRUE);
3737 gtk_notebook_set_scrollable (notebook, FALSE);
3738 break;
3739
3740 case NOTABS:
3741 /* notabs notebook */
3742 gtk_notebook_set_show_tabs (notebook, FALSE);
3743 gtk_notebook_set_show_border (notebook, TRUE);
3744 break;
3745
3746 case BORDERLESS:
3747 /* borderless */
3748 gtk_notebook_set_show_tabs (notebook, FALSE);
3749 gtk_notebook_set_show_border (notebook, FALSE);
3750 break;
3751
3752 case SCROLLABLE:
3753 /* scrollable */
3754 gtk_notebook_set_show_tabs (notebook, TRUE);
3755 gtk_notebook_set_show_border (notebook, TRUE);
3756 gtk_notebook_set_scrollable (notebook, TRUE);
3757 if (gtk_notebook_get_n_pages (notebook) == 5)
3758 create_pages (notebook, start: 6, end: 15);
3759
3760 return;
3761 break;
3762 default:
3763 g_assert_not_reached ();
3764 }
3765
3766 if (gtk_notebook_get_n_pages (notebook) == 15)
3767 for (i = 0; i < 10; i++)
3768 gtk_notebook_remove_page (notebook, page_num: 5);
3769}
3770
3771static void
3772notebook_popup (GtkToggleButton *button,
3773 GtkNotebook *notebook)
3774{
3775 if (gtk_toggle_button_get_active (toggle_button: button))
3776 gtk_notebook_popup_enable (notebook);
3777 else
3778 gtk_notebook_popup_disable (notebook);
3779}
3780
3781static void
3782create_notebook (GtkWidget *widget)
3783{
3784 static GtkWidget *window = NULL;
3785 GtkWidget *box1;
3786 GtkWidget *box2;
3787 GtkWidget *button;
3788 GtkWidget *separator;
3789 GtkWidget *omenu;
3790 GtkWidget *label;
3791
3792 static const char *items[] =
3793 {
3794 "Standard",
3795 "No tabs",
3796 "Borderless",
3797 "Scrollable"
3798 };
3799
3800 if (!window)
3801 {
3802 window = gtk_window_new ();
3803 gtk_window_set_display (GTK_WINDOW (window),
3804 display: gtk_widget_get_display (widget));
3805 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
3806
3807 gtk_window_set_title (GTK_WINDOW (window), title: "notebook");
3808
3809 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
3810 gtk_window_set_child (GTK_WINDOW (window), child: box1);
3811
3812 sample_notebook = gtk_notebook_new ();
3813 g_signal_connect (sample_notebook, "switch_page",
3814 G_CALLBACK (page_switch), NULL);
3815 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), pos: GTK_POS_TOP);
3816 gtk_widget_set_vexpand (widget: sample_notebook, TRUE);
3817 gtk_box_append (GTK_BOX (box1), child: sample_notebook);
3818
3819 gtk_widget_realize (widget: sample_notebook);
3820
3821 if (!book_open)
3822 book_open = gdk_pixbuf_new_from_xpm_data (data: book_open_xpm);
3823
3824 if (!book_closed)
3825 book_closed = gdk_pixbuf_new_from_xpm_data (data: book_closed_xpm);
3826
3827 create_pages (GTK_NOTEBOOK (sample_notebook), start: 1, end: 5);
3828
3829 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
3830 gtk_box_append (GTK_BOX (box1), child: separator);
3831
3832 box2 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 5);
3833 gtk_box_append (GTK_BOX (box1), child: box2);
3834
3835 button = gtk_check_button_new_with_label (label: "popup menu");
3836 gtk_box_append (GTK_BOX (box2), child: button);
3837 g_signal_connect (button, "clicked",
3838 G_CALLBACK (notebook_popup),
3839 sample_notebook);
3840
3841 box2 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 5);
3842 gtk_box_append (GTK_BOX (box1), child: box2);
3843
3844 label = gtk_label_new (str: "Notebook Style :");
3845 gtk_box_append (GTK_BOX (box2), child: label);
3846
3847 omenu = build_option_menu (items, G_N_ELEMENTS (items), history: 0,
3848 func: notebook_type_changed,
3849 data: sample_notebook);
3850 gtk_box_append (GTK_BOX (box2), child: omenu);
3851
3852 button = gtk_button_new_with_label (label: "Show all Pages");
3853 gtk_box_append (GTK_BOX (box2), child: button);
3854 g_signal_connect (button, "clicked",
3855 G_CALLBACK (show_all_pages), sample_notebook);
3856
3857 box2 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 10);
3858 gtk_box_set_homogeneous (GTK_BOX (box2), TRUE);
3859 gtk_box_append (GTK_BOX (box1), child: box2);
3860
3861 button = gtk_button_new_with_label (label: "prev");
3862 g_signal_connect_swapped (button, "clicked",
3863 G_CALLBACK (gtk_notebook_prev_page),
3864 sample_notebook);
3865 gtk_box_append (GTK_BOX (box2), child: button);
3866
3867 button = gtk_button_new_with_label (label: "next");
3868 g_signal_connect_swapped (button, "clicked",
3869 G_CALLBACK (gtk_notebook_next_page),
3870 sample_notebook);
3871 gtk_box_append (GTK_BOX (box2), child: button);
3872
3873 button = gtk_button_new_with_label (label: "rotate");
3874 g_signal_connect (button, "clicked",
3875 G_CALLBACK (rotate_notebook), sample_notebook);
3876 gtk_box_append (GTK_BOX (box2), child: button);
3877
3878 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
3879 gtk_box_append (GTK_BOX (box1), child: separator);
3880
3881 button = gtk_button_new_with_label (label: "close");
3882 g_signal_connect_swapped (button, "clicked",
3883 G_CALLBACK (gtk_window_destroy),
3884 window);
3885 gtk_box_append (GTK_BOX (box1), child: button);
3886 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
3887 }
3888
3889 if (!gtk_widget_get_visible (widget: window))
3890 gtk_widget_show (widget: window);
3891 else
3892 gtk_window_destroy (GTK_WINDOW (window));
3893}
3894
3895/*
3896 * GtkPanes
3897 */
3898
3899static void
3900toggle_resize (GtkWidget *widget, GtkWidget *child)
3901{
3902 GtkPaned *paned = GTK_PANED (gtk_widget_get_parent (child));
3903
3904 if (child == gtk_paned_get_start_child (paned))
3905 gtk_paned_set_resize_start_child (paned, resize: !gtk_paned_get_resize_start_child (paned));
3906 else
3907 gtk_paned_set_resize_end_child (paned, resize: !gtk_paned_get_resize_end_child (paned));
3908}
3909
3910static void
3911toggle_shrink (GtkWidget *widget, GtkWidget *child)
3912{
3913 GtkPaned *paned = GTK_PANED (gtk_widget_get_parent (child));
3914
3915 if (child == gtk_paned_get_start_child (paned))
3916 gtk_paned_set_shrink_start_child (paned, resize: !gtk_paned_get_shrink_start_child (paned));
3917 else
3918 gtk_paned_set_shrink_end_child (paned, resize: !gtk_paned_get_shrink_end_child (paned));
3919}
3920
3921static GtkWidget *
3922create_pane_options (GtkPaned *paned,
3923 const char *frame_label,
3924 const char *label1,
3925 const char *label2)
3926{
3927 GtkWidget *child1, *child2;
3928 GtkWidget *frame;
3929 GtkWidget *grid;
3930 GtkWidget *label;
3931 GtkWidget *check_button;
3932
3933 child1 = gtk_paned_get_start_child (paned);
3934 child2 = gtk_paned_get_end_child (paned);
3935
3936 frame = gtk_frame_new (label: frame_label);
3937
3938 grid = gtk_grid_new ();
3939 gtk_frame_set_child (GTK_FRAME (frame), child: grid);
3940
3941 label = gtk_label_new (str: label1);
3942 gtk_grid_attach (GTK_GRID (grid), child: label, column: 0, row: 0, width: 1, height: 1);
3943
3944 check_button = gtk_check_button_new_with_label (label: "Resize");
3945 gtk_grid_attach (GTK_GRID (grid), child: check_button, column: 0, row: 1, width: 1, height: 1);
3946 g_signal_connect (check_button, "toggled",
3947 G_CALLBACK (toggle_resize),
3948 child1);
3949
3950 check_button = gtk_check_button_new_with_label (label: "Shrink");
3951 gtk_grid_attach (GTK_GRID (grid), child: check_button, column: 0, row: 2, width: 1, height: 1);
3952 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
3953 TRUE);
3954 g_signal_connect (check_button, "toggled",
3955 G_CALLBACK (toggle_shrink),
3956 child1);
3957
3958 label = gtk_label_new (str: label2);
3959 gtk_grid_attach (GTK_GRID (grid), child: label, column: 1, row: 0, width: 1, height: 1);
3960
3961 check_button = gtk_check_button_new_with_label (label: "Resize");
3962 gtk_grid_attach (GTK_GRID (grid), child: check_button, column: 1, row: 1, width: 1, height: 1);
3963 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
3964 TRUE);
3965 g_signal_connect (check_button, "toggled",
3966 G_CALLBACK (toggle_resize),
3967 child2);
3968
3969 check_button = gtk_check_button_new_with_label (label: "Shrink");
3970 gtk_grid_attach (GTK_GRID (grid), child: check_button, column: 1, row: 2, width: 1, height: 1);
3971 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
3972 TRUE);
3973 g_signal_connect (check_button, "toggled",
3974 G_CALLBACK (toggle_shrink),
3975 child2);
3976
3977 return frame;
3978}
3979
3980static void
3981create_panes (GtkWidget *widget)
3982{
3983 static GtkWidget *window = NULL;
3984 GtkWidget *frame;
3985 GtkWidget *hpaned;
3986 GtkWidget *vpaned;
3987 GtkWidget *button;
3988 GtkWidget *vbox;
3989
3990 if (!window)
3991 {
3992 window = gtk_window_new ();
3993
3994 gtk_window_set_display (GTK_WINDOW (window),
3995 display: gtk_widget_get_display (widget));
3996 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
3997
3998 gtk_window_set_title (GTK_WINDOW (window), title: "Panes");
3999
4000 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
4001 gtk_window_set_child (GTK_WINDOW (window), child: vbox);
4002
4003 vpaned = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
4004 gtk_box_append (GTK_BOX (vbox), child: vpaned);
4005
4006 hpaned = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4007 gtk_paned_set_start_child (GTK_PANED (vpaned), child: hpaned);
4008
4009 frame = gtk_frame_new (NULL);
4010 gtk_widget_set_size_request (widget: frame, width: 60, height: 60);
4011 gtk_paned_set_start_child (GTK_PANED (hpaned), child: frame);
4012
4013 button = gtk_button_new_with_label (label: "Hi there");
4014 gtk_frame_set_child (GTK_FRAME (frame), child: button);
4015
4016 frame = gtk_frame_new (NULL);
4017 gtk_widget_set_size_request (widget: frame, width: 80, height: 60);
4018 gtk_paned_set_end_child (GTK_PANED (hpaned), child: frame);
4019
4020 frame = gtk_frame_new (NULL);
4021 gtk_widget_set_size_request (widget: frame, width: 60, height: 80);
4022 gtk_paned_set_end_child (GTK_PANED (vpaned), child: frame);
4023
4024 /* Now create toggle buttons to control sizing */
4025
4026 gtk_box_append (GTK_BOX (vbox),
4027 child: create_pane_options (GTK_PANED (hpaned),
4028 frame_label: "Horizontal",
4029 label1: "Left",
4030 label2: "Right"));
4031
4032 gtk_box_append (GTK_BOX (vbox),
4033 child: create_pane_options (GTK_PANED (vpaned),
4034 frame_label: "Vertical",
4035 label1: "Top",
4036 label2: "Bottom"));
4037 }
4038
4039 if (!gtk_widget_get_visible (widget: window))
4040 gtk_widget_show (widget: window);
4041 else
4042 gtk_window_destroy (GTK_WINDOW (window));
4043}
4044
4045/*
4046 * Paned keyboard navigation
4047 */
4048
4049static GtkWidget*
4050paned_keyboard_window1 (GtkWidget *widget)
4051{
4052 GtkWidget *window1;
4053 GtkWidget *hpaned1;
4054 GtkWidget *frame1;
4055 GtkWidget *vbox1;
4056 GtkWidget *button7;
4057 GtkWidget *button8;
4058 GtkWidget *button9;
4059 GtkWidget *vpaned1;
4060 GtkWidget *frame2;
4061 GtkWidget *frame5;
4062 GtkWidget *hbox1;
4063 GtkWidget *button5;
4064 GtkWidget *button6;
4065 GtkWidget *frame3;
4066 GtkWidget *frame4;
4067 GtkWidget *grid1;
4068 GtkWidget *button1;
4069 GtkWidget *button2;
4070 GtkWidget *button3;
4071 GtkWidget *button4;
4072
4073 window1 = gtk_window_new ();
4074 gtk_window_set_title (GTK_WINDOW (window1), title: "Basic paned navigation");
4075 gtk_window_set_display (GTK_WINDOW (window1),
4076 display: gtk_widget_get_display (widget));
4077
4078 hpaned1 = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4079 gtk_window_set_child (GTK_WINDOW (window1), child: hpaned1);
4080
4081 frame1 = gtk_frame_new (NULL);
4082 gtk_paned_set_start_child (GTK_PANED (hpaned1), child: frame1);
4083 gtk_paned_set_resize_start_child (GTK_PANED (hpaned1), FALSE);
4084 gtk_paned_set_shrink_start_child (GTK_PANED (hpaned1), TRUE);
4085
4086 vbox1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
4087 gtk_frame_set_child (GTK_FRAME (frame1), child: vbox1);
4088
4089 button7 = gtk_button_new_with_label (label: "button7");
4090 gtk_box_append (GTK_BOX (vbox1), child: button7);
4091
4092 button8 = gtk_button_new_with_label (label: "button8");
4093 gtk_box_append (GTK_BOX (vbox1), child: button8);
4094
4095 button9 = gtk_button_new_with_label (label: "button9");
4096 gtk_box_append (GTK_BOX (vbox1), child: button9);
4097
4098 vpaned1 = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
4099 gtk_paned_set_end_child (GTK_PANED (hpaned1), child: vpaned1);
4100 gtk_paned_set_resize_end_child (GTK_PANED (hpaned1), TRUE);
4101 gtk_paned_set_shrink_end_child (GTK_PANED (hpaned1), TRUE);
4102
4103 frame2 = gtk_frame_new (NULL);
4104 gtk_paned_set_start_child (GTK_PANED (vpaned1), child: frame2);
4105 gtk_paned_set_resize_start_child (GTK_PANED (vpaned1), FALSE);
4106 gtk_paned_set_shrink_start_child (GTK_PANED (vpaned1), TRUE);
4107
4108 frame5 = gtk_frame_new (NULL);
4109 gtk_frame_set_child (GTK_FRAME (frame2), child: frame5);
4110
4111 hbox1 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
4112 gtk_frame_set_child (GTK_FRAME (frame5), child: hbox1);
4113
4114 button5 = gtk_button_new_with_label (label: "button5");
4115 gtk_box_append (GTK_BOX (hbox1), child: button5);
4116
4117 button6 = gtk_button_new_with_label (label: "button6");
4118 gtk_box_append (GTK_BOX (hbox1), child: button6);
4119
4120 frame3 = gtk_frame_new (NULL);
4121 gtk_paned_set_end_child (GTK_PANED (vpaned1), child: frame3);
4122 gtk_paned_set_resize_end_child (GTK_PANED (vpaned1), TRUE);
4123 gtk_paned_set_shrink_end_child (GTK_PANED (vpaned1), TRUE);
4124
4125 frame4 = gtk_frame_new (label: "Buttons");
4126 gtk_frame_set_child (GTK_FRAME (frame3), child: frame4);
4127
4128 grid1 = gtk_grid_new ();
4129 gtk_frame_set_child (GTK_FRAME (frame4), child: grid1);
4130
4131 button1 = gtk_button_new_with_label (label: "button1");
4132 gtk_grid_attach (GTK_GRID (grid1), child: button1, column: 0, row: 0, width: 1, height: 1);
4133
4134 button2 = gtk_button_new_with_label (label: "button2");
4135 gtk_grid_attach (GTK_GRID (grid1), child: button2, column: 1, row: 0, width: 1, height: 1);
4136
4137 button3 = gtk_button_new_with_label (label: "button3");
4138 gtk_grid_attach (GTK_GRID (grid1), child: button3, column: 0, row: 1, width: 1, height: 1);
4139
4140 button4 = gtk_button_new_with_label (label: "button4");
4141 gtk_grid_attach (GTK_GRID (grid1), child: button4, column: 1, row: 1, width: 1, height: 1);
4142
4143 return window1;
4144}
4145
4146static GtkWidget*
4147paned_keyboard_window2 (GtkWidget *widget)
4148{
4149 GtkWidget *window2;
4150 GtkWidget *hpaned2;
4151 GtkWidget *frame6;
4152 GtkWidget *button13;
4153 GtkWidget *hbox2;
4154 GtkWidget *vpaned2;
4155 GtkWidget *frame7;
4156 GtkWidget *button12;
4157 GtkWidget *frame8;
4158 GtkWidget *button11;
4159 GtkWidget *button10;
4160
4161 window2 = gtk_window_new ();
4162 gtk_window_set_title (GTK_WINDOW (window2), title: "\"button 10\" is not inside the horizontal pane");
4163
4164 gtk_window_set_display (GTK_WINDOW (window2),
4165 display: gtk_widget_get_display (widget));
4166
4167 hpaned2 = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4168 gtk_window_set_child (GTK_WINDOW (window2), child: hpaned2);
4169
4170 frame6 = gtk_frame_new (NULL);
4171 gtk_paned_set_start_child (GTK_PANED (hpaned2), child: frame6);
4172 gtk_paned_set_resize_start_child (GTK_PANED (hpaned2), FALSE);
4173 gtk_paned_set_shrink_start_child (GTK_PANED (hpaned2), TRUE);
4174
4175 button13 = gtk_button_new_with_label (label: "button13");
4176 gtk_frame_set_child (GTK_FRAME (frame6), child: button13);
4177
4178 hbox2 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
4179 gtk_paned_set_end_child (GTK_PANED (hpaned2), child: hbox2);
4180 gtk_paned_set_resize_end_child (GTK_PANED (hpaned2), TRUE);
4181 gtk_paned_set_shrink_end_child (GTK_PANED (hpaned2), TRUE);
4182
4183 vpaned2 = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
4184 gtk_box_append (GTK_BOX (hbox2), child: vpaned2);
4185
4186 frame7 = gtk_frame_new (NULL);
4187 gtk_paned_set_start_child (GTK_PANED (vpaned2), child: frame7);
4188 gtk_paned_set_resize_start_child (GTK_PANED (vpaned2), FALSE);
4189 gtk_paned_set_shrink_start_child (GTK_PANED (vpaned2), TRUE);
4190
4191 button12 = gtk_button_new_with_label (label: "button12");
4192 gtk_frame_set_child (GTK_FRAME (frame7), child: button12);
4193
4194 frame8 = gtk_frame_new (NULL);
4195 gtk_paned_set_end_child (GTK_PANED (vpaned2), child: frame8);
4196 gtk_paned_set_resize_end_child (GTK_PANED (vpaned2), TRUE);
4197 gtk_paned_set_shrink_end_child (GTK_PANED (vpaned2), TRUE);
4198
4199 button11 = gtk_button_new_with_label (label: "button11");
4200 gtk_frame_set_child (GTK_FRAME (frame8), child: button11);
4201
4202 button10 = gtk_button_new_with_label (label: "button10");
4203 gtk_box_append (GTK_BOX (hbox2), child: button10);
4204
4205 return window2;
4206}
4207
4208static GtkWidget*
4209paned_keyboard_window3 (GtkWidget *widget)
4210{
4211 GtkWidget *window3;
4212 GtkWidget *vbox2;
4213 GtkWidget *label1;
4214 GtkWidget *hpaned3;
4215 GtkWidget *frame9;
4216 GtkWidget *button14;
4217 GtkWidget *hpaned4;
4218 GtkWidget *frame10;
4219 GtkWidget *button15;
4220 GtkWidget *hpaned5;
4221 GtkWidget *frame11;
4222 GtkWidget *button16;
4223 GtkWidget *frame12;
4224 GtkWidget *button17;
4225
4226 window3 = gtk_window_new ();
4227 g_object_set_data (G_OBJECT (window3), key: "window3", data: window3);
4228 gtk_window_set_title (GTK_WINDOW (window3), title: "Nested panes");
4229
4230 gtk_window_set_display (GTK_WINDOW (window3),
4231 display: gtk_widget_get_display (widget));
4232
4233
4234 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
4235 gtk_window_set_child (GTK_WINDOW (window3), child: vbox2);
4236
4237 label1 = gtk_label_new (str: "Three panes nested inside each other");
4238 gtk_box_append (GTK_BOX (vbox2), child: label1);
4239
4240 hpaned3 = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4241 gtk_box_append (GTK_BOX (vbox2), child: hpaned3);
4242
4243 frame9 = gtk_frame_new (NULL);
4244 gtk_paned_set_start_child (GTK_PANED (hpaned3), child: frame9);
4245 gtk_paned_set_resize_start_child (GTK_PANED (hpaned3), FALSE);
4246 gtk_paned_set_shrink_start_child (GTK_PANED (hpaned3), TRUE);
4247
4248 button14 = gtk_button_new_with_label (label: "button14");
4249 gtk_frame_set_child (GTK_FRAME (frame9), child: button14);
4250
4251 hpaned4 = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4252 gtk_paned_set_end_child (GTK_PANED (hpaned3), child: hpaned4);
4253 gtk_paned_set_resize_end_child (GTK_PANED (hpaned3), TRUE);
4254 gtk_paned_set_shrink_end_child (GTK_PANED (hpaned3), TRUE);
4255
4256 frame10 = gtk_frame_new (NULL);
4257 gtk_paned_set_start_child (GTK_PANED (hpaned4), child: frame10);
4258 gtk_paned_set_resize_start_child (GTK_PANED (hpaned4), FALSE);
4259 gtk_paned_set_shrink_start_child (GTK_PANED (hpaned4), TRUE);
4260
4261 button15 = gtk_button_new_with_label (label: "button15");
4262 gtk_frame_set_child (GTK_FRAME (frame10), child: button15);
4263
4264 hpaned5 = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4265 gtk_paned_set_end_child (GTK_PANED (hpaned4), child: hpaned5);
4266 gtk_paned_set_resize_end_child (GTK_PANED (hpaned4), TRUE);
4267 gtk_paned_set_shrink_end_child (GTK_PANED (hpaned4), TRUE);
4268
4269 frame11 = gtk_frame_new (NULL);
4270 gtk_paned_set_start_child (GTK_PANED (hpaned5), child: frame11);
4271 gtk_paned_set_resize_start_child (GTK_PANED (hpaned5), FALSE);
4272 gtk_paned_set_shrink_start_child (GTK_PANED (hpaned5), TRUE);
4273
4274 button16 = gtk_button_new_with_label (label: "button16");
4275 gtk_frame_set_child (GTK_FRAME (frame11), child: button16);
4276
4277 frame12 = gtk_frame_new (NULL);
4278 gtk_paned_set_end_child (GTK_PANED (hpaned5), child: frame12);
4279 gtk_paned_set_resize_end_child (GTK_PANED (hpaned5), TRUE);
4280 gtk_paned_set_shrink_end_child (GTK_PANED (hpaned5), TRUE);
4281
4282 button17 = gtk_button_new_with_label (label: "button17");
4283 gtk_frame_set_child (GTK_FRAME (frame12), child: button17);
4284
4285 return window3;
4286}
4287
4288static GtkWidget*
4289paned_keyboard_window4 (GtkWidget *widget)
4290{
4291 GtkWidget *window4;
4292 GtkWidget *vbox3;
4293 GtkWidget *label2;
4294 GtkWidget *hpaned6;
4295 GtkWidget *vpaned3;
4296 GtkWidget *button19;
4297 GtkWidget *button18;
4298 GtkWidget *hbox3;
4299 GtkWidget *vpaned4;
4300 GtkWidget *button21;
4301 GtkWidget *button20;
4302 GtkWidget *vpaned5;
4303 GtkWidget *button23;
4304 GtkWidget *button22;
4305 GtkWidget *vpaned6;
4306 GtkWidget *button25;
4307 GtkWidget *button24;
4308
4309 window4 = gtk_window_new ();
4310 g_object_set_data (G_OBJECT (window4), key: "window4", data: window4);
4311 gtk_window_set_title (GTK_WINDOW (window4), title: "window4");
4312
4313 gtk_window_set_display (GTK_WINDOW (window4),
4314 display: gtk_widget_get_display (widget));
4315
4316 vbox3 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
4317 gtk_window_set_child (GTK_WINDOW (window4), child: vbox3);
4318
4319 label2 = gtk_label_new (str: "Widget tree:\n\nhpaned \n - vpaned\n - hbox\n - vpaned\n - vpaned\n - vpaned\n");
4320 gtk_box_append (GTK_BOX (vbox3), child: label2);
4321 gtk_label_set_justify (GTK_LABEL (label2), jtype: GTK_JUSTIFY_LEFT);
4322
4323 hpaned6 = gtk_paned_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4324 gtk_box_append (GTK_BOX (vbox3), child: hpaned6);
4325
4326 vpaned3 = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
4327 gtk_paned_set_start_child (GTK_PANED (hpaned6), child: vpaned3);
4328 gtk_paned_set_resize_start_child (GTK_PANED (hpaned6), FALSE);
4329 gtk_paned_set_shrink_start_child (GTK_PANED (hpaned6), TRUE);
4330
4331 button19 = gtk_button_new_with_label (label: "button19");
4332 gtk_paned_set_start_child (GTK_PANED (vpaned3), child: button19);
4333 gtk_paned_set_resize_start_child (GTK_PANED (vpaned3), FALSE);
4334 gtk_paned_set_shrink_start_child (GTK_PANED (vpaned3), TRUE);
4335
4336 button18 = gtk_button_new_with_label (label: "button18");
4337 gtk_paned_set_end_child (GTK_PANED (vpaned3), child: button18);
4338 gtk_paned_set_resize_end_child (GTK_PANED (vpaned3), TRUE);
4339 gtk_paned_set_shrink_end_child (GTK_PANED (vpaned3), TRUE);
4340
4341 hbox3 = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
4342 gtk_paned_set_end_child (GTK_PANED (hpaned6), child: hbox3);
4343 gtk_paned_set_resize_end_child (GTK_PANED (hpaned6), TRUE);
4344 gtk_paned_set_shrink_end_child (GTK_PANED (hpaned6), TRUE);
4345
4346 vpaned4 = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
4347 gtk_box_append (GTK_BOX (hbox3), child: vpaned4);
4348
4349 button21 = gtk_button_new_with_label (label: "button21");
4350 gtk_paned_set_start_child (GTK_PANED (vpaned4), child: button21);
4351 gtk_paned_set_resize_start_child (GTK_PANED (vpaned4), FALSE);
4352 gtk_paned_set_shrink_start_child (GTK_PANED (vpaned4), TRUE);
4353
4354 button20 = gtk_button_new_with_label (label: "button20");
4355 gtk_paned_set_end_child (GTK_PANED (vpaned4), child: button20);
4356 gtk_paned_set_resize_end_child (GTK_PANED (vpaned4), TRUE);
4357 gtk_paned_set_shrink_end_child (GTK_PANED (vpaned4), TRUE);
4358
4359 vpaned5 = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
4360 gtk_box_append (GTK_BOX (hbox3), child: vpaned5);
4361
4362 button23 = gtk_button_new_with_label (label: "button23");
4363 gtk_paned_set_start_child (GTK_PANED (vpaned5), child: button23);
4364 gtk_paned_set_resize_start_child (GTK_PANED (vpaned5), FALSE);
4365 gtk_paned_set_shrink_start_child (GTK_PANED (vpaned5), TRUE);
4366
4367 button22 = gtk_button_new_with_label (label: "button22");
4368 gtk_paned_set_end_child (GTK_PANED (vpaned5), child: button22);
4369 gtk_paned_set_resize_end_child (GTK_PANED (vpaned5), TRUE);
4370 gtk_paned_set_shrink_end_child (GTK_PANED (vpaned5), TRUE);
4371
4372 vpaned6 = gtk_paned_new (orientation: GTK_ORIENTATION_VERTICAL);
4373 gtk_box_append (GTK_BOX (hbox3), child: vpaned6);
4374
4375 button25 = gtk_button_new_with_label (label: "button25");
4376 gtk_paned_set_start_child (GTK_PANED (vpaned6), child: button25);
4377 gtk_paned_set_resize_start_child (GTK_PANED (vpaned6), FALSE);
4378 gtk_paned_set_shrink_start_child (GTK_PANED (vpaned6), TRUE);
4379
4380 button24 = gtk_button_new_with_label (label: "button24");
4381 gtk_paned_set_end_child (GTK_PANED (vpaned6), child: button24);
4382 gtk_paned_set_resize_end_child (GTK_PANED (vpaned6), TRUE);
4383 gtk_paned_set_shrink_end_child (GTK_PANED (vpaned6), TRUE);
4384
4385 return window4;
4386}
4387
4388static void
4389create_paned_keyboard_navigation (GtkWidget *widget)
4390{
4391 static GtkWidget *window1 = NULL;
4392 static GtkWidget *window2 = NULL;
4393 static GtkWidget *window3 = NULL;
4394 static GtkWidget *window4 = NULL;
4395
4396 if (window1 &&
4397 (gtk_widget_get_display (widget: window1) != gtk_widget_get_display (widget)))
4398 {
4399 gtk_window_destroy (GTK_WINDOW (window1));
4400 gtk_window_destroy (GTK_WINDOW (window2));
4401 gtk_window_destroy (GTK_WINDOW (window3));
4402 gtk_window_destroy (GTK_WINDOW (window4));
4403 }
4404
4405 if (!window1)
4406 {
4407 window1 = paned_keyboard_window1 (widget);
4408 g_object_add_weak_pointer (G_OBJECT (window1), weak_pointer_location: (gpointer *)&window1);
4409 }
4410
4411 if (!window2)
4412 {
4413 window2 = paned_keyboard_window2 (widget);
4414 g_object_add_weak_pointer (G_OBJECT (window2), weak_pointer_location: (gpointer *)&window2);
4415 }
4416
4417 if (!window3)
4418 {
4419 window3 = paned_keyboard_window3 (widget);
4420 g_object_add_weak_pointer (G_OBJECT (window3), weak_pointer_location: (gpointer *)&window3);
4421 }
4422
4423 if (!window4)
4424 {
4425 window4 = paned_keyboard_window4 (widget);
4426 g_object_add_weak_pointer (G_OBJECT (window4), weak_pointer_location: (gpointer *)&window4);
4427 }
4428
4429 if (gtk_widget_get_visible (widget: window1))
4430 gtk_window_destroy (GTK_WINDOW (window1));
4431 else
4432 gtk_widget_show (GTK_WIDGET (window1));
4433
4434 if (gtk_widget_get_visible (widget: window2))
4435 gtk_window_destroy (GTK_WINDOW (window2));
4436 else
4437 gtk_widget_show (GTK_WIDGET (window2));
4438
4439 if (gtk_widget_get_visible (widget: window3))
4440 gtk_window_destroy (GTK_WINDOW (window3));
4441 else
4442 gtk_widget_show (GTK_WIDGET (window3));
4443
4444 if (gtk_widget_get_visible (widget: window4))
4445 gtk_window_destroy (GTK_WINDOW (window4));
4446 else
4447 gtk_widget_show (GTK_WIDGET (window4));
4448}
4449
4450/*
4451 * WM Hints demo
4452 */
4453
4454static void
4455create_wmhints (GtkWidget *widget)
4456{
4457 static GtkWidget *window = NULL;
4458 GtkWidget *label;
4459 GtkWidget *separator;
4460 GtkWidget *button;
4461 GtkWidget *box1;
4462 GtkWidget *box2;
4463 GdkPixbuf *pixbuf;
4464 GdkTexture *texture;
4465 GList *list;
4466
4467 if (!window)
4468 {
4469 window = gtk_window_new ();
4470
4471 gtk_window_set_display (GTK_WINDOW (window),
4472 display: gtk_widget_get_display (widget));
4473 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
4474
4475 gtk_window_set_title (GTK_WINDOW (window), title: "WM Hints");
4476
4477 gtk_widget_realize (widget: window);
4478
4479 pixbuf = gdk_pixbuf_new_from_xpm_data (data: (const char **) openfile);
4480 texture = gdk_texture_new_for_pixbuf (pixbuf);
4481
4482 list = g_list_prepend (NULL, data: texture);
4483
4484 g_list_free (list);
4485 g_object_unref (object: texture);
4486 g_object_unref (object: pixbuf);
4487
4488 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
4489 gtk_window_set_child (GTK_WINDOW (window), child: box1);
4490
4491 label = gtk_label_new (str: "Try iconizing me!");
4492 gtk_widget_set_size_request (widget: label, width: 150, height: 50);
4493
4494 gtk_box_append (GTK_BOX (box1), child: label);
4495
4496 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
4497 gtk_box_append (GTK_BOX (box1), child: separator);
4498
4499
4500 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
4501 gtk_box_append (GTK_BOX (box1), child: box2);
4502
4503
4504 button = gtk_button_new_with_label (label: "close");
4505
4506 g_signal_connect_swapped (button, "clicked",
4507 G_CALLBACK (gtk_window_destroy),
4508 window);
4509
4510 gtk_box_append (GTK_BOX (box2), child: button);
4511 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
4512 }
4513
4514 if (!gtk_widget_get_visible (widget: window))
4515 gtk_widget_show (widget: window);
4516 else
4517 gtk_window_destroy (GTK_WINDOW (window));
4518}
4519
4520/*
4521 * Window state tracking
4522 */
4523
4524static void
4525surface_state_callback (GdkSurface *window,
4526 GParamSpec *pspec,
4527 GtkWidget *label)
4528{
4529 char *msg;
4530 GdkToplevelState new_state;
4531
4532 new_state = gdk_toplevel_get_state (toplevel: GDK_TOPLEVEL (ptr: window));
4533 msg = g_strconcat (string1: (const char *)g_object_get_data (G_OBJECT (label), key: "title"), ": ",
4534 (new_state & GDK_TOPLEVEL_STATE_MINIMIZED) ?
4535 "minimized" : "not minimized", ", ",
4536 (new_state & GDK_TOPLEVEL_STATE_STICKY) ?
4537 "sticky" : "not sticky", ", ",
4538 (new_state & GDK_TOPLEVEL_STATE_MAXIMIZED) ?
4539 "maximized" : "not maximized", ", ",
4540 (new_state & GDK_TOPLEVEL_STATE_FULLSCREEN) ?
4541 "fullscreen" : "not fullscreen", ", ",
4542 (new_state & GDK_TOPLEVEL_STATE_ABOVE) ?
4543 "above" : "not above", ", ",
4544 (new_state & GDK_TOPLEVEL_STATE_BELOW) ?
4545 "below" : "not below", ", ",
4546 NULL);
4547
4548 gtk_label_set_text (GTK_LABEL (label), str: msg);
4549
4550 g_free (mem: msg);
4551}
4552
4553static GtkWidget*
4554tracking_label (GtkWidget *window)
4555{
4556 GtkWidget *label;
4557 GtkWidget *hbox;
4558 GtkWidget *button;
4559
4560 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 5);
4561
4562 g_signal_connect_object (instance: hbox,
4563 detailed_signal: "destroy",
4564 G_CALLBACK (gtk_window_destroy),
4565 gobject: window,
4566 connect_flags: G_CONNECT_SWAPPED);
4567
4568 label = gtk_label_new (str: "<no window state events received>");
4569 gtk_label_set_wrap (GTK_LABEL (label), TRUE);
4570 gtk_box_append (GTK_BOX (hbox), child: label);
4571
4572 g_object_set_data (G_OBJECT (label), key: "title", data: (gpointer)gtk_window_get_title (GTK_WINDOW (window)));
4573 g_signal_connect_object (instance: gtk_native_get_surface (self: GTK_NATIVE (ptr: window)), detailed_signal: "notify::state",
4574 G_CALLBACK (surface_state_callback),
4575 gobject: label,
4576 connect_flags: 0);
4577
4578 button = gtk_button_new_with_label (label: "Unminimize");
4579 g_signal_connect_object (instance: button,
4580 detailed_signal: "clicked",
4581 G_CALLBACK (gtk_window_unminimize),
4582 gobject: window,
4583 connect_flags: G_CONNECT_SWAPPED);
4584 gtk_box_append (GTK_BOX (hbox), child: button);
4585
4586 button = gtk_button_new_with_label (label: "Minimize");
4587 g_signal_connect_object (instance: button,
4588 detailed_signal: "clicked",
4589 G_CALLBACK (gtk_window_minimize),
4590 gobject: window,
4591 connect_flags: G_CONNECT_SWAPPED);
4592 gtk_box_append (GTK_BOX (hbox), child: button);
4593
4594 button = gtk_button_new_with_label (label: "Fullscreen");
4595 g_signal_connect_object (instance: button,
4596 detailed_signal: "clicked",
4597 G_CALLBACK (gtk_window_fullscreen),
4598 gobject: window,
4599 connect_flags: G_CONNECT_SWAPPED);
4600 gtk_box_append (GTK_BOX (hbox), child: button);
4601
4602 button = gtk_button_new_with_label (label: "Unfullscreen");
4603 g_signal_connect_object (instance: button,
4604 detailed_signal: "clicked",
4605 G_CALLBACK (gtk_window_unfullscreen),
4606 gobject: window,
4607 connect_flags: G_CONNECT_SWAPPED);
4608 gtk_box_append (GTK_BOX (hbox), child: button);
4609
4610 button = gtk_button_new_with_label (label: "Present");
4611 g_signal_connect_object (instance: button,
4612 detailed_signal: "clicked",
4613 G_CALLBACK (gtk_window_present),
4614 gobject: window,
4615 connect_flags: G_CONNECT_SWAPPED);
4616 gtk_box_append (GTK_BOX (hbox), child: button);
4617
4618 button = gtk_button_new_with_label (label: "Show");
4619 g_signal_connect_object (instance: button,
4620 detailed_signal: "clicked",
4621 G_CALLBACK (gtk_widget_show),
4622 gobject: window,
4623 connect_flags: G_CONNECT_SWAPPED);
4624 gtk_box_append (GTK_BOX (hbox), child: button);
4625
4626 return hbox;
4627}
4628
4629static GtkWidget*
4630get_state_controls (GtkWidget *window)
4631{
4632 GtkWidget *vbox;
4633 GtkWidget *button;
4634
4635 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
4636
4637 button = gtk_button_new_with_label (label: "Maximize");
4638 g_signal_connect_object (instance: button,
4639 detailed_signal: "clicked",
4640 G_CALLBACK (gtk_window_maximize),
4641 gobject: window,
4642 connect_flags: G_CONNECT_SWAPPED);
4643 gtk_box_append (GTK_BOX (vbox), child: button);
4644
4645 button = gtk_button_new_with_label (label: "Unmaximize");
4646 g_signal_connect_object (instance: button,
4647 detailed_signal: "clicked",
4648 G_CALLBACK (gtk_window_unmaximize),
4649 gobject: window,
4650 connect_flags: G_CONNECT_SWAPPED);
4651 gtk_box_append (GTK_BOX (vbox), child: button);
4652
4653 button = gtk_button_new_with_label (label: "Minimize");
4654 g_signal_connect_object (instance: button,
4655 detailed_signal: "clicked",
4656 G_CALLBACK (gtk_window_minimize),
4657 gobject: window,
4658 connect_flags: G_CONNECT_SWAPPED);
4659 gtk_box_append (GTK_BOX (vbox), child: button);
4660
4661 button = gtk_button_new_with_label (label: "Fullscreen");
4662 g_signal_connect_object (instance: button,
4663 detailed_signal: "clicked",
4664 G_CALLBACK (gtk_window_fullscreen),
4665 gobject: window,
4666 connect_flags: G_CONNECT_SWAPPED);
4667 gtk_box_append (GTK_BOX (vbox), child: button);
4668
4669 button = gtk_button_new_with_label (label: "Unfullscreen");
4670 g_signal_connect_object (instance: button,
4671 detailed_signal: "clicked",
4672 G_CALLBACK (gtk_window_unfullscreen),
4673 gobject: window,
4674 connect_flags: G_CONNECT_SWAPPED);
4675 gtk_box_append (GTK_BOX (vbox), child: button);
4676
4677 button = gtk_button_new_with_label (label: "Hide (withdraw)");
4678 g_signal_connect_object (instance: button,
4679 detailed_signal: "clicked",
4680 G_CALLBACK (gtk_widget_hide),
4681 gobject: window,
4682 connect_flags: G_CONNECT_SWAPPED);
4683 gtk_box_append (GTK_BOX (vbox), child: button);
4684
4685 return vbox;
4686}
4687
4688static void
4689create_surface_states (GtkWidget *widget)
4690{
4691 static GtkWidget *window = NULL;
4692 GtkWidget *label;
4693 GtkWidget *box1;
4694 GtkWidget *iconified;
4695 GtkWidget *normal;
4696 GtkWidget *controls;
4697
4698 if (!window)
4699 {
4700 window = gtk_window_new ();
4701 gtk_window_set_display (GTK_WINDOW (window),
4702 display: gtk_widget_get_display (widget));
4703 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
4704
4705 gtk_window_set_title (GTK_WINDOW (window), title: "Surface states");
4706
4707 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
4708 gtk_window_set_child (GTK_WINDOW (window), child: box1);
4709
4710 iconified = gtk_window_new ();
4711
4712 gtk_window_set_display (GTK_WINDOW (iconified),
4713 display: gtk_widget_get_display (widget));
4714
4715 g_signal_connect_object (instance: iconified, detailed_signal: "destroy",
4716 G_CALLBACK (gtk_window_destroy),
4717 gobject: window,
4718 connect_flags: G_CONNECT_SWAPPED);
4719 gtk_window_minimize (GTK_WINDOW (iconified));
4720 gtk_window_set_title (GTK_WINDOW (iconified), title: "Minimized initially");
4721 controls = get_state_controls (window: iconified);
4722 gtk_window_set_child (GTK_WINDOW (iconified), child: controls);
4723
4724 normal = gtk_window_new ();
4725
4726 gtk_window_set_display (GTK_WINDOW (normal),
4727 display: gtk_widget_get_display (widget));
4728
4729 g_signal_connect_object (instance: normal, detailed_signal: "destroy",
4730 G_CALLBACK (gtk_window_destroy),
4731 gobject: window,
4732 connect_flags: G_CONNECT_SWAPPED);
4733
4734 gtk_window_set_title (GTK_WINDOW (normal), title: "Unminimized initially");
4735 controls = get_state_controls (window: normal);
4736 gtk_window_set_child (GTK_WINDOW (normal), child: controls);
4737
4738 gtk_widget_realize (widget: iconified);
4739 gtk_widget_realize (widget: normal);
4740
4741 label = tracking_label (window: iconified);
4742 gtk_box_append (GTK_BOX (box1), child: label);
4743
4744 label = tracking_label (window: normal);
4745 gtk_box_append (GTK_BOX (box1), child: label);
4746
4747 gtk_widget_show (widget: iconified);
4748 gtk_widget_show (widget: normal);
4749 }
4750
4751 if (!gtk_widget_get_visible (widget: window))
4752 gtk_widget_show (widget: window);
4753 else
4754 gtk_window_destroy (GTK_WINDOW (window));
4755}
4756
4757/*
4758 * Window sizing
4759 */
4760
4761static void
4762get_ints (GtkWidget *window,
4763 int *a,
4764 int *b)
4765{
4766 GtkWidget *spin1;
4767 GtkWidget *spin2;
4768
4769 spin1 = g_object_get_data (G_OBJECT (window), key: "spin1");
4770 spin2 = g_object_get_data (G_OBJECT (window), key: "spin2");
4771
4772 *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
4773 *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
4774}
4775
4776static void
4777unset_default_size_callback (GtkWidget *widget,
4778 gpointer data)
4779{
4780 gtk_window_set_default_size (window: g_object_get_data (object: data, key: "target"),
4781 width: -1, height: -1);
4782}
4783
4784static void
4785set_default_size_callback (GtkWidget *widget,
4786 gpointer data)
4787{
4788 int w, h;
4789
4790 get_ints (window: data, a: &w, b: &h);
4791
4792 gtk_window_set_default_size (window: g_object_get_data (object: data, key: "target"),
4793 width: w, height: h);
4794}
4795
4796static void
4797unset_size_request_callback (GtkWidget *widget,
4798 gpointer data)
4799{
4800 gtk_widget_set_size_request (widget: g_object_get_data (object: data, key: "target"),
4801 width: -1, height: -1);
4802}
4803
4804static void
4805set_size_request_callback (GtkWidget *widget,
4806 gpointer data)
4807{
4808 int w, h;
4809
4810 get_ints (window: data, a: &w, b: &h);
4811
4812 gtk_widget_set_size_request (widget: g_object_get_data (object: data, key: "target"),
4813 width: w, height: h);
4814}
4815
4816static void
4817resizable_callback (GtkWidget *widget,
4818 gpointer data)
4819{
4820 g_object_set (object: g_object_get_data (object: data, key: "target"),
4821 first_property_name: "resizable", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)),
4822 NULL);
4823}
4824
4825static GtkWidget*
4826window_controls (GtkWidget *window)
4827{
4828 GtkWidget *control_window;
4829 GtkWidget *label;
4830 GtkWidget *vbox;
4831 GtkWidget *button;
4832 GtkWidget *spin;
4833 GtkAdjustment *adjustment;
4834
4835 control_window = gtk_window_new ();
4836
4837 gtk_window_set_display (GTK_WINDOW (control_window),
4838 display: gtk_widget_get_display (widget: window));
4839
4840 gtk_window_set_title (GTK_WINDOW (control_window), title: "Size controls");
4841
4842 g_object_set_data (G_OBJECT (control_window),
4843 key: "target",
4844 data: window);
4845
4846 g_signal_connect_object (instance: control_window,
4847 detailed_signal: "destroy",
4848 G_CALLBACK (gtk_window_destroy),
4849 gobject: window,
4850 connect_flags: G_CONNECT_SWAPPED);
4851
4852 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
4853
4854 gtk_window_set_child (GTK_WINDOW (control_window), child: vbox);
4855
4856 label = gtk_label_new (str: "<no size>");
4857 gtk_box_append (GTK_BOX (vbox), child: label);
4858
4859 adjustment = gtk_adjustment_new (value: 10.0, lower: -2000.0, upper: 2000.0, step_increment: 1.0, page_increment: 5.0, page_size: 0.0);
4860 spin = gtk_spin_button_new (adjustment, climb_rate: 0, digits: 0);
4861
4862 gtk_box_append (GTK_BOX (vbox), child: spin);
4863
4864 g_object_set_data (G_OBJECT (control_window), key: "spin1", data: spin);
4865
4866 adjustment = gtk_adjustment_new (value: 10.0, lower: -2000.0, upper: 2000.0, step_increment: 1.0, page_increment: 5.0, page_size: 0.0);
4867 spin = gtk_spin_button_new (adjustment, climb_rate: 0, digits: 0);
4868
4869 gtk_box_append (GTK_BOX (vbox), child: spin);
4870
4871 g_object_set_data (G_OBJECT (control_window), key: "spin2", data: spin);
4872
4873 button = gtk_button_new_with_label (label: "Queue resize");
4874 g_signal_connect_object (instance: button,
4875 detailed_signal: "clicked",
4876 G_CALLBACK (gtk_widget_queue_resize),
4877 gobject: window,
4878 connect_flags: G_CONNECT_SWAPPED);
4879 gtk_box_append (GTK_BOX (vbox), child: button);
4880
4881 button = gtk_button_new_with_label (label: "Set default size");
4882 g_signal_connect (button,
4883 "clicked",
4884 G_CALLBACK (set_default_size_callback),
4885 control_window);
4886 gtk_box_append (GTK_BOX (vbox), child: button);
4887
4888 button = gtk_button_new_with_label (label: "Unset default size");
4889 g_signal_connect (button,
4890 "clicked",
4891 G_CALLBACK (unset_default_size_callback),
4892 control_window);
4893 gtk_box_append (GTK_BOX (vbox), child: button);
4894
4895 button = gtk_button_new_with_label (label: "Set size request");
4896 g_signal_connect (button,
4897 "clicked",
4898 G_CALLBACK (set_size_request_callback),
4899 control_window);
4900 gtk_box_append (GTK_BOX (vbox), child: button);
4901
4902 button = gtk_button_new_with_label (label: "Unset size request");
4903 g_signal_connect (button,
4904 "clicked",
4905 G_CALLBACK (unset_size_request_callback),
4906 control_window);
4907 gtk_box_append (GTK_BOX (vbox), child: button);
4908
4909 button = gtk_check_button_new_with_label (label: "Allow resize");
4910 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4911 g_signal_connect (button,
4912 "toggled",
4913 G_CALLBACK (resizable_callback),
4914 control_window);
4915 gtk_box_append (GTK_BOX (vbox), child: button);
4916
4917 button = gtk_button_new_with_mnemonic (label: "_Show");
4918 g_signal_connect_object (instance: button,
4919 detailed_signal: "clicked",
4920 G_CALLBACK (gtk_widget_show),
4921 gobject: window,
4922 connect_flags: G_CONNECT_SWAPPED);
4923 gtk_box_append (GTK_BOX (vbox), child: button);
4924
4925 button = gtk_button_new_with_mnemonic (label: "_Hide");
4926 g_signal_connect_object (instance: button,
4927 detailed_signal: "clicked",
4928 G_CALLBACK (gtk_widget_hide),
4929 gobject: window,
4930 connect_flags: G_CONNECT_SWAPPED);
4931 gtk_box_append (GTK_BOX (vbox), child: button);
4932
4933 return control_window;
4934}
4935
4936static void
4937create_window_sizing (GtkWidget *widget)
4938{
4939 static GtkWidget *window = NULL;
4940 static GtkWidget *target_window = NULL;
4941
4942 if (!target_window)
4943 {
4944 GtkWidget *label;
4945
4946 target_window = gtk_window_new ();
4947 gtk_window_set_display (GTK_WINDOW (target_window),
4948 display: gtk_widget_get_display (widget));
4949 label = gtk_label_new (NULL);
4950 gtk_label_set_markup (GTK_LABEL (label), str: "<span foreground=\"purple\"><big>Window being resized</big></span>\nBlah blah blah blah\nblah blah blah\nblah blah blah blah blah");
4951 gtk_window_set_child (GTK_WINDOW (target_window), child: label);
4952 gtk_widget_show (widget: target_window);
4953
4954 g_object_add_weak_pointer (G_OBJECT (target_window), weak_pointer_location: (gpointer *)&target_window);
4955
4956 window = window_controls (window: target_window);
4957 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
4958
4959 gtk_window_set_title (GTK_WINDOW (target_window), title: "Window to size");
4960 }
4961
4962 /* don't show target window by default, we want to allow testing
4963 * of behavior on first show.
4964 */
4965
4966 if (!gtk_widget_get_visible (widget: window))
4967 gtk_widget_show (widget: window);
4968 else
4969 gtk_window_destroy (GTK_WINDOW (window));
4970}
4971
4972/*
4973 * GtkProgressBar
4974 */
4975
4976typedef struct _ProgressData {
4977 GtkWidget *window;
4978 GtkWidget *pbar;
4979 GtkWidget *block_spin;
4980 GtkWidget *x_align_spin;
4981 GtkWidget *y_align_spin;
4982 GtkWidget *step_spin;
4983 GtkWidget *act_blocks_spin;
4984 GtkWidget *label;
4985 GtkWidget *omenu1;
4986 GtkWidget *elmenu;
4987 GtkWidget *omenu2;
4988 GtkWidget *entry;
4989 int timer;
4990 gboolean activity;
4991} ProgressData;
4992
4993static gboolean
4994progress_timeout (gpointer data)
4995{
4996 ProgressData *pdata = data;
4997 double new_val;
4998 char *text;
4999
5000 if (pdata->activity)
5001 {
5002 gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
5003
5004 text = g_strdup_printf (format: "%s", "???");
5005 }
5006 else
5007 {
5008 new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
5009 if (new_val > 1.00)
5010 new_val = 0.00;
5011 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), fraction: new_val);
5012
5013 text = g_strdup_printf (format: "%.0f%%", 100 * new_val);
5014 }
5015
5016 gtk_label_set_text (GTK_LABEL (pdata->label), str: text);
5017 g_free (mem: text);
5018
5019 return TRUE;
5020}
5021
5022static void
5023destroy_progress (GtkWidget *widget,
5024 ProgressData **pdata)
5025{
5026 if ((*pdata)->timer)
5027 {
5028 g_source_remove (tag: (*pdata)->timer);
5029 (*pdata)->timer = 0;
5030 }
5031 (*pdata)->window = NULL;
5032 g_free (mem: *pdata);
5033 *pdata = NULL;
5034}
5035
5036static void
5037progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
5038{
5039 ProgressData *pdata;
5040 int i;
5041
5042 pdata = (ProgressData *) data;
5043
5044 if (!gtk_widget_get_mapped (widget))
5045 return;
5046
5047 i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
5048
5049 if (i == 0 || i == 1)
5050 gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), orientation: GTK_ORIENTATION_HORIZONTAL);
5051 else
5052 gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), orientation: GTK_ORIENTATION_VERTICAL);
5053
5054 if (i == 1 || i == 2)
5055 gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), TRUE);
5056 else
5057 gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), FALSE);
5058}
5059
5060static void
5061toggle_show_text (GtkWidget *widget, ProgressData *pdata)
5062{
5063 gboolean active;
5064
5065 active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
5066 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (pdata->pbar), show_text: active);
5067}
5068
5069static void
5070progressbar_toggle_ellipsize (GtkWidget *widget,
5071 gpointer data)
5072{
5073 ProgressData *pdata = data;
5074 if (gtk_widget_is_drawable (widget))
5075 {
5076 int i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
5077 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar), mode: i);
5078 }
5079}
5080
5081static void
5082toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
5083{
5084 pdata->activity = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
5085}
5086
5087static void
5088toggle_running (GtkWidget *widget, ProgressData *pdata)
5089{
5090 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
5091 {
5092 if (pdata->timer == 0)
5093 pdata->timer = g_timeout_add (interval: 100, function: (GSourceFunc)progress_timeout, data: pdata);
5094 }
5095 else
5096 {
5097 if (pdata->timer != 0)
5098 {
5099 g_source_remove (tag: pdata->timer);
5100 pdata->timer = 0;
5101 }
5102 }
5103}
5104
5105static void
5106entry_changed (GtkWidget *widget, ProgressData *pdata)
5107{
5108 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar),
5109 text: gtk_editable_get_text (GTK_EDITABLE (pdata->entry)));
5110}
5111
5112static void
5113create_progress_bar (GtkWidget *widget)
5114{
5115 GtkWidget *content_area;
5116 GtkWidget *vbox;
5117 GtkWidget *vbox2;
5118 GtkWidget *hbox;
5119 GtkWidget *check;
5120 GtkWidget *frame;
5121 GtkWidget *grid;
5122 GtkWidget *label;
5123 static ProgressData *pdata = NULL;
5124
5125 static const char *items1[] =
5126 {
5127 "Left-Right",
5128 "Right-Left",
5129 "Bottom-Top",
5130 "Top-Bottom"
5131 };
5132
5133 static const char *ellipsize_items[] = {
5134 "None", // PANGO_ELLIPSIZE_NONE,
5135 "Start", // PANGO_ELLIPSIZE_START,
5136 "Middle", // PANGO_ELLIPSIZE_MIDDLE,
5137 "End", // PANGO_ELLIPSIZE_END
5138 };
5139
5140 if (!pdata)
5141 pdata = g_new0 (ProgressData, 1);
5142
5143 if (!pdata->window)
5144 {
5145 pdata->window = gtk_dialog_new ();
5146
5147 gtk_window_set_display (GTK_WINDOW (pdata->window),
5148 display: gtk_widget_get_display (widget));
5149
5150 gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
5151
5152 g_signal_connect (pdata->window, "destroy",
5153 G_CALLBACK (destroy_progress),
5154 &pdata);
5155 pdata->timer = 0;
5156
5157 content_area = gtk_dialog_get_content_area (GTK_DIALOG (pdata->window));
5158
5159 gtk_window_set_title (GTK_WINDOW (pdata->window), title: "GtkProgressBar");
5160
5161 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
5162 gtk_box_append (GTK_BOX (content_area), child: vbox);
5163
5164 frame = gtk_frame_new (label: "Progress");
5165 gtk_box_append (GTK_BOX (vbox), child: frame);
5166
5167 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
5168 gtk_frame_set_child (GTK_FRAME (frame), child: vbox2);
5169
5170 pdata->pbar = gtk_progress_bar_new ();
5171 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar),
5172 mode: PANGO_ELLIPSIZE_MIDDLE);
5173 gtk_widget_set_halign (widget: pdata->pbar, align: GTK_ALIGN_CENTER);
5174 gtk_widget_set_valign (widget: pdata->pbar, align: GTK_ALIGN_CENTER);
5175 gtk_box_append (GTK_BOX (vbox2), child: pdata->pbar);
5176
5177 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 5);
5178 gtk_widget_set_halign (widget: hbox, align: GTK_ALIGN_CENTER);
5179 gtk_widget_set_valign (widget: hbox, align: GTK_ALIGN_CENTER);
5180 gtk_box_append (GTK_BOX (vbox2), child: hbox);
5181 label = gtk_label_new (str: "Label updated by user :");
5182 gtk_box_append (GTK_BOX (hbox), child: label);
5183 pdata->label = gtk_label_new (str: "");
5184 gtk_box_append (GTK_BOX (hbox), child: pdata->label);
5185
5186 frame = gtk_frame_new (label: "Options");
5187 gtk_box_append (GTK_BOX (vbox), child: frame);
5188
5189 vbox2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
5190 gtk_frame_set_child (GTK_FRAME (frame), child: vbox2);
5191
5192 grid = gtk_grid_new ();
5193 gtk_grid_set_row_spacing (GTK_GRID (grid), spacing: 10);
5194 gtk_grid_set_column_spacing (GTK_GRID (grid), spacing: 10);
5195 gtk_box_append (GTK_BOX (vbox2), child: grid);
5196
5197 label = gtk_label_new (str: "Orientation :");
5198 gtk_grid_attach (GTK_GRID (grid), child: label, column: 0, row: 0, width: 1, height: 1);
5199 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
5200 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
5201
5202 pdata->omenu1 = build_option_menu (items: items1, num_items: 4, history: 0,
5203 func: progressbar_toggle_orientation,
5204 data: pdata);
5205 gtk_grid_attach (GTK_GRID (grid), child: pdata->omenu1, column: 1, row: 0, width: 1, height: 1);
5206
5207 check = gtk_check_button_new_with_label (label: "Running");
5208 g_signal_connect (check, "toggled",
5209 G_CALLBACK (toggle_running),
5210 pdata);
5211 gtk_grid_attach (GTK_GRID (grid), child: check, column: 0, row: 1, width: 2, height: 1);
5212 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
5213
5214 check = gtk_check_button_new_with_label (label: "Show text");
5215 g_signal_connect (check, "clicked",
5216 G_CALLBACK (toggle_show_text),
5217 pdata);
5218 gtk_grid_attach (GTK_GRID (grid), child: check, column: 0, row: 2, width: 1, height: 1);
5219
5220 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 0);
5221 gtk_grid_attach (GTK_GRID (grid), child: hbox, column: 1, row: 2, width: 1, height: 1);
5222
5223 label = gtk_label_new (str: "Text: ");
5224 gtk_box_append (GTK_BOX (hbox), child: label);
5225
5226 pdata->entry = gtk_entry_new ();
5227 gtk_widget_set_hexpand (widget: pdata->entry, TRUE);
5228 g_signal_connect (pdata->entry, "changed",
5229 G_CALLBACK (entry_changed),
5230 pdata);
5231 gtk_box_append (GTK_BOX (hbox), child: pdata->entry);
5232 gtk_widget_set_size_request (widget: pdata->entry, width: 100, height: -1);
5233
5234 label = gtk_label_new (str: "Ellipsize text :");
5235 gtk_grid_attach (GTK_GRID (grid), child: label, column: 0, row: 10, width: 1, height: 1);
5236
5237 gtk_widget_set_halign (widget: label, align: GTK_ALIGN_START);
5238 gtk_widget_set_valign (widget: label, align: GTK_ALIGN_CENTER);
5239 pdata->elmenu = build_option_menu (items: ellipsize_items,
5240 num_items: sizeof (ellipsize_items) / sizeof (ellipsize_items[0]),
5241 history: 2, // PANGO_ELLIPSIZE_MIDDLE
5242 func: progressbar_toggle_ellipsize,
5243 data: pdata);
5244 gtk_grid_attach (GTK_GRID (grid), child: pdata->elmenu, column: 1, row: 10, width: 1, height: 1);
5245
5246 check = gtk_check_button_new_with_label (label: "Activity mode");
5247 g_signal_connect (check, "clicked",
5248 G_CALLBACK (toggle_activity_mode), pdata);
5249 gtk_grid_attach (GTK_GRID (grid), child: check, column: 0, row: 15, width: 1, height: 1);
5250
5251 gtk_dialog_add_button (GTK_DIALOG (pdata->window), button_text: "Close", response_id: GTK_RESPONSE_CLOSE);
5252 g_signal_connect (pdata->window, "response",
5253 G_CALLBACK (gtk_window_destroy),
5254 NULL);
5255 }
5256
5257 if (!gtk_widget_get_visible (widget: pdata->window))
5258 gtk_widget_show (widget: pdata->window);
5259 else
5260 gtk_window_destroy (GTK_WINDOW (pdata->window));
5261}
5262
5263/*
5264 * Timeout Test
5265 */
5266
5267static int timer = 0;
5268
5269static int
5270timeout_test (GtkWidget *label)
5271{
5272 static int count = 0;
5273 static char buffer[32];
5274
5275 sprintf (s: buffer, format: "count: %d", ++count);
5276 gtk_label_set_text (GTK_LABEL (label), str: buffer);
5277
5278 return TRUE;
5279}
5280
5281static void
5282start_timeout_test (GtkWidget *widget,
5283 GtkWidget *label)
5284{
5285 if (!timer)
5286 {
5287 timer = g_timeout_add (interval: 100, function: (GSourceFunc)timeout_test, data: label);
5288 }
5289}
5290
5291static void
5292stop_timeout_test (GtkWidget *widget,
5293 gpointer data)
5294{
5295 if (timer)
5296 {
5297 g_source_remove (tag: timer);
5298 timer = 0;
5299 }
5300}
5301
5302static void
5303destroy_timeout_test (GtkWidget *widget,
5304 GtkWidget **window)
5305{
5306 stop_timeout_test (NULL, NULL);
5307
5308 *window = NULL;
5309}
5310
5311static void
5312create_timeout_test (GtkWidget *widget)
5313{
5314 static GtkWidget *window = NULL;
5315 GtkWidget *action_area, *content_area;
5316 GtkWidget *button;
5317 GtkWidget *label;
5318
5319 if (!window)
5320 {
5321 window = gtk_dialog_new ();
5322
5323 gtk_window_set_display (GTK_WINDOW (window),
5324 display: gtk_widget_get_display (widget));
5325
5326 g_signal_connect (window, "destroy",
5327 G_CALLBACK (destroy_timeout_test),
5328 &window);
5329
5330 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5331 action_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5332
5333 gtk_window_set_title (GTK_WINDOW (window), title: "Timeout Test");
5334
5335 label = gtk_label_new (str: "count: 0");
5336 gtk_widget_set_margin_start (widget: label, margin: 10);
5337 gtk_widget_set_margin_end (widget: label, margin: 10);
5338 gtk_widget_set_margin_top (widget: label, margin: 10);
5339 gtk_widget_set_margin_bottom (widget: label, margin: 10);
5340 gtk_box_append (GTK_BOX (content_area), child: label);
5341
5342 button = gtk_button_new_with_label (label: "close");
5343 g_signal_connect_swapped (button, "clicked",
5344 G_CALLBACK (gtk_window_destroy),
5345 window);
5346 gtk_box_append (GTK_BOX (action_area), child: button);
5347 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
5348
5349 button = gtk_button_new_with_label (label: "start");
5350 g_signal_connect (button, "clicked",
5351 G_CALLBACK(start_timeout_test),
5352 label);
5353 gtk_box_append (GTK_BOX (action_area), child: button);
5354
5355 button = gtk_button_new_with_label (label: "stop");
5356 g_signal_connect (button, "clicked",
5357 G_CALLBACK (stop_timeout_test),
5358 NULL);
5359 gtk_box_append (GTK_BOX (action_area), child: button);
5360 }
5361
5362 if (!gtk_widget_get_visible (widget: window))
5363 gtk_widget_show (widget: window);
5364 else
5365 gtk_window_destroy (GTK_WINDOW (window));
5366}
5367
5368static void
5369show_native (GtkWidget *button,
5370 GtkFileChooserNative *native)
5371{
5372 gtk_native_dialog_show (self: GTK_NATIVE_DIALOG (ptr: native));
5373}
5374
5375static void
5376hide_native (GtkWidget *button,
5377 GtkFileChooserNative *native)
5378{
5379 gtk_native_dialog_hide (self: GTK_NATIVE_DIALOG (ptr: native));
5380}
5381
5382static void
5383native_response (GtkNativeDialog *self,
5384 int response_id,
5385 GtkWidget *label)
5386{
5387 static int count = 0;
5388 char *res;
5389 GString *s;
5390 char *response;
5391 GtkFileFilter *filter;
5392 GListModel *files;
5393 guint i, n;
5394
5395 files = gtk_file_chooser_get_files (GTK_FILE_CHOOSER (self));
5396 filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
5397 s = g_string_new (init: "");
5398 n = g_list_model_get_n_items (list: files);
5399 for (i = 0; i < n; i++)
5400 {
5401 GFile *file = g_list_model_get_item (list: files, position: i);
5402 char *uri = g_file_get_uri (file);
5403 g_string_prepend (string: s, val: uri);
5404 g_string_prepend (string: s, val: "\n");
5405 g_free (mem: uri);
5406 g_object_unref (object: file);
5407 }
5408 g_object_unref (object: files);
5409
5410 switch (response_id)
5411 {
5412 case GTK_RESPONSE_NONE:
5413 response = g_strdup (str: "GTK_RESPONSE_NONE");
5414 break;
5415 case GTK_RESPONSE_ACCEPT:
5416 response = g_strdup (str: "GTK_RESPONSE_ACCEPT");
5417 break;
5418 case GTK_RESPONSE_CANCEL:
5419 response = g_strdup (str: "GTK_RESPONSE_CANCEL");
5420 break;
5421 case GTK_RESPONSE_DELETE_EVENT:
5422 response = g_strdup (str: "GTK_RESPONSE_DELETE_EVENT");
5423 break;
5424 default:
5425 response = g_strdup_printf (format: "%d", response_id);
5426 break;
5427 }
5428
5429 if (filter)
5430 res = g_strdup_printf (format: "Response #%d: %s\n"
5431 "Filter: %s\n"
5432 "Files:\n"
5433 "%s",
5434 ++count,
5435 response,
5436 gtk_file_filter_get_name (filter),
5437 s->str);
5438 else
5439 res = g_strdup_printf (format: "Response #%d: %s\n"
5440 "NO Filter\n"
5441 "Files:\n"
5442 "%s",
5443 ++count,
5444 response,
5445 s->str);
5446 gtk_label_set_text (GTK_LABEL (label), str: res);
5447 g_free (mem: response);
5448 g_string_free (string: s, TRUE);
5449}
5450
5451static void
5452native_modal_toggle (GtkWidget *checkbutton,
5453 GtkFileChooserNative *native)
5454{
5455 gtk_native_dialog_set_modal (self: GTK_NATIVE_DIALOG (ptr: native),
5456 modal: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
5457}
5458
5459static void
5460native_multi_select_toggle (GtkWidget *checkbutton,
5461 GtkFileChooserNative *native)
5462{
5463 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (native),
5464 select_multiple: gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
5465}
5466
5467static void
5468native_visible_notify_show (GObject *object,
5469 GParamSpec *pspec,
5470 GtkWidget *show_button)
5471{
5472 GtkFileChooserNative *native = GTK_FILE_CHOOSER_NATIVE (ptr: object);
5473 gboolean visible;
5474
5475 visible = gtk_native_dialog_get_visible (self: GTK_NATIVE_DIALOG (ptr: native));
5476 gtk_widget_set_sensitive (widget: show_button, sensitive: !visible);
5477}
5478
5479static void
5480native_visible_notify_hide (GObject *object,
5481 GParamSpec *pspec,
5482 GtkWidget *hide_button)
5483{
5484 GtkFileChooserNative *native = GTK_FILE_CHOOSER_NATIVE (ptr: object);
5485 gboolean visible;
5486
5487 visible = gtk_native_dialog_get_visible (self: GTK_NATIVE_DIALOG (ptr: native));
5488 gtk_widget_set_sensitive (widget: hide_button, sensitive: visible);
5489}
5490
5491static GFile *
5492get_some_file (void)
5493{
5494 GFile *dir = g_file_new_for_path (path: g_get_current_dir ());
5495 GFileEnumerator *e;
5496 GFile *res = NULL;
5497
5498 e = g_file_enumerate_children (file: dir, attributes: "*", flags: 0, NULL, NULL);
5499 if (e)
5500 {
5501 GFileInfo *info;
5502
5503 while (res == NULL)
5504 {
5505 info = g_file_enumerator_next_file (enumerator: e, NULL, NULL);
5506 if (info)
5507 {
5508 if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR)
5509 {
5510 GFile *child = g_file_enumerator_get_child (enumerator: e, info);
5511 res = g_steal_pointer (&child);
5512 }
5513 g_object_unref (object: info);
5514 }
5515 else
5516 break;
5517 }
5518 }
5519
5520 return res;
5521}
5522
5523static void
5524native_action_changed (GtkWidget *combo,
5525 GtkFileChooserNative *native)
5526{
5527 int i;
5528 gboolean save_as = FALSE;
5529 i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
5530
5531 if (i == 4) /* Save as */
5532 {
5533 save_as = TRUE;
5534 i = GTK_FILE_CHOOSER_ACTION_SAVE;
5535 }
5536
5537 gtk_file_chooser_set_action (GTK_FILE_CHOOSER (native),
5538 action: (GtkFileChooserAction) i);
5539
5540
5541 if (i == GTK_FILE_CHOOSER_ACTION_SAVE)
5542 {
5543 if (save_as)
5544 {
5545 GFile *file = get_some_file ();
5546 gtk_file_chooser_set_file (GTK_FILE_CHOOSER (native), file, NULL);
5547 }
5548 else
5549 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (native), name: "newname.txt");
5550 }
5551}
5552
5553static void
5554native_filter_changed (GtkWidget *combo,
5555 GtkFileChooserNative *native)
5556{
5557 int i;
5558 GListModel *filters;
5559 GtkFileFilter *filter;
5560
5561 i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
5562
5563 filters = gtk_file_chooser_get_filters (GTK_FILE_CHOOSER (native));
5564 while (g_list_model_get_n_items (list: filters) > 0)
5565 {
5566 GtkFileFilter *f = g_list_model_get_item (list: filters, position: 0);
5567 gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), filter: f);
5568 g_object_unref (object: f);
5569 }
5570 g_object_unref (object: filters);
5571
5572 switch (i)
5573 {
5574 case 0:
5575 break;
5576 case 1: /* pattern */
5577 filter = gtk_file_filter_new ();
5578 gtk_file_filter_set_name (filter, name: "Text");
5579 gtk_file_filter_add_suffix (filter, suffix: "doc");
5580 gtk_file_filter_add_suffix (filter, suffix: "txt");
5581 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
5582 g_object_unref (object: filter);
5583
5584 filter = gtk_file_filter_new ();
5585 gtk_file_filter_set_name (filter, name: "Images");
5586 gtk_file_filter_add_pixbuf_formats (filter);
5587 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
5588 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (native), filter);
5589 g_object_unref (object: filter);
5590
5591 filter = gtk_file_filter_new ();
5592 gtk_file_filter_set_name (filter, name: "All");
5593 gtk_file_filter_add_pattern (filter, pattern: "*");
5594 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
5595 g_object_unref (object: filter);
5596 break;
5597
5598 case 2: /* mimetype */
5599 filter = gtk_file_filter_new ();
5600 gtk_file_filter_set_name (filter, name: "Text");
5601 gtk_file_filter_add_mime_type (filter, mime_type: "text/plain");
5602 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
5603 g_object_unref (object: filter);
5604
5605 filter = gtk_file_filter_new ();
5606 gtk_file_filter_set_name (filter, name: "All");
5607 gtk_file_filter_add_pattern (filter, pattern: "*");
5608 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
5609 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (native), filter);
5610 g_object_unref (object: filter);
5611 break;
5612 default:
5613 g_assert_not_reached ();
5614 }
5615}
5616
5617static void
5618destroy_native (GtkFileChooserNative *native)
5619{
5620 gtk_native_dialog_destroy (self: GTK_NATIVE_DIALOG (ptr: native));
5621 g_object_unref (object: native);
5622}
5623
5624static void
5625create_native_dialogs (GtkWidget *widget)
5626{
5627 static GtkWidget *window = NULL;
5628 GtkWidget *box, *label;
5629 GtkWidget *show_button, *hide_button, *check_button;
5630 GtkFileChooserNative *native;
5631 GtkWidget *combo;
5632
5633 if (!window)
5634 {
5635 GFile *path;
5636
5637 window = gtk_window_new ();
5638 gtk_window_set_display (GTK_WINDOW (window),
5639 display: gtk_widget_get_display (widget));
5640
5641 native = gtk_file_chooser_native_new (title: "Native title",
5642 GTK_WINDOW (window),
5643 action: GTK_FILE_CHOOSER_ACTION_OPEN,
5644 accept_label: "_accept&native",
5645 cancel_label: "_cancel__native");
5646
5647 g_signal_connect_swapped (G_OBJECT (window), "destroy", G_CALLBACK (destroy_native), native);
5648
5649 path = g_file_new_for_path (path: g_get_current_dir ());
5650 gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (native), folder: path, NULL);
5651 g_object_unref (object: path);
5652
5653 gtk_window_set_title (GTK_WINDOW(window), title: "Native dialog parent");
5654
5655 box = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 5);
5656 gtk_window_set_child (GTK_WINDOW (window), child: box);
5657
5658 label = gtk_label_new (str: "");
5659 gtk_box_append (GTK_BOX (box), child: label);
5660
5661 combo = gtk_combo_box_text_new ();
5662
5663 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "Open");
5664 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "Save");
5665 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "Select Folder");
5666 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "Create Folder");
5667 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "Save as");
5668
5669 g_signal_connect (combo, "changed",
5670 G_CALLBACK (native_action_changed), native);
5671 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), index_: GTK_FILE_CHOOSER_ACTION_OPEN);
5672 gtk_box_append (GTK_BOX (box), child: combo);
5673
5674 combo = gtk_combo_box_text_new ();
5675
5676 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "No filters");
5677 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "Pattern filter");
5678 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), text: "Mimetype filter");
5679
5680 g_signal_connect (combo, "changed",
5681 G_CALLBACK (native_filter_changed), native);
5682 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), index_: 0);
5683 gtk_box_append (GTK_BOX (box), child: combo);
5684
5685 check_button = gtk_check_button_new_with_label (label: "Modal");
5686 g_signal_connect (check_button, "toggled",
5687 G_CALLBACK (native_modal_toggle), native);
5688 gtk_box_append (GTK_BOX (box), child: check_button);
5689
5690 check_button = gtk_check_button_new_with_label (label: "Multiple select");
5691 g_signal_connect (check_button, "toggled",
5692 G_CALLBACK (native_multi_select_toggle), native);
5693 gtk_box_append (GTK_BOX (box), child: check_button);
5694
5695 show_button = gtk_button_new_with_label (label: "Show");
5696 hide_button = gtk_button_new_with_label (label: "Hide");
5697 gtk_widget_set_sensitive (widget: hide_button, FALSE);
5698
5699 gtk_box_append (GTK_BOX (box), child: show_button);
5700 gtk_box_append (GTK_BOX (box), child: hide_button);
5701
5702 /* connect signals */
5703 g_signal_connect (native, "response",
5704 G_CALLBACK (native_response), label);
5705 g_signal_connect (show_button, "clicked",
5706 G_CALLBACK (show_native), native);
5707 g_signal_connect (hide_button, "clicked",
5708 G_CALLBACK (hide_native), native);
5709
5710 g_signal_connect (native, "notify::visible",
5711 G_CALLBACK (native_visible_notify_show), show_button);
5712 g_signal_connect (native, "notify::visible",
5713 G_CALLBACK (native_visible_notify_hide), hide_button);
5714
5715 g_object_add_weak_pointer (G_OBJECT (window), weak_pointer_location: (gpointer *)&window);
5716 }
5717
5718 if (!gtk_widget_get_visible (widget: window))
5719 gtk_widget_show (widget: window);
5720 else
5721 gtk_window_destroy (GTK_WINDOW (window));
5722}
5723
5724/*
5725 * Main Window and Exit
5726 */
5727
5728static void
5729do_exit (GtkWidget *widget, GtkWidget *window)
5730{
5731 gtk_window_destroy (GTK_WINDOW (window));
5732 done = TRUE;
5733 g_main_context_wakeup (NULL);
5734}
5735
5736struct {
5737 const char *label;
5738 void (*func) (GtkWidget *widget);
5739 gboolean do_not_benchmark;
5740} buttons[] =
5741{
5742 { "alpha window", create_alpha_window },
5743 { "buttons", create_buttons },
5744 { "check buttons", create_check_buttons },
5745 { "color selection", create_color_selection },
5746 { "cursors", create_cursors },
5747 { "dialog", create_dialog },
5748 { "display", create_display_screen, TRUE },
5749 { "entry", create_entry },
5750 { "expander", create_expander },
5751 { "flipping", create_flipping },
5752 { "font selection", create_font_selection },
5753 { "image", create_image },
5754 { "labels", create_labels },
5755 { "listbox", create_listbox },
5756 { "message dialog", create_message_dialog },
5757 { "modal window", create_modal_window, TRUE },
5758 { "native dialogs", create_native_dialogs },
5759 { "notebook", create_notebook },
5760 { "panes", create_panes },
5761 { "paned keyboard", create_paned_keyboard_navigation },
5762 { "pixbuf", create_pixbuf },
5763 { "progress bar", create_progress_bar },
5764 { "radio buttons", create_radio_buttons },
5765 { "range controls", create_range_controls },
5766 { "rotated text", create_rotated_text },
5767 { "scrolled windows", create_scrolled_windows },
5768 { "size groups", create_size_groups },
5769 { "spinbutton", create_spins },
5770 { "statusbar", create_statusbar },
5771 { "surface states", create_surface_states },
5772 { "test timeout", create_timeout_test },
5773 { "toggle buttons", create_toggle_buttons },
5774 { "tooltips", create_tooltips },
5775 { "WM hints", create_wmhints },
5776 { "window sizing", create_window_sizing }
5777};
5778int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
5779
5780static void
5781quit_cb (GtkWidget *widget,
5782 gpointer user_data)
5783{
5784 gboolean *is_done = user_data;
5785
5786 *is_done = TRUE;
5787
5788 g_main_context_wakeup (NULL);
5789}
5790
5791static void
5792create_main_window (void)
5793{
5794 GtkWidget *window;
5795 GtkWidget *box1;
5796 GtkWidget *box2;
5797 GtkWidget *scrolled_window;
5798 GtkWidget *button;
5799 GtkWidget *label;
5800 char buffer[64];
5801 GtkWidget *separator;
5802 int i;
5803
5804 window = gtk_window_new ();
5805 gtk_widget_set_name (widget: window, name: "main_window");
5806 gtk_window_set_default_size (GTK_WINDOW (window), width: -1, height: 400);
5807
5808 g_signal_connect (window, "destroy", G_CALLBACK (quit_cb), &done);
5809
5810 box1 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
5811 gtk_window_set_child (GTK_WINDOW (window), child: box1);
5812
5813 if (gtk_get_micro_version () > 0)
5814 sprintf (s: buffer,
5815 format: "Gtk+ v%d.%d.%d",
5816 gtk_get_major_version (),
5817 gtk_get_minor_version (),
5818 gtk_get_micro_version ());
5819 else
5820 sprintf (s: buffer,
5821 format: "Gtk+ v%d.%d",
5822 gtk_get_major_version (),
5823 gtk_get_minor_version ());
5824
5825 label = gtk_label_new (str: buffer);
5826 gtk_box_append (GTK_BOX (box1), child: label);
5827 gtk_widget_set_name (widget: label, name: "testgtk-version-label");
5828
5829 scrolled_window = gtk_scrolled_window_new ();
5830 gtk_widget_set_margin_top (widget: scrolled_window, margin: 10);
5831 gtk_widget_set_margin_bottom (widget: scrolled_window, margin: 10);
5832 gtk_widget_set_margin_start (widget: scrolled_window, margin: 10);
5833 gtk_widget_set_margin_end (widget: scrolled_window, margin: 10);
5834 gtk_widget_set_vexpand (widget: scrolled_window, TRUE);
5835 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
5836 hscrollbar_policy: GTK_POLICY_NEVER,
5837 vscrollbar_policy: GTK_POLICY_AUTOMATIC);
5838 gtk_box_append (GTK_BOX (box1), child: scrolled_window);
5839
5840 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 0);
5841 gtk_widget_set_margin_top (widget: box2, margin: 10);
5842 gtk_widget_set_margin_bottom (widget: box2, margin: 10);
5843 gtk_widget_set_margin_start (widget: box2, margin: 10);
5844 gtk_widget_set_margin_end (widget: box2, margin: 10);
5845 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (scrolled_window), child: box2);
5846 gtk_viewport_set_scroll_to_focus (GTK_VIEWPORT (gtk_widget_get_parent (box2)), TRUE);
5847
5848 for (i = 0; i < nbuttons; i++)
5849 {
5850 button = gtk_button_new_with_label (label: buttons[i].label);
5851 if (buttons[i].func)
5852 g_signal_connect (button,
5853 "clicked",
5854 G_CALLBACK(buttons[i].func),
5855 NULL);
5856 else
5857 gtk_widget_set_sensitive (widget: button, FALSE);
5858 gtk_box_append (GTK_BOX (box2), child: button);
5859 }
5860
5861 separator = gtk_separator_new (orientation: GTK_ORIENTATION_HORIZONTAL);
5862 gtk_box_append (GTK_BOX (box1), child: separator);
5863
5864 box2 = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 10);
5865 gtk_box_append (GTK_BOX (box1), child: box2);
5866
5867 button = gtk_button_new_with_mnemonic (label: "_Close");
5868 gtk_widget_set_margin_top (widget: button, margin: 10);
5869 gtk_widget_set_margin_bottom (widget: button, margin: 10);
5870 gtk_widget_set_margin_start (widget: button, margin: 10);
5871 gtk_widget_set_margin_end (widget: button, margin: 10);
5872 g_signal_connect (button, "clicked",
5873 G_CALLBACK (do_exit),
5874 window);
5875 gtk_box_append (GTK_BOX (box2), child: button);
5876 gtk_window_set_default_widget (GTK_WINDOW (window), default_widget: button);
5877
5878 gtk_widget_show (widget: window);
5879}
5880
5881static char *
5882pad (const char *str, int to)
5883{
5884 static char buf[256];
5885 int len = strlen (s: str);
5886 int i;
5887
5888 for (i = 0; i < to; i++)
5889 buf[i] = ' ';
5890
5891 buf[to] = '\0';
5892
5893 memcpy (dest: buf, src: str, n: len);
5894
5895 return buf;
5896}
5897
5898static void
5899bench_iteration (GtkWidget *widget, void (* fn) (GtkWidget *widget))
5900{
5901 fn (widget); /* on */
5902 while (g_main_context_iteration (NULL, FALSE));
5903 fn (widget); /* off */
5904 while (g_main_context_iteration (NULL, FALSE));
5905}
5906
5907static void
5908do_real_bench (GtkWidget *widget, void (* fn) (GtkWidget *widget), const char *name, int num)
5909{
5910 gint64 t0, t1;
5911 double dt_first;
5912 double dt;
5913 int n;
5914 static gboolean printed_headers = FALSE;
5915
5916 if (!printed_headers) {
5917 g_print (format: "Test Iters First Other\n");
5918 g_print (format: "-------------------- ----- ---------- ----------\n");
5919 printed_headers = TRUE;
5920 }
5921
5922 t0 = g_get_monotonic_time ();
5923 bench_iteration (widget, fn);
5924 t1 = g_get_monotonic_time ();
5925
5926 dt_first = ((double)(t1 - t0)) / 1000.0;
5927
5928 t0 = g_get_monotonic_time ();
5929 for (n = 0; n < num - 1; n++)
5930 bench_iteration (widget, fn);
5931 t1 = g_get_monotonic_time ();
5932 dt = ((double)(t1 - t0)) / 1000.0;
5933
5934 g_print (format: "%s %5d ", pad (str: name, to: 20), num);
5935 if (num > 1)
5936 g_print (format: "%10.1f %10.1f\n", dt_first, dt/(num-1));
5937 else
5938 g_print (format: "%10.1f\n", dt_first);
5939}
5940
5941static void
5942do_bench (char* what, int num)
5943{
5944 int i;
5945 GtkWidget *widget;
5946 void (* fn) (GtkWidget *widget);
5947 fn = NULL;
5948 widget = gtk_window_new ();
5949
5950 if (g_ascii_strcasecmp (s1: what, s2: "ALL") == 0)
5951 {
5952 for (i = 0; i < nbuttons; i++)
5953 {
5954 if (!buttons[i].do_not_benchmark)
5955 do_real_bench (widget, fn: buttons[i].func, name: buttons[i].label, num);
5956 }
5957
5958 return;
5959 }
5960 else
5961 {
5962 for (i = 0; i < nbuttons; i++)
5963 {
5964 if (strcmp (s1: buttons[i].label, s2: what) == 0)
5965 {
5966 fn = buttons[i].func;
5967 break;
5968 }
5969 }
5970
5971 if (!fn)
5972 g_print (format: "Can't bench: \"%s\" not found.\n", what);
5973 else
5974 do_real_bench (widget, fn, name: buttons[i].label, num);
5975 }
5976}
5977
5978static void G_GNUC_NORETURN
5979usage (void)
5980{
5981 fprintf (stderr, format: "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
5982 exit (status: 1);
5983}
5984
5985int
5986main (int argc, char *argv[])
5987{
5988 GtkCssProvider *provider, *memory_provider;
5989 GdkDisplay *display;
5990 int i;
5991 gboolean done_benchmarks = FALSE;
5992
5993 srand (seed: time (NULL));
5994
5995 g_set_application_name (application_name: "GTK Test Program");
5996
5997#ifdef GTK_SRCDIR
5998 g_chdir (GTK_SRCDIR);
5999#endif
6000
6001 gtk_init ();
6002
6003 provider = gtk_css_provider_new ();
6004
6005 /* Check to see if we are being run from the correct
6006 * directory.
6007 */
6008 if (file_exists (filename: "testgtk.css"))
6009 gtk_css_provider_load_from_path (css_provider: provider, path: "testgtk.css");
6010 else if (file_exists (filename: "tests/testgtk.css"))
6011 gtk_css_provider_load_from_path (css_provider: provider, path: "tests/testgtk.css");
6012 else
6013 g_warning ("Couldn't find file \"testgtk.css\".");
6014
6015 display = gdk_display_get_default ();
6016
6017 gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (provider),
6018 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
6019 g_object_unref (object: provider);
6020
6021 /* benchmarking
6022 */
6023 for (i = 1; i < argc; i++)
6024 {
6025 if (strncmp (s1: argv[i], s2: "--bench", n: strlen(s: "--bench")) == 0)
6026 {
6027 int num = 1;
6028 char *nextarg;
6029 char *what;
6030 char *count;
6031
6032 nextarg = strchr (s: argv[i], c: '=');
6033 if (nextarg)
6034 nextarg++;
6035 else
6036 {
6037 i++;
6038 if (i == argc)
6039 usage ();
6040 nextarg = argv[i];
6041 }
6042
6043 count = strchr (s: nextarg, c: ':');
6044 if (count)
6045 {
6046 what = g_strndup (str: nextarg, n: count - nextarg);
6047 count++;
6048 num = atoi (nptr: count);
6049 if (num <= 0)
6050 usage ();
6051 }
6052 else
6053 what = g_strdup (str: nextarg);
6054
6055 do_bench (what, num: num ? num : 1);
6056 done_benchmarks = TRUE;
6057 }
6058 else
6059 usage ();
6060 }
6061 if (done_benchmarks)
6062 return 0;
6063
6064 memory_provider = gtk_css_provider_new ();
6065 gtk_css_provider_load_from_data (css_provider: memory_provider,
6066 data: "#testgtk-version-label {\n"
6067 " color: #f00;\n"
6068 " font-family: Sans;\n"
6069 " font-size: 18px;\n"
6070 "}",
6071 length: -1);
6072 gtk_style_context_add_provider_for_display (display, GTK_STYLE_PROVIDER (memory_provider),
6073 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
6074
6075 create_main_window ();
6076
6077 while (!done)
6078 g_main_context_iteration (NULL, TRUE);
6079
6080 if (1)
6081 {
6082 while (g_main_context_pending (NULL))
6083 g_main_context_iteration (NULL, FALSE);
6084#if 0
6085 sleep (1);
6086 while (g_main_context_pending (NULL))
6087 g_main_context_iteration (NULL, FALSE);
6088#endif
6089 }
6090 return 0;
6091}
6092

source code of gtk/tests/testgtk.c