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 "gtk/gtk.h"
41 #include "gdk/gdk.h"
42 #include "gdk/gdkkeysyms.h"
43
44 #ifdef G_OS_WIN32
45 #define sleep(n) _sleep(n)
46 #endif
47
48 #include "test.xpm"
49
50 gboolean
file_exists(const char * filename)51 file_exists (const char *filename)
52 {
53 struct stat statbuf;
54
55 return stat (filename, &statbuf) == 0;
56 }
57
58 GtkWidget *
59 shape_create_icon (GdkScreen *screen,
60 char *xpm_file,
61 gint x,
62 gint y,
63 gint px,
64 gint py,
65 gint window_type);
66
67 static GtkWidget *
68 build_option_menu (gchar *items[],
69 gint num_items,
70 gint history,
71 void (*func) (GtkWidget *widget, gpointer data),
72 gpointer data);
73
74 /* macro, structure and variables used by tree window demos */
75 #define DEFAULT_NUMBER_OF_ITEM 3
76 #define DEFAULT_RECURSION_LEVEL 3
77
78 struct {
79 GSList* selection_mode_group;
80 GtkWidget* single_button;
81 GtkWidget* browse_button;
82 GtkWidget* multiple_button;
83 GtkWidget* draw_line_button;
84 GtkWidget* view_line_button;
85 GtkWidget* no_root_item_button;
86 GtkWidget* nb_item_spinner;
87 GtkWidget* recursion_spinner;
88 } sTreeSampleSelection;
89
90 typedef struct sTreeButtons {
91 guint nb_item_add;
92 GtkWidget* add_button;
93 GtkWidget* remove_button;
94 GtkWidget* subtree_button;
95 } sTreeButtons;
96 /* end of tree section */
97
98 static GtkWidget *
build_option_menu(gchar * items[],gint num_items,gint history,void (* func)(GtkWidget * widget,gpointer data),gpointer data)99 build_option_menu (gchar *items[],
100 gint num_items,
101 gint history,
102 void (*func)(GtkWidget *widget, gpointer data),
103 gpointer data)
104 {
105 GtkWidget *omenu;
106 gint i;
107
108 omenu = gtk_combo_box_text_new ();
109 g_signal_connect (omenu, "changed",
110 G_CALLBACK (func), data);
111
112 for (i = 0; i < num_items; i++)
113 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (omenu), items[i]);
114
115 gtk_combo_box_set_active (GTK_COMBO_BOX (omenu), history);
116
117 return omenu;
118 }
119
120 /*
121 * Windows with an alpha channel
122 */
123
124
125 static gboolean
on_alpha_window_draw(GtkWidget * widget,cairo_t * cr)126 on_alpha_window_draw (GtkWidget *widget,
127 cairo_t *cr)
128 {
129 cairo_pattern_t *pattern;
130 int radius, width, height;
131
132 /* Get the child allocation to avoid painting over the borders */
133 GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
134 GtkAllocation child_allocation;
135 int border_width = gtk_container_get_border_width (GTK_CONTAINER (child));
136
137 gtk_widget_get_allocation (child, &child_allocation);
138 child_allocation.x -= border_width;
139 child_allocation.y -= border_width;
140 child_allocation.width += 2 * border_width;
141 child_allocation.height += 2 * border_width;
142
143 cairo_translate (cr, child_allocation.x, child_allocation.y);
144
145 cairo_rectangle (cr, 0, 0, child_allocation.width, child_allocation.height);
146 cairo_clip (cr);
147
148 width = gtk_widget_get_allocated_width (widget);
149 height = gtk_widget_get_allocated_height (widget);
150 radius = MIN (width, height) / 2;
151 pattern = cairo_pattern_create_radial (width / 2,
152 height / 2,
153 0.0,
154 width / 2,
155 height / 2,
156 radius * 1.33);
157
158 if (gdk_screen_get_rgba_visual (gtk_widget_get_screen (widget)) &&
159 gtk_widget_is_composited (widget))
160 cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); /* transparent */
161 else
162 cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); /* opaque white */
163
164 cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
165 cairo_paint (cr);
166
167 cairo_pattern_add_color_stop_rgba (pattern, 0.0,
168 1.0, 0.75, 0.0, 1.0); /* solid orange */
169 cairo_pattern_add_color_stop_rgba (pattern, 1.0,
170 1.0, 0.75, 0.0, 0.0); /* transparent orange */
171
172 cairo_set_source (cr, pattern);
173 cairo_pattern_destroy (pattern);
174
175 cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
176 cairo_paint (cr);
177
178 return FALSE;
179 }
180
181 static GtkWidget *
build_alpha_widgets(void)182 build_alpha_widgets (void)
183 {
184 GtkWidget *grid;
185 GtkWidget *radio_button;
186 GtkWidget *check_button;
187 GtkWidget *hbox;
188 GtkWidget *label;
189 GtkWidget *entry;
190
191 grid = gtk_grid_new ();
192
193 radio_button = gtk_radio_button_new_with_label (NULL, "Red");
194 gtk_widget_set_hexpand (radio_button, TRUE);
195 gtk_grid_attach (GTK_GRID (grid), radio_button, 0, 0, 1, 1);
196
197 radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Green");
198 gtk_widget_set_hexpand (radio_button, TRUE);
199 gtk_grid_attach (GTK_GRID (grid), radio_button, 0, 1, 1, 1);
200
201 radio_button = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_button), "Blue"),
202 gtk_widget_set_hexpand (radio_button, TRUE);
203 gtk_grid_attach (GTK_GRID (grid), radio_button, 0, 2, 1, 1);
204
205 check_button = gtk_check_button_new_with_label ("Sedentary"),
206 gtk_widget_set_hexpand (check_button, TRUE);
207 gtk_grid_attach (GTK_GRID (grid), check_button, 1, 0, 1, 1);
208
209 check_button = gtk_check_button_new_with_label ("Nocturnal"),
210 gtk_widget_set_hexpand (check_button, TRUE);
211 gtk_grid_attach (GTK_GRID (grid), check_button, 1, 1, 1, 1);
212
213 check_button = gtk_check_button_new_with_label ("Compulsive"),
214 gtk_widget_set_hexpand (check_button, TRUE);
215 gtk_grid_attach (GTK_GRID (grid), check_button, 1, 2, 1, 1);
216
217 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
218 label = gtk_label_new (NULL);
219 gtk_label_set_markup (GTK_LABEL (label), "<i>Entry: </i>");
220 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
221 entry = gtk_entry_new ();
222 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
223 gtk_widget_set_hexpand (hbox, TRUE);
224 gtk_grid_attach (GTK_GRID (grid), hbox, 0, 3, 2, 1);
225
226 return grid;
227 }
228
229 static void
on_alpha_screen_changed(GtkWindow * window,GdkScreen * old_screen,GtkWidget * label)230 on_alpha_screen_changed (GtkWindow *window,
231 GdkScreen *old_screen,
232 GtkWidget *label)
233 {
234 GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (window));
235 GdkVisual *visual = gdk_screen_get_rgba_visual (screen);
236
237 if (!visual)
238 {
239 visual = gdk_screen_get_system_visual (screen);
240 gtk_label_set_markup (GTK_LABEL (label), "<b>Screen doesn't support alpha</b>");
241 }
242 else
243 {
244 gtk_label_set_markup (GTK_LABEL (label), "<b>Screen supports alpha</b>");
245 }
246
247 gtk_widget_set_visual (GTK_WIDGET (window), visual);
248 }
249
250 static void
on_composited_changed(GtkWidget * window,GtkLabel * label)251 on_composited_changed (GtkWidget *window,
252 GtkLabel *label)
253 {
254 gboolean is_composited = gtk_widget_is_composited (window);
255
256 if (is_composited)
257 gtk_label_set_text (label, "Composited");
258 else
259 gtk_label_set_text (label, "Not composited");
260 }
261
262 void
create_alpha_window(GtkWidget * widget)263 create_alpha_window (GtkWidget *widget)
264 {
265 static GtkWidget *window;
266
267 if (!window)
268 {
269 GtkWidget *content_area;
270 GtkWidget *vbox;
271 GtkWidget *label;
272
273 window = gtk_dialog_new_with_buttons ("Alpha Window",
274 GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
275 "_Close", 0,
276 NULL);
277
278 gtk_widget_set_app_paintable (window, TRUE);
279 g_signal_connect (window, "draw",
280 G_CALLBACK (on_alpha_window_draw), NULL);
281
282 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
283
284 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 8);
285 gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
286 gtk_box_pack_start (GTK_BOX (content_area), vbox,
287 TRUE, TRUE, 0);
288
289 label = gtk_label_new (NULL);
290 gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
291 on_alpha_screen_changed (GTK_WINDOW (window), NULL, label);
292 g_signal_connect (window, "screen-changed",
293 G_CALLBACK (on_alpha_screen_changed), label);
294
295 label = gtk_label_new (NULL);
296 gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
297 on_composited_changed (window, GTK_LABEL (label));
298 g_signal_connect (window, "composited_changed", G_CALLBACK (on_composited_changed), label);
299
300 gtk_box_pack_start (GTK_BOX (vbox), build_alpha_widgets (), TRUE, TRUE, 0);
301
302 g_signal_connect (window, "destroy",
303 G_CALLBACK (gtk_widget_destroyed),
304 &window);
305
306 g_signal_connect (window, "response",
307 G_CALLBACK (gtk_widget_destroy),
308 NULL);
309 }
310
311 if (!gtk_widget_get_visible (window))
312 gtk_widget_show_all (window);
313 else
314 gtk_widget_destroy (window);
315 }
316
317 /*
318 * Composited non-toplevel window
319 */
320
321 /* The draw event handler for the event box.
322 *
323 * This function simply draws a transparency onto a widget on the area
324 * for which it receives expose events. This is intended to give the
325 * event box a "transparent" background.
326 *
327 * In order for this to work properly, the widget must have an RGBA
328 * colourmap. The widget should also be set as app-paintable since it
329 * doesn't make sense for GTK to draw a background if we are drawing it
330 * (and because GTK might actually replace our transparency with its
331 * default background colour).
332 */
333 static gboolean
transparent_draw(GtkWidget * widget,cairo_t * cr)334 transparent_draw (GtkWidget *widget,
335 cairo_t *cr)
336 {
337 cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
338 cairo_paint (cr);
339
340 return FALSE;
341 }
342
343 /* The expose event handler for the window.
344 *
345 * This function performs the actual compositing of the event box onto
346 * the already-existing background of the window at 50% normal opacity.
347 *
348 * In this case we do not want app-paintable to be set on the widget
349 * since we want it to draw its own (red) background. Because of this,
350 * however, we must ensure that we use g_signal_register_after so that
351 * this handler is called after the red has been drawn. If it was
352 * called before then GTK would just blindly paint over our work.
353 */
354 static gboolean
window_draw(GtkWidget * widget,cairo_t * cr)355 window_draw (GtkWidget *widget,
356 cairo_t *cr)
357 {
358 GtkAllocation allocation;
359 GtkWidget *child;
360
361 /* put a red background on the window */
362 cairo_set_source_rgb (cr, 1, 0, 0);
363 cairo_paint (cr);
364
365 /* get our child (in this case, the event box) */
366 child = gtk_bin_get_child (GTK_BIN (widget));
367
368 gtk_widget_get_allocation (child, &allocation);
369
370 /* the source data is the (composited) event box */
371 gdk_cairo_set_source_window (cr, gtk_widget_get_window (child),
372 allocation.x,
373 allocation.y);
374
375 /* composite, with a 50% opacity */
376 cairo_paint_with_alpha (cr, 0.5);
377
378 return FALSE;
379 }
380
381 void
create_composited_window(GtkWidget * widget)382 create_composited_window (GtkWidget *widget)
383 {
384 static GtkWidget *window;
385
386 if (!window)
387 {
388 GtkWidget *event, *button;
389
390 /* make the widgets */
391 button = gtk_button_new_with_label ("A Button");
392 event = gtk_event_box_new ();
393 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
394
395 g_signal_connect (window, "destroy",
396 G_CALLBACK (gtk_widget_destroyed),
397 &window);
398
399 /* set our event box to have a fully-transparent background
400 * drawn on it. currently there is no way to simply tell gtk
401 * that "transparency" is the background colour for a widget.
402 */
403 gtk_widget_set_app_paintable (GTK_WIDGET (event), TRUE);
404 g_signal_connect (event, "draw",
405 G_CALLBACK (transparent_draw), NULL);
406
407 /* put them inside one another */
408 gtk_container_set_border_width (GTK_CONTAINER (window), 10);
409 gtk_container_add (GTK_CONTAINER (window), event);
410 gtk_container_add (GTK_CONTAINER (event), button);
411
412 /* realise and show everything */
413 gtk_widget_realize (button);
414
415 /* set the event box GdkWindow to be composited.
416 * obviously must be performed after event box is realised.
417 */
418 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
419 gdk_window_set_composited (gtk_widget_get_window (event),
420 TRUE);
421 G_GNUC_END_IGNORE_DEPRECATIONS
422
423 /* set up the compositing handler.
424 * note that we do _after so that the normal (red) background is drawn
425 * by gtk before our compositing occurs.
426 */
427 g_signal_connect_after (window, "draw",
428 G_CALLBACK (window_draw), NULL);
429 }
430
431 if (!gtk_widget_get_visible (window))
432 gtk_widget_show_all (window);
433 else
434 gtk_widget_destroy (window);
435 }
436
437 /*
438 * Big windows and guffaw scrolling
439 */
440
441 static void
pattern_set_bg(GtkWidget * widget,GdkWindow * child,gint level)442 pattern_set_bg (GtkWidget *widget,
443 GdkWindow *child,
444 gint level)
445 {
446 static GdkRGBA colors[] = {
447 { 0.27, 0.27, 1.0, 1.0 },
448 { 0.53, 0.53, 1.0, 1.0},
449 { 0.67, 0.67, 1.0, 1.0 }
450 };
451
452 gdk_window_set_user_data (child, widget);
453 gdk_window_set_background_rgba (child, &colors[level]);
454 }
455
456 static void
create_pattern(GtkWidget * widget,GdkWindow * parent,gint level,gint width,gint height)457 create_pattern (GtkWidget *widget,
458 GdkWindow *parent,
459 gint level,
460 gint width,
461 gint height)
462 {
463 gint h = 1;
464 gint i = 0;
465
466 GdkWindow *child;
467
468 while (2 * h <= height)
469 {
470 gint w = 1;
471 gint j = 0;
472
473 while (2 * w <= width)
474 {
475 if ((i + j) % 2 == 0)
476 {
477 gint x = w - 1;
478 gint y = h - 1;
479
480 GdkWindowAttr attributes;
481
482 attributes.window_type = GDK_WINDOW_CHILD;
483 attributes.x = x;
484 attributes.y = y;
485 attributes.width = w;
486 attributes.height = h;
487 attributes.wclass = GDK_INPUT_OUTPUT;
488 attributes.event_mask = GDK_EXPOSURE_MASK;
489 attributes.visual = gtk_widget_get_visual (widget);
490
491 child = gdk_window_new (parent, &attributes,
492 GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL);
493
494 pattern_set_bg (widget, child, level);
495
496 if (level < 2)
497 create_pattern (widget, child, level + 1, w, h);
498
499 gdk_window_show (child);
500 }
501 j++;
502 w *= 2;
503 }
504 i++;
505 h *= 2;
506 }
507 }
508
509 #define PATTERN_SIZE (1 << 18)
510
511 static void
pattern_hadj_changed(GtkAdjustment * adjustment,GtkWidget * darea)512 pattern_hadj_changed (GtkAdjustment *adjustment,
513 GtkWidget *darea)
514 {
515 gint *old_value = g_object_get_data (G_OBJECT (adjustment), "old-value");
516 gint new_value = gtk_adjustment_get_value (adjustment);
517
518 if (gtk_widget_get_realized (darea))
519 {
520 gdk_window_scroll (gtk_widget_get_window (darea),
521 *old_value - new_value, 0);
522 *old_value = new_value;
523 }
524 }
525
526 static void
pattern_vadj_changed(GtkAdjustment * adjustment,GtkWidget * darea)527 pattern_vadj_changed (GtkAdjustment *adjustment,
528 GtkWidget *darea)
529 {
530 gint *old_value = g_object_get_data (G_OBJECT (adjustment), "old-value");
531 gint new_value = gtk_adjustment_get_value (adjustment);
532
533 if (gtk_widget_get_realized (darea))
534 {
535 gdk_window_scroll (gtk_widget_get_window (darea),
536 0, *old_value - new_value);
537 *old_value = new_value;
538 }
539 }
540
541 static void
pattern_realize(GtkWidget * widget,gpointer data)542 pattern_realize (GtkWidget *widget,
543 gpointer data)
544 {
545 GdkWindow *window;
546
547 window = gtk_widget_get_window (widget);
548 pattern_set_bg (widget, window, 0);
549 create_pattern (widget, window, 1, PATTERN_SIZE, PATTERN_SIZE);
550 }
551
552 static void
create_big_windows(GtkWidget * widget)553 create_big_windows (GtkWidget *widget)
554 {
555 static GtkWidget *window = NULL;
556 GtkWidget *content_area;
557 GtkWidget *darea, *grid, *scrollbar;
558 GtkWidget *eventbox;
559 GtkAdjustment *hadjustment;
560 GtkAdjustment *vadjustment;
561 static gint current_x;
562 static gint current_y;
563
564 if (!window)
565 {
566 current_x = 0;
567 current_y = 0;
568
569 window = gtk_dialog_new_with_buttons ("Big Windows",
570 NULL, 0,
571 "_Close",
572 GTK_RESPONSE_NONE,
573 NULL);
574
575 gtk_window_set_screen (GTK_WINDOW (window),
576 gtk_widget_get_screen (widget));
577
578 gtk_window_set_default_size (GTK_WINDOW (window), 200, 300);
579
580 g_signal_connect (window, "destroy",
581 G_CALLBACK (gtk_widget_destroyed),
582 &window);
583
584 g_signal_connect (window, "response",
585 G_CALLBACK (gtk_widget_destroy),
586 NULL);
587
588 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
589
590 grid = gtk_grid_new ();
591 gtk_box_pack_start (GTK_BOX (content_area), grid, TRUE, TRUE, 0);
592
593 darea = gtk_drawing_area_new ();
594
595 hadjustment = gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
596 g_signal_connect (hadjustment, "value_changed",
597 G_CALLBACK (pattern_hadj_changed), darea);
598 g_object_set_data (G_OBJECT (hadjustment), "old-value", ¤t_x);
599
600 vadjustment = gtk_adjustment_new (0, 0, PATTERN_SIZE, 10, 100, 100);
601 g_signal_connect (vadjustment, "value_changed",
602 G_CALLBACK (pattern_vadj_changed), darea);
603 g_object_set_data (G_OBJECT (vadjustment), "old-value", ¤t_y);
604
605 g_signal_connect (darea, "realize",
606 G_CALLBACK (pattern_realize),
607 NULL);
608
609 eventbox = gtk_event_box_new ();
610 gtk_widget_set_hexpand (eventbox, TRUE);
611 gtk_widget_set_vexpand (eventbox, TRUE);
612 gtk_grid_attach (GTK_GRID (grid), eventbox, 0, 0, 1, 1);
613
614 gtk_container_add (GTK_CONTAINER (eventbox), darea);
615
616 scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, hadjustment);
617 gtk_widget_set_hexpand (scrollbar, TRUE);
618 gtk_grid_attach (GTK_GRID (grid), scrollbar, 0, 1, 1, 1);
619
620 scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, vadjustment);
621 gtk_widget_set_vexpand (scrollbar, TRUE);
622 gtk_grid_attach (GTK_GRID (grid), scrollbar, 1, 0, 1, 1);
623 }
624
625 if (!gtk_widget_get_visible (window))
626 gtk_widget_show_all (window);
627 else
628 gtk_widget_hide (window);
629 }
630
631 /*
632 * GtkButton
633 */
634
635 static void
button_window(GtkWidget * widget,GtkWidget * button)636 button_window (GtkWidget *widget,
637 GtkWidget *button)
638 {
639 if (!gtk_widget_get_visible (button))
640 gtk_widget_show (button);
641 else
642 gtk_widget_hide (button);
643 }
644
645 static void
create_buttons(GtkWidget * widget)646 create_buttons (GtkWidget *widget)
647 {
648 static GtkWidget *window = NULL;
649 GtkWidget *box1;
650 GtkWidget *box2;
651 GtkWidget *grid;
652 GtkWidget *separator;
653 GtkWidget *button[10];
654 int button_x[9] = { 0, 1, 2, 0, 2, 1, 1, 2, 0 };
655 int button_y[9] = { 0, 1, 2, 2, 0, 2, 0, 1, 1 };
656 guint i;
657
658 if (!window)
659 {
660 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
661 gtk_window_set_screen (GTK_WINDOW (window),
662 gtk_widget_get_screen (widget));
663
664 g_signal_connect (window, "destroy",
665 G_CALLBACK (gtk_widget_destroyed),
666 &window);
667
668 gtk_window_set_title (GTK_WINDOW (window), "GtkButton");
669 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
670
671 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
672 gtk_container_add (GTK_CONTAINER (window), box1);
673
674 grid = gtk_grid_new ();
675 gtk_grid_set_row_spacing (GTK_GRID (grid), 5);
676 gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
677 gtk_container_set_border_width (GTK_CONTAINER (grid), 10);
678 gtk_box_pack_start (GTK_BOX (box1), grid, TRUE, TRUE, 0);
679
680 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
681 button[0] = gtk_button_new_with_label ("button1");
682 button[1] = gtk_button_new_with_mnemonic ("_button2");
683 button[2] = gtk_button_new_with_mnemonic ("_button3");
684 button[3] = gtk_button_new_from_stock (GTK_STOCK_OK);
685 button[4] = gtk_button_new_with_label ("button5");
686 button[5] = gtk_button_new_with_label ("button6");
687 button[6] = gtk_button_new_with_label ("button7");
688 button[7] = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
689 button[8] = gtk_button_new_with_label ("button9");
690 G_GNUC_END_IGNORE_DEPRECATIONS;
691
692 for (i = 0; i < 9; i++)
693 {
694 g_signal_connect (button[i], "clicked",
695 G_CALLBACK (button_window),
696 button[(i + 1) % 9]);
697 gtk_widget_set_hexpand (button[i], TRUE);
698 gtk_widget_set_vexpand (button[i], TRUE);
699
700 gtk_grid_attach (GTK_GRID (grid), button[i],
701 button_x[i], button_y[i] + 1, 1, 1);
702 }
703
704 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
705 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
706
707 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
708 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
709 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
710
711 button[9] = gtk_button_new_with_label ("close");
712 g_signal_connect_swapped (button[9], "clicked",
713 G_CALLBACK (gtk_widget_destroy),
714 window);
715 gtk_box_pack_start (GTK_BOX (box2), button[9], TRUE, TRUE, 0);
716 gtk_widget_set_can_default (button[9], TRUE);
717 gtk_widget_grab_default (button[9]);
718 }
719
720 if (!gtk_widget_get_visible (window))
721 gtk_widget_show_all (window);
722 else
723 gtk_widget_destroy (window);
724 }
725
726 /*
727 * GtkToggleButton
728 */
729
730 static void
create_toggle_buttons(GtkWidget * widget)731 create_toggle_buttons (GtkWidget *widget)
732 {
733 static GtkWidget *window = NULL;
734 GtkWidget *box1;
735 GtkWidget *box2;
736 GtkWidget *button;
737 GtkWidget *separator;
738
739 if (!window)
740 {
741 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
742 gtk_window_set_screen (GTK_WINDOW (window),
743 gtk_widget_get_screen (widget));
744
745 g_signal_connect (window, "destroy",
746 G_CALLBACK (gtk_widget_destroyed),
747 &window);
748
749 gtk_window_set_title (GTK_WINDOW (window), "GtkToggleButton");
750 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
751
752 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
753 gtk_container_add (GTK_CONTAINER (window), box1);
754
755 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
756 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
757 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
758
759 button = gtk_toggle_button_new_with_label ("button1");
760 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
761
762 button = gtk_toggle_button_new_with_label ("button2");
763 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
764
765 button = gtk_toggle_button_new_with_label ("button3");
766 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
767
768 button = gtk_toggle_button_new_with_label ("inconsistent");
769 gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
770 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
771
772 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
773 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
774
775 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
776 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
777 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
778
779 button = gtk_button_new_with_label ("close");
780 g_signal_connect_swapped (button, "clicked",
781 G_CALLBACK (gtk_widget_destroy),
782 window);
783 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
784 gtk_widget_set_can_default (button, TRUE);
785 gtk_widget_grab_default (button);
786 }
787
788 if (!gtk_widget_get_visible (window))
789 gtk_widget_show_all (window);
790 else
791 gtk_widget_destroy (window);
792 }
793
794 static GtkWidget *
create_widget_grid(GType widget_type)795 create_widget_grid (GType widget_type)
796 {
797 GtkWidget *grid;
798 GtkWidget *group_widget = NULL;
799 gint i, j;
800
801 grid = gtk_grid_new ();
802
803 for (i = 0; i < 5; i++)
804 {
805 for (j = 0; j < 5; j++)
806 {
807 GtkWidget *widget;
808 char *tmp;
809
810 if (i == 0 && j == 0)
811 {
812 widget = NULL;
813 }
814 else if (i == 0)
815 {
816 tmp = g_strdup_printf ("%d", j);
817 widget = gtk_label_new (tmp);
818 g_free (tmp);
819 }
820 else if (j == 0)
821 {
822 tmp = g_strdup_printf ("%c", 'A' + i - 1);
823 widget = gtk_label_new (tmp);
824 g_free (tmp);
825 }
826 else
827 {
828 widget = g_object_new (widget_type, NULL);
829
830 if (g_type_is_a (widget_type, GTK_TYPE_RADIO_BUTTON))
831 {
832 if (!group_widget)
833 group_widget = widget;
834 else
835 g_object_set (widget, "group", group_widget, NULL);
836 }
837 }
838
839 if (widget)
840 gtk_grid_attach (GTK_GRID (grid), widget, i, j, 1, 1);
841 }
842 }
843
844 return grid;
845 }
846
847 /*
848 * GtkCheckButton
849 */
850
851 static void
create_check_buttons(GtkWidget * widget)852 create_check_buttons (GtkWidget *widget)
853 {
854 static GtkWidget *window = NULL;
855 GtkWidget *box1;
856 GtkWidget *box2;
857 GtkWidget *button;
858 GtkWidget *separator;
859 GtkWidget *table;
860
861 if (!window)
862 {
863 window = gtk_dialog_new_with_buttons ("Check Buttons",
864 NULL, 0,
865 "_Close",
866 GTK_RESPONSE_NONE,
867 NULL);
868
869 gtk_window_set_screen (GTK_WINDOW (window),
870 gtk_widget_get_screen (widget));
871
872 g_signal_connect (window, "destroy",
873 G_CALLBACK (gtk_widget_destroyed),
874 &window);
875 g_signal_connect (window, "response",
876 G_CALLBACK (gtk_widget_destroy),
877 NULL);
878
879 box1 = gtk_dialog_get_content_area (GTK_DIALOG (window));
880
881 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
882 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
883 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
884
885 button = gtk_check_button_new_with_mnemonic ("_button1");
886 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
887
888 button = gtk_check_button_new_with_label ("button2");
889 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
890
891 button = gtk_check_button_new_with_label ("button3");
892 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
893
894 button = gtk_check_button_new_with_label ("inconsistent");
895 gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
896 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
897
898 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
899 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
900
901 table = create_widget_grid (GTK_TYPE_CHECK_BUTTON);
902 gtk_container_set_border_width (GTK_CONTAINER (table), 10);
903 gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
904 }
905
906 if (!gtk_widget_get_visible (window))
907 gtk_widget_show_all (window);
908 else
909 gtk_widget_destroy (window);
910 }
911
912 /*
913 * GtkRadioButton
914 */
915
916 static void
create_radio_buttons(GtkWidget * widget)917 create_radio_buttons (GtkWidget *widget)
918 {
919 static GtkWidget *window = NULL;
920 GtkWidget *box1;
921 GtkWidget *box2;
922 GtkWidget *button;
923 GtkWidget *separator;
924 GtkWidget *table;
925
926 if (!window)
927 {
928 window = gtk_dialog_new_with_buttons ("Radio Buttons",
929 NULL, 0,
930 "_Close",
931 GTK_RESPONSE_NONE,
932 NULL);
933
934 gtk_window_set_screen (GTK_WINDOW (window),
935 gtk_widget_get_screen (widget));
936
937 g_signal_connect (window, "destroy",
938 G_CALLBACK (gtk_widget_destroyed),
939 &window);
940 g_signal_connect (window, "response",
941 G_CALLBACK (gtk_widget_destroy),
942 NULL);
943
944 box1 = gtk_dialog_get_content_area (GTK_DIALOG (window));
945
946 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
947 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
948 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
949
950 button = gtk_radio_button_new_with_label (NULL, "button1");
951 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
952
953 button = gtk_radio_button_new_with_label (
954 gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
955 "button2");
956 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
957 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
958
959 button = gtk_radio_button_new_with_label (
960 gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
961 "button3");
962 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
963
964 button = gtk_radio_button_new_with_label (
965 gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
966 "inconsistent");
967 gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (button), TRUE);
968 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
969
970 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
971 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
972
973 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
974 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
975 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
976
977 button = gtk_radio_button_new_with_label (NULL, "button4");
978 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
979 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
980
981 button = gtk_radio_button_new_with_label (
982 gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
983 "button5");
984 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
985 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
986 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
987
988 button = gtk_radio_button_new_with_label (
989 gtk_radio_button_get_group (GTK_RADIO_BUTTON (button)),
990 "button6");
991 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (button), FALSE);
992 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
993
994 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
995 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
996
997 table = create_widget_grid (GTK_TYPE_RADIO_BUTTON);
998 gtk_container_set_border_width (GTK_CONTAINER (table), 10);
999 gtk_box_pack_start (GTK_BOX (box1), table, TRUE, TRUE, 0);
1000 }
1001
1002 if (!gtk_widget_get_visible (window))
1003 gtk_widget_show_all (window);
1004 else
1005 gtk_widget_destroy (window);
1006 }
1007
1008 /*
1009 * GtkButtonBox
1010 */
1011
1012 static GtkWidget *
create_bbox(gint horizontal,char * title,gint spacing,gint child_w,gint child_h,gint layout)1013 create_bbox (gint horizontal,
1014 char* title,
1015 gint spacing,
1016 gint child_w,
1017 gint child_h,
1018 gint layout)
1019 {
1020 GtkWidget *frame;
1021 GtkWidget *bbox;
1022 GtkWidget *button;
1023
1024 frame = gtk_frame_new (title);
1025
1026 if (horizontal)
1027 bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
1028 else
1029 bbox = gtk_button_box_new (GTK_ORIENTATION_VERTICAL);
1030
1031 gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
1032 gtk_container_add (GTK_CONTAINER (frame), bbox);
1033
1034 gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), layout);
1035 gtk_box_set_spacing (GTK_BOX (bbox), spacing);
1036
1037 button = gtk_button_new_with_label ("OK");
1038 gtk_container_add (GTK_CONTAINER (bbox), button);
1039
1040 button = gtk_button_new_with_label ("Cancel");
1041 gtk_container_add (GTK_CONTAINER (bbox), button);
1042
1043 button = gtk_button_new_with_label ("Help");
1044 gtk_container_add (GTK_CONTAINER (bbox), button);
1045
1046 return frame;
1047 }
1048
1049 static void
create_button_box(GtkWidget * widget)1050 create_button_box (GtkWidget *widget)
1051 {
1052 static GtkWidget* window = NULL;
1053 GtkWidget *main_vbox;
1054 GtkWidget *vbox;
1055 GtkWidget *hbox;
1056 GtkWidget *frame_horz;
1057 GtkWidget *frame_vert;
1058
1059 if (!window)
1060 {
1061 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1062 gtk_window_set_screen (GTK_WINDOW (window), gtk_widget_get_screen (widget));
1063 gtk_window_set_title (GTK_WINDOW (window), "Button Boxes");
1064
1065 g_signal_connect (window, "destroy",
1066 G_CALLBACK (gtk_widget_destroyed),
1067 &window);
1068
1069 gtk_container_set_border_width (GTK_CONTAINER (window), 10);
1070
1071 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1072 gtk_container_add (GTK_CONTAINER (window), main_vbox);
1073
1074 frame_horz = gtk_frame_new ("Horizontal Button Boxes");
1075 gtk_box_pack_start (GTK_BOX (main_vbox), frame_horz, TRUE, TRUE, 10);
1076
1077 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1078 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
1079 gtk_container_add (GTK_CONTAINER (frame_horz), vbox);
1080
1081 gtk_box_pack_start (GTK_BOX (vbox),
1082 create_bbox (TRUE, "Spread", 40, 85, 20, GTK_BUTTONBOX_SPREAD),
1083 TRUE, TRUE, 0);
1084
1085 gtk_box_pack_start (GTK_BOX (vbox),
1086 create_bbox (TRUE, "Edge", 40, 85, 20, GTK_BUTTONBOX_EDGE),
1087 TRUE, TRUE, 5);
1088
1089 gtk_box_pack_start (GTK_BOX (vbox),
1090 create_bbox (TRUE, "Start", 40, 85, 20, GTK_BUTTONBOX_START),
1091 TRUE, TRUE, 5);
1092
1093 gtk_box_pack_start (GTK_BOX (vbox),
1094 create_bbox (TRUE, "End", 40, 85, 20, GTK_BUTTONBOX_END),
1095 TRUE, TRUE, 5);
1096
1097 gtk_box_pack_start (GTK_BOX (vbox),
1098 create_bbox (TRUE, "Center", 40, 85, 20, GTK_BUTTONBOX_CENTER),
1099 TRUE, TRUE, 5);
1100
1101 frame_vert = gtk_frame_new ("Vertical Button Boxes");
1102 gtk_box_pack_start (GTK_BOX (main_vbox), frame_vert, TRUE, TRUE, 10);
1103
1104 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1105 gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
1106 gtk_container_add (GTK_CONTAINER (frame_vert), hbox);
1107
1108 gtk_box_pack_start (GTK_BOX (hbox),
1109 create_bbox (FALSE, "Spread", 30, 85, 20, GTK_BUTTONBOX_SPREAD),
1110 TRUE, TRUE, 0);
1111
1112 gtk_box_pack_start (GTK_BOX (hbox),
1113 create_bbox (FALSE, "Edge", 30, 85, 20, GTK_BUTTONBOX_EDGE),
1114 TRUE, TRUE, 5);
1115
1116 gtk_box_pack_start (GTK_BOX (hbox),
1117 create_bbox (FALSE, "Start", 30, 85, 20, GTK_BUTTONBOX_START),
1118 TRUE, TRUE, 5);
1119
1120 gtk_box_pack_start (GTK_BOX (hbox),
1121 create_bbox (FALSE, "End", 30, 85, 20, GTK_BUTTONBOX_END),
1122 TRUE, TRUE, 5);
1123
1124 gtk_box_pack_start (GTK_BOX (hbox),
1125 create_bbox (FALSE, "Center", 30, 85, 20, GTK_BUTTONBOX_CENTER),
1126 TRUE, TRUE, 5);
1127 }
1128
1129 if (!gtk_widget_get_visible (window))
1130 gtk_widget_show_all (window);
1131 else
1132 gtk_widget_destroy (window);
1133 }
1134
1135 /*
1136 * GtkToolBar
1137 */
1138
1139 static GtkWidget*
new_pixbuf(char * filename,GdkWindow * window)1140 new_pixbuf (char *filename,
1141 GdkWindow *window)
1142 {
1143 GtkWidget *widget;
1144 GdkPixbuf *pixbuf;
1145
1146 if (strcmp (filename, "test.xpm") == 0)
1147 pixbuf = NULL;
1148 else
1149 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
1150
1151 if (pixbuf == NULL)
1152 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
1153
1154 widget = gtk_image_new_from_pixbuf (pixbuf);
1155
1156 g_object_unref (pixbuf);
1157
1158 return widget;
1159 }
1160
1161
1162 static void
set_toolbar_small_stock(GtkWidget * widget,gpointer data)1163 set_toolbar_small_stock (GtkWidget *widget,
1164 gpointer data)
1165 {
1166 gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_SMALL_TOOLBAR);
1167 }
1168
1169 static void
set_toolbar_large_stock(GtkWidget * widget,gpointer data)1170 set_toolbar_large_stock (GtkWidget *widget,
1171 gpointer data)
1172 {
1173 gtk_toolbar_set_icon_size (GTK_TOOLBAR (data), GTK_ICON_SIZE_LARGE_TOOLBAR);
1174 }
1175
1176 static void
set_toolbar_horizontal(GtkWidget * widget,gpointer data)1177 set_toolbar_horizontal (GtkWidget *widget,
1178 gpointer data)
1179 {
1180 gtk_orientable_set_orientation (GTK_ORIENTABLE (data), GTK_ORIENTATION_HORIZONTAL);
1181 }
1182
1183 static void
set_toolbar_vertical(GtkWidget * widget,gpointer data)1184 set_toolbar_vertical (GtkWidget *widget,
1185 gpointer data)
1186 {
1187 gtk_orientable_set_orientation (GTK_ORIENTABLE (data), GTK_ORIENTATION_VERTICAL);
1188 }
1189
1190 static void
set_toolbar_icons(GtkWidget * widget,gpointer data)1191 set_toolbar_icons (GtkWidget *widget,
1192 gpointer data)
1193 {
1194 gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_ICONS);
1195 }
1196
1197 static void
set_toolbar_text(GtkWidget * widget,gpointer data)1198 set_toolbar_text (GtkWidget *widget,
1199 gpointer data)
1200 {
1201 gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_TEXT);
1202 }
1203
1204 static void
set_toolbar_both(GtkWidget * widget,gpointer data)1205 set_toolbar_both (GtkWidget *widget,
1206 gpointer data)
1207 {
1208 gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH);
1209 }
1210
1211 static void
set_toolbar_both_horiz(GtkWidget * widget,gpointer data)1212 set_toolbar_both_horiz (GtkWidget *widget,
1213 gpointer data)
1214 {
1215 gtk_toolbar_set_style (GTK_TOOLBAR (data), GTK_TOOLBAR_BOTH_HORIZ);
1216 }
1217
1218 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1219 static GtkActionEntry create_toolbar_items[] = {
1220 { NULL, GTK_STOCK_NEW, NULL, NULL, "Stock icon: New",
1221 G_CALLBACK (set_toolbar_small_stock) },
1222 { NULL, GTK_STOCK_OPEN, NULL, NULL, "Stock icon: Open",
1223 G_CALLBACK (set_toolbar_large_stock) },
1224 { NULL, NULL, "Horizontal", NULL, "Horizontal toolbar layout",
1225 G_CALLBACK (set_toolbar_horizontal) },
1226 { NULL, NULL, "Vertical", NULL, "Vertical toolbar layout",
1227 G_CALLBACK (set_toolbar_vertical) },
1228 { NULL },
1229 { NULL, NULL, "Icons", NULL, "Only show toolbar icons",
1230 G_CALLBACK (set_toolbar_icons) },
1231 { NULL, NULL, "Text", NULL, "Only show toolbar text",
1232 G_CALLBACK (set_toolbar_text) },
1233 { NULL, NULL, "Both", NULL, "Show toolbar icons and text",
1234 G_CALLBACK (set_toolbar_both) },
1235 { NULL, NULL, "Both (horizontal)", NULL, "Show toolbar icons and text in a horizontal fashion",
1236 G_CALLBACK (set_toolbar_both_horiz) },
1237 { NULL },
1238 { "entry", NULL, NULL, "This is an unusable GtkEntry ;)",
1239 NULL },
1240 { NULL },
1241 { NULL },
1242 { NULL, NULL, "Frobate", NULL, "Frobate tooltip",
1243 NULL },
1244 { NULL, NULL, "Baz", NULL, "Baz tooltip",
1245 NULL },
1246 { NULL },
1247 { NULL, NULL, "Blah", NULL, "Blash tooltip",
1248 NULL },
1249 { NULL, NULL, "Bar", NULL, "Bar tooltip",
1250 NULL },
1251 };
1252 G_GNUC_END_IGNORE_DEPRECATIONS;
1253
1254 static void
create_toolbar(GtkWidget * widget)1255 create_toolbar (GtkWidget *widget)
1256 {
1257 static GtkWidget *window = NULL;
1258 GtkWidget *toolbar;
1259
1260 if (!window)
1261 {
1262 guint i;
1263
1264 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1265 gtk_window_set_screen (GTK_WINDOW (window),
1266 gtk_widget_get_screen (widget));
1267
1268 gtk_window_set_title (GTK_WINDOW (window), "Toolbar test");
1269
1270 g_signal_connect (window, "destroy",
1271 G_CALLBACK (gtk_widget_destroyed),
1272 &window);
1273
1274 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1275 gtk_widget_realize (window);
1276
1277 toolbar = gtk_toolbar_new ();
1278 for (i = 0; i < G_N_ELEMENTS (create_toolbar_items); i++)
1279 {
1280 GtkToolItem *toolitem;
1281
1282 if (create_toolbar_items[i].tooltip == NULL)
1283 toolitem = gtk_separator_tool_item_new ();
1284 else if (g_strcmp0 (create_toolbar_items[i].name, "entry") == 0)
1285 {
1286 GtkWidget *entry;
1287
1288 toolitem = gtk_tool_item_new ();
1289 entry = gtk_entry_new ();
1290 gtk_container_add (GTK_CONTAINER (toolitem), entry);
1291 }
1292 else if (create_toolbar_items[i].stock_id)
1293 {
1294 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1295 toolitem = gtk_tool_button_new_from_stock (create_toolbar_items[i].stock_id);
1296 G_GNUC_END_IGNORE_DEPRECATIONS;
1297 }
1298 else
1299 {
1300 GtkWidget *icon;
1301
1302 icon = new_pixbuf ("test.xpm", gtk_widget_get_window (window));
1303 toolitem = gtk_tool_button_new (icon, create_toolbar_items[i].label);
1304 }
1305 if (create_toolbar_items[i].callback)
1306 g_signal_connect (toolitem, "clicked",
1307 create_toolbar_items[i].callback, toolbar);
1308 gtk_tool_item_set_tooltip_text (toolitem, create_toolbar_items[i].tooltip);
1309 gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
1310 }
1311
1312 gtk_container_add (GTK_CONTAINER (window), toolbar);
1313
1314 gtk_widget_set_size_request (toolbar, 200, -1);
1315 }
1316
1317 if (!gtk_widget_get_visible (window))
1318 gtk_widget_show_all (window);
1319 else
1320 gtk_widget_destroy (window);
1321 }
1322
1323 /*
1324 * GtkStatusBar
1325 */
1326
1327 static guint statusbar_counter = 1;
1328
1329 static void
statusbar_push(GtkWidget * button,GtkStatusbar * statusbar)1330 statusbar_push (GtkWidget *button,
1331 GtkStatusbar *statusbar)
1332 {
1333 gchar text[1024];
1334
1335 sprintf (text, "something %d", statusbar_counter++);
1336
1337 gtk_statusbar_push (statusbar, 1, text);
1338 }
1339
1340 static void
statusbar_push_long(GtkWidget * button,GtkStatusbar * statusbar)1341 statusbar_push_long (GtkWidget *button,
1342 GtkStatusbar *statusbar)
1343 {
1344 gchar text[1024];
1345
1346 sprintf (text, "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\").");
1347
1348 gtk_statusbar_push (statusbar, 1, text);
1349 }
1350
1351 static void
statusbar_pop(GtkWidget * button,GtkStatusbar * statusbar)1352 statusbar_pop (GtkWidget *button,
1353 GtkStatusbar *statusbar)
1354 {
1355 gtk_statusbar_pop (statusbar, 1);
1356 }
1357
1358 static void
statusbar_steal(GtkWidget * button,GtkStatusbar * statusbar)1359 statusbar_steal (GtkWidget *button,
1360 GtkStatusbar *statusbar)
1361 {
1362 gtk_statusbar_remove (statusbar, 1, 4);
1363 }
1364
1365 static void
statusbar_popped(GtkStatusbar * statusbar,guint context_id,const gchar * text)1366 statusbar_popped (GtkStatusbar *statusbar,
1367 guint context_id,
1368 const gchar *text)
1369 {
1370 if (!text)
1371 statusbar_counter = 1;
1372 }
1373
1374 static void
statusbar_contexts(GtkStatusbar * statusbar)1375 statusbar_contexts (GtkStatusbar *statusbar)
1376 {
1377 gchar *string;
1378
1379 string = "any context";
1380 g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1381 string,
1382 gtk_statusbar_get_context_id (statusbar, string));
1383
1384 string = "idle messages";
1385 g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1386 string,
1387 gtk_statusbar_get_context_id (statusbar, string));
1388
1389 string = "some text";
1390 g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1391 string,
1392 gtk_statusbar_get_context_id (statusbar, string));
1393
1394 string = "hit the mouse";
1395 g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1396 string,
1397 gtk_statusbar_get_context_id (statusbar, string));
1398
1399 string = "hit the mouse2";
1400 g_print ("GtkStatusBar: context=\"%s\", context_id=%d\n",
1401 string,
1402 gtk_statusbar_get_context_id (statusbar, string));
1403 }
1404
1405 static void
create_statusbar(GtkWidget * widget)1406 create_statusbar (GtkWidget *widget)
1407 {
1408 static GtkWidget *window = NULL;
1409 GtkWidget *box1;
1410 GtkWidget *box2;
1411 GtkWidget *button;
1412 GtkWidget *separator;
1413 GtkWidget *statusbar;
1414
1415 if (!window)
1416 {
1417 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1418 gtk_window_set_screen (GTK_WINDOW (window),
1419 gtk_widget_get_screen (widget));
1420
1421 g_signal_connect (window, "destroy",
1422 G_CALLBACK (gtk_widget_destroyed),
1423 &window);
1424
1425 gtk_window_set_title (GTK_WINDOW (window), "statusbar");
1426 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1427
1428 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1429 gtk_container_add (GTK_CONTAINER (window), box1);
1430
1431 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
1432 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1433 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
1434
1435 statusbar = gtk_statusbar_new ();
1436 gtk_box_pack_end (GTK_BOX (box1), statusbar, TRUE, TRUE, 0);
1437 g_signal_connect (statusbar,
1438 "text_popped",
1439 G_CALLBACK (statusbar_popped),
1440 NULL);
1441
1442 button = g_object_new (gtk_button_get_type (),
1443 "label", "push something",
1444 "visible", TRUE,
1445 "parent", box2,
1446 NULL);
1447 g_object_connect (button,
1448 "signal::clicked", statusbar_push, statusbar,
1449 NULL);
1450
1451 button = g_object_connect (g_object_new (gtk_button_get_type (),
1452 "label", "pop",
1453 "visible", TRUE,
1454 "parent", box2,
1455 NULL),
1456 "signal_after::clicked", statusbar_pop, statusbar,
1457 NULL);
1458
1459 button = g_object_connect (g_object_new (gtk_button_get_type (),
1460 "label", "steal #4",
1461 "visible", TRUE,
1462 "parent", box2,
1463 NULL),
1464 "signal_after::clicked", statusbar_steal, statusbar,
1465 NULL);
1466
1467 button = g_object_connect (g_object_new (gtk_button_get_type (),
1468 "label", "test contexts",
1469 "visible", TRUE,
1470 "parent", box2,
1471 NULL),
1472 "swapped_signal_after::clicked", statusbar_contexts, statusbar,
1473 NULL);
1474
1475 button = g_object_connect (g_object_new (gtk_button_get_type (),
1476 "label", "push something long",
1477 "visible", TRUE,
1478 "parent", box2,
1479 NULL),
1480 "signal_after::clicked", statusbar_push_long, statusbar,
1481 NULL);
1482
1483 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
1484 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
1485
1486 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
1487 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
1488 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
1489
1490 button = gtk_button_new_with_label ("close");
1491 g_signal_connect_swapped (button, "clicked",
1492 G_CALLBACK (gtk_widget_destroy),
1493 window);
1494 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
1495 gtk_widget_set_can_default (button, TRUE);
1496 gtk_widget_grab_default (button);
1497 }
1498
1499 if (!gtk_widget_get_visible (window))
1500 gtk_widget_show_all (window);
1501 else
1502 gtk_widget_destroy (window);
1503 }
1504
1505 /* Alpha demo */
1506
1507 static void
alpha_changed(GtkRange * range,GtkWidget * widget)1508 alpha_changed (GtkRange *range, GtkWidget *widget)
1509 {
1510 gdouble alpha;
1511
1512 alpha = gtk_range_get_value (range);
1513
1514 gtk_widget_set_opacity (widget, alpha / 100.0);
1515 }
1516
1517
1518 void
create_alpha_widgets(GtkWidget * widget)1519 create_alpha_widgets (GtkWidget *widget)
1520 {
1521 static GtkWidget *window = NULL;
1522
1523 if (!window)
1524 {
1525 GtkWidget *vbox2, *vbox, *main_hbox;
1526 GtkWidget *button, *event_box, *label, *scale;
1527 GtkWidget *alpha1, *alpha2, *alpha3;
1528
1529 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1530 gtk_window_set_screen (GTK_WINDOW (window),
1531 gtk_widget_get_screen (widget));
1532 gtk_window_set_default_size (GTK_WINDOW (window),
1533 450, 450);
1534
1535 g_signal_connect (window, "destroy",
1536 G_CALLBACK (gtk_widget_destroyed), &window);
1537
1538 gtk_window_set_title (GTK_WINDOW (window), "Alpha");
1539 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
1540
1541 main_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1542 gtk_container_add (GTK_CONTAINER (window), main_hbox);
1543
1544 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1545
1546 gtk_box_pack_start (GTK_BOX (main_hbox), vbox, FALSE, FALSE, 0);
1547
1548 /* Plain button (no gdkwindows */
1549
1550 label = gtk_label_new ("non-window widget");
1551 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
1552
1553 alpha1 = button = gtk_button_new_with_label ("A Button");
1554 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1555
1556 /* windowed container with both windowed and normal button */
1557 label = gtk_label_new ("\nwindow widget");
1558 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
1559
1560 alpha2 = event_box = gtk_event_box_new ();
1561 gtk_box_pack_start (GTK_BOX (vbox), event_box, FALSE, FALSE, 0);
1562
1563 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1564 gtk_container_add (GTK_CONTAINER (event_box), vbox2);
1565
1566 button = gtk_button_new_with_label ("A Button");
1567 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1568
1569 event_box = gtk_event_box_new ();
1570 button = gtk_button_new_with_label ("A Button (in window)");
1571 gtk_container_add (GTK_CONTAINER (event_box), button);
1572 gtk_box_pack_start (GTK_BOX (vbox2), event_box, FALSE, FALSE, 0);
1573
1574 /* non-windowed container with both windowed and normal button */
1575 label = gtk_label_new ("\nnon-window widget with widget child");
1576 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
1577
1578 alpha3 = vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
1579 gtk_box_pack_start (GTK_BOX (vbox), vbox2, FALSE, FALSE, 0);
1580
1581 button = gtk_button_new_with_label ("A Button");
1582 gtk_box_pack_start (GTK_BOX (vbox2), button, FALSE, FALSE, 0);
1583
1584 event_box = gtk_event_box_new ();
1585 button = gtk_button_new_with_label ("A Button (in window)");
1586 gtk_container_add (GTK_CONTAINER (event_box), button);
1587 gtk_box_pack_start (GTK_BOX (vbox2), event_box, FALSE, FALSE, 0);
1588
1589 scale = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
1590 0, 100, 1);
1591 gtk_box_pack_start (GTK_BOX (main_hbox), scale, FALSE, FALSE, 0);
1592 g_signal_connect (scale, "value_changed", G_CALLBACK (alpha_changed), alpha1);
1593 gtk_range_set_value (GTK_RANGE (scale), 50);
1594
1595 scale = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
1596 0, 100, 1);
1597 gtk_box_pack_start (GTK_BOX (main_hbox), scale, FALSE, FALSE, 0);
1598 g_signal_connect (scale, "value_changed", G_CALLBACK (alpha_changed), alpha2);
1599 gtk_range_set_value (GTK_RANGE (scale), 50);
1600
1601 scale = gtk_scale_new_with_range (GTK_ORIENTATION_VERTICAL,
1602 0, 100, 1);
1603 gtk_box_pack_start (GTK_BOX (main_hbox), scale, FALSE, FALSE, 0);
1604 g_signal_connect (scale, "value_changed", G_CALLBACK (alpha_changed), alpha3);
1605 gtk_range_set_value (GTK_RANGE (scale), 50);
1606
1607 gtk_widget_show_all (main_hbox);
1608 }
1609
1610 if (!gtk_widget_get_visible (window))
1611 gtk_widget_show (window);
1612 else
1613 gtk_widget_destroy (window);
1614 }
1615
1616
1617 /*
1618 * Label Demo
1619 */
1620 static void
sensitivity_toggled(GtkWidget * toggle,GtkWidget * widget)1621 sensitivity_toggled (GtkWidget *toggle,
1622 GtkWidget *widget)
1623 {
1624 gtk_widget_set_sensitive (widget,
1625 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
1626 }
1627
1628 static GtkWidget*
create_sensitivity_control(GtkWidget * widget)1629 create_sensitivity_control (GtkWidget *widget)
1630 {
1631 GtkWidget *button;
1632
1633 button = gtk_toggle_button_new_with_label ("Sensitive");
1634
1635 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
1636 gtk_widget_is_sensitive (widget));
1637
1638 g_signal_connect (button,
1639 "toggled",
1640 G_CALLBACK (sensitivity_toggled),
1641 widget);
1642
1643 gtk_widget_show_all (button);
1644
1645 return button;
1646 }
1647
1648 static void
set_selectable_recursive(GtkWidget * widget,gboolean setting)1649 set_selectable_recursive (GtkWidget *widget,
1650 gboolean setting)
1651 {
1652 if (GTK_IS_CONTAINER (widget))
1653 {
1654 GList *children;
1655 GList *tmp;
1656
1657 children = gtk_container_get_children (GTK_CONTAINER (widget));
1658 tmp = children;
1659 while (tmp)
1660 {
1661 set_selectable_recursive (tmp->data, setting);
1662
1663 tmp = tmp->next;
1664 }
1665 g_list_free (children);
1666 }
1667 else if (GTK_IS_LABEL (widget))
1668 {
1669 gtk_label_set_selectable (GTK_LABEL (widget), setting);
1670 }
1671 }
1672
1673 static void
selectable_toggled(GtkWidget * toggle,GtkWidget * widget)1674 selectable_toggled (GtkWidget *toggle,
1675 GtkWidget *widget)
1676 {
1677 set_selectable_recursive (widget,
1678 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (toggle)));
1679 }
1680
1681 static GtkWidget*
create_selectable_control(GtkWidget * widget)1682 create_selectable_control (GtkWidget *widget)
1683 {
1684 GtkWidget *button;
1685
1686 button = gtk_toggle_button_new_with_label ("Selectable");
1687
1688 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
1689 FALSE);
1690
1691 g_signal_connect (button,
1692 "toggled",
1693 G_CALLBACK (selectable_toggled),
1694 widget);
1695
1696 gtk_widget_show_all (button);
1697
1698 return button;
1699 }
1700
1701 static void
dialog_response(GtkWidget * dialog,gint response_id,GtkLabel * label)1702 dialog_response (GtkWidget *dialog, gint response_id, GtkLabel *label)
1703 {
1704 const gchar *text;
1705
1706 gtk_widget_destroy (dialog);
1707
1708 text = "Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
1709 "as hyperlinks, which can be clicked\n"
1710 "or activated via <a href=\"keynav\">keynav</a>.\n"
1711 "The links remain the same.";
1712 gtk_label_set_markup (label, text);
1713 }
1714
1715 static gboolean
activate_link(GtkWidget * label,const gchar * uri,gpointer data)1716 activate_link (GtkWidget *label, const gchar *uri, gpointer data)
1717 {
1718 if (g_strcmp0 (uri, "keynav") == 0)
1719 {
1720 GtkWidget *dialog;
1721
1722 dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (gtk_widget_get_toplevel (label)),
1723 GTK_DIALOG_DESTROY_WITH_PARENT,
1724 GTK_MESSAGE_INFO,
1725 GTK_BUTTONS_OK,
1726 "The term <i>keynav</i> is a shorthand for "
1727 "keyboard navigation and refers to the process of using a program "
1728 "(exclusively) via keyboard input.");
1729
1730 gtk_window_present (GTK_WINDOW (dialog));
1731
1732 g_signal_connect (dialog, "response", G_CALLBACK (dialog_response), label);
1733
1734 return TRUE;
1735 }
1736
1737 return FALSE;
1738 }
1739
create_labels(GtkWidget * widget)1740 void create_labels (GtkWidget *widget)
1741 {
1742 static GtkWidget *window = NULL;
1743 GtkWidget *hbox;
1744 GtkWidget *vbox;
1745 GtkWidget *frame;
1746 GtkWidget *label;
1747 GtkWidget *button;
1748
1749 if (!window)
1750 {
1751 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1752
1753 gtk_window_set_screen (GTK_WINDOW (window),
1754 gtk_widget_get_screen (widget));
1755
1756 g_signal_connect (window, "destroy",
1757 G_CALLBACK (gtk_widget_destroyed),
1758 &window);
1759
1760 gtk_window_set_title (GTK_WINDOW (window), "Label");
1761
1762 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
1763
1764 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
1765 gtk_container_add (GTK_CONTAINER (window), vbox);
1766
1767 gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
1768
1769 button = create_sensitivity_control (hbox);
1770
1771 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1772
1773 button = create_selectable_control (hbox);
1774
1775 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
1776
1777 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
1778
1779 gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
1780 gtk_container_set_border_width (GTK_CONTAINER (window), 5);
1781
1782 frame = gtk_frame_new ("Normal Label");
1783 label = gtk_label_new ("This is a Normal label");
1784 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
1785 gtk_container_add (GTK_CONTAINER (frame), label);
1786 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1787
1788 frame = gtk_frame_new ("Multi-line Label");
1789 label = gtk_label_new ("This is a Multi-line label.\nSecond line\nThird line");
1790 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
1791 gtk_container_add (GTK_CONTAINER (frame), label);
1792 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1793
1794 frame = gtk_frame_new ("Left Justified Label");
1795 label = gtk_label_new ("This is a Left-Justified\nMulti-line label.\nThird line");
1796 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
1797 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1798 gtk_container_add (GTK_CONTAINER (frame), label);
1799 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1800
1801 frame = gtk_frame_new ("Right Justified Label");
1802 gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_START);
1803 label = gtk_label_new ("This is a Right-Justified\nMulti-line label.\nFourth line, (j/k)");
1804 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_RIGHT);
1805 gtk_container_add (GTK_CONTAINER (frame), label);
1806 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1807
1808 frame = gtk_frame_new ("Internationalized Label");
1809 label = gtk_label_new (NULL);
1810 gtk_label_set_markup (GTK_LABEL (label),
1811 "French (Fran\303\247ais) Bonjour, Salut\n"
1812 "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"
1813 "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"
1814 "Chinese (Simplified) <span lang=\"zh-cn\">\345\205\203\346\260\224 \345\274\200\345\217\221</span>\n"
1815 "Chinese (Traditional) <span lang=\"zh-tw\">\345\205\203\346\260\243 \351\226\213\347\231\274</span>\n"
1816 "Japanese <span lang=\"ja\">\345\205\203\346\260\227 \351\226\213\347\231\272</span>");
1817 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1818 gtk_container_add (GTK_CONTAINER (frame), label);
1819 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1820
1821 frame = gtk_frame_new ("Bidirection Label");
1822 label = gtk_label_new ("\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"
1823 "\342\200\217Hebrew \327\251\327\234\327\225\327\235");
1824 gtk_container_add (GTK_CONTAINER (frame), label);
1825 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1826
1827 frame = gtk_frame_new ("Links in a label");
1828 label = gtk_label_new ("Some <a href=\"http://en.wikipedia.org/wiki/Text\" title=\"plain text\">text</a> may be marked up\n"
1829 "as hyperlinks, which can be clicked\n"
1830 "or activated via <a href=\"keynav\">keynav</a>");
1831 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
1832 gtk_container_add (GTK_CONTAINER (frame), label);
1833 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1834 g_signal_connect (label, "activate-link", G_CALLBACK (activate_link), NULL);
1835
1836 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
1837 gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
1838 frame = gtk_frame_new ("Line wrapped label");
1839 label = gtk_label_new ("This is an example of a line-wrapped label. It should not be taking "\
1840 "up the entire "/* big space to test spacing */\
1841 "width allocated to it, but automatically wraps the words to fit. "\
1842 "The time has come, for all good men, to come to the aid of their party. "\
1843 "The sixth sheik's six sheep's sick.\n"\
1844 " It supports multiple paragraphs correctly, and correctly adds "\
1845 "many extra spaces. ");
1846
1847 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1848 gtk_container_add (GTK_CONTAINER (frame), label);
1849 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1850
1851 frame = gtk_frame_new ("Filled, wrapped label");
1852 label = gtk_label_new ("This is an example of a line-wrapped, filled label. It should be taking "\
1853 "up the entire width allocated to it. Here is a seneance to prove "\
1854 "my point. Here is another sentence. "\
1855 "Here comes the sun, do de do de do.\n"\
1856 " This is a new paragraph.\n"\
1857 " This is another newer, longer, better paragraph. It is coming to an end, "\
1858 "unfortunately.");
1859 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_FILL);
1860 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
1861 gtk_container_add (GTK_CONTAINER (frame), label);
1862 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1863
1864 frame = gtk_frame_new ("Underlined label");
1865 label = gtk_label_new ("This label is underlined!\n"
1866 "This one is underlined (\343\201\223\343\202\223\343\201\253\343\201\241\343\201\257) in quite a funky fashion");
1867 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
1868 gtk_label_set_pattern (GTK_LABEL (label), "_________________________ _ _________ _ _____ _ __ __ ___ ____ _____");
1869 gtk_container_add (GTK_CONTAINER (frame), label);
1870 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1871
1872 frame = gtk_frame_new ("Markup label");
1873 label = gtk_label_new (NULL);
1874
1875 /* There's also a gtk_label_set_markup() without accel if you
1876 * don't have an accelerator key
1877 */
1878 gtk_label_set_markup_with_mnemonic (GTK_LABEL (label),
1879 "This <span foreground=\"blue\" background=\"orange\">label</span> has "
1880 "<b>markup</b> _such as "
1881 "<big><i>Big Italics</i></big>\n"
1882 "<tt>Monospace font</tt>\n"
1883 "<u>Underline!</u>\n"
1884 "foo\n"
1885 "<span foreground=\"green\" background=\"red\">Ugly colors</span>\n"
1886 "and nothing on this line,\n"
1887 "or this.\n"
1888 "or this either\n"
1889 "or even on this one\n"
1890 "la <big>la <big>la <big>la <big>la</big></big></big></big>\n"
1891 "but this _word is <span foreground=\"purple\"><big>purple</big></span>\n"
1892 "<span underline=\"double\">We like <sup>superscript</sup> and <sub>subscript</sub> too</span>");
1893
1894 g_assert (gtk_label_get_mnemonic_keyval (GTK_LABEL (label)) == GDK_KEY_s);
1895
1896 gtk_container_add (GTK_CONTAINER (frame), label);
1897 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1898 }
1899
1900 if (!gtk_widget_get_visible (window))
1901 gtk_widget_show_all (window);
1902 else
1903 gtk_widget_destroy (window);
1904 }
1905
1906 static void
on_angle_scale_changed(GtkRange * range,GtkLabel * label)1907 on_angle_scale_changed (GtkRange *range,
1908 GtkLabel *label)
1909 {
1910 gtk_label_set_angle (GTK_LABEL (label), gtk_range_get_value (range));
1911 }
1912
1913 static void
create_rotated_label(GtkWidget * widget)1914 create_rotated_label (GtkWidget *widget)
1915 {
1916 static GtkWidget *window = NULL;
1917 GtkWidget *content_area;
1918 GtkWidget *vbox;
1919 GtkWidget *hscale;
1920 GtkWidget *label;
1921 GtkWidget *scale_label;
1922 GtkWidget *scale_hbox;
1923
1924 if (!window)
1925 {
1926 window = gtk_dialog_new_with_buttons ("Rotated Label",
1927 GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
1928 "_Close", GTK_RESPONSE_CLOSE,
1929 NULL);
1930
1931 gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
1932
1933 gtk_window_set_screen (GTK_WINDOW (window),
1934 gtk_widget_get_screen (widget));
1935
1936 g_signal_connect (window, "response",
1937 G_CALLBACK (gtk_widget_destroy), NULL);
1938 g_signal_connect (window, "destroy",
1939 G_CALLBACK (gtk_widget_destroyed), &window);
1940
1941 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
1942
1943 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
1944 gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
1945 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
1946
1947 label = gtk_label_new (NULL);
1948 gtk_label_set_markup (GTK_LABEL (label), "Hello World\n<i>Rotate</i> <span underline='single' foreground='blue'>me</span>");
1949 gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
1950
1951 scale_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1952 gtk_box_pack_start (GTK_BOX (vbox), scale_hbox, FALSE, FALSE, 0);
1953
1954 scale_label = gtk_label_new (NULL);
1955 gtk_label_set_markup (GTK_LABEL (scale_label), "<i>Angle: </i>");
1956 gtk_box_pack_start (GTK_BOX (scale_hbox), scale_label, FALSE, FALSE, 0);
1957
1958 hscale = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
1959 0, 360, 5);
1960 g_signal_connect (hscale, "value-changed",
1961 G_CALLBACK (on_angle_scale_changed), label);
1962
1963 gtk_range_set_value (GTK_RANGE (hscale), 45);
1964 gtk_widget_set_size_request (hscale, 200, -1);
1965 gtk_box_pack_start (GTK_BOX (scale_hbox), hscale, TRUE, TRUE, 0);
1966 }
1967
1968 if (!gtk_widget_get_visible (window))
1969 gtk_widget_show_all (window);
1970 else
1971 gtk_widget_destroy (window);
1972 }
1973
1974 #define DEFAULT_TEXT_RADIUS 200
1975
1976 static void
on_rotated_text_unrealize(GtkWidget * widget)1977 on_rotated_text_unrealize (GtkWidget *widget)
1978 {
1979 g_object_set_data (G_OBJECT (widget), "text-gc", NULL);
1980 }
1981
1982 static gboolean
on_rotated_text_draw(GtkWidget * widget,cairo_t * cr,GdkPixbuf * tile_pixbuf)1983 on_rotated_text_draw (GtkWidget *widget,
1984 cairo_t *cr,
1985 GdkPixbuf *tile_pixbuf)
1986 {
1987 static const gchar *words[] = { "The", "grand", "old", "Duke", "of", "York",
1988 "had", "10,000", "men" };
1989 int n_words;
1990 int i;
1991 int width, height;
1992 double radius;
1993 PangoLayout *layout;
1994 PangoContext *context;
1995 PangoFontDescription *desc;
1996
1997 cairo_set_source_rgb (cr, 1, 1, 1);
1998 cairo_paint (cr);
1999
2000 if (tile_pixbuf)
2001 {
2002 gdk_cairo_set_source_pixbuf (cr, tile_pixbuf, 0, 0);
2003 cairo_pattern_set_extend (cairo_get_source (cr), CAIRO_EXTEND_REPEAT);
2004 }
2005 else
2006 cairo_set_source_rgb (cr, 0, 0, 0);
2007
2008 width = gtk_widget_get_allocated_width (widget);
2009 height = gtk_widget_get_allocated_height (widget);
2010 radius = MIN (width, height) / 2.;
2011
2012 cairo_translate (cr,
2013 radius + (width - 2 * radius) / 2,
2014 radius + (height - 2 * radius) / 2);
2015 cairo_scale (cr, radius / DEFAULT_TEXT_RADIUS, radius / DEFAULT_TEXT_RADIUS);
2016
2017 context = gtk_widget_get_pango_context (widget);
2018 layout = pango_layout_new (context);
2019 desc = pango_font_description_from_string ("Sans Bold 30");
2020 pango_layout_set_font_description (layout, desc);
2021 pango_font_description_free (desc);
2022
2023 n_words = G_N_ELEMENTS (words);
2024 for (i = 0; i < n_words; i++)
2025 {
2026 int width, height;
2027
2028 cairo_save (cr);
2029
2030 cairo_rotate (cr, 2 * G_PI * i / n_words);
2031 pango_cairo_update_layout (cr, layout);
2032
2033 pango_layout_set_text (layout, words[i], -1);
2034 pango_layout_get_size (layout, &width, &height);
2035
2036 cairo_move_to (cr, - width / 2 / PANGO_SCALE, - DEFAULT_TEXT_RADIUS);
2037 pango_cairo_show_layout (cr, layout);
2038
2039 cairo_restore (cr);
2040 }
2041
2042 g_object_unref (layout);
2043
2044 return FALSE;
2045 }
2046
2047 static void
create_rotated_text(GtkWidget * widget)2048 create_rotated_text (GtkWidget *widget)
2049 {
2050 static GtkWidget *window = NULL;
2051
2052 if (!window)
2053 {
2054 GtkRequisition requisition;
2055 GtkWidget *content_area;
2056 GtkWidget *drawing_area;
2057 GdkPixbuf *tile_pixbuf;
2058
2059 window = gtk_dialog_new_with_buttons ("Rotated Text",
2060 GTK_WINDOW (gtk_widget_get_toplevel (widget)), 0,
2061 "_Close", GTK_RESPONSE_CLOSE,
2062 NULL);
2063
2064 gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
2065
2066 gtk_window_set_screen (GTK_WINDOW (window),
2067 gtk_widget_get_screen (widget));
2068
2069 g_signal_connect (window, "response",
2070 G_CALLBACK (gtk_widget_destroy), NULL);
2071 g_signal_connect (window, "destroy",
2072 G_CALLBACK (gtk_widget_destroyed), &window);
2073
2074 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
2075
2076 drawing_area = gtk_drawing_area_new ();
2077 gtk_box_pack_start (GTK_BOX (content_area), drawing_area, TRUE, TRUE, 0);
2078
2079 tile_pixbuf = gdk_pixbuf_new_from_file ("marble.xpm", NULL);
2080
2081 g_signal_connect (drawing_area, "draw",
2082 G_CALLBACK (on_rotated_text_draw), tile_pixbuf);
2083 g_signal_connect (drawing_area, "unrealize",
2084 G_CALLBACK (on_rotated_text_unrealize), NULL);
2085
2086 gtk_widget_show_all (gtk_bin_get_child (GTK_BIN (window)));
2087
2088 gtk_widget_set_size_request (drawing_area, DEFAULT_TEXT_RADIUS * 2, DEFAULT_TEXT_RADIUS * 2);
2089 gtk_widget_get_preferred_size ( (window),
2090 &requisition, NULL);
2091 gtk_widget_set_size_request (drawing_area, -1, -1);
2092 gtk_window_resize (GTK_WINDOW (window), requisition.width, requisition.height);
2093 }
2094
2095 if (!gtk_widget_get_visible (window))
2096 gtk_widget_show (window);
2097 else
2098 gtk_widget_destroy (window);
2099 }
2100
2101 /*
2102 * Reparent demo
2103 */
2104
2105 static void
reparent_label(GtkWidget * widget,GtkWidget * new_parent)2106 reparent_label (GtkWidget *widget,
2107 GtkWidget *new_parent)
2108 {
2109 GtkWidget *label;
2110
2111 label = g_object_get_data (G_OBJECT (widget), "user_data");
2112
2113 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2114 gtk_widget_reparent (label, new_parent);
2115 G_GNUC_END_IGNORE_DEPRECATIONS
2116 }
2117
2118 static void
set_parent_signal(GtkWidget * child,GtkWidget * old_parent,gpointer func_data)2119 set_parent_signal (GtkWidget *child,
2120 GtkWidget *old_parent,
2121 gpointer func_data)
2122 {
2123 GtkWidget *parent;
2124
2125 parent = gtk_widget_get_parent (child);
2126 g_message ("set_parent for \"%s\": new parent: \"%s\", old parent: \"%s\", data: %d\n",
2127 g_type_name (G_OBJECT_TYPE (child)),
2128 parent ? g_type_name (G_OBJECT_TYPE (parent)) : "NULL",
2129 old_parent ? g_type_name (G_OBJECT_TYPE (old_parent)) : "NULL",
2130 GPOINTER_TO_INT (func_data));
2131 }
2132
2133 static void
create_reparent(GtkWidget * widget)2134 create_reparent (GtkWidget *widget)
2135 {
2136 static GtkWidget *window = NULL;
2137 GtkWidget *box1;
2138 GtkWidget *box2;
2139 GtkWidget *box3;
2140 GtkWidget *frame;
2141 GtkWidget *button;
2142 GtkWidget *label;
2143 GtkWidget *separator;
2144 GtkWidget *event_box;
2145
2146 if (!window)
2147 {
2148 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2149
2150 gtk_window_set_screen (GTK_WINDOW (window),
2151 gtk_widget_get_screen (widget));
2152
2153 g_signal_connect (window, "destroy",
2154 G_CALLBACK (gtk_widget_destroyed),
2155 &window);
2156
2157 gtk_window_set_title (GTK_WINDOW (window), "reparent");
2158 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2159
2160 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2161 gtk_container_add (GTK_CONTAINER (window), box1);
2162
2163 box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
2164 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2165 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2166
2167 label = gtk_label_new ("Hello World");
2168
2169 frame = gtk_frame_new ("Frame 1");
2170 gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
2171
2172 box3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
2173 gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
2174 gtk_container_add (GTK_CONTAINER (frame), box3);
2175
2176 button = gtk_button_new_with_label ("switch");
2177 g_object_set_data (G_OBJECT (button), "user_data", label);
2178 gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
2179
2180 event_box = gtk_event_box_new ();
2181 gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
2182 gtk_container_add (GTK_CONTAINER (event_box), label);
2183
2184 g_signal_connect (button, "clicked",
2185 G_CALLBACK (reparent_label),
2186 event_box);
2187
2188 g_signal_connect (label, "parent_set",
2189 G_CALLBACK (set_parent_signal),
2190 GINT_TO_POINTER (42));
2191
2192 frame = gtk_frame_new ("Frame 2");
2193 gtk_box_pack_start (GTK_BOX (box2), frame, TRUE, TRUE, 0);
2194
2195 box3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
2196 gtk_container_set_border_width (GTK_CONTAINER (box3), 5);
2197 gtk_container_add (GTK_CONTAINER (frame), box3);
2198
2199 button = gtk_button_new_with_label ("switch");
2200 g_object_set_data (G_OBJECT (button), "user_data", label);
2201 gtk_box_pack_start (GTK_BOX (box3), button, FALSE, TRUE, 0);
2202
2203 event_box = gtk_event_box_new ();
2204 gtk_box_pack_start (GTK_BOX (box3), event_box, FALSE, TRUE, 0);
2205
2206 g_signal_connect (button, "clicked",
2207 G_CALLBACK (reparent_label),
2208 event_box);
2209
2210 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
2211 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2212
2213 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
2214 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2215 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2216
2217 button = gtk_button_new_with_label ("close");
2218 g_signal_connect_swapped (button, "clicked",
2219 G_CALLBACK (gtk_widget_destroy), window);
2220 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2221 gtk_widget_set_can_default (button, TRUE);
2222 gtk_widget_grab_default (button);
2223 }
2224
2225 if (!gtk_widget_get_visible (window))
2226 gtk_widget_show_all (window);
2227 else
2228 gtk_widget_destroy (window);
2229 }
2230
2231 /*
2232 * Resize Grips
2233 */
2234 static gboolean
grippy_button_press(GtkWidget * area,GdkEventButton * event,GdkWindowEdge edge)2235 grippy_button_press (GtkWidget *area, GdkEventButton *event, GdkWindowEdge edge)
2236 {
2237 if (event->type == GDK_BUTTON_PRESS)
2238 {
2239 if (event->button == GDK_BUTTON_PRIMARY)
2240 gtk_window_begin_resize_drag (GTK_WINDOW (gtk_widget_get_toplevel (area)), edge,
2241 event->button, event->x_root, event->y_root,
2242 event->time);
2243 else if (event->button == GDK_BUTTON_MIDDLE)
2244 gtk_window_begin_move_drag (GTK_WINDOW (gtk_widget_get_toplevel (area)),
2245 event->button, event->x_root, event->y_root,
2246 event->time);
2247 }
2248 return TRUE;
2249 }
2250
2251 static gboolean
grippy_draw(GtkWidget * area,cairo_t * cr,GdkWindowEdge edge)2252 grippy_draw (GtkWidget *area, cairo_t *cr, GdkWindowEdge edge)
2253 {
2254 GtkStyleContext *context;
2255 GtkJunctionSides sides;
2256
2257 switch (edge)
2258 {
2259 case GDK_WINDOW_EDGE_NORTH_WEST:
2260 sides = GTK_JUNCTION_CORNER_TOPLEFT;
2261 break;
2262 case GDK_WINDOW_EDGE_NORTH:
2263 sides = GTK_JUNCTION_TOP;
2264 break;
2265 case GDK_WINDOW_EDGE_NORTH_EAST:
2266 sides = GTK_JUNCTION_CORNER_TOPRIGHT;
2267 break;
2268 case GDK_WINDOW_EDGE_WEST:
2269 sides = GTK_JUNCTION_LEFT;
2270 break;
2271 case GDK_WINDOW_EDGE_EAST:
2272 sides = GTK_JUNCTION_RIGHT;
2273 break;
2274 case GDK_WINDOW_EDGE_SOUTH_WEST:
2275 sides = GTK_JUNCTION_CORNER_BOTTOMLEFT;
2276 break;
2277 case GDK_WINDOW_EDGE_SOUTH:
2278 sides = GTK_JUNCTION_BOTTOM;
2279 break;
2280 case GDK_WINDOW_EDGE_SOUTH_EAST:
2281 sides = GTK_JUNCTION_CORNER_BOTTOMRIGHT;
2282 break;
2283 default:
2284 g_assert_not_reached();
2285 }
2286
2287 context = gtk_widget_get_style_context (area);
2288 gtk_style_context_save (context);
2289 gtk_style_context_add_class (context, "grip");
2290 gtk_style_context_set_junction_sides (context, sides);
2291 gtk_render_handle (context, cr,
2292 0, 0,
2293 gtk_widget_get_allocated_width (area),
2294 gtk_widget_get_allocated_height (area));
2295
2296 gtk_style_context_restore (context);
2297
2298 return TRUE;
2299 }
2300
2301 static void
create_resize_grips(GtkWidget * widget)2302 create_resize_grips (GtkWidget *widget)
2303 {
2304 static GtkWidget *window = NULL;
2305 GtkWidget *area;
2306 GtkWidget *hbox, *vbox;
2307 if (!window)
2308 {
2309 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2310
2311 gtk_window_set_screen (GTK_WINDOW (window),
2312 gtk_widget_get_screen (widget));
2313
2314 gtk_window_set_title (GTK_WINDOW (window), "resize grips");
2315
2316 g_signal_connect (window, "destroy",
2317 G_CALLBACK (gtk_widget_destroyed),
2318 &window);
2319
2320 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2321 gtk_container_add (GTK_CONTAINER (window), vbox);
2322
2323 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2324 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2325
2326 /* North west */
2327 area = gtk_drawing_area_new ();
2328 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2329 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2330 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2331 GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_WEST));
2332 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2333 GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_WEST));
2334
2335 /* North */
2336 area = gtk_drawing_area_new ();
2337 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2338 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2339 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2340 GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH));
2341 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2342 GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH));
2343
2344 /* North east */
2345 area = gtk_drawing_area_new ();
2346 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2347 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2348 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2349 GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_EAST));
2350 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2351 GINT_TO_POINTER (GDK_WINDOW_EDGE_NORTH_EAST));
2352
2353 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2354 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2355
2356 /* West */
2357 area = gtk_drawing_area_new ();
2358 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2359 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2360 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2361 GINT_TO_POINTER (GDK_WINDOW_EDGE_WEST));
2362 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2363 GINT_TO_POINTER (GDK_WINDOW_EDGE_WEST));
2364
2365 /* Middle */
2366 area = gtk_drawing_area_new ();
2367 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2368
2369 /* East */
2370 area = gtk_drawing_area_new ();
2371 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2372 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2373 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2374 GINT_TO_POINTER (GDK_WINDOW_EDGE_EAST));
2375 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2376 GINT_TO_POINTER (GDK_WINDOW_EDGE_EAST));
2377
2378
2379 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2380 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
2381
2382 /* South west */
2383 area = gtk_drawing_area_new ();
2384 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2385 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2386 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2387 GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
2388 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2389 GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_WEST));
2390 /* South */
2391 area = gtk_drawing_area_new ();
2392 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2393 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2394 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2395 GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
2396 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2397 GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH));
2398
2399 /* South east */
2400 area = gtk_drawing_area_new ();
2401 gtk_widget_add_events (area, GDK_BUTTON_PRESS_MASK);
2402 gtk_box_pack_start (GTK_BOX (hbox), area, TRUE, TRUE, 0);
2403 g_signal_connect (area, "draw", G_CALLBACK (grippy_draw),
2404 GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
2405 g_signal_connect (area, "button_press_event", G_CALLBACK (grippy_button_press),
2406 GINT_TO_POINTER (GDK_WINDOW_EDGE_SOUTH_EAST));
2407 }
2408
2409 if (!gtk_widget_get_visible (window))
2410 gtk_widget_show_all (window);
2411 else
2412 gtk_widget_destroy (window);
2413 }
2414
2415 /*
2416 * Saved Position
2417 */
2418 gint upositionx = 0;
2419 gint upositiony = 0;
2420
2421 static gint
uposition_configure(GtkWidget * window)2422 uposition_configure (GtkWidget *window)
2423 {
2424 GtkLabel *lx;
2425 GtkLabel *ly;
2426 gchar buffer[64];
2427
2428 lx = g_object_get_data (G_OBJECT (window), "x");
2429 ly = g_object_get_data (G_OBJECT (window), "y");
2430
2431 gdk_window_get_root_origin (gtk_widget_get_window (window),
2432 &upositionx, &upositiony);
2433 sprintf (buffer, "%d", upositionx);
2434 gtk_label_set_text (lx, buffer);
2435 sprintf (buffer, "%d", upositiony);
2436 gtk_label_set_text (ly, buffer);
2437
2438 return FALSE;
2439 }
2440
2441 static void
uposition_stop_configure(GtkToggleButton * toggle,GObject * window)2442 uposition_stop_configure (GtkToggleButton *toggle,
2443 GObject *window)
2444 {
2445 if (gtk_toggle_button_get_active (toggle))
2446 g_signal_handlers_block_by_func (window, G_CALLBACK (uposition_configure), NULL);
2447 else
2448 g_signal_handlers_unblock_by_func (window, G_CALLBACK (uposition_configure), NULL);
2449 }
2450
2451 static void
create_saved_position(GtkWidget * widget)2452 create_saved_position (GtkWidget *widget)
2453 {
2454 static GtkWidget *window = NULL;
2455
2456 if (!window)
2457 {
2458 GtkWidget *hbox;
2459 GtkWidget *main_vbox;
2460 GtkWidget *vbox;
2461 GtkWidget *x_label;
2462 GtkWidget *y_label;
2463 GtkWidget *button;
2464 GtkWidget *label;
2465 GtkWidget *any;
2466
2467 window = g_object_connect (g_object_new (GTK_TYPE_WINDOW,
2468 "type", GTK_WINDOW_TOPLEVEL,
2469 "title", "Saved Position",
2470 NULL),
2471 "signal::configure_event", uposition_configure, NULL,
2472 NULL);
2473
2474 gtk_window_move (GTK_WINDOW (window), upositionx, upositiony);
2475
2476 gtk_window_set_screen (GTK_WINDOW (window),
2477 gtk_widget_get_screen (widget));
2478
2479
2480 g_signal_connect (window, "destroy",
2481 G_CALLBACK (gtk_widget_destroyed),
2482 &window);
2483
2484 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
2485 gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
2486 gtk_container_add (GTK_CONTAINER (window), main_vbox);
2487
2488 vbox =
2489 g_object_new (GTK_TYPE_BOX,
2490 "orientation", GTK_ORIENTATION_VERTICAL,
2491 "GtkBox::homogeneous", FALSE,
2492 "GtkBox::spacing", 5,
2493 "GtkContainer::border_width", 10,
2494 "GtkWidget::parent", main_vbox,
2495 "GtkWidget::visible", TRUE,
2496 "child", g_object_connect (g_object_new (GTK_TYPE_TOGGLE_BUTTON,
2497 "label", "Stop Events",
2498 "active", FALSE,
2499 "visible", TRUE,
2500 NULL),
2501 "signal::clicked", uposition_stop_configure, window,
2502 NULL),
2503 NULL);
2504
2505 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2506 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2507 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2508
2509 label = gtk_label_new ("X Origin : ");
2510 gtk_widget_set_halign (label, GTK_ALIGN_START);
2511 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
2512 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2513
2514 x_label = gtk_label_new ("");
2515 gtk_box_pack_start (GTK_BOX (hbox), x_label, TRUE, TRUE, 0);
2516 g_object_set_data (G_OBJECT (window), "x", x_label);
2517
2518 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2519 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
2520 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
2521
2522 label = gtk_label_new ("Y Origin : ");
2523 gtk_widget_set_halign (label, GTK_ALIGN_START);
2524 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
2525 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
2526
2527 y_label = gtk_label_new ("");
2528 gtk_box_pack_start (GTK_BOX (hbox), y_label, TRUE, TRUE, 0);
2529 g_object_set_data (G_OBJECT (window), "y", y_label);
2530
2531 any =
2532 g_object_new (gtk_separator_get_type (),
2533 "GtkWidget::visible", TRUE,
2534 NULL);
2535 gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
2536
2537 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2538 gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
2539 gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
2540
2541 button = gtk_button_new_with_label ("Close");
2542 g_signal_connect_swapped (button, "clicked",
2543 G_CALLBACK (gtk_widget_destroy),
2544 window);
2545 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
2546 gtk_widget_set_can_default (button, TRUE);
2547 gtk_widget_grab_default (button);
2548
2549 gtk_widget_show_all (window);
2550 }
2551 else
2552 gtk_widget_destroy (window);
2553 }
2554
2555 /*
2556 * GtkPixmap
2557 */
2558
2559 static void
create_pixbuf(GtkWidget * widget)2560 create_pixbuf (GtkWidget *widget)
2561 {
2562 static GtkWidget *window = NULL;
2563 GtkWidget *box1;
2564 GtkWidget *box2;
2565 GtkWidget *box3;
2566 GtkWidget *button;
2567 GtkWidget *label;
2568 GtkWidget *separator;
2569 GtkWidget *pixbufwid;
2570 GdkWindow *gdk_window;
2571
2572 if (!window)
2573 {
2574 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2575
2576 gtk_window_set_screen (GTK_WINDOW (window),
2577 gtk_widget_get_screen (widget));
2578
2579 g_signal_connect (window, "destroy",
2580 G_CALLBACK (gtk_widget_destroyed),
2581 &window);
2582
2583 gtk_window_set_title (GTK_WINDOW (window), "GtkPixmap");
2584 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
2585 gtk_widget_realize(window);
2586
2587 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2588 gtk_container_add (GTK_CONTAINER (window), box1);
2589
2590 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
2591 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2592 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2593
2594 button = gtk_button_new ();
2595 gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
2596
2597 gdk_window = gtk_widget_get_window (window);
2598
2599 pixbufwid = new_pixbuf ("test.xpm", gdk_window);
2600
2601 label = gtk_label_new ("Pixbuf\ntest");
2602 box3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2603 gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
2604 gtk_container_add (GTK_CONTAINER (box3), pixbufwid);
2605 gtk_container_add (GTK_CONTAINER (box3), label);
2606 gtk_container_add (GTK_CONTAINER (button), box3);
2607
2608 button = gtk_button_new ();
2609 gtk_box_pack_start (GTK_BOX (box2), button, FALSE, FALSE, 0);
2610
2611 pixbufwid = new_pixbuf ("test.xpm", gdk_window);
2612
2613 label = gtk_label_new ("Pixbuf\ntest");
2614 box3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
2615 gtk_container_set_border_width (GTK_CONTAINER (box3), 2);
2616 gtk_container_add (GTK_CONTAINER (box3), pixbufwid);
2617 gtk_container_add (GTK_CONTAINER (box3), label);
2618 gtk_container_add (GTK_CONTAINER (button), box3);
2619
2620 gtk_widget_set_sensitive (button, FALSE);
2621
2622 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
2623 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2624
2625 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
2626 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2627 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2628
2629 button = gtk_button_new_with_label ("close");
2630 g_signal_connect_swapped (button, "clicked",
2631 G_CALLBACK (gtk_widget_destroy),
2632 window);
2633 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2634 gtk_widget_set_can_default (button, TRUE);
2635 gtk_widget_grab_default (button);
2636 }
2637
2638 if (!gtk_widget_get_visible (window))
2639 gtk_widget_show_all (window);
2640 else
2641 gtk_widget_destroy (window);
2642 }
2643
2644 static void
create_tooltips(GtkWidget * widget)2645 create_tooltips (GtkWidget *widget)
2646 {
2647 static GtkWidget *window = NULL;
2648 GtkWidget *box1;
2649 GtkWidget *box2;
2650 GtkWidget *box3;
2651 GtkWidget *button;
2652 GtkWidget *toggle;
2653 GtkWidget *frame;
2654 GtkWidget *separator;
2655
2656 if (!window)
2657 {
2658 window =
2659 g_object_new (gtk_window_get_type (),
2660 "GtkWindow::type", GTK_WINDOW_TOPLEVEL,
2661 "GtkContainer::border_width", 0,
2662 "GtkWindow::title", "Tooltips",
2663 "GtkWindow::resizable", FALSE,
2664 NULL);
2665
2666 gtk_window_set_screen (GTK_WINDOW (window),
2667 gtk_widget_get_screen (widget));
2668
2669 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2670 gtk_container_add (GTK_CONTAINER (window), box1);
2671
2672 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
2673 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2674 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
2675
2676 button = gtk_toggle_button_new_with_label ("button1");
2677 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2678
2679 gtk_widget_set_tooltip_text (button, "This is button 1");
2680
2681 button = gtk_toggle_button_new_with_label ("button2");
2682 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2683
2684 gtk_widget_set_tooltip_text (button,
2685 "This is button 2. This is also a really long tooltip which probably "
2686 "won't fit on a single line and will therefore need to be wrapped. "
2687 "Hopefully the wrapping will work correctly.");
2688
2689 toggle = gtk_toggle_button_new_with_label ("Override TipsQuery Label");
2690 gtk_box_pack_start (GTK_BOX (box2), toggle, TRUE, TRUE, 0);
2691
2692 gtk_widget_set_tooltip_text (toggle, "Toggle TipsQuery view.");
2693
2694 box3 =
2695 g_object_new (GTK_TYPE_BOX,
2696 "orientation", GTK_ORIENTATION_VERTICAL,
2697 "homogeneous", FALSE,
2698 "spacing", 5,
2699 "border_width", 5,
2700 "visible", TRUE,
2701 NULL);
2702
2703 button =
2704 g_object_new (gtk_button_get_type (),
2705 "label", "[?]",
2706 "visible", TRUE,
2707 "parent", box3,
2708 NULL);
2709 gtk_box_set_child_packing (GTK_BOX (box3), button, FALSE, FALSE, 0, GTK_PACK_START);
2710 gtk_widget_set_tooltip_text (button, "Start the Tooltips Inspector");
2711
2712 frame = g_object_new (gtk_frame_get_type (),
2713 "label", "ToolTips Inspector",
2714 "label_xalign", (double) 0.5,
2715 "border_width", 0,
2716 "visible", TRUE,
2717 "parent", box2,
2718 "child", box3,
2719 NULL);
2720 gtk_box_set_child_packing (GTK_BOX (box2), frame, TRUE, TRUE, 10, GTK_PACK_START);
2721
2722 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
2723 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
2724
2725 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
2726 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
2727 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
2728
2729 button = gtk_button_new_with_label ("close");
2730 g_signal_connect_swapped (button, "clicked",
2731 G_CALLBACK (gtk_widget_destroy),
2732 window);
2733 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
2734 gtk_widget_set_can_default (button, TRUE);
2735 gtk_widget_grab_default (button);
2736
2737 gtk_widget_set_tooltip_text (button, "Push this button to close window");
2738 }
2739
2740 if (!gtk_widget_get_visible (window))
2741 gtk_widget_show_all (window);
2742 else
2743 gtk_widget_destroy (window);
2744 }
2745
2746 /*
2747 * GtkImage
2748 */
2749
2750 static void
pack_image(GtkWidget * box,const gchar * text,GtkWidget * image)2751 pack_image (GtkWidget *box,
2752 const gchar *text,
2753 GtkWidget *image)
2754 {
2755 gtk_box_pack_start (GTK_BOX (box),
2756 gtk_label_new (text),
2757 FALSE, FALSE, 0);
2758
2759 gtk_box_pack_start (GTK_BOX (box),
2760 image,
2761 TRUE, TRUE, 0);
2762 }
2763
2764 static void
create_image(GtkWidget * widget)2765 create_image (GtkWidget *widget)
2766 {
2767 static GtkWidget *window = NULL;
2768
2769 if (window == NULL)
2770 {
2771 GtkWidget *vbox;
2772 GdkPixbuf *pixbuf;
2773
2774 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2775
2776 gtk_window_set_screen (GTK_WINDOW (window),
2777 gtk_widget_get_screen (widget));
2778
2779 /* this is bogus for testing drawing when allocation < request,
2780 * don't copy into real code
2781 */
2782 gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
2783
2784 g_signal_connect (window, "destroy",
2785 G_CALLBACK (gtk_widget_destroyed),
2786 &window);
2787
2788 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
2789
2790 gtk_container_add (GTK_CONTAINER (window), vbox);
2791
2792 pack_image (vbox, "Stock Warning Dialog",
2793 gtk_image_new_from_icon_name ("dialog-warning",
2794 GTK_ICON_SIZE_DIALOG));
2795
2796 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
2797
2798 pack_image (vbox, "Pixbuf",
2799 gtk_image_new_from_pixbuf (pixbuf));
2800
2801 g_object_unref (pixbuf);
2802 }
2803
2804 if (!gtk_widget_get_visible (window))
2805 gtk_widget_show_all (window);
2806 else
2807 gtk_widget_destroy (window);
2808 }
2809
2810 /*
2811 * ListBox demo
2812 */
2813
2814 static int
list_sort_cb(GtkListBoxRow * a,GtkListBoxRow * b,gpointer data)2815 list_sort_cb (GtkListBoxRow *a, GtkListBoxRow *b, gpointer data)
2816 {
2817 gint aa = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (a), "value"));
2818 gint bb = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (b), "value"));
2819 return aa - bb;
2820 }
2821
2822 static gboolean
list_filter_all_cb(GtkListBoxRow * row,gpointer data)2823 list_filter_all_cb (GtkListBoxRow *row, gpointer data)
2824 {
2825 return FALSE;
2826 }
2827
2828 static gboolean
list_filter_odd_cb(GtkListBoxRow * row,gpointer data)2829 list_filter_odd_cb (GtkListBoxRow *row, gpointer data)
2830 {
2831 gint value = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (row), "value"));
2832
2833 return value % 2 == 0;
2834 }
2835
2836 static void
list_sort_clicked_cb(GtkButton * button,gpointer data)2837 list_sort_clicked_cb (GtkButton *button,
2838 gpointer data)
2839 {
2840 GtkListBox *list = data;
2841
2842 gtk_list_box_set_sort_func (list, list_sort_cb, NULL, NULL);
2843 }
2844
2845 static void
list_filter_odd_clicked_cb(GtkButton * button,gpointer data)2846 list_filter_odd_clicked_cb (GtkButton *button,
2847 gpointer data)
2848 {
2849 GtkListBox *list = data;
2850
2851 gtk_list_box_set_filter_func (list, list_filter_odd_cb, NULL, NULL);
2852 }
2853
2854 static void
list_filter_all_clicked_cb(GtkButton * button,gpointer data)2855 list_filter_all_clicked_cb (GtkButton *button,
2856 gpointer data)
2857 {
2858 GtkListBox *list = data;
2859
2860 gtk_list_box_set_filter_func (list, list_filter_all_cb, NULL, NULL);
2861 }
2862
2863
2864 static void
list_unfilter_clicked_cb(GtkButton * button,gpointer data)2865 list_unfilter_clicked_cb (GtkButton *button,
2866 gpointer data)
2867 {
2868 GtkListBox *list = data;
2869
2870 gtk_list_box_set_filter_func (list, NULL, NULL, NULL);
2871 }
2872
2873 static void
add_placeholder_clicked_cb(GtkButton * button,gpointer data)2874 add_placeholder_clicked_cb (GtkButton *button,
2875 gpointer data)
2876 {
2877 GtkListBox *list = data;
2878 GtkWidget *label;
2879
2880 label = gtk_label_new ("You filtered everything!!!");
2881 gtk_widget_show (label);
2882 gtk_list_box_set_placeholder (GTK_LIST_BOX (list), label);
2883 }
2884
2885 static void
remove_placeholder_clicked_cb(GtkButton * button,gpointer data)2886 remove_placeholder_clicked_cb (GtkButton *button,
2887 gpointer data)
2888 {
2889 GtkListBox *list = data;
2890
2891 gtk_list_box_set_placeholder (GTK_LIST_BOX (list), NULL);
2892 }
2893
2894
2895 static void
create_listbox(GtkWidget * widget)2896 create_listbox (GtkWidget *widget)
2897 {
2898 static GtkWidget *window = NULL;
2899
2900 if (!window)
2901 {
2902 GtkWidget *hbox, *vbox, *scrolled, *scrolled_box, *list, *label, *button;
2903 GdkScreen *screen = gtk_widget_get_screen (widget);
2904 int i;
2905
2906 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
2907 gtk_window_set_screen (GTK_WINDOW (window), screen);
2908
2909 g_signal_connect (window, "destroy",
2910 G_CALLBACK (gtk_widget_destroyed),
2911 &window);
2912 g_signal_connect (window, "delete-event",
2913 G_CALLBACK (gtk_true),
2914 NULL);
2915
2916 gtk_window_set_title (GTK_WINDOW (window), "listbox");
2917
2918 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
2919 gtk_container_add (GTK_CONTAINER (window), hbox);
2920
2921 scrolled = gtk_scrolled_window_new (NULL, NULL);
2922 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
2923 gtk_container_add (GTK_CONTAINER (hbox), scrolled);
2924
2925 scrolled_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2926 gtk_container_add (GTK_CONTAINER (scrolled), scrolled_box);
2927
2928 label = gtk_label_new ("This is \na LABEL\nwith rows");
2929 gtk_container_add (GTK_CONTAINER (scrolled_box), label);
2930
2931 list = gtk_list_box_new();
2932 gtk_list_box_set_adjustment (GTK_LIST_BOX (list), gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled)));
2933 gtk_container_add (GTK_CONTAINER (scrolled_box), list);
2934
2935 for (i = 0; i < 1000; i++)
2936 {
2937 gint value = g_random_int_range (0, 10000);
2938 label = gtk_label_new (g_strdup_printf ("Value %u", value));
2939 gtk_widget_show (label);
2940 gtk_container_add (GTK_CONTAINER (list), label);
2941 g_object_set_data (G_OBJECT (gtk_widget_get_parent (label)), "value", GINT_TO_POINTER (value));
2942 }
2943
2944 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
2945 gtk_container_add (GTK_CONTAINER (hbox), vbox);
2946
2947 button = gtk_button_new_with_label ("sort");
2948 gtk_container_add (GTK_CONTAINER (vbox), button);
2949 g_signal_connect (button, "clicked", G_CALLBACK (list_sort_clicked_cb), list);
2950
2951 button = gtk_button_new_with_label ("filter odd");
2952 gtk_container_add (GTK_CONTAINER (vbox), button);
2953 g_signal_connect (button, "clicked", G_CALLBACK (list_filter_odd_clicked_cb), list);
2954
2955 button = gtk_button_new_with_label ("filter all");
2956 gtk_container_add (GTK_CONTAINER (vbox), button);
2957 g_signal_connect (button, "clicked", G_CALLBACK (list_filter_all_clicked_cb), list);
2958
2959 button = gtk_button_new_with_label ("unfilter");
2960 gtk_container_add (GTK_CONTAINER (vbox), button);
2961 g_signal_connect (button, "clicked", G_CALLBACK (list_unfilter_clicked_cb), list);
2962
2963 button = gtk_button_new_with_label ("add placeholder");
2964 gtk_container_add (GTK_CONTAINER (vbox), button);
2965 g_signal_connect (button, "clicked", G_CALLBACK (add_placeholder_clicked_cb), list);
2966
2967 button = gtk_button_new_with_label ("remove placeholder");
2968 gtk_container_add (GTK_CONTAINER (vbox), button);
2969 g_signal_connect (button, "clicked", G_CALLBACK (remove_placeholder_clicked_cb), list);
2970 }
2971
2972 if (!gtk_widget_get_visible (window))
2973 gtk_widget_show_all (window);
2974 else
2975 gtk_widget_destroy (window);
2976 }
2977
2978
2979 /*
2980 * Menu demo
2981 */
2982
2983 static GtkWidget*
create_menu(GdkScreen * screen,gint depth,gint length)2984 create_menu (GdkScreen *screen, gint depth, gint length)
2985 {
2986 GtkWidget *menu;
2987 GtkWidget *menuitem;
2988 GtkWidget *image;
2989 GSList *group;
2990 char buf[32];
2991 int i, j;
2992
2993 if (depth < 1)
2994 return NULL;
2995
2996 menu = gtk_menu_new ();
2997 gtk_menu_set_screen (GTK_MENU (menu), screen);
2998
2999 group = NULL;
3000
3001 image = gtk_image_new_from_icon_name ("document-open",
3002 GTK_ICON_SIZE_MENU);
3003 gtk_widget_show (image);
3004 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
3005 menuitem = gtk_image_menu_item_new_with_label ("Image item");
3006 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3007 gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
3008 G_GNUC_END_IGNORE_DEPRECATIONS;
3009 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3010 gtk_widget_show (menuitem);
3011
3012 for (i = 0, j = 1; i < length; i++, j++)
3013 {
3014 sprintf (buf, "item %2d - %d", depth, j);
3015
3016 menuitem = gtk_radio_menu_item_new_with_label (group, buf);
3017 group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menuitem));
3018
3019 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3020 gtk_widget_show (menuitem);
3021 if (i == 3)
3022 gtk_widget_set_sensitive (menuitem, FALSE);
3023
3024 if (i == 5)
3025 gtk_check_menu_item_set_inconsistent (GTK_CHECK_MENU_ITEM (menuitem),
3026 TRUE);
3027
3028 if (i < 5)
3029 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem),
3030 create_menu (screen, depth - 1, 5));
3031 }
3032
3033 return menu;
3034 }
3035
3036 static GtkWidget*
create_table_menu(GdkScreen * screen,gint cols,gint rows)3037 create_table_menu (GdkScreen *screen, gint cols, gint rows)
3038 {
3039 GtkWidget *menu;
3040 GtkWidget *menuitem;
3041 GtkWidget *submenu;
3042 GtkWidget *image;
3043 char buf[32];
3044 int i, j;
3045
3046 menu = gtk_menu_new ();
3047 gtk_menu_set_screen (GTK_MENU (menu), screen);
3048
3049 j = 0;
3050
3051 menuitem = gtk_menu_item_new_with_label ("items");
3052 gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
3053
3054 submenu = gtk_menu_new ();
3055 gtk_menu_set_screen (GTK_MENU (submenu), screen);
3056 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3057 gtk_widget_show (menuitem);
3058 j++;
3059
3060 /* now fill the items submenu */
3061 image = gtk_image_new_from_icon_name ("help-broswer",
3062 GTK_ICON_SIZE_MENU);
3063 gtk_widget_show (image);
3064 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
3065 menuitem = gtk_image_menu_item_new_with_label ("Image");
3066 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3067 gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
3068 G_GNUC_END_IGNORE_DEPRECATIONS;
3069 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
3070 gtk_widget_show (menuitem);
3071
3072 menuitem = gtk_menu_item_new_with_label ("x");
3073 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 0, 1);
3074 gtk_widget_show (menuitem);
3075
3076 menuitem = gtk_menu_item_new_with_label ("x");
3077 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 2);
3078 gtk_widget_show (menuitem);
3079
3080 image = gtk_image_new_from_icon_name ("help-browser",
3081 GTK_ICON_SIZE_MENU);
3082 gtk_widget_show (image);
3083 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
3084 menuitem = gtk_image_menu_item_new_with_label ("Image");
3085 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3086 gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
3087 G_GNUC_END_IGNORE_DEPRECATIONS;
3088 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
3089 gtk_widget_show (menuitem);
3090
3091 menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
3092 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 2, 3);
3093 gtk_widget_show (menuitem);
3094
3095 menuitem = gtk_menu_item_new_with_label ("x");
3096 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 2, 3);
3097 gtk_widget_show (menuitem);
3098
3099 menuitem = gtk_menu_item_new_with_label ("x");
3100 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 3, 4);
3101 gtk_widget_show (menuitem);
3102
3103 menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio");
3104 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 3, 4);
3105 gtk_widget_show (menuitem);
3106
3107 menuitem = gtk_check_menu_item_new_with_label ("Check");
3108 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 4, 5);
3109 gtk_widget_show (menuitem);
3110
3111 menuitem = gtk_menu_item_new_with_label ("x");
3112 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 4, 5);
3113 gtk_widget_show (menuitem);
3114
3115 menuitem = gtk_menu_item_new_with_label ("x");
3116 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 5, 6);
3117 gtk_widget_show (menuitem);
3118
3119 menuitem = gtk_check_menu_item_new_with_label ("Check");
3120 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 5, 6);
3121 gtk_widget_show (menuitem);
3122
3123 menuitem = gtk_menu_item_new_with_label ("1. Inserted normally (8)");
3124 gtk_widget_show (menuitem);
3125 gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 8);
3126
3127 menuitem = gtk_menu_item_new_with_label ("2. Inserted normally (2)");
3128 gtk_widget_show (menuitem);
3129 gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 2);
3130
3131 menuitem = gtk_menu_item_new_with_label ("3. Inserted normally (0)");
3132 gtk_widget_show (menuitem);
3133 gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, 0);
3134
3135 menuitem = gtk_menu_item_new_with_label ("4. Inserted normally (-1)");
3136 gtk_widget_show (menuitem);
3137 gtk_menu_shell_insert (GTK_MENU_SHELL (submenu), menuitem, -1);
3138
3139 /* end of items submenu */
3140
3141 menuitem = gtk_menu_item_new_with_label ("spanning");
3142 gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1);
3143
3144 submenu = gtk_menu_new ();
3145 gtk_menu_set_screen (GTK_MENU (submenu), screen);
3146 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3147 gtk_widget_show (menuitem);
3148 j++;
3149
3150 /* now fill the spanning submenu */
3151 menuitem = gtk_menu_item_new_with_label ("a");
3152 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 2, 0, 1);
3153 gtk_widget_show (menuitem);
3154
3155 menuitem = gtk_menu_item_new_with_label ("b");
3156 gtk_menu_attach (GTK_MENU (submenu), menuitem, 2, 3, 0, 2);
3157 gtk_widget_show (menuitem);
3158
3159 menuitem = gtk_menu_item_new_with_label ("c");
3160 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 3);
3161 gtk_widget_show (menuitem);
3162
3163 menuitem = gtk_menu_item_new_with_label ("d");
3164 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2);
3165 gtk_widget_show (menuitem);
3166
3167 menuitem = gtk_menu_item_new_with_label ("e");
3168 gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 3, 2, 3);
3169 gtk_widget_show (menuitem);
3170 /* end of spanning submenu */
3171
3172 menuitem = gtk_menu_item_new_with_label ("left");
3173 gtk_menu_attach (GTK_MENU (menu), menuitem, 0, 1, j, j + 1);
3174 submenu = gtk_menu_new ();
3175 gtk_menu_set_screen (GTK_MENU (submenu), screen);
3176 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3177 gtk_widget_show (menuitem);
3178
3179 menuitem = gtk_menu_item_new_with_label ("Empty");
3180 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
3181 submenu = gtk_menu_new ();
3182 gtk_menu_set_screen (GTK_MENU (submenu), screen);
3183 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3184 gtk_widget_show (menuitem);
3185
3186 menuitem = gtk_menu_item_new_with_label ("right");
3187 gtk_menu_attach (GTK_MENU (menu), menuitem, 1, 2, j, j + 1);
3188 submenu = gtk_menu_new ();
3189 gtk_menu_set_screen (GTK_MENU (submenu), screen);
3190 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
3191 gtk_widget_show (menuitem);
3192
3193 menuitem = gtk_menu_item_new_with_label ("Empty");
3194 gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1);
3195 gtk_widget_show (menuitem);
3196
3197 j++;
3198
3199 for (; j < rows; j++)
3200 for (i = 0; i < cols; i++)
3201 {
3202 sprintf (buf, "(%d %d)", i, j);
3203 menuitem = gtk_menu_item_new_with_label (buf);
3204 gtk_menu_attach (GTK_MENU (menu), menuitem, i, i + 1, j, j + 1);
3205 gtk_widget_show (menuitem);
3206 }
3207
3208 menuitem = gtk_menu_item_new_with_label ("1. Inserted normally (8)");
3209 gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 8);
3210 gtk_widget_show (menuitem);
3211 menuitem = gtk_menu_item_new_with_label ("2. Inserted normally (2)");
3212 gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 2);
3213 gtk_widget_show (menuitem);
3214 menuitem = gtk_menu_item_new_with_label ("3. Inserted normally (0)");
3215 gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, 0);
3216 gtk_widget_show (menuitem);
3217 menuitem = gtk_menu_item_new_with_label ("4. Inserted normally (-1)");
3218 gtk_menu_shell_insert (GTK_MENU_SHELL (menu), menuitem, -1);
3219 gtk_widget_show (menuitem);
3220
3221 return menu;
3222 }
3223
3224 static void
create_menus(GtkWidget * widget)3225 create_menus (GtkWidget *widget)
3226 {
3227 static GtkWidget *window = NULL;
3228 GtkWidget *box1;
3229 GtkWidget *box2;
3230 GtkWidget *button;
3231 GtkWidget *optionmenu;
3232 GtkWidget *separator;
3233
3234 if (!window)
3235 {
3236 GtkWidget *menubar;
3237 GtkWidget *menu;
3238 GtkWidget *menuitem;
3239 GtkAccelGroup *accel_group;
3240 GtkWidget *image;
3241 GdkScreen *screen = gtk_widget_get_screen (widget);
3242
3243 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3244
3245 gtk_window_set_screen (GTK_WINDOW (window), screen);
3246
3247 g_signal_connect (window, "destroy",
3248 G_CALLBACK (gtk_widget_destroyed),
3249 &window);
3250 g_signal_connect (window, "delete-event",
3251 G_CALLBACK (gtk_true),
3252 NULL);
3253
3254 accel_group = gtk_accel_group_new ();
3255 gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3256
3257 gtk_window_set_title (GTK_WINDOW (window), "menus");
3258 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3259
3260
3261 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3262 gtk_container_add (GTK_CONTAINER (window), box1);
3263 gtk_widget_show (box1);
3264
3265 menubar = gtk_menu_bar_new ();
3266 gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3267 gtk_widget_show (menubar);
3268
3269 menu = create_menu (screen, 2, 50);
3270
3271 menuitem = gtk_menu_item_new_with_label ("test\nline2");
3272 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3273 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3274 gtk_widget_show (menuitem);
3275
3276 menu = create_table_menu (screen, 2, 50);
3277
3278 menuitem = gtk_menu_item_new_with_label ("table");
3279 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3280 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3281 gtk_widget_show (menuitem);
3282
3283 menuitem = gtk_menu_item_new_with_label ("foo");
3284 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5));
3285 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3286 gtk_widget_show (menuitem);
3287
3288 image = gtk_image_new_from_icon_name ("help-browser",
3289 GTK_ICON_SIZE_MENU);
3290 gtk_widget_show (image);
3291 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
3292 menuitem = gtk_image_menu_item_new_with_label ("Help");
3293 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
3294 gtk_image_menu_item_set_always_show_image (GTK_IMAGE_MENU_ITEM (menuitem), TRUE);
3295 G_GNUC_END_IGNORE_DEPRECATIONS;
3296 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 4, 5));
3297 gtk_widget_set_hexpand (menuitem, TRUE);
3298 gtk_widget_set_halign (menuitem, GTK_ALIGN_END);
3299 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3300 gtk_widget_show (menuitem);
3301
3302 menubar = gtk_menu_bar_new ();
3303 gtk_box_pack_start (GTK_BOX (box1), menubar, FALSE, TRUE, 0);
3304 gtk_widget_show (menubar);
3305
3306 menu = create_menu (screen, 2, 10);
3307
3308 menuitem = gtk_menu_item_new_with_label ("Second menu bar");
3309 gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu);
3310 gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem);
3311 gtk_widget_show (menuitem);
3312
3313 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
3314 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3315 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3316 gtk_widget_show (box2);
3317
3318 menu = create_menu (screen, 1, 5);
3319 gtk_menu_set_accel_group (GTK_MENU (menu), accel_group);
3320
3321 menuitem = gtk_check_menu_item_new_with_label ("Accelerate Me");
3322 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3323 gtk_widget_show (menuitem);
3324 gtk_widget_add_accelerator (menuitem,
3325 "activate",
3326 accel_group,
3327 GDK_KEY_F1,
3328 0,
3329 GTK_ACCEL_VISIBLE);
3330 menuitem = gtk_check_menu_item_new_with_label ("Accelerator Locked");
3331 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3332 gtk_widget_show (menuitem);
3333 gtk_widget_add_accelerator (menuitem,
3334 "activate",
3335 accel_group,
3336 GDK_KEY_F2,
3337 0,
3338 GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3339 menuitem = gtk_check_menu_item_new_with_label ("Accelerators Frozen");
3340 gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
3341 gtk_widget_show (menuitem);
3342 gtk_widget_add_accelerator (menuitem,
3343 "activate",
3344 accel_group,
3345 GDK_KEY_F2,
3346 0,
3347 GTK_ACCEL_VISIBLE);
3348 gtk_widget_add_accelerator (menuitem,
3349 "activate",
3350 accel_group,
3351 GDK_KEY_F3,
3352 0,
3353 GTK_ACCEL_VISIBLE);
3354
3355 optionmenu = gtk_combo_box_text_new ();
3356 gtk_combo_box_set_active (GTK_COMBO_BOX (optionmenu), 3);
3357 gtk_box_pack_start (GTK_BOX (box2), optionmenu, TRUE, TRUE, 0);
3358 gtk_widget_show (optionmenu);
3359
3360 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
3361 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3362 gtk_widget_show (separator);
3363
3364 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
3365 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3366 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3367 gtk_widget_show (box2);
3368
3369 button = gtk_button_new_with_label ("close");
3370 g_signal_connect_swapped (button, "clicked",
3371 G_CALLBACK (gtk_widget_destroy),
3372 window);
3373 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3374 gtk_widget_set_can_default (button, TRUE);
3375 gtk_widget_grab_default (button);
3376 gtk_widget_show (button);
3377 }
3378
3379 if (!gtk_widget_get_visible (window))
3380 gtk_widget_show (window);
3381 else
3382 gtk_widget_destroy (window);
3383 }
3384
3385
3386 static GtkWidget *
accel_button_new(GtkAccelGroup * accel_group,const gchar * text,const gchar * accel)3387 accel_button_new (GtkAccelGroup *accel_group,
3388 const gchar *text,
3389 const gchar *accel)
3390 {
3391 guint keyval;
3392 GdkModifierType modifiers;
3393 GtkWidget *button;
3394 GtkWidget *label;
3395
3396 gtk_accelerator_parse (accel, &keyval, &modifiers);
3397 g_assert (keyval);
3398
3399 button = gtk_button_new ();
3400 gtk_widget_add_accelerator (button, "activate", accel_group,
3401 keyval, modifiers, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED);
3402
3403 label = gtk_accel_label_new (text);
3404 gtk_accel_label_set_accel_widget (GTK_ACCEL_LABEL (label), button);
3405 gtk_widget_show (label);
3406
3407 gtk_container_add (GTK_CONTAINER (button), label);
3408
3409 return button;
3410 }
3411
3412 static void
create_key_lookup(GtkWidget * widget)3413 create_key_lookup (GtkWidget *widget)
3414 {
3415 static GtkWidget *window = NULL;
3416 gpointer window_ptr;
3417
3418 if (!window)
3419 {
3420 GtkAccelGroup *accel_group = gtk_accel_group_new ();
3421 GtkWidget *button;
3422 GtkWidget *content_area;
3423
3424 window = gtk_dialog_new_with_buttons ("Key Lookup", NULL, 0,
3425 "_Close", GTK_RESPONSE_CLOSE,
3426 NULL);
3427
3428 gtk_window_set_screen (GTK_WINDOW (window),
3429 gtk_widget_get_screen (widget));
3430
3431 /* We have to expand it so the accel labels will draw their labels
3432 */
3433 gtk_window_set_default_size (GTK_WINDOW (window), 300, -1);
3434
3435 gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
3436
3437 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
3438
3439 button = gtk_button_new_with_mnemonic ("Button 1 (_a)");
3440 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3441 button = gtk_button_new_with_mnemonic ("Button 2 (_A)");
3442 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3443 button = gtk_button_new_with_mnemonic ("Button 3 (_\321\204)");
3444 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3445 button = gtk_button_new_with_mnemonic ("Button 4 (_\320\244)");
3446 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3447 button = gtk_button_new_with_mnemonic ("Button 6 (_b)");
3448 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3449 button = accel_button_new (accel_group, "Button 7", "<Alt><Shift>b");
3450 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3451 button = accel_button_new (accel_group, "Button 8", "<Alt>d");
3452 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3453 button = accel_button_new (accel_group, "Button 9", "<Alt>Cyrillic_ve");
3454 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3455 button = gtk_button_new_with_mnemonic ("Button 10 (_1)");
3456 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3457 button = gtk_button_new_with_mnemonic ("Button 11 (_!)");
3458 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3459 button = accel_button_new (accel_group, "Button 12", "<Super>a");
3460 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3461 button = accel_button_new (accel_group, "Button 13", "<Hyper>a");
3462 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3463 button = accel_button_new (accel_group, "Button 14", "<Meta>a");
3464 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3465 button = accel_button_new (accel_group, "Button 15", "<Shift><Mod4>b");
3466 gtk_box_pack_start (GTK_BOX (content_area), button, FALSE, FALSE, 0);
3467
3468 window_ptr = &window;
3469 g_object_add_weak_pointer (G_OBJECT (window), window_ptr);
3470 g_signal_connect (window, "response", G_CALLBACK (gtk_widget_destroy), NULL);
3471
3472 gtk_widget_show_all (window);
3473 }
3474 else
3475 gtk_widget_destroy (window);
3476 }
3477
3478
3479 /*
3480 create_modal_window
3481 */
3482
3483 static gboolean
cmw_destroy_cb(GtkWidget * widget)3484 cmw_destroy_cb(GtkWidget *widget)
3485 {
3486 /* This is needed to get out of gtk_main */
3487 gtk_main_quit ();
3488
3489 return FALSE;
3490 }
3491
3492 static void
cmw_color(GtkWidget * widget,GtkWidget * parent)3493 cmw_color (GtkWidget *widget, GtkWidget *parent)
3494 {
3495 GtkWidget *csd;
3496
3497 csd = gtk_color_chooser_dialog_new ("This is a modal color selection dialog", GTK_WINDOW (parent));
3498
3499 /* Set as modal */
3500 gtk_window_set_modal (GTK_WINDOW(csd),TRUE);
3501
3502 g_signal_connect (csd, "destroy",
3503 G_CALLBACK (cmw_destroy_cb), NULL);
3504 g_signal_connect (csd, "response",
3505 G_CALLBACK (gtk_widget_destroy), NULL);
3506
3507 /* wait until destroy calls gtk_main_quit */
3508 gtk_widget_show (csd);
3509 gtk_main ();
3510 }
3511
3512 static void
cmw_file(GtkWidget * widget,GtkWidget * parent)3513 cmw_file (GtkWidget *widget, GtkWidget *parent)
3514 {
3515 GtkWidget *fs;
3516
3517 fs = gtk_file_chooser_dialog_new ("This is a modal file selection dialog",
3518 GTK_WINDOW (parent),
3519 GTK_FILE_CHOOSER_ACTION_OPEN,
3520 "_Open", GTK_RESPONSE_ACCEPT,
3521 "_Cancel", GTK_RESPONSE_CANCEL,
3522 NULL);
3523 gtk_window_set_screen (GTK_WINDOW (fs), gtk_widget_get_screen (parent));
3524 gtk_window_set_modal (GTK_WINDOW (fs), TRUE);
3525
3526 g_signal_connect (fs, "destroy",
3527 G_CALLBACK (cmw_destroy_cb), NULL);
3528 g_signal_connect_swapped (fs, "response",
3529 G_CALLBACK (gtk_widget_destroy), fs);
3530
3531 /* wait until destroy calls gtk_main_quit */
3532 gtk_widget_show (fs);
3533 gtk_main();
3534 }
3535
3536
3537 static void
create_modal_window(GtkWidget * widget)3538 create_modal_window (GtkWidget *widget)
3539 {
3540 GtkWidget *window = NULL;
3541 GtkWidget *box1,*box2;
3542 GtkWidget *frame1;
3543 GtkWidget *btnColor,*btnFile,*btnClose;
3544
3545 /* Create modal window (Here you can use any window descendent )*/
3546 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3547 gtk_window_set_screen (GTK_WINDOW (window),
3548 gtk_widget_get_screen (widget));
3549
3550 gtk_window_set_title (GTK_WINDOW(window),"This window is modal");
3551
3552 /* Set window as modal */
3553 gtk_window_set_modal (GTK_WINDOW(window),TRUE);
3554
3555 /* Create widgets */
3556 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
3557 frame1 = gtk_frame_new ("Standard dialogs in modal form");
3558 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
3559 gtk_box_set_homogeneous (GTK_BOX (box2), TRUE);
3560 btnColor = gtk_button_new_with_label ("Color");
3561 btnFile = gtk_button_new_with_label ("File Selection");
3562 btnClose = gtk_button_new_with_label ("Close");
3563
3564 /* Init widgets */
3565 gtk_container_set_border_width (GTK_CONTAINER (box1), 3);
3566 gtk_container_set_border_width (GTK_CONTAINER (box2), 3);
3567
3568 /* Pack widgets */
3569 gtk_container_add (GTK_CONTAINER (window), box1);
3570 gtk_box_pack_start (GTK_BOX (box1), frame1, TRUE, TRUE, 4);
3571 gtk_container_add (GTK_CONTAINER (frame1), box2);
3572 gtk_box_pack_start (GTK_BOX (box2), btnColor, FALSE, FALSE, 4);
3573 gtk_box_pack_start (GTK_BOX (box2), btnFile, FALSE, FALSE, 4);
3574 gtk_box_pack_start (GTK_BOX (box1), gtk_separator_new (GTK_ORIENTATION_HORIZONTAL), FALSE, FALSE, 4);
3575 gtk_box_pack_start (GTK_BOX (box1), btnClose, FALSE, FALSE, 4);
3576
3577 /* connect signals */
3578 g_signal_connect_swapped (btnClose, "clicked",
3579 G_CALLBACK (gtk_widget_destroy), window);
3580
3581 g_signal_connect (window, "destroy",
3582 G_CALLBACK (cmw_destroy_cb), NULL);
3583
3584 g_signal_connect (btnColor, "clicked",
3585 G_CALLBACK (cmw_color), window);
3586 g_signal_connect (btnFile, "clicked",
3587 G_CALLBACK (cmw_file), window);
3588
3589 /* Show widgets */
3590 gtk_widget_show_all (window);
3591
3592 /* wait until dialog get destroyed */
3593 gtk_main();
3594 }
3595
3596 /*
3597 * GtkMessageDialog
3598 */
3599
3600 static void
make_message_dialog(GdkScreen * screen,GtkWidget ** dialog,GtkMessageType type,GtkButtonsType buttons,guint default_response)3601 make_message_dialog (GdkScreen *screen,
3602 GtkWidget **dialog,
3603 GtkMessageType type,
3604 GtkButtonsType buttons,
3605 guint default_response)
3606 {
3607 if (*dialog)
3608 {
3609 gtk_widget_destroy (*dialog);
3610
3611 return;
3612 }
3613
3614 *dialog = gtk_message_dialog_new (NULL, 0, type, buttons,
3615 "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.)");
3616
3617 gtk_window_set_screen (GTK_WINDOW (*dialog), screen);
3618
3619 g_signal_connect_swapped (*dialog,
3620 "response",
3621 G_CALLBACK (gtk_widget_destroy),
3622 *dialog);
3623
3624 g_signal_connect (*dialog,
3625 "destroy",
3626 G_CALLBACK (gtk_widget_destroyed),
3627 dialog);
3628
3629 gtk_dialog_set_default_response (GTK_DIALOG (*dialog), default_response);
3630
3631 gtk_widget_show (*dialog);
3632 }
3633
3634 static void
create_message_dialog(GtkWidget * widget)3635 create_message_dialog (GtkWidget *widget)
3636 {
3637 static GtkWidget *info = NULL;
3638 static GtkWidget *warning = NULL;
3639 static GtkWidget *error = NULL;
3640 static GtkWidget *question = NULL;
3641 GdkScreen *screen = gtk_widget_get_screen (widget);
3642
3643 make_message_dialog (screen, &info, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, GTK_RESPONSE_OK);
3644 make_message_dialog (screen, &warning, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE, GTK_RESPONSE_CLOSE);
3645 make_message_dialog (screen, &error, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK_CANCEL, GTK_RESPONSE_OK);
3646 make_message_dialog (screen, &question, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, GTK_RESPONSE_NO);
3647 }
3648
3649 /*
3650 * GtkScrolledWindow
3651 */
3652
3653 static GtkWidget *sw_parent = NULL;
3654 static GtkWidget *sw_float_parent;
3655 static gulong sw_destroyed_handler = 0;
3656
3657 static gboolean
scrolled_windows_delete_cb(GtkWidget * widget,GdkEventAny * event,GtkWidget * scrollwin)3658 scrolled_windows_delete_cb (GtkWidget *widget, GdkEventAny *event, GtkWidget *scrollwin)
3659 {
3660 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3661 gtk_widget_reparent (scrollwin, sw_parent);
3662 G_GNUC_END_IGNORE_DEPRECATIONS
3663
3664 g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
3665 sw_float_parent = NULL;
3666 sw_parent = NULL;
3667 sw_destroyed_handler = 0;
3668
3669 return FALSE;
3670 }
3671
3672 static void
scrolled_windows_destroy_cb(GtkWidget * widget,GtkWidget * scrollwin)3673 scrolled_windows_destroy_cb (GtkWidget *widget, GtkWidget *scrollwin)
3674 {
3675 gtk_widget_destroy (sw_float_parent);
3676
3677 sw_float_parent = NULL;
3678 sw_parent = NULL;
3679 sw_destroyed_handler = 0;
3680 }
3681
3682 static void
scrolled_windows_remove(GtkWidget * dialog,gint response,GtkWidget * scrollwin)3683 scrolled_windows_remove (GtkWidget *dialog, gint response, GtkWidget *scrollwin)
3684 {
3685 if (response != GTK_RESPONSE_APPLY)
3686 {
3687 gtk_widget_destroy (dialog);
3688 return;
3689 }
3690
3691 if (sw_parent)
3692 {
3693 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3694 gtk_widget_reparent (scrollwin, sw_parent);
3695 G_GNUC_END_IGNORE_DEPRECATIONS
3696 gtk_widget_destroy (sw_float_parent);
3697
3698 g_signal_handler_disconnect (sw_parent, sw_destroyed_handler);
3699 sw_float_parent = NULL;
3700 sw_parent = NULL;
3701 sw_destroyed_handler = 0;
3702 }
3703 else
3704 {
3705 sw_parent = gtk_widget_get_parent (scrollwin);
3706 sw_float_parent = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3707 gtk_window_set_screen (GTK_WINDOW (sw_float_parent),
3708 gtk_widget_get_screen (dialog));
3709
3710 gtk_window_set_default_size (GTK_WINDOW (sw_float_parent), 200, 200);
3711
3712 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
3713 gtk_widget_reparent (scrollwin, sw_float_parent);
3714 G_GNUC_END_IGNORE_DEPRECATIONS
3715 gtk_widget_show (sw_float_parent);
3716
3717 sw_destroyed_handler =
3718 g_signal_connect (sw_parent, "destroy",
3719 G_CALLBACK (scrolled_windows_destroy_cb), scrollwin);
3720 g_signal_connect (sw_float_parent, "delete_event",
3721 G_CALLBACK (scrolled_windows_delete_cb), scrollwin);
3722 }
3723 }
3724
3725 static void
create_scrolled_windows(GtkWidget * widget)3726 create_scrolled_windows (GtkWidget *widget)
3727 {
3728 static GtkWidget *window;
3729 GtkWidget *content_area;
3730 GtkWidget *scrolled_window;
3731 GtkWidget *button;
3732 GtkWidget *grid;
3733 char buffer[32];
3734 int i, j;
3735
3736 if (!window)
3737 {
3738 window = gtk_dialog_new ();
3739
3740 gtk_window_set_screen (GTK_WINDOW (window),
3741 gtk_widget_get_screen (widget));
3742
3743 g_signal_connect (window, "destroy",
3744 G_CALLBACK (gtk_widget_destroyed),
3745 &window);
3746
3747 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
3748
3749 gtk_window_set_title (GTK_WINDOW (window), "dialog");
3750 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3751
3752 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
3753 gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
3754 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
3755 GTK_POLICY_AUTOMATIC,
3756 GTK_POLICY_AUTOMATIC);
3757 gtk_box_pack_start (GTK_BOX (content_area), scrolled_window, TRUE, TRUE, 0);
3758 gtk_widget_show (scrolled_window);
3759
3760 grid = gtk_grid_new ();
3761 gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
3762 gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
3763 gtk_container_add (GTK_CONTAINER (scrolled_window), grid);
3764 gtk_container_set_focus_hadjustment (GTK_CONTAINER (grid),
3765 gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
3766 gtk_container_set_focus_vadjustment (GTK_CONTAINER (grid),
3767 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
3768 gtk_widget_show (grid);
3769
3770 for (i = 0; i < 20; i++)
3771 for (j = 0; j < 20; j++)
3772 {
3773 sprintf (buffer, "button (%d,%d)\n", i, j);
3774 button = gtk_toggle_button_new_with_label (buffer);
3775 gtk_grid_attach (GTK_GRID (grid), button, i, j, 1, 1);
3776 gtk_widget_show (button);
3777 }
3778
3779 gtk_dialog_add_button (GTK_DIALOG (window),
3780 "Close",
3781 GTK_RESPONSE_CLOSE);
3782
3783 gtk_dialog_add_button (GTK_DIALOG (window),
3784 "Reparent Out",
3785 GTK_RESPONSE_APPLY);
3786
3787 g_signal_connect (window, "response",
3788 G_CALLBACK (scrolled_windows_remove),
3789 scrolled_window);
3790
3791 gtk_window_set_default_size (GTK_WINDOW (window), 300, 300);
3792 }
3793
3794 if (!gtk_widget_get_visible (window))
3795 gtk_widget_show (window);
3796 else
3797 gtk_widget_destroy (window);
3798 }
3799
3800 /*
3801 * GtkEntry
3802 */
3803
3804 static void
entry_toggle_frame(GtkWidget * checkbutton,GtkWidget * entry)3805 entry_toggle_frame (GtkWidget *checkbutton,
3806 GtkWidget *entry)
3807 {
3808 gtk_entry_set_has_frame (GTK_ENTRY(entry),
3809 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)));
3810 }
3811
3812 static void
entry_toggle_sensitive(GtkWidget * checkbutton,GtkWidget * entry)3813 entry_toggle_sensitive (GtkWidget *checkbutton,
3814 GtkWidget *entry)
3815 {
3816 gtk_widget_set_sensitive (entry,
3817 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
3818 }
3819
3820 static gboolean
entry_progress_timeout(gpointer data)3821 entry_progress_timeout (gpointer data)
3822 {
3823 if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (data), "progress-pulse")))
3824 {
3825 gtk_entry_progress_pulse (GTK_ENTRY (data));
3826 }
3827 else
3828 {
3829 gdouble fraction;
3830
3831 fraction = gtk_entry_get_progress_fraction (GTK_ENTRY (data));
3832
3833 fraction += 0.05;
3834 if (fraction > 1.0001)
3835 fraction = 0.0;
3836
3837 gtk_entry_set_progress_fraction (GTK_ENTRY (data), fraction);
3838 }
3839
3840 return G_SOURCE_CONTINUE;
3841 }
3842
3843 static void
entry_remove_timeout(gpointer data)3844 entry_remove_timeout (gpointer data)
3845 {
3846 g_source_remove (GPOINTER_TO_UINT (data));
3847 }
3848
3849 static void
entry_toggle_progress(GtkWidget * checkbutton,GtkWidget * entry)3850 entry_toggle_progress (GtkWidget *checkbutton,
3851 GtkWidget *entry)
3852 {
3853 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)))
3854 {
3855 guint timeout = gdk_threads_add_timeout (100,
3856 entry_progress_timeout,
3857 entry);
3858 g_object_set_data_full (G_OBJECT (entry), "timeout-id",
3859 GUINT_TO_POINTER (timeout),
3860 entry_remove_timeout);
3861 }
3862 else
3863 {
3864 g_object_set_data (G_OBJECT (entry), "timeout-id",
3865 GUINT_TO_POINTER (0));
3866
3867 gtk_entry_set_progress_fraction (GTK_ENTRY (entry), 0.0);
3868 }
3869 }
3870
3871 static void
entry_toggle_pulse(GtkWidget * checkbutton,GtkWidget * entry)3872 entry_toggle_pulse (GtkWidget *checkbutton,
3873 GtkWidget *entry)
3874 {
3875 g_object_set_data (G_OBJECT (entry), "progress-pulse",
3876 GUINT_TO_POINTER ((guint) gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton))));
3877 }
3878
3879 static void
create_entry(GtkWidget * widget)3880 create_entry (GtkWidget *widget)
3881 {
3882 static GtkWidget *window = NULL;
3883 GtkWidget *box1;
3884 GtkWidget *box2;
3885 GtkWidget *hbox;
3886 GtkWidget *has_frame_check;
3887 GtkWidget *sensitive_check;
3888 GtkWidget *progress_check;
3889 GtkWidget *entry;
3890 GtkComboBoxText *cb;
3891 GtkWidget *cb_entry;
3892 GtkWidget *button;
3893 GtkWidget *separator;
3894
3895 if (!window)
3896 {
3897 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3898 gtk_window_set_screen (GTK_WINDOW (window),
3899 gtk_widget_get_screen (widget));
3900
3901 g_signal_connect (window, "destroy",
3902 G_CALLBACK (gtk_widget_destroyed),
3903 &window);
3904
3905 gtk_window_set_title (GTK_WINDOW (window), "entry");
3906 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
3907
3908
3909 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
3910 gtk_container_add (GTK_CONTAINER (window), box1);
3911
3912
3913 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
3914 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3915 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
3916
3917 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
3918 gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
3919
3920 entry = gtk_entry_new ();
3921 gtk_entry_set_text (GTK_ENTRY (entry), "hello world \330\247\331\204\330\263\331\204\330\247\331\205 \330\271\331\204\331\212\331\203\331\205");
3922 gtk_editable_select_region (GTK_EDITABLE (entry), 0, 5);
3923 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
3924
3925 cb = GTK_COMBO_BOX_TEXT (gtk_combo_box_text_new_with_entry ());
3926
3927 gtk_combo_box_text_append_text (cb, "item0");
3928 gtk_combo_box_text_append_text (cb, "item0");
3929 gtk_combo_box_text_append_text (cb, "item1 item1");
3930 gtk_combo_box_text_append_text (cb, "item2 item2 item2");
3931 gtk_combo_box_text_append_text (cb, "item3 item3 item3 item3");
3932 gtk_combo_box_text_append_text (cb, "item4 item4 item4 item4 item4");
3933 gtk_combo_box_text_append_text (cb, "item5 item5 item5 item5 item5 item5");
3934 gtk_combo_box_text_append_text (cb, "item6 item6 item6 item6 item6");
3935 gtk_combo_box_text_append_text (cb, "item7 item7 item7 item7");
3936 gtk_combo_box_text_append_text (cb, "item8 item8 item8");
3937 gtk_combo_box_text_append_text (cb, "item9 item9");
3938
3939 cb_entry = gtk_bin_get_child (GTK_BIN (cb));
3940 gtk_entry_set_text (GTK_ENTRY (cb_entry), "hello world \n\n\n foo");
3941 gtk_editable_select_region (GTK_EDITABLE (cb_entry), 0, -1);
3942 gtk_box_pack_start (GTK_BOX (box2), GTK_WIDGET (cb), TRUE, TRUE, 0);
3943
3944 sensitive_check = gtk_check_button_new_with_label("Sensitive");
3945 gtk_box_pack_start (GTK_BOX (box2), sensitive_check, FALSE, TRUE, 0);
3946 g_signal_connect (sensitive_check, "toggled",
3947 G_CALLBACK (entry_toggle_sensitive), entry);
3948 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (sensitive_check), TRUE);
3949
3950 has_frame_check = gtk_check_button_new_with_label("Has Frame");
3951 gtk_box_pack_start (GTK_BOX (box2), has_frame_check, FALSE, TRUE, 0);
3952 g_signal_connect (has_frame_check, "toggled",
3953 G_CALLBACK (entry_toggle_frame), entry);
3954 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (has_frame_check), TRUE);
3955
3956 progress_check = gtk_check_button_new_with_label("Show Progress");
3957 gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
3958 g_signal_connect (progress_check, "toggled",
3959 G_CALLBACK (entry_toggle_progress), entry);
3960
3961 progress_check = gtk_check_button_new_with_label("Pulse Progress");
3962 gtk_box_pack_start (GTK_BOX (box2), progress_check, FALSE, TRUE, 0);
3963 g_signal_connect (progress_check, "toggled",
3964 G_CALLBACK (entry_toggle_pulse), entry);
3965
3966 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
3967 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
3968
3969 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
3970 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
3971 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
3972
3973 button = gtk_button_new_with_label ("close");
3974 g_signal_connect_swapped (button, "clicked",
3975 G_CALLBACK (gtk_widget_destroy),
3976 window);
3977 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
3978 gtk_widget_set_can_default (button, TRUE);
3979 gtk_widget_grab_default (button);
3980 }
3981
3982 if (!gtk_widget_get_visible (window))
3983 gtk_widget_show_all (window);
3984 else
3985 gtk_widget_destroy (window);
3986 }
3987
3988 static void
create_expander(GtkWidget * widget)3989 create_expander (GtkWidget *widget)
3990 {
3991 GtkWidget *box1;
3992 GtkWidget *expander;
3993 GtkWidget *hidden;
3994 static GtkWidget *window = NULL;
3995
3996 if (!window)
3997 {
3998 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
3999 gtk_window_set_screen (GTK_WINDOW (window),
4000 gtk_widget_get_screen (widget));
4001
4002 g_signal_connect (window, "destroy",
4003 G_CALLBACK (gtk_widget_destroyed),
4004 &window);
4005
4006 gtk_window_set_title (GTK_WINDOW (window), "expander");
4007 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4008
4009 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4010 gtk_container_add (GTK_CONTAINER (window), box1);
4011
4012 expander = gtk_expander_new ("The Hidden");
4013
4014 gtk_box_pack_start (GTK_BOX (box1), expander, TRUE, TRUE, 0);
4015
4016 hidden = gtk_label_new ("Revealed!");
4017
4018 gtk_container_add (GTK_CONTAINER (expander), hidden);
4019 }
4020
4021 if (!gtk_widget_get_visible (window))
4022 gtk_widget_show_all (window);
4023 else
4024 gtk_widget_destroy (window);
4025 }
4026
4027
4028 /* GtkEventBox */
4029
4030
4031 static gboolean
event_box_draw(GtkWidget * widget,cairo_t * cr,gpointer user_data)4032 event_box_draw (GtkWidget *widget,
4033 cairo_t *cr,
4034 gpointer user_data)
4035 {
4036 if (gtk_widget_get_window (widget) ==
4037 gtk_widget_get_window (gtk_widget_get_parent (widget)))
4038 return FALSE;
4039
4040 cairo_set_source_rgb (cr, 0, 1, 0);
4041 cairo_paint (cr);
4042
4043 return FALSE;
4044 }
4045
4046 static void
event_box_label_pressed(GtkWidget * widget,GdkEventButton * event,gpointer user_data)4047 event_box_label_pressed (GtkWidget *widget,
4048 GdkEventButton *event,
4049 gpointer user_data)
4050 {
4051 g_print ("clicked on event box\n");
4052 }
4053
4054 static void
event_box_button_clicked(GtkWidget * widget,GtkWidget * button,gpointer user_data)4055 event_box_button_clicked (GtkWidget *widget,
4056 GtkWidget *button,
4057 gpointer user_data)
4058 {
4059 g_print ("pushed button\n");
4060 }
4061
4062 static void
event_box_toggle_visible_window(GtkWidget * checkbutton,GtkEventBox * event_box)4063 event_box_toggle_visible_window (GtkWidget *checkbutton,
4064 GtkEventBox *event_box)
4065 {
4066 gtk_event_box_set_visible_window (event_box,
4067 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)));
4068 }
4069
4070 static void
event_box_toggle_above_child(GtkWidget * checkbutton,GtkEventBox * event_box)4071 event_box_toggle_above_child (GtkWidget *checkbutton,
4072 GtkEventBox *event_box)
4073 {
4074 gtk_event_box_set_above_child (event_box,
4075 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (checkbutton)));
4076 }
4077
4078 static void
create_event_box(GtkWidget * widget)4079 create_event_box (GtkWidget *widget)
4080 {
4081 static GtkWidget *window = NULL;
4082 GtkWidget *box1;
4083 GtkWidget *box2;
4084 GtkWidget *hbox;
4085 GtkWidget *vbox;
4086 GtkWidget *button;
4087 GtkWidget *separator;
4088 GtkWidget *event_box;
4089 GtkWidget *label;
4090 GtkWidget *visible_window_check;
4091 GtkWidget *above_child_check;
4092
4093 if (!window)
4094 {
4095 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4096 gtk_window_set_screen (GTK_WINDOW (window),
4097 gtk_widget_get_screen (widget));
4098
4099 g_signal_connect (window, "destroy",
4100 G_CALLBACK (gtk_widget_destroyed),
4101 &window);
4102
4103 gtk_window_set_title (GTK_WINDOW (window), "event box");
4104 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
4105
4106 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4107 gtk_container_add (GTK_CONTAINER (window), box1);
4108
4109 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4110 gtk_box_pack_start (GTK_BOX (box1), hbox, TRUE, FALSE, 0);
4111
4112 event_box = gtk_event_box_new ();
4113 gtk_box_pack_start (GTK_BOX (hbox), event_box, TRUE, FALSE, 0);
4114
4115 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4116 gtk_container_add (GTK_CONTAINER (event_box), vbox);
4117 g_signal_connect (event_box, "button_press_event",
4118 G_CALLBACK (event_box_label_pressed),
4119 NULL);
4120 g_signal_connect (event_box, "draw",
4121 G_CALLBACK (event_box_draw),
4122 NULL);
4123
4124 label = gtk_label_new ("Click on this label");
4125 gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, FALSE, 0);
4126
4127 button = gtk_button_new_with_label ("button in eventbox");
4128 gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, FALSE, 0);
4129 g_signal_connect (button, "clicked",
4130 G_CALLBACK (event_box_button_clicked),
4131 NULL);
4132
4133
4134 visible_window_check = gtk_check_button_new_with_label("Visible Window");
4135 gtk_box_pack_start (GTK_BOX (box1), visible_window_check, FALSE, TRUE, 0);
4136 g_signal_connect (visible_window_check, "toggled",
4137 G_CALLBACK (event_box_toggle_visible_window), event_box);
4138 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (visible_window_check), TRUE);
4139
4140 above_child_check = gtk_check_button_new_with_label("Above Child");
4141 gtk_box_pack_start (GTK_BOX (box1), above_child_check, FALSE, TRUE, 0);
4142 g_signal_connect (above_child_check, "toggled",
4143 G_CALLBACK (event_box_toggle_above_child), event_box);
4144 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (above_child_check), FALSE);
4145
4146 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
4147 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
4148
4149 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
4150 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
4151 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
4152
4153 button = gtk_button_new_with_label ("close");
4154 g_signal_connect_swapped (button, "clicked",
4155 G_CALLBACK (gtk_widget_destroy),
4156 window);
4157 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
4158 gtk_widget_set_can_default (button, TRUE);
4159 gtk_widget_grab_default (button);
4160 }
4161
4162 if (!gtk_widget_get_visible (window))
4163 gtk_widget_show_all (window);
4164 else
4165 gtk_widget_destroy (window);
4166 }
4167
4168
4169 /*
4170 * GtkSizeGroup
4171 */
4172
4173 #define SIZE_GROUP_INITIAL_SIZE 50
4174
4175 static void
size_group_hsize_changed(GtkSpinButton * spin_button,GtkWidget * button)4176 size_group_hsize_changed (GtkSpinButton *spin_button,
4177 GtkWidget *button)
4178 {
4179 gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
4180 gtk_spin_button_get_value_as_int (spin_button),
4181 -1);
4182 }
4183
4184 static void
size_group_vsize_changed(GtkSpinButton * spin_button,GtkWidget * button)4185 size_group_vsize_changed (GtkSpinButton *spin_button,
4186 GtkWidget *button)
4187 {
4188 gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (button)),
4189 -1,
4190 gtk_spin_button_get_value_as_int (spin_button));
4191 }
4192
4193 static GtkWidget *
create_size_group_window(GdkScreen * screen,GtkSizeGroup * master_size_group)4194 create_size_group_window (GdkScreen *screen,
4195 GtkSizeGroup *master_size_group)
4196 {
4197 GtkWidget *content_area;
4198 GtkWidget *window;
4199 GtkWidget *grid;
4200 GtkWidget *main_button;
4201 GtkWidget *button;
4202 GtkWidget *spin_button;
4203 GtkWidget *hbox;
4204 GtkSizeGroup *hgroup1;
4205 GtkSizeGroup *hgroup2;
4206 GtkSizeGroup *vgroup1;
4207 GtkSizeGroup *vgroup2;
4208
4209 window = gtk_dialog_new_with_buttons ("GtkSizeGroup",
4210 NULL, 0,
4211 "_Close",
4212 GTK_RESPONSE_NONE,
4213 NULL);
4214
4215 gtk_window_set_screen (GTK_WINDOW (window), screen);
4216
4217 gtk_window_set_resizable (GTK_WINDOW (window), TRUE);
4218
4219 g_signal_connect (window, "response",
4220 G_CALLBACK (gtk_widget_destroy),
4221 NULL);
4222
4223 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
4224
4225 grid = gtk_grid_new ();
4226 gtk_box_pack_start (GTK_BOX (content_area), grid, TRUE, TRUE, 0);
4227
4228 gtk_grid_set_row_spacing (GTK_GRID (grid), 5);
4229 gtk_grid_set_column_spacing (GTK_GRID (grid), 5);
4230 gtk_container_set_border_width (GTK_CONTAINER (grid), 5);
4231 gtk_widget_set_size_request (grid, 250, 250);
4232
4233 hgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4234 hgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
4235 vgroup1 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4236 vgroup2 = gtk_size_group_new (GTK_SIZE_GROUP_VERTICAL);
4237
4238 main_button = gtk_button_new_with_label ("X");
4239 gtk_widget_set_hexpand (main_button, TRUE);
4240 gtk_widget_set_vexpand (main_button, TRUE);
4241 gtk_widget_set_halign (main_button, GTK_ALIGN_CENTER);
4242 gtk_widget_set_valign (main_button, GTK_ALIGN_CENTER);
4243 gtk_grid_attach (GTK_GRID (grid), main_button, 0, 0, 1, 1);
4244
4245 gtk_size_group_add_widget (master_size_group, main_button);
4246 gtk_size_group_add_widget (hgroup1, main_button);
4247 gtk_size_group_add_widget (vgroup1, main_button);
4248 gtk_widget_set_size_request (gtk_bin_get_child (GTK_BIN (main_button)),
4249 SIZE_GROUP_INITIAL_SIZE,
4250 SIZE_GROUP_INITIAL_SIZE);
4251
4252 button = gtk_button_new ();
4253 gtk_widget_set_hexpand (button, TRUE);
4254 gtk_widget_set_vexpand (button, TRUE);
4255 gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
4256 gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
4257 gtk_grid_attach (GTK_GRID (grid), button, 1, 0, 1, 1);
4258
4259 gtk_size_group_add_widget (vgroup1, button);
4260 gtk_size_group_add_widget (vgroup2, button);
4261
4262 button = gtk_button_new ();
4263 gtk_widget_set_hexpand (button, TRUE);
4264 gtk_widget_set_vexpand (button, TRUE);
4265 gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
4266 gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
4267 gtk_grid_attach (GTK_GRID (grid), button, 0, 1, 1, 1);
4268
4269 gtk_size_group_add_widget (hgroup1, button);
4270 gtk_size_group_add_widget (hgroup2, button);
4271
4272 button = gtk_button_new ();
4273 gtk_widget_set_hexpand (button, TRUE);
4274 gtk_widget_set_vexpand (button, TRUE);
4275 gtk_widget_set_halign (button, GTK_ALIGN_CENTER);
4276 gtk_widget_set_valign (button, GTK_ALIGN_CENTER);
4277 gtk_grid_attach (GTK_GRID (grid), button, 1, 1, 1, 1);
4278
4279 gtk_size_group_add_widget (hgroup2, button);
4280 gtk_size_group_add_widget (vgroup2, button);
4281
4282 g_object_unref (hgroup1);
4283 g_object_unref (hgroup2);
4284 g_object_unref (vgroup1);
4285 g_object_unref (vgroup2);
4286
4287 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
4288 gtk_box_pack_start (GTK_BOX (content_area), hbox, FALSE, FALSE, 0);
4289
4290 spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4291 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4292 gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4293 g_signal_connect (spin_button, "value_changed",
4294 G_CALLBACK (size_group_hsize_changed), main_button);
4295
4296 spin_button = gtk_spin_button_new_with_range (1, 100, 1);
4297 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spin_button), SIZE_GROUP_INITIAL_SIZE);
4298 gtk_box_pack_start (GTK_BOX (hbox), spin_button, TRUE, TRUE, 0);
4299 g_signal_connect (spin_button, "value_changed",
4300 G_CALLBACK (size_group_vsize_changed), main_button);
4301
4302 return window;
4303 }
4304
4305 static void
create_size_groups(GtkWidget * widget)4306 create_size_groups (GtkWidget *widget)
4307 {
4308 static GtkWidget *window1 = NULL;
4309 static GtkWidget *window2 = NULL;
4310 static GtkSizeGroup *master_size_group;
4311
4312 if (!master_size_group)
4313 master_size_group = gtk_size_group_new (GTK_SIZE_GROUP_BOTH);
4314
4315 if (!window1)
4316 {
4317 window1 = create_size_group_window (gtk_widget_get_screen (widget),
4318 master_size_group);
4319
4320 g_signal_connect (window1, "destroy",
4321 G_CALLBACK (gtk_widget_destroyed),
4322 &window1);
4323 }
4324
4325 if (!window2)
4326 {
4327 window2 = create_size_group_window (gtk_widget_get_screen (widget),
4328 master_size_group);
4329
4330 g_signal_connect (window2, "destroy",
4331 G_CALLBACK (gtk_widget_destroyed),
4332 &window2);
4333 }
4334
4335 if (gtk_widget_get_visible (window1) && gtk_widget_get_visible (window2))
4336 {
4337 gtk_widget_destroy (window1);
4338 gtk_widget_destroy (window2);
4339 }
4340 else
4341 {
4342 if (!gtk_widget_get_visible (window1))
4343 gtk_widget_show_all (window1);
4344 if (!gtk_widget_get_visible (window2))
4345 gtk_widget_show_all (window2);
4346 }
4347 }
4348
4349 /*
4350 * GtkSpinButton
4351 */
4352
4353 static GtkWidget *spinner1;
4354
4355 static void
toggle_snap(GtkWidget * widget,GtkSpinButton * spin)4356 toggle_snap (GtkWidget *widget, GtkSpinButton *spin)
4357 {
4358 gtk_spin_button_set_snap_to_ticks (spin,
4359 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
4360 }
4361
4362 static void
toggle_numeric(GtkWidget * widget,GtkSpinButton * spin)4363 toggle_numeric (GtkWidget *widget, GtkSpinButton *spin)
4364 {
4365 gtk_spin_button_set_numeric (spin,
4366 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)));
4367 }
4368
4369 static void
change_digits(GtkWidget * widget,GtkSpinButton * spin)4370 change_digits (GtkWidget *widget, GtkSpinButton *spin)
4371 {
4372 gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spinner1),
4373 gtk_spin_button_get_value_as_int (spin));
4374 }
4375
4376 static void
get_value(GtkWidget * widget,gpointer data)4377 get_value (GtkWidget *widget, gpointer data)
4378 {
4379 gchar buf[32];
4380 GtkLabel *label;
4381 GtkSpinButton *spin;
4382
4383 spin = GTK_SPIN_BUTTON (spinner1);
4384 label = GTK_LABEL (g_object_get_data (G_OBJECT (widget), "user_data"));
4385 if (GPOINTER_TO_INT (data) == 1)
4386 sprintf (buf, "%d", gtk_spin_button_get_value_as_int (spin));
4387 else
4388 sprintf (buf, "%0.*f",
4389 gtk_spin_button_get_digits (spin),
4390 gtk_spin_button_get_value (spin));
4391
4392 gtk_label_set_text (label, buf);
4393 }
4394
4395 static void
get_spin_value(GtkWidget * widget,gpointer data)4396 get_spin_value (GtkWidget *widget, gpointer data)
4397 {
4398 gchar *buffer;
4399 GtkLabel *label;
4400 GtkSpinButton *spin;
4401
4402 spin = GTK_SPIN_BUTTON (widget);
4403 label = GTK_LABEL (data);
4404
4405 buffer = g_strdup_printf ("%0.*f",
4406 gtk_spin_button_get_digits (spin),
4407 gtk_spin_button_get_value (spin));
4408 gtk_label_set_text (label, buffer);
4409
4410 g_free (buffer);
4411 }
4412
4413 static gint
spin_button_time_output_func(GtkSpinButton * spin_button)4414 spin_button_time_output_func (GtkSpinButton *spin_button)
4415 {
4416 GtkAdjustment *adjustment;
4417 static gchar buf[6];
4418 gdouble hours;
4419 gdouble minutes;
4420
4421 adjustment = gtk_spin_button_get_adjustment (spin_button);
4422 hours = gtk_adjustment_get_value (adjustment) / 60.0;
4423 minutes = (fabs(floor (hours) - hours) < 1e-5) ? 0.0 : 30;
4424 sprintf (buf, "%02.0f:%02.0f", floor (hours), minutes);
4425 if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4426 gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4427 return TRUE;
4428 }
4429
4430 static gint
spin_button_month_input_func(GtkSpinButton * spin_button,gdouble * new_val)4431 spin_button_month_input_func (GtkSpinButton *spin_button,
4432 gdouble *new_val)
4433 {
4434 gint i;
4435 static gchar *month[12] = { "January", "February", "March", "April",
4436 "May", "June", "July", "August",
4437 "September", "October", "November", "December" };
4438 gchar *tmp1, *tmp2;
4439 gboolean found = FALSE;
4440
4441 for (i = 1; i <= 12; i++)
4442 {
4443 tmp1 = g_ascii_strup (month[i - 1], -1);
4444 tmp2 = g_ascii_strup (gtk_entry_get_text (GTK_ENTRY (spin_button)), -1);
4445 if (strstr (tmp1, tmp2) == tmp1)
4446 found = TRUE;
4447 g_free (tmp1);
4448 g_free (tmp2);
4449 if (found)
4450 break;
4451 }
4452 if (!found)
4453 {
4454 *new_val = 0.0;
4455 return GTK_INPUT_ERROR;
4456 }
4457 *new_val = (gdouble) i;
4458 return TRUE;
4459 }
4460
4461 static gint
spin_button_month_output_func(GtkSpinButton * spin_button)4462 spin_button_month_output_func (GtkSpinButton *spin_button)
4463 {
4464 GtkAdjustment *adjustment;
4465 gdouble value;
4466 gint i;
4467 static gchar *month[12] = { "January", "February", "March", "April",
4468 "May", "June", "July", "August", "September",
4469 "October", "November", "December" };
4470
4471 adjustment = gtk_spin_button_get_adjustment (spin_button);
4472 value = gtk_adjustment_get_value (adjustment);
4473 for (i = 1; i <= 12; i++)
4474 if (fabs (value - (double)i) < 1e-5)
4475 {
4476 if (strcmp (month[i-1], gtk_entry_get_text (GTK_ENTRY (spin_button))))
4477 gtk_entry_set_text (GTK_ENTRY (spin_button), month[i-1]);
4478 }
4479 return TRUE;
4480 }
4481
4482 static gint
spin_button_hex_input_func(GtkSpinButton * spin_button,gdouble * new_val)4483 spin_button_hex_input_func (GtkSpinButton *spin_button,
4484 gdouble *new_val)
4485 {
4486 const gchar *buf;
4487 gchar *err;
4488 gdouble res;
4489
4490 buf = gtk_entry_get_text (GTK_ENTRY (spin_button));
4491 res = strtol(buf, &err, 16);
4492 *new_val = res;
4493 if (*err)
4494 return GTK_INPUT_ERROR;
4495 else
4496 return TRUE;
4497 }
4498
4499 static gint
spin_button_hex_output_func(GtkSpinButton * spin_button)4500 spin_button_hex_output_func (GtkSpinButton *spin_button)
4501 {
4502 GtkAdjustment *adjustment;
4503 static gchar buf[7];
4504 gint val;
4505
4506 adjustment = gtk_spin_button_get_adjustment (spin_button);
4507 val = (gint) gtk_adjustment_get_value (adjustment);
4508 if (fabs (val) < 1e-5)
4509 sprintf (buf, "0x00");
4510 else
4511 sprintf (buf, "0x%.2X", val);
4512 if (strcmp (buf, gtk_entry_get_text (GTK_ENTRY (spin_button))))
4513 gtk_entry_set_text (GTK_ENTRY (spin_button), buf);
4514 return TRUE;
4515 }
4516
4517 static void
create_spins(GtkWidget * widget)4518 create_spins (GtkWidget *widget)
4519 {
4520 static GtkWidget *window = NULL;
4521 GtkWidget *frame;
4522 GtkWidget *hbox;
4523 GtkWidget *main_vbox;
4524 GtkWidget *vbox;
4525 GtkWidget *vbox2;
4526 GtkWidget *spinner2;
4527 GtkWidget *spinner;
4528 GtkWidget *button;
4529 GtkWidget *label;
4530 GtkWidget *val_label;
4531 GtkAdjustment *adjustment;
4532
4533 if (!window)
4534 {
4535 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4536 gtk_window_set_screen (GTK_WINDOW (window),
4537 gtk_widget_get_screen (widget));
4538
4539 g_signal_connect (window, "destroy",
4540 G_CALLBACK (gtk_widget_destroyed),
4541 &window);
4542
4543 gtk_window_set_title (GTK_WINDOW (window), "GtkSpinButton");
4544
4545 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
4546 gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 10);
4547 gtk_container_add (GTK_CONTAINER (window), main_vbox);
4548
4549 frame = gtk_frame_new ("Not accelerated");
4550 gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4551
4552 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4553 gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4554 gtk_container_add (GTK_CONTAINER (frame), vbox);
4555
4556 /* Time, month, hex spinners */
4557
4558 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4559 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 5);
4560
4561 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4562 gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4563
4564 label = gtk_label_new ("Time :");
4565 gtk_widget_set_halign (label, GTK_ALIGN_START);
4566 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4567 gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4568
4569 adjustment = gtk_adjustment_new (0, 0, 1410, 30, 60, 0);
4570 spinner = gtk_spin_button_new (adjustment, 0, 0);
4571 gtk_editable_set_editable (GTK_EDITABLE (spinner), FALSE);
4572 g_signal_connect (spinner,
4573 "output",
4574 G_CALLBACK (spin_button_time_output_func),
4575 NULL);
4576 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4577 gtk_entry_set_width_chars (GTK_ENTRY (spinner), 5);
4578 gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4579
4580 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4581 gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4582
4583 label = gtk_label_new ("Month :");
4584 gtk_widget_set_halign (label, GTK_ALIGN_START);
4585 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4586 gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4587
4588 adjustment = gtk_adjustment_new (1.0, 1.0, 12.0, 1.0,
4589 5.0, 0.0);
4590 spinner = gtk_spin_button_new (adjustment, 0, 0);
4591 gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (spinner),
4592 GTK_UPDATE_IF_VALID);
4593 g_signal_connect (spinner,
4594 "input",
4595 G_CALLBACK (spin_button_month_input_func),
4596 NULL);
4597 g_signal_connect (spinner,
4598 "output",
4599 G_CALLBACK (spin_button_month_output_func),
4600 NULL);
4601 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4602 gtk_entry_set_width_chars (GTK_ENTRY (spinner), 9);
4603 gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4604
4605 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4606 gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 5);
4607
4608 label = gtk_label_new ("Hex :");
4609 gtk_widget_set_halign (label, GTK_ALIGN_START);
4610 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4611 gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4612
4613 adjustment = gtk_adjustment_new (0, 0, 255, 1, 16, 0);
4614 spinner = gtk_spin_button_new (adjustment, 0, 0);
4615 gtk_editable_set_editable (GTK_EDITABLE (spinner), TRUE);
4616 g_signal_connect (spinner,
4617 "input",
4618 G_CALLBACK (spin_button_hex_input_func),
4619 NULL);
4620 g_signal_connect (spinner,
4621 "output",
4622 G_CALLBACK (spin_button_hex_output_func),
4623 NULL);
4624 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner), TRUE);
4625 gtk_entry_set_width_chars (GTK_ENTRY (spinner), 4);
4626 gtk_box_pack_start (GTK_BOX (vbox2), spinner, FALSE, TRUE, 0);
4627
4628 frame = gtk_frame_new ("Accelerated");
4629 gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4630
4631 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4632 gtk_container_set_border_width (GTK_CONTAINER (vbox), 5);
4633 gtk_container_add (GTK_CONTAINER (frame), vbox);
4634
4635 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4636 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4637
4638 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4639 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4640
4641 label = gtk_label_new ("Value :");
4642 gtk_widget_set_halign (label, GTK_ALIGN_START);
4643 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4644 gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4645
4646 adjustment = gtk_adjustment_new (0.0, -10000.0, 10000.0,
4647 0.5, 100.0, 0.0);
4648 spinner1 = gtk_spin_button_new (adjustment, 1.0, 2);
4649 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (spinner1), TRUE);
4650 gtk_box_pack_start (GTK_BOX (vbox2), spinner1, FALSE, TRUE, 0);
4651
4652 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
4653 gtk_box_pack_start (GTK_BOX (hbox), vbox2, FALSE, FALSE, 5);
4654
4655 label = gtk_label_new ("Digits :");
4656 gtk_widget_set_halign (label, GTK_ALIGN_START);
4657 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
4658 gtk_box_pack_start (GTK_BOX (vbox2), label, FALSE, TRUE, 0);
4659
4660 adjustment = gtk_adjustment_new (2, 1, 15, 1, 1, 0);
4661 spinner2 = gtk_spin_button_new (adjustment, 0.0, 0);
4662 g_signal_connect (adjustment, "value_changed",
4663 G_CALLBACK (change_digits),
4664 spinner2);
4665 gtk_box_pack_start (GTK_BOX (vbox2), spinner2, FALSE, TRUE, 0);
4666
4667 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4668 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 5);
4669
4670 button = gtk_check_button_new_with_label ("Snap to 0.5-ticks");
4671 g_signal_connect (button, "clicked",
4672 G_CALLBACK (toggle_snap),
4673 spinner1);
4674 gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4675 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4676
4677 button = gtk_check_button_new_with_label ("Numeric only input mode");
4678 g_signal_connect (button, "clicked",
4679 G_CALLBACK (toggle_numeric),
4680 spinner1);
4681 gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
4682 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
4683
4684 val_label = gtk_label_new ("");
4685
4686 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4687 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
4688
4689 button = gtk_button_new_with_label ("Value as Int");
4690 g_object_set_data (G_OBJECT (button), "user_data", val_label);
4691 g_signal_connect (button, "clicked",
4692 G_CALLBACK (get_value),
4693 GINT_TO_POINTER (1));
4694 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4695
4696 button = gtk_button_new_with_label ("Value as Float");
4697 g_object_set_data (G_OBJECT (button), "user_data", val_label);
4698 g_signal_connect (button, "clicked",
4699 G_CALLBACK (get_value),
4700 GINT_TO_POINTER (2));
4701 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4702
4703 gtk_box_pack_start (GTK_BOX (vbox), val_label, TRUE, TRUE, 0);
4704 gtk_label_set_text (GTK_LABEL (val_label), "0");
4705
4706 frame = gtk_frame_new ("Using Convenience Constructor");
4707 gtk_box_pack_start (GTK_BOX (main_vbox), frame, TRUE, TRUE, 0);
4708
4709 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4710 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
4711 gtk_container_add (GTK_CONTAINER (frame), hbox);
4712
4713 val_label = gtk_label_new ("0.0");
4714
4715 spinner = gtk_spin_button_new_with_range (0.0, 10.0, 0.009);
4716 gtk_spin_button_set_value (GTK_SPIN_BUTTON (spinner), 0.0);
4717 g_signal_connect (spinner, "value_changed",
4718 G_CALLBACK (get_spin_value), val_label);
4719 gtk_box_pack_start (GTK_BOX (hbox), spinner, TRUE, TRUE, 5);
4720 gtk_box_pack_start (GTK_BOX (hbox), val_label, TRUE, TRUE, 5);
4721
4722 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
4723 gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
4724
4725 button = gtk_button_new_with_label ("Close");
4726 g_signal_connect_swapped (button, "clicked",
4727 G_CALLBACK (gtk_widget_destroy),
4728 window);
4729 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
4730 }
4731
4732 if (!gtk_widget_get_visible (window))
4733 gtk_widget_show_all (window);
4734 else
4735 gtk_widget_destroy (window);
4736 }
4737
4738
4739 /*
4740 * Cursors
4741 */
4742
4743 static gint
cursor_draw(GtkWidget * widget,cairo_t * cr,gpointer user_data)4744 cursor_draw (GtkWidget *widget,
4745 cairo_t *cr,
4746 gpointer user_data)
4747 {
4748 int width, height;
4749
4750 width = gtk_widget_get_allocated_width (widget);
4751 height = gtk_widget_get_allocated_height (widget);
4752
4753 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
4754 cairo_rectangle (cr, 0, 0, width, height);
4755 cairo_rectangle (cr, width / 3, height / 3, width / 3, height / 3);
4756 cairo_clip (cr);
4757
4758 cairo_set_source_rgb (cr, 1, 1, 1);
4759 cairo_rectangle (cr, 0, 0, width, height / 2);
4760 cairo_fill (cr);
4761
4762 cairo_set_source_rgb (cr, 0, 0, 0);
4763 cairo_rectangle (cr, 0, height / 2, width, height / 2);
4764 cairo_fill (cr);
4765
4766 return TRUE;
4767 }
4768
4769 static const gchar *cursor_names[] = {
4770 "all-scroll",
4771 "arrow",
4772 "bd_double_arrow",
4773 "boat",
4774 "bottom_left_corner",
4775 "bottom_right_corner",
4776 "bottom_side",
4777 "bottom_tee",
4778 "box_spiral",
4779 "center_ptr",
4780 "circle",
4781 "clock",
4782 "coffee_mug",
4783 "copy",
4784 "cross",
4785 "crossed_circle",
4786 "cross_reverse",
4787 "crosshair",
4788 "diamond_cross",
4789 "dnd-ask",
4790 "dnd-copy",
4791 "dnd-link",
4792 "dnd-move",
4793 "dnd-none",
4794 "dot",
4795 "dotbox",
4796 "double_arrow",
4797 "draft_large",
4798 "draft_small",
4799 "draped_box",
4800 "exchange",
4801 "fd_double_arrow",
4802 "fleur",
4803 "gobbler",
4804 "gumby",
4805 "grab",
4806 "grabbing",
4807 "hand",
4808 "hand1",
4809 "hand2",
4810 "heart",
4811 "h_double_arrow",
4812 "help",
4813 "icon",
4814 "iron_cross",
4815 "left_ptr",
4816 "left_ptr_help",
4817 "left_ptr_watch",
4818 "left_side",
4819 "left_tee",
4820 "leftbutton",
4821 "link",
4822 "ll_angle",
4823 "lr_angle",
4824 "man",
4825 "middlebutton",
4826 "mouse",
4827 "move",
4828 "pencil",
4829 "pirate",
4830 "plus",
4831 "question_arrow",
4832 "right_ptr",
4833 "right_side",
4834 "right_tee",
4835 "rightbutton",
4836 "rtl_logo",
4837 "sailboat",
4838 "sb_down_arrow",
4839 "sb_h_double_arrow",
4840 "sb_left_arrow",
4841 "sb_right_arrow",
4842 "sb_up_arrow",
4843 "sb_v_double_arrow",
4844 "shuttle",
4845 "sizing",
4846 "spider",
4847 "spraycan",
4848 "star",
4849 "target",
4850 "tcross",
4851 "top_left_arrow",
4852 "top_left_corner",
4853 "top_right_corner",
4854 "top_side",
4855 "top_tee",
4856 "trek",
4857 "ul_angle",
4858 "umbrella",
4859 "ur_angle",
4860 "v_double_arrow",
4861 "vertical-text",
4862 "watch",
4863 "X_cursor",
4864 "xterm",
4865 "zoom-in",
4866 "zoom-out"
4867 };
4868
4869 static GtkTreeModel *
cursor_model(void)4870 cursor_model (void)
4871 {
4872 GtkListStore *store;
4873 gint i;
4874 store = gtk_list_store_new (1, G_TYPE_STRING);
4875
4876 for (i = 0; i < G_N_ELEMENTS (cursor_names); i++)
4877 gtk_list_store_insert_with_values (store, NULL, -1, 0, cursor_names[i], -1);
4878
4879 return (GtkTreeModel *)store;
4880 }
4881
4882 static gint
cursor_event(GtkWidget * widget,GdkEvent * event,GtkWidget * entry)4883 cursor_event (GtkWidget *widget,
4884 GdkEvent *event,
4885 GtkWidget *entry)
4886 {
4887 const gchar *name;
4888 gint i;
4889 const gint n = G_N_ELEMENTS (cursor_names);
4890
4891 name = (const gchar *)g_object_get_data (G_OBJECT (widget), "name");
4892 if (name != NULL)
4893 {
4894 for (i = 0; i < n; i++)
4895 if (strcmp (name, cursor_names[i]) == 0)
4896 break;
4897 }
4898 else
4899 i = 0;
4900
4901 if ((event->type == GDK_BUTTON_PRESS) &&
4902 ((event->button.button == GDK_BUTTON_PRIMARY) ||
4903 (event->button.button == GDK_BUTTON_SECONDARY)))
4904 {
4905 if (event->button.button == GDK_BUTTON_PRIMARY)
4906 i = (i + 1) % n;
4907 else
4908 i = (i + n - 1) % n;
4909
4910 gtk_entry_set_text (GTK_ENTRY (entry), cursor_names[i]);
4911
4912 return TRUE;
4913 }
4914
4915 return FALSE;
4916 }
4917
4918 static void
set_cursor_from_name(GtkWidget * entry,GtkWidget * widget)4919 set_cursor_from_name (GtkWidget *entry,
4920 GtkWidget *widget)
4921 {
4922 const gchar *name;
4923 GdkCursor *cursor;
4924
4925 name = gtk_entry_get_text (GTK_ENTRY (entry));
4926 cursor = gdk_cursor_new_from_name (gtk_widget_get_display (widget), name);
4927
4928 if (cursor == NULL)
4929 {
4930 name = NULL;
4931 cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget), GDK_BLANK_CURSOR);
4932 }
4933
4934 gdk_window_set_cursor (gtk_widget_get_window (widget), cursor);
4935 g_object_unref (cursor);
4936
4937 g_object_set_data_full (G_OBJECT (widget), "name", g_strdup (name), g_free);
4938 }
4939
4940 #ifdef GDK_WINDOWING_X11
4941 #include "x11/gdkx.h"
4942 #endif
4943 #ifdef GDK_WINDOWING_WAYLAND
4944 #include "wayland/gdkwayland.h"
4945 #endif
4946
4947 static void
change_cursor_theme(GtkWidget * widget,gpointer data)4948 change_cursor_theme (GtkWidget *widget,
4949 gpointer data)
4950 {
4951 #if defined(GDK_WINDOWING_X11) || defined (GDK_WINDOWING_WAYLAND)
4952 const gchar *theme;
4953 gint size;
4954 GList *children;
4955 GdkDisplay *display;
4956
4957 children = gtk_container_get_children (GTK_CONTAINER (data));
4958
4959 theme = gtk_entry_get_text (GTK_ENTRY (children->next->data));
4960 size = (gint) gtk_spin_button_get_value (GTK_SPIN_BUTTON (children->next->next->data));
4961
4962 g_list_free (children);
4963
4964 display = gtk_widget_get_display (widget);
4965 #ifdef GDK_WINDOWING_X11
4966 if (GDK_IS_X11_DISPLAY (display))
4967 gdk_x11_display_set_cursor_theme (display, theme, size);
4968 #endif
4969 #ifdef GDK_WINDOWING_WAYLAND
4970 if (GDK_IS_WAYLAND_DISPLAY (display))
4971 gdk_wayland_display_set_cursor_theme (display, theme, size);
4972 #endif
4973 #endif
4974 }
4975
4976
4977 static void
create_cursors(GtkWidget * widget)4978 create_cursors (GtkWidget *widget)
4979 {
4980 static GtkWidget *window = NULL;
4981 GtkWidget *frame;
4982 GtkWidget *hbox;
4983 GtkWidget *main_vbox;
4984 GtkWidget *vbox;
4985 GtkWidget *darea;
4986 GtkWidget *button;
4987 GtkWidget *label;
4988 GtkWidget *any;
4989 GtkWidget *entry;
4990 GtkWidget *size;
4991 GtkEntryCompletion *completion;
4992 GtkTreeModel *model;
4993 gboolean cursor_demo = FALSE;
4994
4995 if (!window)
4996 {
4997 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
4998 gtk_window_set_screen (GTK_WINDOW (window),
4999 gtk_widget_get_screen (widget));
5000
5001 g_signal_connect (window, "destroy",
5002 G_CALLBACK (gtk_widget_destroyed),
5003 &window);
5004
5005 gtk_window_set_title (GTK_WINDOW (window), "Cursors");
5006
5007 main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
5008 gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 0);
5009 gtk_container_add (GTK_CONTAINER (window), main_vbox);
5010
5011 vbox =
5012 g_object_new (GTK_TYPE_BOX,
5013 "orientation", GTK_ORIENTATION_VERTICAL,
5014 "GtkBox::homogeneous", FALSE,
5015 "GtkBox::spacing", 5,
5016 "GtkContainer::border_width", 10,
5017 "GtkWidget::parent", main_vbox,
5018 "GtkWidget::visible", TRUE,
5019 NULL);
5020
5021 #ifdef GDK_WINDOWING_X11
5022 if (GDK_IS_X11_DISPLAY (gtk_widget_get_display (vbox)))
5023 cursor_demo = TRUE;
5024 #endif
5025 #ifdef GDK_WINDOWING_WAYLAND
5026 if (GDK_IS_WAYLAND_DISPLAY (gtk_widget_get_display (vbox)))
5027 cursor_demo = TRUE;
5028 #endif
5029
5030 if (cursor_demo)
5031 {
5032 guint w, h;
5033
5034 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
5035 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5036 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5037
5038 label = gtk_label_new ("Cursor Theme:");
5039 gtk_widget_set_halign (label, GTK_ALIGN_START);
5040 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
5041 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5042
5043 entry = gtk_entry_new ();
5044 gtk_entry_set_text (GTK_ENTRY (entry), "default");
5045 gtk_box_pack_start (GTK_BOX (hbox), entry, FALSE, TRUE, 0);
5046
5047 gdk_display_get_maximal_cursor_size (gtk_widget_get_display (vbox), &w, &h);
5048 size = gtk_spin_button_new_with_range (1.0, MIN (w, h), 1.0);
5049 gtk_spin_button_set_value (GTK_SPIN_BUTTON (size), 24.0);
5050 gtk_box_pack_start (GTK_BOX (hbox), size, TRUE, TRUE, 0);
5051
5052 g_signal_connect (entry, "changed",
5053 G_CALLBACK (change_cursor_theme), hbox);
5054 g_signal_connect (size, "value-changed",
5055 G_CALLBACK (change_cursor_theme), hbox);
5056 }
5057
5058 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
5059 gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
5060 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
5061
5062 label = gtk_label_new ("Cursor Name:");
5063 gtk_widget_set_halign (label, GTK_ALIGN_START);
5064 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
5065 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
5066
5067 entry = gtk_entry_new ();
5068 completion = gtk_entry_completion_new ();
5069 model = cursor_model ();
5070 gtk_entry_completion_set_model (completion, model);
5071 gtk_entry_completion_set_text_column (completion, 0);
5072 gtk_entry_set_completion (GTK_ENTRY (entry), completion);
5073 g_object_unref (model);
5074 gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
5075
5076 frame =
5077 g_object_new (gtk_frame_get_type (),
5078 "GtkFrame::label_xalign", 0.5,
5079 "GtkFrame::label", "Cursor Area",
5080 "GtkContainer::border_width", 10,
5081 "GtkWidget::parent", vbox,
5082 "GtkWidget::visible", TRUE,
5083 NULL);
5084
5085 darea = gtk_drawing_area_new ();
5086 gtk_widget_set_size_request (darea, 80, 80);
5087 gtk_container_add (GTK_CONTAINER (frame), darea);
5088 g_signal_connect (darea,
5089 "draw",
5090 G_CALLBACK (cursor_draw),
5091 NULL);
5092 gtk_widget_set_events (darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
5093 g_signal_connect (darea, "button_press_event",
5094 G_CALLBACK (cursor_event), entry);
5095 gtk_widget_show (darea);
5096
5097 g_signal_connect (entry, "changed",
5098 G_CALLBACK (set_cursor_from_name), darea);
5099
5100
5101 any = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
5102 gtk_box_pack_start (GTK_BOX (main_vbox), any, FALSE, TRUE, 0);
5103
5104 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
5105 gtk_container_set_border_width (GTK_CONTAINER (hbox), 10);
5106 gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, TRUE, 0);
5107
5108 button = gtk_button_new_with_label ("Close");
5109 g_signal_connect_swapped (button, "clicked",
5110 G_CALLBACK (gtk_widget_destroy),
5111 window);
5112 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
5113
5114 gtk_widget_show_all (window);
5115
5116 gtk_entry_set_text (GTK_ENTRY (entry), "arrow");
5117 }
5118 else
5119 gtk_widget_destroy (window);
5120 }
5121
5122 /*
5123 * GtkColorSelection
5124 */
5125
5126 void
create_color_selection(GtkWidget * widget)5127 create_color_selection (GtkWidget *widget)
5128 {
5129 static GtkWidget *window = NULL;
5130
5131 if (!window)
5132 {
5133 GtkWidget *picker;
5134 GtkWidget *hbox;
5135 GtkWidget *label;
5136
5137 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5138 gtk_window_set_screen (GTK_WINDOW (window),
5139 gtk_widget_get_screen (widget));
5140
5141 g_signal_connect (window, "destroy",
5142 G_CALLBACK (gtk_widget_destroyed),
5143 &window);
5144
5145 gtk_window_set_title (GTK_WINDOW (window), "GtkColorButton");
5146 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5147
5148 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
5149 gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5150 gtk_container_add (GTK_CONTAINER (window), hbox);
5151
5152 label = gtk_label_new ("Pick a color");
5153 gtk_container_add (GTK_CONTAINER (hbox), label);
5154
5155 picker = gtk_color_button_new ();
5156 gtk_color_chooser_set_use_alpha (GTK_COLOR_CHOOSER (picker), TRUE);
5157 gtk_container_add (GTK_CONTAINER (hbox), picker);
5158 }
5159
5160 if (!gtk_widget_get_visible (window))
5161 gtk_widget_show_all (window);
5162 else
5163 gtk_widget_destroy (window);
5164 }
5165
5166 void
flipping_toggled_cb(GtkWidget * widget,gpointer data)5167 flipping_toggled_cb (GtkWidget *widget, gpointer data)
5168 {
5169 int state = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
5170 int new_direction = state ? GTK_TEXT_DIR_RTL : GTK_TEXT_DIR_LTR;
5171
5172 gtk_widget_set_default_direction (new_direction);
5173 }
5174
5175 static void
orientable_toggle_orientation(GtkOrientable * orientable)5176 orientable_toggle_orientation (GtkOrientable *orientable)
5177 {
5178 GtkOrientation orientation;
5179
5180 orientation = gtk_orientable_get_orientation (orientable);
5181 gtk_orientable_set_orientation (orientable,
5182 orientation == GTK_ORIENTATION_HORIZONTAL ?
5183 GTK_ORIENTATION_VERTICAL :
5184 GTK_ORIENTATION_HORIZONTAL);
5185
5186 if (GTK_IS_CONTAINER (orientable))
5187 {
5188 GList *children;
5189 GList *child;
5190
5191 children = gtk_container_get_children (GTK_CONTAINER (orientable));
5192
5193 for (child = children; child; child = child->next)
5194 {
5195 if (GTK_IS_ORIENTABLE (child->data))
5196 orientable_toggle_orientation (child->data);
5197 }
5198
5199 g_list_free (children);
5200 }
5201 }
5202
5203 void
flipping_orientation_toggled_cb(GtkWidget * widget,gpointer data)5204 flipping_orientation_toggled_cb (GtkWidget *widget, gpointer data)
5205 {
5206 GtkWidget *content_area;
5207 GtkWidget *toplevel;
5208
5209 toplevel = gtk_widget_get_toplevel (widget);
5210 content_area = gtk_dialog_get_content_area (GTK_DIALOG (toplevel));
5211 orientable_toggle_orientation (GTK_ORIENTABLE (content_area));
5212 }
5213
5214 static void
set_direction_recurse(GtkWidget * widget,gpointer data)5215 set_direction_recurse (GtkWidget *widget,
5216 gpointer data)
5217 {
5218 GtkTextDirection *dir = data;
5219
5220 gtk_widget_set_direction (widget, *dir);
5221 if (GTK_IS_CONTAINER (widget))
5222 gtk_container_foreach (GTK_CONTAINER (widget),
5223 set_direction_recurse,
5224 data);
5225 }
5226
5227 static GtkWidget *
create_forward_back(const char * title,GtkTextDirection text_dir)5228 create_forward_back (const char *title,
5229 GtkTextDirection text_dir)
5230 {
5231 GtkWidget *frame = gtk_frame_new (title);
5232 GtkWidget *bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
5233 GtkWidget *back_button = gtk_button_new_with_label ("Back");
5234 GtkWidget *forward_button = gtk_button_new_with_label ("Forward");
5235
5236 gtk_container_set_border_width (GTK_CONTAINER (bbox), 5);
5237
5238 gtk_container_add (GTK_CONTAINER (frame), bbox);
5239 gtk_container_add (GTK_CONTAINER (bbox), back_button);
5240 gtk_container_add (GTK_CONTAINER (bbox), forward_button);
5241
5242 set_direction_recurse (frame, &text_dir);
5243
5244 return frame;
5245 }
5246
5247 void
create_flipping(GtkWidget * widget)5248 create_flipping (GtkWidget *widget)
5249 {
5250 static GtkWidget *window = NULL;
5251 GtkWidget *check_button;
5252 GtkWidget *content_area;
5253
5254 if (!window)
5255 {
5256 window = gtk_dialog_new ();
5257
5258 gtk_window_set_screen (GTK_WINDOW (window),
5259 gtk_widget_get_screen (widget));
5260
5261 g_signal_connect (window, "destroy",
5262 G_CALLBACK (gtk_widget_destroyed),
5263 &window);
5264
5265 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5266
5267 gtk_window_set_title (GTK_WINDOW (window), "Bidirectional Flipping");
5268
5269 check_button = gtk_check_button_new_with_label ("Right-to-left global direction");
5270 gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
5271 gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
5272
5273 if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
5274 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button), TRUE);
5275
5276 g_signal_connect (check_button, "toggled",
5277 G_CALLBACK (flipping_toggled_cb), NULL);
5278
5279 check_button = gtk_check_button_new_with_label ("Toggle orientation of all boxes");
5280 gtk_container_set_border_width (GTK_CONTAINER (check_button), 10);
5281 gtk_box_pack_start (GTK_BOX (content_area), check_button, TRUE, TRUE, 0);
5282
5283 g_signal_connect (check_button, "toggled",
5284 G_CALLBACK (flipping_orientation_toggled_cb), NULL);
5285
5286 gtk_box_pack_start (GTK_BOX (content_area),
5287 create_forward_back ("Default", GTK_TEXT_DIR_NONE),
5288 TRUE, TRUE, 0);
5289
5290 gtk_box_pack_start (GTK_BOX (content_area),
5291 create_forward_back ("Left-to-Right", GTK_TEXT_DIR_LTR),
5292 TRUE, TRUE, 0);
5293
5294 gtk_box_pack_start (GTK_BOX (content_area),
5295 create_forward_back ("Right-to-Left", GTK_TEXT_DIR_RTL),
5296 TRUE, TRUE, 0);
5297
5298 gtk_dialog_add_button (GTK_DIALOG (window), "Close", GTK_RESPONSE_CLOSE);
5299 g_signal_connect (window, "response", G_CALLBACK (gtk_widget_destroy), NULL);
5300 }
5301
5302 if (!gtk_widget_get_visible (window))
5303 gtk_widget_show_all (window);
5304 else
5305 gtk_widget_destroy (window);
5306 }
5307
5308 /*
5309 * Focus test
5310 */
5311
5312 static GtkWidget*
make_focus_table(GList ** list)5313 make_focus_table (GList **list)
5314 {
5315 GtkWidget *grid;
5316 gint i, j;
5317
5318 grid = gtk_grid_new ();
5319
5320 gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
5321 gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
5322
5323 for (i = 0; i < 5; i++)
5324 {
5325 for (j = 0; j < 5; j++)
5326 {
5327 GtkWidget *widget;
5328
5329 if ((i + j) % 2)
5330 widget = gtk_entry_new ();
5331 else
5332 widget = gtk_button_new_with_label ("Foo");
5333
5334 *list = g_list_prepend (*list, widget);
5335
5336 gtk_widget_set_hexpand (widget, TRUE);
5337 gtk_widget_set_vexpand (widget, TRUE);
5338
5339 gtk_grid_attach (GTK_GRID (grid), widget, i, j, 1, 1);
5340 }
5341 }
5342
5343 *list = g_list_reverse (*list);
5344
5345 return grid;
5346 }
5347
5348 static void
create_focus(GtkWidget * widget)5349 create_focus (GtkWidget *widget)
5350 {
5351 static GtkWidget *window = NULL;
5352
5353 if (!window)
5354 {
5355 GtkWidget *content_area;
5356 GtkWidget *table;
5357 GtkWidget *frame;
5358 GList *list = NULL;
5359
5360 window = gtk_dialog_new_with_buttons ("Keyboard focus navigation",
5361 NULL, 0,
5362 "_Close",
5363 GTK_RESPONSE_NONE,
5364 NULL);
5365
5366 gtk_window_set_screen (GTK_WINDOW (window),
5367 gtk_widget_get_screen (widget));
5368
5369 g_signal_connect (window, "destroy",
5370 G_CALLBACK (gtk_widget_destroyed),
5371 &window);
5372
5373 g_signal_connect (window, "response",
5374 G_CALLBACK (gtk_widget_destroy),
5375 NULL);
5376
5377 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
5378
5379 gtk_window_set_title (GTK_WINDOW (window), "Keyboard Focus Navigation");
5380
5381 frame = gtk_frame_new ("Weird tab focus chain");
5382
5383 gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5384
5385 table = make_focus_table (&list);
5386
5387 gtk_container_add (GTK_CONTAINER (frame), table);
5388
5389 gtk_container_set_focus_chain (GTK_CONTAINER (table),
5390 list);
5391
5392 g_list_free (list);
5393
5394 frame = gtk_frame_new ("Default tab focus chain");
5395
5396 gtk_box_pack_start (GTK_BOX (content_area), frame, TRUE, TRUE, 0);
5397
5398 list = NULL;
5399 table = make_focus_table (&list);
5400
5401 g_list_free (list);
5402
5403 gtk_container_add (GTK_CONTAINER (frame), table);
5404 }
5405
5406 if (!gtk_widget_get_visible (window))
5407 gtk_widget_show_all (window);
5408 else
5409 gtk_widget_destroy (window);
5410 }
5411
5412 /*
5413 * GtkFontSelection
5414 */
5415
5416 void
create_font_selection(GtkWidget * widget)5417 create_font_selection (GtkWidget *widget)
5418 {
5419 static GtkWidget *window = NULL;
5420
5421 if (!window)
5422 {
5423 GtkWidget *picker;
5424 GtkWidget *hbox;
5425 GtkWidget *label;
5426
5427 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5428 gtk_window_set_screen (GTK_WINDOW (window),
5429 gtk_widget_get_screen (widget));
5430
5431 g_signal_connect (window, "destroy",
5432 G_CALLBACK (gtk_widget_destroyed),
5433 &window);
5434
5435 gtk_window_set_title (GTK_WINDOW (window), "GtkFontButton");
5436 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5437
5438 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
5439 gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
5440 gtk_container_add (GTK_CONTAINER (window), hbox);
5441
5442 label = gtk_label_new ("Pick a font");
5443 gtk_container_add (GTK_CONTAINER (hbox), label);
5444
5445 picker = gtk_font_button_new ();
5446 gtk_font_button_set_use_font (GTK_FONT_BUTTON (picker), TRUE);
5447 gtk_container_add (GTK_CONTAINER (hbox), picker);
5448 }
5449
5450 if (!gtk_widget_get_visible (window))
5451 gtk_widget_show_all (window);
5452 else
5453 gtk_widget_destroy (window);
5454 }
5455
5456 /*
5457 * GtkDialog
5458 */
5459
5460 static GtkWidget *dialog_window = NULL;
5461
5462 static void
dialog_response_cb(GtkWidget * widget,gint response,gpointer unused)5463 dialog_response_cb (GtkWidget *widget, gint response, gpointer unused)
5464 {
5465 GtkWidget *content_area;
5466 GList *l, *children;
5467
5468 if (response == GTK_RESPONSE_APPLY)
5469 {
5470 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog_window));
5471 children = gtk_container_get_children (GTK_CONTAINER (content_area));
5472
5473 for (l = children; l; l = l->next)
5474 {
5475 if (GTK_IS_LABEL (l->data))
5476 {
5477 gtk_container_remove (GTK_CONTAINER (content_area), l->data);
5478 break;
5479 }
5480 }
5481
5482 /* no label removed, so add one */
5483 if (l == NULL)
5484 {
5485 GtkWidget *label;
5486
5487 label = gtk_label_new ("Dialog Test");
5488 g_object_set (label, "margin", 10, NULL);
5489 gtk_box_pack_start (GTK_BOX (content_area),
5490 label, TRUE, TRUE, 0);
5491 gtk_widget_show (label);
5492 }
5493
5494 g_list_free (children);
5495 }
5496 }
5497
5498 static void
create_dialog(GtkWidget * widget)5499 create_dialog (GtkWidget *widget)
5500 {
5501 if (!dialog_window)
5502 {
5503 /* This is a terrible example; it's much simpler to create
5504 * dialogs than this. Don't use testgtk for example code,
5505 * use gtk-demo ;-)
5506 */
5507
5508 dialog_window = gtk_dialog_new ();
5509 gtk_window_set_screen (GTK_WINDOW (dialog_window),
5510 gtk_widget_get_screen (widget));
5511
5512 g_signal_connect (dialog_window, "destroy",
5513 G_CALLBACK (gtk_widget_destroyed),
5514 &dialog_window);
5515
5516
5517 gtk_window_set_title (GTK_WINDOW (dialog_window), "GtkDialog");
5518 gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5519
5520 gtk_dialog_add_button (GTK_DIALOG (dialog_window),
5521 "OK",
5522 GTK_RESPONSE_OK);
5523
5524 gtk_dialog_add_button (GTK_DIALOG (dialog_window),
5525 "Toggle",
5526 GTK_RESPONSE_APPLY);
5527
5528 g_signal_connect (dialog_window, "response",
5529 G_CALLBACK (dialog_response_cb),
5530 NULL);
5531 }
5532
5533 if (!gtk_widget_get_visible (dialog_window))
5534 gtk_widget_show (dialog_window);
5535 else
5536 gtk_widget_destroy (dialog_window);
5537 }
5538
5539 /* Display & Screen test
5540 */
5541
5542 typedef struct
5543 {
5544 GtkWidget *combo;
5545 GtkWidget *entry;
5546 GtkWidget *toplevel;
5547 GtkWidget *dialog_window;
5548 } ScreenDisplaySelection;
5549
5550 static void
screen_display_check(GtkWidget * widget,ScreenDisplaySelection * data)5551 screen_display_check (GtkWidget *widget, ScreenDisplaySelection *data)
5552 {
5553 const gchar *display_name;
5554 GdkDisplay *display;
5555 GtkWidget *dialog;
5556 GdkScreen *new_screen = NULL;
5557 GdkScreen *current_screen = gtk_widget_get_screen (widget);
5558
5559 display_name = gtk_entry_get_text (GTK_ENTRY (data->entry));
5560 display = gdk_display_open (display_name);
5561
5562 if (!display)
5563 {
5564 dialog = gtk_message_dialog_new (GTK_WINDOW (gtk_widget_get_toplevel (widget)),
5565 GTK_DIALOG_DESTROY_WITH_PARENT,
5566 GTK_MESSAGE_ERROR,
5567 GTK_BUTTONS_OK,
5568 "The display :\n%s\ncannot be opened",
5569 display_name);
5570 gtk_window_set_screen (GTK_WINDOW (dialog), current_screen);
5571 gtk_widget_show (dialog);
5572 g_signal_connect (dialog, "response",
5573 G_CALLBACK (gtk_widget_destroy),
5574 NULL);
5575 }
5576 else
5577 {
5578 GtkTreeModel *model = gtk_combo_box_get_model (GTK_COMBO_BOX (data->combo));
5579 gint i = 0;
5580 GtkTreeIter iter;
5581 gboolean found = FALSE;
5582 while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i++))
5583 {
5584 gchar *name;
5585 gtk_tree_model_get (model, &iter, 0, &name, -1);
5586 found = !g_ascii_strcasecmp (display_name, name);
5587 g_free (name);
5588
5589 if (found)
5590 break;
5591 }
5592 if (!found)
5593 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (data->combo), display_name);
5594 new_screen = gdk_display_get_default_screen (display);
5595
5596 gtk_window_set_screen (GTK_WINDOW (data->toplevel), new_screen);
5597 gtk_widget_destroy (data->dialog_window);
5598 }
5599 }
5600
5601 void
screen_display_destroy_diag(GtkWidget * widget,GtkWidget * data)5602 screen_display_destroy_diag (GtkWidget *widget, GtkWidget *data)
5603 {
5604 gtk_widget_destroy (data);
5605 }
5606
5607 void
create_display_screen(GtkWidget * widget)5608 create_display_screen (GtkWidget *widget)
5609 {
5610 GtkWidget *grid, *frame, *window, *combo_dpy, *vbox;
5611 GtkWidget *label_dpy, *applyb, *cancelb;
5612 GtkWidget *bbox;
5613 ScreenDisplaySelection *scr_dpy_data;
5614 GdkScreen *screen = gtk_widget_get_screen (widget);
5615
5616 window = g_object_new (gtk_window_get_type (),
5617 "screen", screen,
5618 "type", GTK_WINDOW_TOPLEVEL,
5619 "title", "Screen or Display selection",
5620 "border_width",
5621 10, NULL);
5622 g_signal_connect (window, "destroy",
5623 G_CALLBACK (gtk_widget_destroy), NULL);
5624
5625 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 3);
5626 gtk_container_add (GTK_CONTAINER (window), vbox);
5627
5628 frame = gtk_frame_new ("Select display");
5629 gtk_container_add (GTK_CONTAINER (vbox), frame);
5630
5631 grid = gtk_grid_new ();
5632 gtk_grid_set_row_spacing (GTK_GRID (grid), 3);
5633 gtk_grid_set_column_spacing (GTK_GRID (grid), 3);
5634
5635 gtk_container_add (GTK_CONTAINER (frame), grid);
5636
5637 label_dpy = gtk_label_new ("move to another X display");
5638 combo_dpy = gtk_combo_box_text_new_with_entry ();
5639 gtk_widget_set_hexpand (combo_dpy, TRUE);
5640 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo_dpy), "diabolo:0.0");
5641 gtk_entry_set_text (GTK_ENTRY (gtk_bin_get_child (GTK_BIN (combo_dpy))),
5642 "<hostname>:<X Server Num>.<Screen Num>");
5643
5644 gtk_grid_attach (GTK_GRID (grid), label_dpy, 0, 0, 1, 1);
5645 gtk_grid_attach (GTK_GRID (grid), combo_dpy, 0, 1, 1, 1);
5646
5647 bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
5648 applyb = gtk_button_new_with_label ("_Apply");
5649 cancelb = gtk_button_new_with_label ("_Cancel");
5650
5651 gtk_container_add (GTK_CONTAINER (vbox), bbox);
5652
5653 gtk_container_add (GTK_CONTAINER (bbox), applyb);
5654 gtk_container_add (GTK_CONTAINER (bbox), cancelb);
5655
5656 scr_dpy_data = g_new0 (ScreenDisplaySelection, 1);
5657
5658 scr_dpy_data->entry = gtk_bin_get_child (GTK_BIN (combo_dpy));
5659 scr_dpy_data->toplevel = gtk_widget_get_toplevel (widget);
5660 scr_dpy_data->dialog_window = window;
5661
5662 g_signal_connect (cancelb, "clicked",
5663 G_CALLBACK (screen_display_destroy_diag), window);
5664 g_signal_connect (applyb, "clicked",
5665 G_CALLBACK (screen_display_check), scr_dpy_data);
5666 gtk_widget_show_all (window);
5667 }
5668
5669 /* Event Watcher
5670 */
5671 static gulong event_watcher_enter_id = 0;
5672 static gulong event_watcher_leave_id = 0;
5673
5674 static gboolean
event_watcher(GSignalInvocationHint * ihint,guint n_param_values,const GValue * param_values,gpointer data)5675 event_watcher (GSignalInvocationHint *ihint,
5676 guint n_param_values,
5677 const GValue *param_values,
5678 gpointer data)
5679 {
5680 g_print ("Watch: \"%s\" emitted for %s\n",
5681 g_signal_name (ihint->signal_id),
5682 G_OBJECT_TYPE_NAME (g_value_get_object (param_values + 0)));
5683
5684 return TRUE;
5685 }
5686
5687 static void
event_watcher_down(void)5688 event_watcher_down (void)
5689 {
5690 if (event_watcher_enter_id)
5691 {
5692 guint signal_id;
5693
5694 signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5695 g_signal_remove_emission_hook (signal_id, event_watcher_enter_id);
5696 event_watcher_enter_id = 0;
5697 signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5698 g_signal_remove_emission_hook (signal_id, event_watcher_leave_id);
5699 event_watcher_leave_id = 0;
5700 }
5701 }
5702
5703 static void
event_watcher_toggle(void)5704 event_watcher_toggle (void)
5705 {
5706 if (event_watcher_enter_id)
5707 event_watcher_down ();
5708 else
5709 {
5710 guint signal_id;
5711
5712 signal_id = g_signal_lookup ("enter_notify_event", GTK_TYPE_WIDGET);
5713 event_watcher_enter_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5714 signal_id = g_signal_lookup ("leave_notify_event", GTK_TYPE_WIDGET);
5715 event_watcher_leave_id = g_signal_add_emission_hook (signal_id, 0, event_watcher, NULL, NULL);
5716 }
5717 }
5718
5719 static void
create_event_watcher(GtkWidget * widget)5720 create_event_watcher (GtkWidget *widget)
5721 {
5722 GtkWidget *content_area;
5723 GtkWidget *button;
5724
5725 if (!dialog_window)
5726 {
5727 dialog_window = gtk_dialog_new ();
5728 gtk_window_set_screen (GTK_WINDOW (dialog_window),
5729 gtk_widget_get_screen (widget));
5730
5731 g_signal_connect (dialog_window, "destroy",
5732 G_CALLBACK (gtk_widget_destroyed),
5733 &dialog_window);
5734 g_signal_connect (dialog_window, "destroy",
5735 G_CALLBACK (event_watcher_down),
5736 NULL);
5737
5738 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog_window));
5739
5740 gtk_window_set_title (GTK_WINDOW (dialog_window), "Event Watcher");
5741 gtk_container_set_border_width (GTK_CONTAINER (dialog_window), 0);
5742 gtk_widget_set_size_request (dialog_window, 200, 110);
5743
5744 button = gtk_toggle_button_new_with_label ("Activate Watch");
5745 g_signal_connect (button, "clicked",
5746 G_CALLBACK (event_watcher_toggle),
5747 NULL);
5748 gtk_container_set_border_width (GTK_CONTAINER (button), 10);
5749 gtk_box_pack_start (GTK_BOX (content_area), button, TRUE, TRUE, 0);
5750 gtk_widget_show (button);
5751
5752 gtk_dialog_add_button (GTK_DIALOG (dialog_window), "Close", GTK_RESPONSE_CLOSE);
5753 g_signal_connect (dialog_window, "response", G_CALLBACK (gtk_widget_destroy), NULL);
5754 }
5755
5756 if (!gtk_widget_get_visible (dialog_window))
5757 gtk_widget_show (dialog_window);
5758 else
5759 gtk_widget_destroy (dialog_window);
5760 }
5761
5762 /*
5763 * GtkRange
5764 */
5765
5766 static gchar*
reformat_value(GtkScale * scale,gdouble value)5767 reformat_value (GtkScale *scale,
5768 gdouble value)
5769 {
5770 return g_strdup_printf ("-->%0.*g<--",
5771 gtk_scale_get_digits (scale), value);
5772 }
5773
5774 static void
create_range_controls(GtkWidget * widget)5775 create_range_controls (GtkWidget *widget)
5776 {
5777 static GtkWidget *window = NULL;
5778 GtkWidget *box1;
5779 GtkWidget *box2;
5780 GtkWidget *button;
5781 GtkWidget *scrollbar;
5782 GtkWidget *scale;
5783 GtkWidget *separator;
5784 GtkAdjustment *adjustment;
5785 GtkWidget *hbox;
5786
5787 if (!window)
5788 {
5789 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
5790
5791 gtk_window_set_screen (GTK_WINDOW (window),
5792 gtk_widget_get_screen (widget));
5793
5794 g_signal_connect (window, "destroy",
5795 G_CALLBACK (gtk_widget_destroyed),
5796 &window);
5797
5798 gtk_window_set_title (GTK_WINDOW (window), "range controls");
5799 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
5800
5801
5802 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
5803 gtk_container_add (GTK_CONTAINER (window), box1);
5804 gtk_widget_show (box1);
5805
5806
5807 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
5808 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5809 gtk_box_pack_start (GTK_BOX (box1), box2, TRUE, TRUE, 0);
5810 gtk_widget_show (box2);
5811
5812
5813 adjustment = gtk_adjustment_new (0.0, 0.0, 101.0, 0.1, 1.0, 1.0);
5814
5815 scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5816 gtk_widget_set_size_request (GTK_WIDGET (scale), 150, -1);
5817 gtk_scale_set_digits (GTK_SCALE (scale), 1);
5818 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5819 gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5820 gtk_widget_show (scale);
5821
5822 scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5823 gtk_box_pack_start (GTK_BOX (box2), scrollbar, TRUE, TRUE, 0);
5824 gtk_widget_show (scrollbar);
5825
5826 scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, GTK_ADJUSTMENT (adjustment));
5827 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5828 g_signal_connect (scale,
5829 "format_value",
5830 G_CALLBACK (reformat_value),
5831 NULL);
5832 gtk_box_pack_start (GTK_BOX (box2), scale, TRUE, TRUE, 0);
5833 gtk_widget_show (scale);
5834
5835 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
5836
5837 scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5838 gtk_widget_set_size_request (scale, -1, 200);
5839 gtk_scale_set_digits (GTK_SCALE (scale), 2);
5840 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5841 gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5842 gtk_widget_show (scale);
5843
5844 scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5845 gtk_widget_set_size_request (scale, -1, 200);
5846 gtk_scale_set_digits (GTK_SCALE (scale), 2);
5847 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5848 gtk_range_set_inverted (GTK_RANGE (scale), TRUE);
5849 gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5850 gtk_widget_show (scale);
5851
5852 scale = gtk_scale_new (GTK_ORIENTATION_VERTICAL, GTK_ADJUSTMENT (adjustment));
5853 gtk_scale_set_draw_value (GTK_SCALE (scale), TRUE);
5854 g_signal_connect (scale,
5855 "format_value",
5856 G_CALLBACK (reformat_value),
5857 NULL);
5858 gtk_box_pack_start (GTK_BOX (hbox), scale, TRUE, TRUE, 0);
5859 gtk_widget_show (scale);
5860
5861
5862 gtk_box_pack_start (GTK_BOX (box2), hbox, TRUE, TRUE, 0);
5863 gtk_widget_show (hbox);
5864
5865 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
5866 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
5867 gtk_widget_show (separator);
5868
5869
5870 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
5871 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
5872 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
5873 gtk_widget_show (box2);
5874
5875
5876 button = gtk_button_new_with_label ("close");
5877 g_signal_connect_swapped (button, "clicked",
5878 G_CALLBACK (gtk_widget_destroy),
5879 window);
5880 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
5881 gtk_widget_set_can_default (button, TRUE);
5882 gtk_widget_grab_default (button);
5883 gtk_widget_show (button);
5884 }
5885
5886 if (!gtk_widget_get_visible (window))
5887 gtk_widget_show (window);
5888 else
5889 gtk_widget_destroy (window);
5890 }
5891
5892 struct {
5893 GdkColor color;
5894 gchar *name;
5895 } text_colors[] = {
5896 { { 0, 0x0000, 0x0000, 0x0000 }, "black" },
5897 { { 0, 0xFFFF, 0xFFFF, 0xFFFF }, "white" },
5898 { { 0, 0xFFFF, 0x0000, 0x0000 }, "red" },
5899 { { 0, 0x0000, 0xFFFF, 0x0000 }, "green" },
5900 { { 0, 0x0000, 0x0000, 0xFFFF }, "blue" },
5901 { { 0, 0x0000, 0xFFFF, 0xFFFF }, "cyan" },
5902 { { 0, 0xFFFF, 0x0000, 0xFFFF }, "magenta" },
5903 { { 0, 0xFFFF, 0xFFFF, 0x0000 }, "yellow" }
5904 };
5905
5906 int ntext_colors = sizeof(text_colors) / sizeof(text_colors[0]);
5907
5908 /*
5909 * GtkNotebook
5910 */
5911
5912 static const char * book_open_xpm[] = {
5913 "16 16 4 1",
5914 " c None s None",
5915 ". c black",
5916 "X c #808080",
5917 "o c white",
5918 " ",
5919 " .. ",
5920 " .Xo. ... ",
5921 " .Xoo. ..oo. ",
5922 " .Xooo.Xooo... ",
5923 " .Xooo.oooo.X. ",
5924 " .Xooo.Xooo.X. ",
5925 " .Xooo.oooo.X. ",
5926 " .Xooo.Xooo.X. ",
5927 " .Xooo.oooo.X. ",
5928 " .Xoo.Xoo..X. ",
5929 " .Xo.o..ooX. ",
5930 " .X..XXXXX. ",
5931 " ..X....... ",
5932 " .. ",
5933 " "};
5934
5935 static const char * book_closed_xpm[] = {
5936 "16 16 6 1",
5937 " c None s None",
5938 ". c black",
5939 "X c red",
5940 "o c yellow",
5941 "O c #808080",
5942 "# c white",
5943 " ",
5944 " .. ",
5945 " ..XX. ",
5946 " ..XXXXX. ",
5947 " ..XXXXXXXX. ",
5948 ".ooXXXXXXXXX. ",
5949 "..ooXXXXXXXXX. ",
5950 ".X.ooXXXXXXXXX. ",
5951 ".XX.ooXXXXXX.. ",
5952 " .XX.ooXXX..#O ",
5953 " .XX.oo..##OO. ",
5954 " .XX..##OO.. ",
5955 " .X.#OO.. ",
5956 " ..O.. ",
5957 " .. ",
5958 " "};
5959
5960 GdkPixbuf *book_open;
5961 GdkPixbuf *book_closed;
5962 GtkWidget *sample_notebook;
5963
5964 static void
set_page_image(GtkNotebook * notebook,gint page_num,GdkPixbuf * pixbuf)5965 set_page_image (GtkNotebook *notebook, gint page_num, GdkPixbuf *pixbuf)
5966 {
5967 GtkWidget *page_widget;
5968 GtkWidget *pixwid;
5969
5970 page_widget = gtk_notebook_get_nth_page (notebook, page_num);
5971
5972 pixwid = g_object_get_data (G_OBJECT (page_widget), "tab_pixmap");
5973 gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
5974
5975 pixwid = g_object_get_data (G_OBJECT (page_widget), "menu_pixmap");
5976 gtk_image_set_from_pixbuf (GTK_IMAGE (pixwid), pixbuf);
5977 }
5978
5979 static void
page_switch(GtkWidget * widget,gpointer * page,gint page_num)5980 page_switch (GtkWidget *widget, gpointer *page, gint page_num)
5981 {
5982 GtkNotebook *notebook = GTK_NOTEBOOK (widget);
5983 gint old_page_num = gtk_notebook_get_current_page (notebook);
5984
5985 if (page_num == old_page_num)
5986 return;
5987
5988 set_page_image (notebook, page_num, book_open);
5989
5990 if (old_page_num != -1)
5991 set_page_image (notebook, old_page_num, book_closed);
5992 }
5993
5994 static void
tab_fill(GtkToggleButton * button,GtkWidget * child)5995 tab_fill (GtkToggleButton *button, GtkWidget *child)
5996 {
5997 gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
5998 "tab-fill", gtk_toggle_button_get_active (button),
5999 NULL);
6000 }
6001
6002 static void
tab_expand(GtkToggleButton * button,GtkWidget * child)6003 tab_expand (GtkToggleButton *button, GtkWidget *child)
6004 {
6005 gtk_container_child_set (GTK_CONTAINER (sample_notebook), child,
6006 "tab-expand", gtk_toggle_button_get_active (button),
6007 NULL);
6008 }
6009
6010 static void
create_pages(GtkNotebook * notebook,gint start,gint end)6011 create_pages (GtkNotebook *notebook, gint start, gint end)
6012 {
6013 GtkWidget *child = NULL;
6014 GtkWidget *button;
6015 GtkWidget *label;
6016 GtkWidget *hbox;
6017 GtkWidget *vbox;
6018 GtkWidget *label_box;
6019 GtkWidget *menu_box;
6020 GtkWidget *pixwid;
6021 gint i;
6022 char buffer[32];
6023 char accel_buffer[32];
6024
6025 for (i = start; i <= end; i++)
6026 {
6027 sprintf (buffer, "Page %d", i);
6028 sprintf (accel_buffer, "Page _%d", i);
6029
6030 child = gtk_frame_new (buffer);
6031 gtk_container_set_border_width (GTK_CONTAINER (child), 10);
6032
6033 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6034 gtk_box_set_homogeneous (GTK_BOX (vbox), TRUE);
6035 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
6036 gtk_container_add (GTK_CONTAINER (child), vbox);
6037
6038 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6039 gtk_box_set_homogeneous (GTK_BOX (hbox), TRUE);
6040 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 5);
6041
6042 button = gtk_check_button_new_with_label ("Fill Tab");
6043 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6044 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
6045 g_signal_connect (button, "toggled",
6046 G_CALLBACK (tab_fill), child);
6047
6048 button = gtk_check_button_new_with_label ("Expand Tab");
6049 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 5);
6050 g_signal_connect (button, "toggled",
6051 G_CALLBACK (tab_expand), child);
6052
6053 button = gtk_button_new_with_label ("Hide Page");
6054 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 5);
6055 g_signal_connect_swapped (button, "clicked",
6056 G_CALLBACK (gtk_widget_hide),
6057 child);
6058
6059 gtk_widget_show_all (child);
6060
6061 label_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6062 pixwid = gtk_image_new_from_pixbuf (book_closed);
6063 g_object_set_data (G_OBJECT (child), "tab_pixmap", pixwid);
6064
6065 gtk_box_pack_start (GTK_BOX (label_box), pixwid, FALSE, TRUE, 0);
6066 gtk_widget_set_margin_start (pixwid, 3);
6067 gtk_widget_set_margin_end (pixwid, 3);
6068 gtk_widget_set_margin_bottom (pixwid, 1);
6069 gtk_widget_set_margin_top (pixwid, 1);
6070 label = gtk_label_new_with_mnemonic (accel_buffer);
6071 gtk_box_pack_start (GTK_BOX (label_box), label, FALSE, TRUE, 0);
6072 gtk_widget_show_all (label_box);
6073
6074
6075 menu_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6076 pixwid = gtk_image_new_from_pixbuf (book_closed);
6077 g_object_set_data (G_OBJECT (child), "menu_pixmap", pixwid);
6078
6079 gtk_box_pack_start (GTK_BOX (menu_box), pixwid, FALSE, TRUE, 0);
6080 gtk_widget_set_margin_start (pixwid, 3);
6081 gtk_widget_set_margin_end (pixwid, 3);
6082 gtk_widget_set_margin_bottom (pixwid, 1);
6083 gtk_widget_set_margin_top (pixwid, 1);
6084 label = gtk_label_new (buffer);
6085 gtk_box_pack_start (GTK_BOX (menu_box), label, FALSE, TRUE, 0);
6086 gtk_widget_show_all (menu_box);
6087
6088 gtk_notebook_append_page_menu (notebook, child, label_box, menu_box);
6089 }
6090 }
6091
6092 static void
rotate_notebook(GtkButton * button,GtkNotebook * notebook)6093 rotate_notebook (GtkButton *button,
6094 GtkNotebook *notebook)
6095 {
6096 gtk_notebook_set_tab_pos (notebook, (gtk_notebook_get_tab_pos (notebook) + 1) % 4);
6097 }
6098
6099 static void
show_all_pages(GtkButton * button,GtkNotebook * notebook)6100 show_all_pages (GtkButton *button,
6101 GtkNotebook *notebook)
6102 {
6103 gtk_container_foreach (GTK_CONTAINER (notebook),
6104 (GtkCallback) gtk_widget_show, NULL);
6105 }
6106
6107 static void
notebook_type_changed(GtkWidget * optionmenu,gpointer data)6108 notebook_type_changed (GtkWidget *optionmenu,
6109 gpointer data)
6110 {
6111 GtkNotebook *notebook;
6112 gint i, c;
6113
6114 enum {
6115 STANDARD,
6116 NOTABS,
6117 BORDERLESS,
6118 SCROLLABLE
6119 };
6120
6121 notebook = GTK_NOTEBOOK (data);
6122
6123 c = gtk_combo_box_get_active (GTK_COMBO_BOX (optionmenu));
6124
6125 switch (c)
6126 {
6127 case STANDARD:
6128 /* standard notebook */
6129 gtk_notebook_set_show_tabs (notebook, TRUE);
6130 gtk_notebook_set_show_border (notebook, TRUE);
6131 gtk_notebook_set_scrollable (notebook, FALSE);
6132 break;
6133
6134 case NOTABS:
6135 /* notabs notebook */
6136 gtk_notebook_set_show_tabs (notebook, FALSE);
6137 gtk_notebook_set_show_border (notebook, TRUE);
6138 break;
6139
6140 case BORDERLESS:
6141 /* borderless */
6142 gtk_notebook_set_show_tabs (notebook, FALSE);
6143 gtk_notebook_set_show_border (notebook, FALSE);
6144 break;
6145
6146 case SCROLLABLE:
6147 /* scrollable */
6148 gtk_notebook_set_show_tabs (notebook, TRUE);
6149 gtk_notebook_set_show_border (notebook, TRUE);
6150 gtk_notebook_set_scrollable (notebook, TRUE);
6151 if (gtk_notebook_get_n_pages (notebook) == 5)
6152 create_pages (notebook, 6, 15);
6153
6154 return;
6155 break;
6156 }
6157
6158 if (gtk_notebook_get_n_pages (notebook) == 15)
6159 for (i = 0; i < 10; i++)
6160 gtk_notebook_remove_page (notebook, 5);
6161 }
6162
6163 static void
notebook_popup(GtkToggleButton * button,GtkNotebook * notebook)6164 notebook_popup (GtkToggleButton *button,
6165 GtkNotebook *notebook)
6166 {
6167 if (gtk_toggle_button_get_active (button))
6168 gtk_notebook_popup_enable (notebook);
6169 else
6170 gtk_notebook_popup_disable (notebook);
6171 }
6172
6173 static void
create_notebook(GtkWidget * widget)6174 create_notebook (GtkWidget *widget)
6175 {
6176 static GtkWidget *window = NULL;
6177 GtkWidget *box1;
6178 GtkWidget *box2;
6179 GtkWidget *button;
6180 GtkWidget *separator;
6181 GtkWidget *omenu;
6182 GtkWidget *label;
6183
6184 static gchar *items[] =
6185 {
6186 "Standard",
6187 "No tabs",
6188 "Borderless",
6189 "Scrollable"
6190 };
6191
6192 if (!window)
6193 {
6194 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6195 gtk_window_set_screen (GTK_WINDOW (window),
6196 gtk_widget_get_screen (widget));
6197
6198 g_signal_connect (window, "destroy",
6199 G_CALLBACK (gtk_widget_destroyed),
6200 &window);
6201
6202 gtk_window_set_title (GTK_WINDOW (window), "notebook");
6203 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6204
6205 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6206 gtk_container_add (GTK_CONTAINER (window), box1);
6207
6208 sample_notebook = gtk_notebook_new ();
6209 g_signal_connect (sample_notebook, "switch_page",
6210 G_CALLBACK (page_switch), NULL);
6211 gtk_notebook_set_tab_pos (GTK_NOTEBOOK (sample_notebook), GTK_POS_TOP);
6212 gtk_box_pack_start (GTK_BOX (box1), sample_notebook, TRUE, TRUE, 0);
6213 gtk_container_set_border_width (GTK_CONTAINER (sample_notebook), 10);
6214
6215 gtk_widget_realize (sample_notebook);
6216
6217 if (!book_open)
6218 book_open = gdk_pixbuf_new_from_xpm_data (book_open_xpm);
6219
6220 if (!book_closed)
6221 book_closed = gdk_pixbuf_new_from_xpm_data (book_closed_xpm);
6222
6223 create_pages (GTK_NOTEBOOK (sample_notebook), 1, 5);
6224
6225 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
6226 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 10);
6227
6228 box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
6229 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6230 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6231
6232 button = gtk_check_button_new_with_label ("popup menu");
6233 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, FALSE, 0);
6234 g_signal_connect (button, "clicked",
6235 G_CALLBACK (notebook_popup),
6236 sample_notebook);
6237
6238 box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
6239 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6240 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6241
6242 label = gtk_label_new ("Notebook Style :");
6243 gtk_box_pack_start (GTK_BOX (box2), label, FALSE, TRUE, 0);
6244
6245 omenu = build_option_menu (items, G_N_ELEMENTS (items), 0,
6246 notebook_type_changed,
6247 sample_notebook);
6248 gtk_box_pack_start (GTK_BOX (box2), omenu, FALSE, TRUE, 0);
6249
6250 button = gtk_button_new_with_label ("Show all Pages");
6251 gtk_box_pack_start (GTK_BOX (box2), button, FALSE, TRUE, 0);
6252 g_signal_connect (button, "clicked",
6253 G_CALLBACK (show_all_pages), sample_notebook);
6254
6255 box2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 10);
6256 gtk_box_set_homogeneous (GTK_BOX (box2), TRUE);
6257 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
6258 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
6259
6260 button = gtk_button_new_with_label ("prev");
6261 g_signal_connect_swapped (button, "clicked",
6262 G_CALLBACK (gtk_notebook_prev_page),
6263 sample_notebook);
6264 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6265
6266 button = gtk_button_new_with_label ("next");
6267 g_signal_connect_swapped (button, "clicked",
6268 G_CALLBACK (gtk_notebook_next_page),
6269 sample_notebook);
6270 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6271
6272 button = gtk_button_new_with_label ("rotate");
6273 g_signal_connect (button, "clicked",
6274 G_CALLBACK (rotate_notebook), sample_notebook);
6275 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
6276
6277 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
6278 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 5);
6279
6280 button = gtk_button_new_with_label ("close");
6281 gtk_container_set_border_width (GTK_CONTAINER (button), 5);
6282 g_signal_connect_swapped (button, "clicked",
6283 G_CALLBACK (gtk_widget_destroy),
6284 window);
6285 gtk_box_pack_start (GTK_BOX (box1), button, FALSE, FALSE, 0);
6286 gtk_widget_set_can_default (button, TRUE);
6287 gtk_widget_grab_default (button);
6288 }
6289
6290 if (!gtk_widget_get_visible (window))
6291 gtk_widget_show_all (window);
6292 else
6293 gtk_widget_destroy (window);
6294 }
6295
6296 /*
6297 * GtkPanes
6298 */
6299
6300 void
toggle_resize(GtkWidget * widget,GtkWidget * child)6301 toggle_resize (GtkWidget *widget, GtkWidget *child)
6302 {
6303 GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6304 GValue value = G_VALUE_INIT;
6305 g_value_init (&value, G_TYPE_BOOLEAN);
6306 gtk_container_child_get_property (container, child, "resize", &value);
6307 g_value_set_boolean (&value, !g_value_get_boolean (&value));
6308 gtk_container_child_set_property (container, child, "resize", &value);
6309 }
6310
6311 void
toggle_shrink(GtkWidget * widget,GtkWidget * child)6312 toggle_shrink (GtkWidget *widget, GtkWidget *child)
6313 {
6314 GtkContainer *container = GTK_CONTAINER (gtk_widget_get_parent (child));
6315 GValue value = G_VALUE_INIT;
6316 g_value_init (&value, G_TYPE_BOOLEAN);
6317 gtk_container_child_get_property (container, child, "shrink", &value);
6318 g_value_set_boolean (&value, !g_value_get_boolean (&value));
6319 gtk_container_child_set_property (container, child, "shrink", &value);
6320 }
6321
6322 GtkWidget *
create_pane_options(GtkPaned * paned,const gchar * frame_label,const gchar * label1,const gchar * label2)6323 create_pane_options (GtkPaned *paned,
6324 const gchar *frame_label,
6325 const gchar *label1,
6326 const gchar *label2)
6327 {
6328 GtkWidget *child1, *child2;
6329 GtkWidget *frame;
6330 GtkWidget *grid;
6331 GtkWidget *label;
6332 GtkWidget *check_button;
6333
6334 child1 = gtk_paned_get_child1 (paned);
6335 child2 = gtk_paned_get_child2 (paned);
6336
6337 frame = gtk_frame_new (frame_label);
6338 gtk_container_set_border_width (GTK_CONTAINER (frame), 4);
6339
6340 grid = gtk_grid_new ();
6341 gtk_container_add (GTK_CONTAINER (frame), grid);
6342
6343 label = gtk_label_new (label1);
6344 gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
6345
6346 check_button = gtk_check_button_new_with_label ("Resize");
6347 gtk_grid_attach (GTK_GRID (grid), check_button, 0, 1, 1, 1);
6348 g_signal_connect (check_button, "toggled",
6349 G_CALLBACK (toggle_resize),
6350 child1);
6351
6352 check_button = gtk_check_button_new_with_label ("Shrink");
6353 gtk_grid_attach (GTK_GRID (grid), check_button, 0, 2, 1, 1);
6354 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6355 TRUE);
6356 g_signal_connect (check_button, "toggled",
6357 G_CALLBACK (toggle_shrink),
6358 child1);
6359
6360 label = gtk_label_new (label2);
6361 gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
6362
6363 check_button = gtk_check_button_new_with_label ("Resize");
6364 gtk_grid_attach (GTK_GRID (grid), check_button, 1, 1, 1, 1);
6365 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6366 TRUE);
6367 g_signal_connect (check_button, "toggled",
6368 G_CALLBACK (toggle_resize),
6369 child2);
6370
6371 check_button = gtk_check_button_new_with_label ("Shrink");
6372 gtk_grid_attach (GTK_GRID (grid), check_button, 1, 2, 1, 1);
6373 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check_button),
6374 TRUE);
6375 g_signal_connect (check_button, "toggled",
6376 G_CALLBACK (toggle_shrink),
6377 child2);
6378
6379 return frame;
6380 }
6381
6382 void
create_panes(GtkWidget * widget)6383 create_panes (GtkWidget *widget)
6384 {
6385 static GtkWidget *window = NULL;
6386 GtkWidget *frame;
6387 GtkWidget *hpaned;
6388 GtkWidget *vpaned;
6389 GtkWidget *button;
6390 GtkWidget *vbox;
6391
6392 if (!window)
6393 {
6394 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6395
6396 gtk_window_set_screen (GTK_WINDOW (window),
6397 gtk_widget_get_screen (widget));
6398
6399 g_signal_connect (window, "destroy",
6400 G_CALLBACK (gtk_widget_destroyed),
6401 &window);
6402
6403 gtk_window_set_title (GTK_WINDOW (window), "Panes");
6404 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
6405
6406 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6407 gtk_container_add (GTK_CONTAINER (window), vbox);
6408
6409 vpaned = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6410 gtk_box_pack_start (GTK_BOX (vbox), vpaned, TRUE, TRUE, 0);
6411 gtk_container_set_border_width (GTK_CONTAINER(vpaned), 5);
6412
6413 hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6414 gtk_paned_add1 (GTK_PANED (vpaned), hpaned);
6415
6416 frame = gtk_frame_new (NULL);
6417 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6418 gtk_widget_set_size_request (frame, 60, 60);
6419 gtk_paned_add1 (GTK_PANED (hpaned), frame);
6420
6421 button = gtk_button_new_with_label ("Hi there");
6422 gtk_container_add (GTK_CONTAINER(frame), button);
6423
6424 frame = gtk_frame_new (NULL);
6425 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6426 gtk_widget_set_size_request (frame, 80, 60);
6427 gtk_paned_add2 (GTK_PANED (hpaned), frame);
6428
6429 frame = gtk_frame_new (NULL);
6430 gtk_frame_set_shadow_type (GTK_FRAME(frame), GTK_SHADOW_IN);
6431 gtk_widget_set_size_request (frame, 60, 80);
6432 gtk_paned_add2 (GTK_PANED (vpaned), frame);
6433
6434 /* Now create toggle buttons to control sizing */
6435
6436 gtk_box_pack_start (GTK_BOX (vbox),
6437 create_pane_options (GTK_PANED (hpaned),
6438 "Horizontal",
6439 "Left",
6440 "Right"),
6441 FALSE, FALSE, 0);
6442
6443 gtk_box_pack_start (GTK_BOX (vbox),
6444 create_pane_options (GTK_PANED (vpaned),
6445 "Vertical",
6446 "Top",
6447 "Bottom"),
6448 FALSE, FALSE, 0);
6449
6450 gtk_widget_show_all (vbox);
6451 }
6452
6453 if (!gtk_widget_get_visible (window))
6454 gtk_widget_show (window);
6455 else
6456 gtk_widget_destroy (window);
6457 }
6458
6459 /*
6460 * Paned keyboard navigation
6461 */
6462
6463 static GtkWidget*
paned_keyboard_window1(GtkWidget * widget)6464 paned_keyboard_window1 (GtkWidget *widget)
6465 {
6466 GtkWidget *window1;
6467 GtkWidget *hpaned1;
6468 GtkWidget *frame1;
6469 GtkWidget *vbox1;
6470 GtkWidget *button7;
6471 GtkWidget *button8;
6472 GtkWidget *button9;
6473 GtkWidget *vpaned1;
6474 GtkWidget *frame2;
6475 GtkWidget *frame5;
6476 GtkWidget *hbox1;
6477 GtkWidget *button5;
6478 GtkWidget *button6;
6479 GtkWidget *frame3;
6480 GtkWidget *frame4;
6481 GtkWidget *grid1;
6482 GtkWidget *button1;
6483 GtkWidget *button2;
6484 GtkWidget *button3;
6485 GtkWidget *button4;
6486
6487 window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6488 gtk_window_set_title (GTK_WINDOW (window1), "Basic paned navigation");
6489 gtk_window_set_screen (GTK_WINDOW (window1),
6490 gtk_widget_get_screen (widget));
6491
6492 hpaned1 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6493 gtk_container_add (GTK_CONTAINER (window1), hpaned1);
6494
6495 frame1 = gtk_frame_new (NULL);
6496 gtk_paned_pack1 (GTK_PANED (hpaned1), frame1, FALSE, TRUE);
6497 gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
6498
6499 vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6500 gtk_container_add (GTK_CONTAINER (frame1), vbox1);
6501
6502 button7 = gtk_button_new_with_label ("button7");
6503 gtk_box_pack_start (GTK_BOX (vbox1), button7, FALSE, FALSE, 0);
6504
6505 button8 = gtk_button_new_with_label ("button8");
6506 gtk_box_pack_start (GTK_BOX (vbox1), button8, FALSE, FALSE, 0);
6507
6508 button9 = gtk_button_new_with_label ("button9");
6509 gtk_box_pack_start (GTK_BOX (vbox1), button9, FALSE, FALSE, 0);
6510
6511 vpaned1 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6512 gtk_paned_pack2 (GTK_PANED (hpaned1), vpaned1, TRUE, TRUE);
6513
6514 frame2 = gtk_frame_new (NULL);
6515 gtk_paned_pack1 (GTK_PANED (vpaned1), frame2, FALSE, TRUE);
6516 gtk_frame_set_shadow_type (GTK_FRAME (frame2), GTK_SHADOW_IN);
6517
6518 frame5 = gtk_frame_new (NULL);
6519 gtk_container_add (GTK_CONTAINER (frame2), frame5);
6520
6521 hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6522 gtk_container_add (GTK_CONTAINER (frame5), hbox1);
6523
6524 button5 = gtk_button_new_with_label ("button5");
6525 gtk_box_pack_start (GTK_BOX (hbox1), button5, FALSE, FALSE, 0);
6526
6527 button6 = gtk_button_new_with_label ("button6");
6528 gtk_box_pack_start (GTK_BOX (hbox1), button6, FALSE, FALSE, 0);
6529
6530 frame3 = gtk_frame_new (NULL);
6531 gtk_paned_pack2 (GTK_PANED (vpaned1), frame3, TRUE, TRUE);
6532 gtk_frame_set_shadow_type (GTK_FRAME (frame3), GTK_SHADOW_IN);
6533
6534 frame4 = gtk_frame_new ("Buttons");
6535 gtk_container_add (GTK_CONTAINER (frame3), frame4);
6536 gtk_container_set_border_width (GTK_CONTAINER (frame4), 15);
6537
6538 grid1 = gtk_grid_new ();
6539 gtk_container_add (GTK_CONTAINER (frame4), grid1);
6540 gtk_container_set_border_width (GTK_CONTAINER (grid1), 11);
6541
6542 button1 = gtk_button_new_with_label ("button1");
6543 gtk_grid_attach (GTK_GRID (grid1), button1, 0, 0, 1, 1);
6544
6545 button2 = gtk_button_new_with_label ("button2");
6546 gtk_grid_attach (GTK_GRID (grid1), button2, 1, 0, 1, 1);
6547
6548 button3 = gtk_button_new_with_label ("button3");
6549 gtk_grid_attach (GTK_GRID (grid1), button3, 0, 1, 1, 1);
6550
6551 button4 = gtk_button_new_with_label ("button4");
6552 gtk_grid_attach (GTK_GRID (grid1), button4, 1, 1, 1, 1);
6553
6554 return window1;
6555 }
6556
6557 static GtkWidget*
paned_keyboard_window2(GtkWidget * widget)6558 paned_keyboard_window2 (GtkWidget *widget)
6559 {
6560 GtkWidget *window2;
6561 GtkWidget *hpaned2;
6562 GtkWidget *frame6;
6563 GtkWidget *button13;
6564 GtkWidget *hbox2;
6565 GtkWidget *vpaned2;
6566 GtkWidget *frame7;
6567 GtkWidget *button12;
6568 GtkWidget *frame8;
6569 GtkWidget *button11;
6570 GtkWidget *button10;
6571
6572 window2 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6573 gtk_window_set_title (GTK_WINDOW (window2), "\"button 10\" is not inside the horisontal pane");
6574
6575 gtk_window_set_screen (GTK_WINDOW (window2),
6576 gtk_widget_get_screen (widget));
6577
6578 hpaned2 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6579 gtk_container_add (GTK_CONTAINER (window2), hpaned2);
6580
6581 frame6 = gtk_frame_new (NULL);
6582 gtk_paned_pack1 (GTK_PANED (hpaned2), frame6, FALSE, TRUE);
6583 gtk_frame_set_shadow_type (GTK_FRAME (frame6), GTK_SHADOW_IN);
6584
6585 button13 = gtk_button_new_with_label ("button13");
6586 gtk_container_add (GTK_CONTAINER (frame6), button13);
6587
6588 hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6589 gtk_paned_pack2 (GTK_PANED (hpaned2), hbox2, TRUE, TRUE);
6590
6591 vpaned2 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6592 gtk_box_pack_start (GTK_BOX (hbox2), vpaned2, TRUE, TRUE, 0);
6593
6594 frame7 = gtk_frame_new (NULL);
6595 gtk_paned_pack1 (GTK_PANED (vpaned2), frame7, FALSE, TRUE);
6596 gtk_frame_set_shadow_type (GTK_FRAME (frame7), GTK_SHADOW_IN);
6597
6598 button12 = gtk_button_new_with_label ("button12");
6599 gtk_container_add (GTK_CONTAINER (frame7), button12);
6600
6601 frame8 = gtk_frame_new (NULL);
6602 gtk_paned_pack2 (GTK_PANED (vpaned2), frame8, TRUE, TRUE);
6603 gtk_frame_set_shadow_type (GTK_FRAME (frame8), GTK_SHADOW_IN);
6604
6605 button11 = gtk_button_new_with_label ("button11");
6606 gtk_container_add (GTK_CONTAINER (frame8), button11);
6607
6608 button10 = gtk_button_new_with_label ("button10");
6609 gtk_box_pack_start (GTK_BOX (hbox2), button10, FALSE, FALSE, 0);
6610
6611 return window2;
6612 }
6613
6614 static GtkWidget*
paned_keyboard_window3(GtkWidget * widget)6615 paned_keyboard_window3 (GtkWidget *widget)
6616 {
6617 GtkWidget *window3;
6618 GtkWidget *vbox2;
6619 GtkWidget *label1;
6620 GtkWidget *hpaned3;
6621 GtkWidget *frame9;
6622 GtkWidget *button14;
6623 GtkWidget *hpaned4;
6624 GtkWidget *frame10;
6625 GtkWidget *button15;
6626 GtkWidget *hpaned5;
6627 GtkWidget *frame11;
6628 GtkWidget *button16;
6629 GtkWidget *frame12;
6630 GtkWidget *button17;
6631
6632 window3 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6633 g_object_set_data (G_OBJECT (window3), "window3", window3);
6634 gtk_window_set_title (GTK_WINDOW (window3), "Nested panes");
6635
6636 gtk_window_set_screen (GTK_WINDOW (window3),
6637 gtk_widget_get_screen (widget));
6638
6639
6640 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6641 gtk_container_add (GTK_CONTAINER (window3), vbox2);
6642
6643 label1 = gtk_label_new ("Three panes nested inside each other");
6644 gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0);
6645
6646 hpaned3 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6647 gtk_box_pack_start (GTK_BOX (vbox2), hpaned3, TRUE, TRUE, 0);
6648
6649 frame9 = gtk_frame_new (NULL);
6650 gtk_paned_pack1 (GTK_PANED (hpaned3), frame9, FALSE, TRUE);
6651 gtk_frame_set_shadow_type (GTK_FRAME (frame9), GTK_SHADOW_IN);
6652
6653 button14 = gtk_button_new_with_label ("button14");
6654 gtk_container_add (GTK_CONTAINER (frame9), button14);
6655
6656 hpaned4 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6657 gtk_paned_pack2 (GTK_PANED (hpaned3), hpaned4, TRUE, TRUE);
6658
6659 frame10 = gtk_frame_new (NULL);
6660 gtk_paned_pack1 (GTK_PANED (hpaned4), frame10, FALSE, TRUE);
6661 gtk_frame_set_shadow_type (GTK_FRAME (frame10), GTK_SHADOW_IN);
6662
6663 button15 = gtk_button_new_with_label ("button15");
6664 gtk_container_add (GTK_CONTAINER (frame10), button15);
6665
6666 hpaned5 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6667 gtk_paned_pack2 (GTK_PANED (hpaned4), hpaned5, TRUE, TRUE);
6668
6669 frame11 = gtk_frame_new (NULL);
6670 gtk_paned_pack1 (GTK_PANED (hpaned5), frame11, FALSE, TRUE);
6671 gtk_frame_set_shadow_type (GTK_FRAME (frame11), GTK_SHADOW_IN);
6672
6673 button16 = gtk_button_new_with_label ("button16");
6674 gtk_container_add (GTK_CONTAINER (frame11), button16);
6675
6676 frame12 = gtk_frame_new (NULL);
6677 gtk_paned_pack2 (GTK_PANED (hpaned5), frame12, TRUE, TRUE);
6678 gtk_frame_set_shadow_type (GTK_FRAME (frame12), GTK_SHADOW_IN);
6679
6680 button17 = gtk_button_new_with_label ("button17");
6681 gtk_container_add (GTK_CONTAINER (frame12), button17);
6682
6683 return window3;
6684 }
6685
6686 static GtkWidget*
paned_keyboard_window4(GtkWidget * widget)6687 paned_keyboard_window4 (GtkWidget *widget)
6688 {
6689 GtkWidget *window4;
6690 GtkWidget *vbox3;
6691 GtkWidget *label2;
6692 GtkWidget *hpaned6;
6693 GtkWidget *vpaned3;
6694 GtkWidget *button19;
6695 GtkWidget *button18;
6696 GtkWidget *hbox3;
6697 GtkWidget *vpaned4;
6698 GtkWidget *button21;
6699 GtkWidget *button20;
6700 GtkWidget *vpaned5;
6701 GtkWidget *button23;
6702 GtkWidget *button22;
6703 GtkWidget *vpaned6;
6704 GtkWidget *button25;
6705 GtkWidget *button24;
6706
6707 window4 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
6708 g_object_set_data (G_OBJECT (window4), "window4", window4);
6709 gtk_window_set_title (GTK_WINDOW (window4), "window4");
6710
6711 gtk_window_set_screen (GTK_WINDOW (window4),
6712 gtk_widget_get_screen (widget));
6713
6714 vbox3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
6715 gtk_container_add (GTK_CONTAINER (window4), vbox3);
6716
6717 label2 = gtk_label_new ("Widget tree:\n\nhpaned \n - vpaned\n - hbox\n - vpaned\n - vpaned\n - vpaned\n");
6718 gtk_box_pack_start (GTK_BOX (vbox3), label2, FALSE, FALSE, 0);
6719 gtk_label_set_justify (GTK_LABEL (label2), GTK_JUSTIFY_LEFT);
6720
6721 hpaned6 = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
6722 gtk_box_pack_start (GTK_BOX (vbox3), hpaned6, TRUE, TRUE, 0);
6723
6724 vpaned3 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6725 gtk_paned_pack1 (GTK_PANED (hpaned6), vpaned3, FALSE, TRUE);
6726
6727 button19 = gtk_button_new_with_label ("button19");
6728 gtk_paned_pack1 (GTK_PANED (vpaned3), button19, FALSE, TRUE);
6729
6730 button18 = gtk_button_new_with_label ("button18");
6731 gtk_paned_pack2 (GTK_PANED (vpaned3), button18, TRUE, TRUE);
6732
6733 hbox3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
6734 gtk_paned_pack2 (GTK_PANED (hpaned6), hbox3, TRUE, TRUE);
6735
6736 vpaned4 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6737 gtk_box_pack_start (GTK_BOX (hbox3), vpaned4, TRUE, TRUE, 0);
6738
6739 button21 = gtk_button_new_with_label ("button21");
6740 gtk_paned_pack1 (GTK_PANED (vpaned4), button21, FALSE, TRUE);
6741
6742 button20 = gtk_button_new_with_label ("button20");
6743 gtk_paned_pack2 (GTK_PANED (vpaned4), button20, TRUE, TRUE);
6744
6745 vpaned5 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6746 gtk_box_pack_start (GTK_BOX (hbox3), vpaned5, TRUE, TRUE, 0);
6747
6748 button23 = gtk_button_new_with_label ("button23");
6749 gtk_paned_pack1 (GTK_PANED (vpaned5), button23, FALSE, TRUE);
6750
6751 button22 = gtk_button_new_with_label ("button22");
6752 gtk_paned_pack2 (GTK_PANED (vpaned5), button22, TRUE, TRUE);
6753
6754 vpaned6 = gtk_paned_new (GTK_ORIENTATION_VERTICAL);
6755 gtk_box_pack_start (GTK_BOX (hbox3), vpaned6, TRUE, TRUE, 0);
6756
6757 button25 = gtk_button_new_with_label ("button25");
6758 gtk_paned_pack1 (GTK_PANED (vpaned6), button25, FALSE, TRUE);
6759
6760 button24 = gtk_button_new_with_label ("button24");
6761 gtk_paned_pack2 (GTK_PANED (vpaned6), button24, TRUE, TRUE);
6762
6763 return window4;
6764 }
6765
6766 static void
create_paned_keyboard_navigation(GtkWidget * widget)6767 create_paned_keyboard_navigation (GtkWidget *widget)
6768 {
6769 static GtkWidget *window1 = NULL;
6770 static GtkWidget *window2 = NULL;
6771 static GtkWidget *window3 = NULL;
6772 static GtkWidget *window4 = NULL;
6773
6774 if (window1 &&
6775 (gtk_widget_get_screen (window1) != gtk_widget_get_screen (widget)))
6776 {
6777 gtk_widget_destroy (window1);
6778 gtk_widget_destroy (window2);
6779 gtk_widget_destroy (window3);
6780 gtk_widget_destroy (window4);
6781 }
6782
6783 if (!window1)
6784 {
6785 window1 = paned_keyboard_window1 (widget);
6786 g_signal_connect (window1, "destroy",
6787 G_CALLBACK (gtk_widget_destroyed),
6788 &window1);
6789 }
6790
6791 if (!window2)
6792 {
6793 window2 = paned_keyboard_window2 (widget);
6794 g_signal_connect (window2, "destroy",
6795 G_CALLBACK (gtk_widget_destroyed),
6796 &window2);
6797 }
6798
6799 if (!window3)
6800 {
6801 window3 = paned_keyboard_window3 (widget);
6802 g_signal_connect (window3, "destroy",
6803 G_CALLBACK (gtk_widget_destroyed),
6804 &window3);
6805 }
6806
6807 if (!window4)
6808 {
6809 window4 = paned_keyboard_window4 (widget);
6810 g_signal_connect (window4, "destroy",
6811 G_CALLBACK (gtk_widget_destroyed),
6812 &window4);
6813 }
6814
6815 if (gtk_widget_get_visible (window1))
6816 gtk_widget_destroy (GTK_WIDGET (window1));
6817 else
6818 gtk_widget_show_all (GTK_WIDGET (window1));
6819
6820 if (gtk_widget_get_visible (window2))
6821 gtk_widget_destroy (GTK_WIDGET (window2));
6822 else
6823 gtk_widget_show_all (GTK_WIDGET (window2));
6824
6825 if (gtk_widget_get_visible (window3))
6826 gtk_widget_destroy (GTK_WIDGET (window3));
6827 else
6828 gtk_widget_show_all (GTK_WIDGET (window3));
6829
6830 if (gtk_widget_get_visible (window4))
6831 gtk_widget_destroy (GTK_WIDGET (window4));
6832 else
6833 gtk_widget_show_all (GTK_WIDGET (window4));
6834 }
6835
6836
6837 /*
6838 * Shaped Windows
6839 */
6840
6841 typedef struct _cursoroffset {gint x,y;} CursorOffset;
6842
6843 static void
shape_pressed(GtkWidget * widget,GdkEventButton * event)6844 shape_pressed (GtkWidget *widget, GdkEventButton *event)
6845 {
6846 CursorOffset *p;
6847
6848 /* ignore double and triple click */
6849 if (event->type != GDK_BUTTON_PRESS)
6850 return;
6851
6852 p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6853 p->x = (int) event->x;
6854 p->y = (int) event->y;
6855
6856 gtk_grab_add (widget);
6857 gdk_seat_grab (gdk_event_get_seat ((GdkEvent *) event),
6858 gtk_widget_get_window (widget),
6859 GDK_SEAT_CAPABILITY_ALL_POINTING,
6860 TRUE, NULL, (GdkEvent *) event, NULL, NULL);
6861 }
6862
6863 static void
shape_released(GtkWidget * widget,GdkEventButton * event)6864 shape_released (GtkWidget *widget,
6865 GdkEventButton *event)
6866 {
6867 gtk_grab_remove (widget);
6868 gdk_seat_ungrab (gdk_event_get_seat ((GdkEvent *) event));
6869 }
6870
6871 static void
shape_motion(GtkWidget * widget,GdkEventMotion * event)6872 shape_motion (GtkWidget *widget,
6873 GdkEventMotion *event)
6874 {
6875 gint xp, yp;
6876 CursorOffset * p;
6877
6878 p = g_object_get_data (G_OBJECT (widget), "cursor_offset");
6879
6880 /*
6881 * Can't use event->x / event->y here
6882 * because I need absolute coordinates.
6883 */
6884 gdk_window_get_device_position (gdk_screen_get_root_window (gtk_widget_get_screen (widget)),
6885 gdk_event_get_device ((GdkEvent *) event),
6886 &xp, &yp, NULL);
6887 gtk_window_move (GTK_WINDOW (widget), xp - p->x, yp - p->y);
6888 }
6889
6890 GtkWidget *
shape_create_icon(GdkScreen * screen,char * xpm_file,gint x,gint y,gint px,gint py,gint window_type)6891 shape_create_icon (GdkScreen *screen,
6892 char *xpm_file,
6893 gint x,
6894 gint y,
6895 gint px,
6896 gint py,
6897 gint window_type)
6898 {
6899 GtkWidget *window;
6900 GtkWidget *image;
6901 GtkWidget *fixed;
6902 CursorOffset* icon_pos;
6903 cairo_surface_t *mask;
6904 cairo_region_t *mask_region;
6905 GdkPixbuf *pixbuf;
6906 cairo_t *cr;
6907
6908 /*
6909 * GDK_WINDOW_TOPLEVEL works also, giving you a title border
6910 */
6911 window = gtk_window_new (window_type);
6912 gtk_window_set_screen (GTK_WINDOW (window), screen);
6913
6914 fixed = gtk_fixed_new ();
6915 gtk_widget_set_size_request (fixed, 100, 100);
6916 gtk_container_add (GTK_CONTAINER (window), fixed);
6917 gtk_widget_show (fixed);
6918
6919 gtk_widget_set_events (window,
6920 gtk_widget_get_events (window) |
6921 GDK_BUTTON_MOTION_MASK |
6922 GDK_BUTTON_PRESS_MASK);
6923
6924 gtk_widget_realize (window);
6925
6926 pixbuf = gdk_pixbuf_new_from_file (xpm_file, NULL);
6927 g_assert (pixbuf); /* FIXME: error handling */
6928
6929 mask = cairo_image_surface_create (CAIRO_FORMAT_A1,
6930 gdk_pixbuf_get_width (pixbuf),
6931 gdk_pixbuf_get_height (pixbuf));
6932 cr = cairo_create (mask);
6933 gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
6934 cairo_paint (cr);
6935 cairo_destroy (cr);
6936
6937 mask_region = gdk_cairo_region_create_from_surface (mask);
6938
6939 cairo_region_translate (mask_region, px, py);
6940
6941 image = gtk_image_new_from_pixbuf (pixbuf);
6942 gtk_fixed_put (GTK_FIXED (fixed), image, px,py);
6943 gtk_widget_show (image);
6944
6945 gtk_widget_shape_combine_region (window, mask_region);
6946
6947 cairo_region_destroy (mask_region);
6948 cairo_surface_destroy (mask);
6949 g_object_unref (pixbuf);
6950
6951 g_signal_connect (window, "button_press_event",
6952 G_CALLBACK (shape_pressed), NULL);
6953 g_signal_connect (window, "button_release_event",
6954 G_CALLBACK (shape_released), NULL);
6955 g_signal_connect (window, "motion_notify_event",
6956 G_CALLBACK (shape_motion), NULL);
6957
6958 icon_pos = g_new (CursorOffset, 1);
6959 g_object_set_data (G_OBJECT (window), "cursor_offset", icon_pos);
6960
6961 gtk_window_move (GTK_WINDOW (window), x, y);
6962 gtk_widget_show (window);
6963
6964 return window;
6965 }
6966
6967 void
create_shapes(GtkWidget * widget)6968 create_shapes (GtkWidget *widget)
6969 {
6970 /* Variables used by the Drag/Drop and Shape Window demos */
6971 static GtkWidget *modeller = NULL;
6972 static GtkWidget *sheets = NULL;
6973 static GtkWidget *rings = NULL;
6974 static GtkWidget *with_region = NULL;
6975 GdkScreen *screen = gtk_widget_get_screen (widget);
6976
6977 if (!(file_exists ("Modeller.xpm") &&
6978 file_exists ("FilesQueue.xpm") &&
6979 file_exists ("3DRings.xpm")))
6980 return;
6981
6982
6983 if (!modeller)
6984 {
6985 modeller = shape_create_icon (screen, "Modeller.xpm",
6986 440, 140, 0,0, GTK_WINDOW_POPUP);
6987
6988 g_signal_connect (modeller, "destroy",
6989 G_CALLBACK (gtk_widget_destroyed),
6990 &modeller);
6991 }
6992 else
6993 gtk_widget_destroy (modeller);
6994
6995 if (!sheets)
6996 {
6997 sheets = shape_create_icon (screen, "FilesQueue.xpm",
6998 580, 170, 0,0, GTK_WINDOW_POPUP);
6999
7000 g_signal_connect (sheets, "destroy",
7001 G_CALLBACK (gtk_widget_destroyed),
7002 &sheets);
7003
7004 }
7005 else
7006 gtk_widget_destroy (sheets);
7007
7008 if (!rings)
7009 {
7010 rings = shape_create_icon (screen, "3DRings.xpm",
7011 460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7012
7013 g_signal_connect (rings, "destroy",
7014 G_CALLBACK (gtk_widget_destroyed),
7015 &rings);
7016 }
7017 else
7018 gtk_widget_destroy (rings);
7019
7020 if (!with_region)
7021 {
7022 cairo_region_t *region;
7023 gint x, y;
7024
7025 with_region = shape_create_icon (screen, "3DRings.xpm",
7026 460, 270, 25,25, GTK_WINDOW_TOPLEVEL);
7027
7028 gtk_window_set_decorated (GTK_WINDOW (with_region), FALSE);
7029
7030 g_signal_connect (with_region, "destroy",
7031 G_CALLBACK (gtk_widget_destroyed),
7032 &with_region);
7033
7034 /* reset shape from mask to a region */
7035 x = 0;
7036 y = 0;
7037 region = cairo_region_create ();
7038
7039 while (x < 460)
7040 {
7041 while (y < 270)
7042 {
7043 GdkRectangle rect;
7044 rect.x = x;
7045 rect.y = y;
7046 rect.width = 10;
7047 rect.height = 10;
7048
7049 cairo_region_union_rectangle (region, &rect);
7050
7051 y += 20;
7052 }
7053 y = 0;
7054 x += 20;
7055 }
7056
7057 gdk_window_shape_combine_region (gtk_widget_get_window (with_region),
7058 region,
7059 0, 0);
7060 }
7061 else
7062 gtk_widget_destroy (with_region);
7063 }
7064
7065 /*
7066 * WM Hints demo
7067 */
7068
7069 void
create_wmhints(GtkWidget * widget)7070 create_wmhints (GtkWidget *widget)
7071 {
7072 static GtkWidget *window = NULL;
7073 GtkWidget *label;
7074 GtkWidget *separator;
7075 GtkWidget *button;
7076 GtkWidget *box1;
7077 GtkWidget *box2;
7078 GdkWindow *gdk_window;
7079 GdkPixbuf *pixbuf;
7080 GList *list;
7081
7082 if (!window)
7083 {
7084 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7085
7086 gtk_window_set_screen (GTK_WINDOW (window),
7087 gtk_widget_get_screen (widget));
7088
7089 g_signal_connect (window, "destroy",
7090 G_CALLBACK (gtk_widget_destroyed),
7091 &window);
7092
7093 gtk_window_set_title (GTK_WINDOW (window), "WM Hints");
7094 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
7095
7096 gtk_widget_realize (window);
7097
7098 gdk_window = gtk_widget_get_window (window);
7099
7100 pixbuf = gdk_pixbuf_new_from_xpm_data ((const char **) openfile);
7101 list = g_list_prepend (NULL, pixbuf);
7102
7103 gdk_window_set_icon_list (gdk_window, list);
7104
7105 g_list_free (list);
7106 g_object_unref (pixbuf);
7107
7108 gdk_window_set_icon_name (gdk_window, "WMHints Test Icon");
7109
7110 gdk_window_set_decorations (gdk_window, GDK_DECOR_ALL | GDK_DECOR_MENU);
7111 gdk_window_set_functions (gdk_window, GDK_FUNC_ALL | GDK_FUNC_RESIZE);
7112
7113 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7114 gtk_container_add (GTK_CONTAINER (window), box1);
7115 gtk_widget_show (box1);
7116
7117 label = gtk_label_new ("Try iconizing me!");
7118 gtk_widget_set_size_request (label, 150, 50);
7119 gtk_box_pack_start (GTK_BOX (box1), label, TRUE, TRUE, 0);
7120 gtk_widget_show (label);
7121
7122
7123 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
7124 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
7125 gtk_widget_show (separator);
7126
7127
7128 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
7129 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
7130 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
7131 gtk_widget_show (box2);
7132
7133
7134 button = gtk_button_new_with_label ("close");
7135
7136 g_signal_connect_swapped (button, "clicked",
7137 G_CALLBACK (gtk_widget_destroy),
7138 window);
7139
7140 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
7141 gtk_widget_set_can_default (button, TRUE);
7142 gtk_widget_grab_default (button);
7143 gtk_widget_show (button);
7144 }
7145
7146 if (!gtk_widget_get_visible (window))
7147 gtk_widget_show (window);
7148 else
7149 gtk_widget_destroy (window);
7150 }
7151
7152
7153 /*
7154 * Window state tracking
7155 */
7156
7157 static gint
window_state_callback(GtkWidget * widget,GdkEventWindowState * event,gpointer data)7158 window_state_callback (GtkWidget *widget,
7159 GdkEventWindowState *event,
7160 gpointer data)
7161 {
7162 GtkWidget *label = data;
7163 gchar *msg;
7164
7165 msg = g_strconcat (gtk_window_get_title (GTK_WINDOW (widget)), ": ",
7166 (event->new_window_state & GDK_WINDOW_STATE_WITHDRAWN) ?
7167 "withdrawn" : "not withdrawn", ", ",
7168 (event->new_window_state & GDK_WINDOW_STATE_ICONIFIED) ?
7169 "iconified" : "not iconified", ", ",
7170 (event->new_window_state & GDK_WINDOW_STATE_STICKY) ?
7171 "sticky" : "not sticky", ", ",
7172 (event->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) ?
7173 "maximized" : "not maximized", ", ",
7174 (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN) ?
7175 "fullscreen" : "not fullscreen",
7176 (event->new_window_state & GDK_WINDOW_STATE_ABOVE) ?
7177 "above" : "not above", ", ",
7178 (event->new_window_state & GDK_WINDOW_STATE_BELOW) ?
7179 "below" : "not below", ", ",
7180 NULL);
7181
7182 gtk_label_set_text (GTK_LABEL (label), msg);
7183
7184 g_free (msg);
7185
7186 return FALSE;
7187 }
7188
7189 static GtkWidget*
tracking_label(GtkWidget * window)7190 tracking_label (GtkWidget *window)
7191 {
7192 GtkWidget *label;
7193 GtkWidget *hbox;
7194 GtkWidget *button;
7195
7196 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
7197
7198 g_signal_connect_object (hbox,
7199 "destroy",
7200 G_CALLBACK (gtk_widget_destroy),
7201 window,
7202 G_CONNECT_SWAPPED);
7203
7204 label = gtk_label_new ("<no window state events received>");
7205 gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
7206 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
7207
7208 g_signal_connect (window,
7209 "window_state_event",
7210 G_CALLBACK (window_state_callback),
7211 label);
7212
7213 button = gtk_button_new_with_label ("Deiconify");
7214 g_signal_connect_object (button,
7215 "clicked",
7216 G_CALLBACK (gtk_window_deiconify),
7217 window,
7218 G_CONNECT_SWAPPED);
7219 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7220
7221 button = gtk_button_new_with_label ("Iconify");
7222 g_signal_connect_object (button,
7223 "clicked",
7224 G_CALLBACK (gtk_window_iconify),
7225 window,
7226 G_CONNECT_SWAPPED);
7227 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7228
7229 button = gtk_button_new_with_label ("Fullscreen");
7230 g_signal_connect_object (button,
7231 "clicked",
7232 G_CALLBACK (gtk_window_fullscreen),
7233 window,
7234 G_CONNECT_SWAPPED);
7235 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7236
7237 button = gtk_button_new_with_label ("Unfullscreen");
7238 g_signal_connect_object (button,
7239 "clicked",
7240 G_CALLBACK (gtk_window_unfullscreen),
7241 window,
7242 G_CONNECT_SWAPPED);
7243 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7244
7245 button = gtk_button_new_with_label ("Present");
7246 g_signal_connect_object (button,
7247 "clicked",
7248 G_CALLBACK (gtk_window_present),
7249 window,
7250 G_CONNECT_SWAPPED);
7251 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7252
7253 button = gtk_button_new_with_label ("Show");
7254 g_signal_connect_object (button,
7255 "clicked",
7256 G_CALLBACK (gtk_widget_show),
7257 window,
7258 G_CONNECT_SWAPPED);
7259 gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
7260
7261 gtk_widget_show_all (hbox);
7262
7263 return hbox;
7264 }
7265
7266 void
keep_window_above(GtkToggleButton * togglebutton,gpointer data)7267 keep_window_above (GtkToggleButton *togglebutton, gpointer data)
7268 {
7269 GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7270
7271 gtk_window_set_keep_above (GTK_WINDOW (data),
7272 gtk_toggle_button_get_active (togglebutton));
7273
7274 if (gtk_toggle_button_get_active (togglebutton))
7275 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7276 }
7277
7278 void
keep_window_below(GtkToggleButton * togglebutton,gpointer data)7279 keep_window_below (GtkToggleButton *togglebutton, gpointer data)
7280 {
7281 GtkWidget *button = g_object_get_data (G_OBJECT (togglebutton), "radio");
7282
7283 gtk_window_set_keep_below (GTK_WINDOW (data),
7284 gtk_toggle_button_get_active (togglebutton));
7285
7286 if (gtk_toggle_button_get_active (togglebutton))
7287 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), FALSE);
7288 }
7289
7290
7291 static GtkWidget*
get_state_controls(GtkWidget * window)7292 get_state_controls (GtkWidget *window)
7293 {
7294 GtkWidget *vbox;
7295 GtkWidget *button;
7296 GtkWidget *button_above;
7297 GtkWidget *button_below;
7298
7299 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7300
7301 button = gtk_button_new_with_label ("Stick");
7302 g_signal_connect_object (button,
7303 "clicked",
7304 G_CALLBACK (gtk_window_stick),
7305 window,
7306 G_CONNECT_SWAPPED);
7307 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7308
7309 button = gtk_button_new_with_label ("Unstick");
7310 g_signal_connect_object (button,
7311 "clicked",
7312 G_CALLBACK (gtk_window_unstick),
7313 window,
7314 G_CONNECT_SWAPPED);
7315 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7316
7317 button = gtk_button_new_with_label ("Maximize");
7318 g_signal_connect_object (button,
7319 "clicked",
7320 G_CALLBACK (gtk_window_maximize),
7321 window,
7322 G_CONNECT_SWAPPED);
7323 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7324
7325 button = gtk_button_new_with_label ("Unmaximize");
7326 g_signal_connect_object (button,
7327 "clicked",
7328 G_CALLBACK (gtk_window_unmaximize),
7329 window,
7330 G_CONNECT_SWAPPED);
7331 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7332
7333 button = gtk_button_new_with_label ("Iconify");
7334 g_signal_connect_object (button,
7335 "clicked",
7336 G_CALLBACK (gtk_window_iconify),
7337 window,
7338 G_CONNECT_SWAPPED);
7339 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7340
7341 button = gtk_button_new_with_label ("Fullscreen");
7342 g_signal_connect_object (button,
7343 "clicked",
7344 G_CALLBACK (gtk_window_fullscreen),
7345 window,
7346 G_CONNECT_SWAPPED);
7347 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7348
7349 button = gtk_button_new_with_label ("Unfullscreen");
7350 g_signal_connect_object (button,
7351 "clicked",
7352 G_CALLBACK (gtk_window_unfullscreen),
7353 window,
7354 G_CONNECT_SWAPPED);
7355 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7356
7357 button_above = gtk_toggle_button_new_with_label ("Keep above");
7358 g_signal_connect (button_above,
7359 "toggled",
7360 G_CALLBACK (keep_window_above),
7361 window);
7362 gtk_box_pack_start (GTK_BOX (vbox), button_above, FALSE, FALSE, 0);
7363
7364 button_below = gtk_toggle_button_new_with_label ("Keep below");
7365 g_signal_connect (button_below,
7366 "toggled",
7367 G_CALLBACK (keep_window_below),
7368 window);
7369 gtk_box_pack_start (GTK_BOX (vbox), button_below, FALSE, FALSE, 0);
7370
7371 g_object_set_data (G_OBJECT (button_above), "radio", button_below);
7372 g_object_set_data (G_OBJECT (button_below), "radio", button_above);
7373
7374 button = gtk_button_new_with_label ("Hide (withdraw)");
7375 g_signal_connect_object (button,
7376 "clicked",
7377 G_CALLBACK (gtk_widget_hide),
7378 window,
7379 G_CONNECT_SWAPPED);
7380 gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7381
7382 gtk_widget_show_all (vbox);
7383
7384 return vbox;
7385 }
7386
7387 void
create_window_states(GtkWidget * widget)7388 create_window_states (GtkWidget *widget)
7389 {
7390 static GtkWidget *window = NULL;
7391 GtkWidget *label;
7392 GtkWidget *box1;
7393 GtkWidget *iconified;
7394 GtkWidget *normal;
7395 GtkWidget *controls;
7396
7397 if (!window)
7398 {
7399 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7400 gtk_window_set_screen (GTK_WINDOW (window),
7401 gtk_widget_get_screen (widget));
7402
7403 g_signal_connect (window, "destroy",
7404 G_CALLBACK (gtk_widget_destroyed),
7405 &window);
7406
7407 gtk_window_set_title (GTK_WINDOW (window), "Window states");
7408
7409 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7410 gtk_container_add (GTK_CONTAINER (window), box1);
7411
7412 iconified = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7413
7414 gtk_window_set_screen (GTK_WINDOW (iconified),
7415 gtk_widget_get_screen (widget));
7416
7417 g_signal_connect_object (iconified, "destroy",
7418 G_CALLBACK (gtk_widget_destroy),
7419 window,
7420 G_CONNECT_SWAPPED);
7421 gtk_window_iconify (GTK_WINDOW (iconified));
7422 gtk_window_set_title (GTK_WINDOW (iconified), "Iconified initially");
7423 controls = get_state_controls (iconified);
7424 gtk_container_add (GTK_CONTAINER (iconified), controls);
7425
7426 normal = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7427
7428 gtk_window_set_screen (GTK_WINDOW (normal),
7429 gtk_widget_get_screen (widget));
7430
7431 g_signal_connect_object (normal, "destroy",
7432 G_CALLBACK (gtk_widget_destroy),
7433 window,
7434 G_CONNECT_SWAPPED);
7435
7436 gtk_window_set_title (GTK_WINDOW (normal), "Deiconified initially");
7437 controls = get_state_controls (normal);
7438 gtk_container_add (GTK_CONTAINER (normal), controls);
7439
7440 label = tracking_label (iconified);
7441 gtk_container_add (GTK_CONTAINER (box1), label);
7442
7443 label = tracking_label (normal);
7444 gtk_container_add (GTK_CONTAINER (box1), label);
7445
7446 gtk_widget_show_all (iconified);
7447 gtk_widget_show_all (normal);
7448 gtk_widget_show_all (box1);
7449 }
7450
7451 if (!gtk_widget_get_visible (window))
7452 gtk_widget_show (window);
7453 else
7454 gtk_widget_destroy (window);
7455 }
7456
7457 /*
7458 * Window sizing
7459 */
7460
7461 static gint
configure_event_callback(GtkWidget * widget,GdkEventConfigure * event,gpointer data)7462 configure_event_callback (GtkWidget *widget,
7463 GdkEventConfigure *event,
7464 gpointer data)
7465 {
7466 GtkWidget *label = data;
7467 gchar *msg;
7468 gint x, y;
7469
7470 gtk_window_get_position (GTK_WINDOW (widget), &x, &y);
7471
7472 msg = g_strdup_printf ("event: %d,%d %d x %d\n"
7473 "position: %d, %d",
7474 event->x, event->y, event->width, event->height,
7475 x, y);
7476
7477 gtk_label_set_text (GTK_LABEL (label), msg);
7478
7479 g_free (msg);
7480
7481 return FALSE;
7482 }
7483
7484 static void
get_ints(GtkWidget * window,gint * a,gint * b)7485 get_ints (GtkWidget *window,
7486 gint *a,
7487 gint *b)
7488 {
7489 GtkWidget *spin1;
7490 GtkWidget *spin2;
7491
7492 spin1 = g_object_get_data (G_OBJECT (window), "spin1");
7493 spin2 = g_object_get_data (G_OBJECT (window), "spin2");
7494
7495 *a = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin1));
7496 *b = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (spin2));
7497 }
7498
7499 static void
set_size_callback(GtkWidget * widget,gpointer data)7500 set_size_callback (GtkWidget *widget,
7501 gpointer data)
7502 {
7503 gint w, h;
7504
7505 get_ints (data, &w, &h);
7506
7507 gtk_window_resize (GTK_WINDOW (g_object_get_data (data, "target")), w, h);
7508 }
7509
7510 static void
unset_default_size_callback(GtkWidget * widget,gpointer data)7511 unset_default_size_callback (GtkWidget *widget,
7512 gpointer data)
7513 {
7514 gtk_window_set_default_size (g_object_get_data (data, "target"),
7515 -1, -1);
7516 }
7517
7518 static void
set_default_size_callback(GtkWidget * widget,gpointer data)7519 set_default_size_callback (GtkWidget *widget,
7520 gpointer data)
7521 {
7522 gint w, h;
7523
7524 get_ints (data, &w, &h);
7525
7526 gtk_window_set_default_size (g_object_get_data (data, "target"),
7527 w, h);
7528 }
7529
7530 static void
unset_size_request_callback(GtkWidget * widget,gpointer data)7531 unset_size_request_callback (GtkWidget *widget,
7532 gpointer data)
7533 {
7534 gtk_widget_set_size_request (g_object_get_data (data, "target"),
7535 -1, -1);
7536 }
7537
7538 static void
set_size_request_callback(GtkWidget * widget,gpointer data)7539 set_size_request_callback (GtkWidget *widget,
7540 gpointer data)
7541 {
7542 gint w, h;
7543
7544 get_ints (data, &w, &h);
7545
7546 gtk_widget_set_size_request (g_object_get_data (data, "target"),
7547 w, h);
7548 }
7549
7550 static void
set_location_callback(GtkWidget * widget,gpointer data)7551 set_location_callback (GtkWidget *widget,
7552 gpointer data)
7553 {
7554 gint x, y;
7555
7556 get_ints (data, &x, &y);
7557
7558 gtk_window_move (g_object_get_data (data, "target"), x, y);
7559 }
7560
7561 static void
move_to_position_callback(GtkWidget * widget,gpointer data)7562 move_to_position_callback (GtkWidget *widget,
7563 gpointer data)
7564 {
7565 gint x, y;
7566 GtkWindow *window;
7567
7568 window = g_object_get_data (data, "target");
7569
7570 gtk_window_get_position (window, &x, &y);
7571
7572 gtk_window_move (window, x, y);
7573 }
7574
7575 static void
set_geometry_callback(GtkWidget * entry,gpointer data)7576 set_geometry_callback (GtkWidget *entry,
7577 gpointer data)
7578 {
7579 gchar *text;
7580 GtkWindow *target;
7581
7582 target = GTK_WINDOW (g_object_get_data (G_OBJECT (data), "target"));
7583
7584 text = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1);
7585
7586 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
7587 if (!gtk_window_parse_geometry (target, text))
7588 g_print ("Bad geometry string '%s'\n", text);
7589 G_GNUC_END_IGNORE_DEPRECATIONS
7590
7591 g_free (text);
7592 }
7593
7594 static void
resizable_callback(GtkWidget * widget,gpointer data)7595 resizable_callback (GtkWidget *widget,
7596 gpointer data)
7597 {
7598 g_object_set (g_object_get_data (data, "target"),
7599 "resizable", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)),
7600 NULL);
7601 }
7602
7603 static void
gravity_selected(GtkWidget * widget,gpointer data)7604 gravity_selected (GtkWidget *widget,
7605 gpointer data)
7606 {
7607 gtk_window_set_gravity (GTK_WINDOW (g_object_get_data (data, "target")),
7608 gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GDK_GRAVITY_NORTH_WEST);
7609 }
7610
7611 static void
pos_selected(GtkWidget * widget,gpointer data)7612 pos_selected (GtkWidget *widget,
7613 gpointer data)
7614 {
7615 gtk_window_set_position (GTK_WINDOW (g_object_get_data (data, "target")),
7616 gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) + GTK_WIN_POS_NONE);
7617 }
7618
7619 static void
move_gravity_window_to_current_position(GtkWidget * widget,gpointer data)7620 move_gravity_window_to_current_position (GtkWidget *widget,
7621 gpointer data)
7622 {
7623 gint x, y;
7624 GtkWindow *window;
7625
7626 window = GTK_WINDOW (data);
7627
7628 gtk_window_get_position (window, &x, &y);
7629
7630 gtk_window_move (window, x, y);
7631 }
7632
7633 static void
get_screen_corner(GtkWindow * window,gint * x,gint * y)7634 get_screen_corner (GtkWindow *window,
7635 gint *x,
7636 gint *y)
7637 {
7638 int w, h;
7639 GdkScreen * screen = gtk_window_get_screen (window);
7640
7641 gtk_window_get_size (GTK_WINDOW (window), &w, &h);
7642
7643 switch (gtk_window_get_gravity (window))
7644 {
7645 case GDK_GRAVITY_SOUTH_EAST:
7646 *x = gdk_screen_get_width (screen) - w;
7647 *y = gdk_screen_get_height (screen) - h;
7648 break;
7649
7650 case GDK_GRAVITY_NORTH_EAST:
7651 *x = gdk_screen_get_width (screen) - w;
7652 *y = 0;
7653 break;
7654
7655 case GDK_GRAVITY_SOUTH_WEST:
7656 *x = 0;
7657 *y = gdk_screen_get_height (screen) - h;
7658 break;
7659
7660 case GDK_GRAVITY_NORTH_WEST:
7661 *x = 0;
7662 *y = 0;
7663 break;
7664
7665 case GDK_GRAVITY_SOUTH:
7666 *x = (gdk_screen_get_width (screen) - w) / 2;
7667 *y = gdk_screen_get_height (screen) - h;
7668 break;
7669
7670 case GDK_GRAVITY_NORTH:
7671 *x = (gdk_screen_get_width (screen) - w) / 2;
7672 *y = 0;
7673 break;
7674
7675 case GDK_GRAVITY_WEST:
7676 *x = 0;
7677 *y = (gdk_screen_get_height (screen) - h) / 2;
7678 break;
7679
7680 case GDK_GRAVITY_EAST:
7681 *x = gdk_screen_get_width (screen) - w;
7682 *y = (gdk_screen_get_height (screen) - h) / 2;
7683 break;
7684
7685 case GDK_GRAVITY_CENTER:
7686 *x = (gdk_screen_get_width (screen) - w) / 2;
7687 *y = (gdk_screen_get_height (screen) - h) / 2;
7688 break;
7689
7690 case GDK_GRAVITY_STATIC:
7691 /* pick some random numbers */
7692 *x = 350;
7693 *y = 350;
7694 break;
7695
7696 default:
7697 g_assert_not_reached ();
7698 break;
7699 }
7700 }
7701
7702 static void
move_gravity_window_to_starting_position(GtkWidget * widget,gpointer data)7703 move_gravity_window_to_starting_position (GtkWidget *widget,
7704 gpointer data)
7705 {
7706 gint x, y;
7707 GtkWindow *window;
7708
7709 window = GTK_WINDOW (data);
7710
7711 get_screen_corner (window,
7712 &x, &y);
7713
7714 gtk_window_move (window, x, y);
7715 }
7716
7717 static GtkWidget*
make_gravity_window(GtkWidget * destroy_with,GdkGravity gravity,const gchar * title)7718 make_gravity_window (GtkWidget *destroy_with,
7719 GdkGravity gravity,
7720 const gchar *title)
7721 {
7722 GtkWidget *window;
7723 GtkWidget *button;
7724 GtkWidget *vbox;
7725 int x, y;
7726
7727 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7728
7729 gtk_window_set_screen (GTK_WINDOW (window),
7730 gtk_widget_get_screen (destroy_with));
7731
7732 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
7733 gtk_widget_show (vbox);
7734
7735 gtk_container_add (GTK_CONTAINER (window), vbox);
7736 gtk_window_set_title (GTK_WINDOW (window), title);
7737 gtk_window_set_gravity (GTK_WINDOW (window), gravity);
7738
7739 g_signal_connect_object (destroy_with,
7740 "destroy",
7741 G_CALLBACK (gtk_widget_destroy),
7742 window,
7743 G_CONNECT_SWAPPED);
7744
7745
7746 button = gtk_button_new_with_mnemonic ("_Move to current position");
7747
7748 g_signal_connect (button, "clicked",
7749 G_CALLBACK (move_gravity_window_to_current_position),
7750 window);
7751
7752 gtk_container_add (GTK_CONTAINER (vbox), button);
7753 gtk_widget_show (button);
7754
7755 button = gtk_button_new_with_mnemonic ("Move to _starting position");
7756
7757 g_signal_connect (button, "clicked",
7758 G_CALLBACK (move_gravity_window_to_starting_position),
7759 window);
7760
7761 gtk_container_add (GTK_CONTAINER (vbox), button);
7762 gtk_widget_show (button);
7763
7764 /* Pretend this is the result of --geometry.
7765 * DO NOT COPY THIS CODE unless you are setting --geometry results,
7766 * and in that case you probably should just use gtk_window_parse_geometry().
7767 * AGAIN, DO NOT SET GDK_HINT_USER_POS! It violates the ICCCM unless
7768 * you are parsing --geometry or equivalent.
7769 */
7770 gtk_window_set_geometry_hints (GTK_WINDOW (window),
7771 NULL, NULL,
7772 GDK_HINT_USER_POS);
7773
7774 gtk_window_set_default_size (GTK_WINDOW (window),
7775 200, 200);
7776
7777 get_screen_corner (GTK_WINDOW (window), &x, &y);
7778
7779 gtk_window_move (GTK_WINDOW (window),
7780 x, y);
7781
7782 return window;
7783 }
7784
7785 static void
do_gravity_test(GtkWidget * widget,gpointer data)7786 do_gravity_test (GtkWidget *widget,
7787 gpointer data)
7788 {
7789 GtkWidget *destroy_with = data;
7790 GtkWidget *window;
7791
7792 /* We put a window at each gravity point on the screen. */
7793 window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_WEST,
7794 "NorthWest");
7795 gtk_widget_show (window);
7796
7797 window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_EAST,
7798 "SouthEast");
7799 gtk_widget_show (window);
7800
7801 window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH_EAST,
7802 "NorthEast");
7803 gtk_widget_show (window);
7804
7805 window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH_WEST,
7806 "SouthWest");
7807 gtk_widget_show (window);
7808
7809 window = make_gravity_window (destroy_with, GDK_GRAVITY_SOUTH,
7810 "South");
7811 gtk_widget_show (window);
7812
7813 window = make_gravity_window (destroy_with, GDK_GRAVITY_NORTH,
7814 "North");
7815 gtk_widget_show (window);
7816
7817
7818 window = make_gravity_window (destroy_with, GDK_GRAVITY_WEST,
7819 "West");
7820 gtk_widget_show (window);
7821
7822
7823 window = make_gravity_window (destroy_with, GDK_GRAVITY_EAST,
7824 "East");
7825 gtk_widget_show (window);
7826
7827 window = make_gravity_window (destroy_with, GDK_GRAVITY_CENTER,
7828 "Center");
7829 gtk_widget_show (window);
7830
7831 window = make_gravity_window (destroy_with, GDK_GRAVITY_STATIC,
7832 "Static");
7833 gtk_widget_show (window);
7834 }
7835
7836 static GtkWidget*
window_controls(GtkWidget * window)7837 window_controls (GtkWidget *window)
7838 {
7839 GtkWidget *control_window;
7840 GtkWidget *label;
7841 GtkWidget *vbox;
7842 GtkWidget *button;
7843 GtkWidget *spin;
7844 GtkAdjustment *adjustment;
7845 GtkWidget *entry;
7846 GtkWidget *om;
7847 gint i;
7848
7849 control_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
7850
7851 gtk_window_set_screen (GTK_WINDOW (control_window),
7852 gtk_widget_get_screen (window));
7853
7854 gtk_window_set_title (GTK_WINDOW (control_window), "Size controls");
7855
7856 g_object_set_data (G_OBJECT (control_window),
7857 "target",
7858 window);
7859
7860 g_signal_connect_object (control_window,
7861 "destroy",
7862 G_CALLBACK (gtk_widget_destroy),
7863 window,
7864 G_CONNECT_SWAPPED);
7865
7866 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
7867
7868 gtk_container_add (GTK_CONTAINER (control_window), vbox);
7869
7870 label = gtk_label_new ("<no configure events>");
7871 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
7872
7873 g_signal_connect (window,
7874 "configure_event",
7875 G_CALLBACK (configure_event_callback),
7876 label);
7877
7878 adjustment = gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0, 5.0, 0.0);
7879 spin = gtk_spin_button_new (adjustment, 0, 0);
7880
7881 gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
7882
7883 g_object_set_data (G_OBJECT (control_window), "spin1", spin);
7884
7885 adjustment = gtk_adjustment_new (10.0, -2000.0, 2000.0, 1.0, 5.0, 0.0);
7886 spin = gtk_spin_button_new (adjustment, 0, 0);
7887
7888 gtk_box_pack_start (GTK_BOX (vbox), spin, FALSE, FALSE, 0);
7889
7890 g_object_set_data (G_OBJECT (control_window), "spin2", spin);
7891
7892 entry = gtk_entry_new ();
7893 gtk_box_pack_start (GTK_BOX (vbox), entry, FALSE, FALSE, 0);
7894
7895 g_signal_connect (entry, "changed",
7896 G_CALLBACK (set_geometry_callback),
7897 control_window);
7898
7899 button = gtk_button_new_with_label ("Show gravity test windows");
7900 g_signal_connect_swapped (button,
7901 "clicked",
7902 G_CALLBACK (do_gravity_test),
7903 control_window);
7904 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7905
7906 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
7907 button = gtk_button_new_with_label ("Reshow with initial size");
7908 g_signal_connect_object (button,
7909 "clicked",
7910 G_CALLBACK (gtk_window_reshow_with_initial_size),
7911 window,
7912 G_CONNECT_SWAPPED);
7913 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7914 G_GNUC_END_IGNORE_DEPRECATIONS;
7915
7916 button = gtk_button_new_with_label ("Queue resize");
7917 g_signal_connect_object (button,
7918 "clicked",
7919 G_CALLBACK (gtk_widget_queue_resize),
7920 window,
7921 G_CONNECT_SWAPPED);
7922 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7923
7924 button = gtk_button_new_with_label ("Resize");
7925 g_signal_connect (button,
7926 "clicked",
7927 G_CALLBACK (set_size_callback),
7928 control_window);
7929 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7930
7931 button = gtk_button_new_with_label ("Set default size");
7932 g_signal_connect (button,
7933 "clicked",
7934 G_CALLBACK (set_default_size_callback),
7935 control_window);
7936 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7937
7938 button = gtk_button_new_with_label ("Unset default size");
7939 g_signal_connect (button,
7940 "clicked",
7941 G_CALLBACK (unset_default_size_callback),
7942 control_window);
7943 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7944
7945 button = gtk_button_new_with_label ("Set size request");
7946 g_signal_connect (button,
7947 "clicked",
7948 G_CALLBACK (set_size_request_callback),
7949 control_window);
7950 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7951
7952 button = gtk_button_new_with_label ("Unset size request");
7953 g_signal_connect (button,
7954 "clicked",
7955 G_CALLBACK (unset_size_request_callback),
7956 control_window);
7957 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7958
7959 button = gtk_button_new_with_label ("Move");
7960 g_signal_connect (button,
7961 "clicked",
7962 G_CALLBACK (set_location_callback),
7963 control_window);
7964 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7965
7966 button = gtk_button_new_with_label ("Move to current position");
7967 g_signal_connect (button,
7968 "clicked",
7969 G_CALLBACK (move_to_position_callback),
7970 control_window);
7971 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7972
7973 button = gtk_check_button_new_with_label ("Allow resize");
7974 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
7975 g_signal_connect (button,
7976 "toggled",
7977 G_CALLBACK (resizable_callback),
7978 control_window);
7979 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7980
7981 button = gtk_button_new_with_mnemonic ("_Show");
7982 g_signal_connect_object (button,
7983 "clicked",
7984 G_CALLBACK (gtk_widget_show),
7985 window,
7986 G_CONNECT_SWAPPED);
7987 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7988
7989 button = gtk_button_new_with_mnemonic ("_Hide");
7990 g_signal_connect_object (button,
7991 "clicked",
7992 G_CALLBACK (gtk_widget_hide),
7993 window,
7994 G_CONNECT_SWAPPED);
7995 gtk_box_pack_end (GTK_BOX (vbox), button, FALSE, FALSE, 0);
7996
7997 om = gtk_combo_box_text_new ();
7998 i = 0;
7999 while (i < 10)
8000 {
8001 static gchar *names[] = {
8002 "GDK_GRAVITY_NORTH_WEST",
8003 "GDK_GRAVITY_NORTH",
8004 "GDK_GRAVITY_NORTH_EAST",
8005 "GDK_GRAVITY_WEST",
8006 "GDK_GRAVITY_CENTER",
8007 "GDK_GRAVITY_EAST",
8008 "GDK_GRAVITY_SOUTH_WEST",
8009 "GDK_GRAVITY_SOUTH",
8010 "GDK_GRAVITY_SOUTH_EAST",
8011 "GDK_GRAVITY_STATIC",
8012 NULL
8013 };
8014
8015 g_assert (names[i]);
8016 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
8017
8018 ++i;
8019 }
8020
8021 g_signal_connect (om,
8022 "changed",
8023 G_CALLBACK (gravity_selected),
8024 control_window);
8025
8026 gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8027
8028
8029 om = gtk_combo_box_text_new ();
8030 i = 0;
8031 while (i < 5)
8032 {
8033 static gchar *names[] = {
8034 "GTK_WIN_POS_NONE",
8035 "GTK_WIN_POS_CENTER",
8036 "GTK_WIN_POS_MOUSE",
8037 "GTK_WIN_POS_CENTER_ALWAYS",
8038 "GTK_WIN_POS_CENTER_ON_PARENT",
8039 NULL
8040 };
8041
8042 g_assert (names[i]);
8043 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (om), names[i]);
8044
8045 ++i;
8046 }
8047
8048 g_signal_connect (om,
8049 "changed",
8050 G_CALLBACK (pos_selected),
8051 control_window);
8052
8053 gtk_box_pack_end (GTK_BOX (vbox), om, FALSE, FALSE, 0);
8054
8055 gtk_widget_show_all (vbox);
8056
8057 return control_window;
8058 }
8059
8060 void
create_window_sizing(GtkWidget * widget)8061 create_window_sizing (GtkWidget *widget)
8062 {
8063 static GtkWidget *window = NULL;
8064 static GtkWidget *target_window = NULL;
8065
8066 if (!target_window)
8067 {
8068 GtkWidget *label;
8069
8070 target_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8071 gtk_window_set_screen (GTK_WINDOW (target_window),
8072 gtk_widget_get_screen (widget));
8073 label = gtk_label_new (NULL);
8074 gtk_label_set_markup (GTK_LABEL (label), "<span foreground=\"purple\"><big>Window being resized</big></span>\nBlah blah blah blah\nblah blah blah\nblah blah blah blah blah");
8075 gtk_container_add (GTK_CONTAINER (target_window), label);
8076 gtk_widget_show (label);
8077
8078 g_signal_connect (target_window, "destroy",
8079 G_CALLBACK (gtk_widget_destroyed),
8080 &target_window);
8081
8082 window = window_controls (target_window);
8083
8084 g_signal_connect (window, "destroy",
8085 G_CALLBACK (gtk_widget_destroyed),
8086 &window);
8087
8088 gtk_window_set_title (GTK_WINDOW (target_window), "Window to size");
8089 }
8090
8091 /* don't show target window by default, we want to allow testing
8092 * of behavior on first show.
8093 */
8094
8095 if (!gtk_widget_get_visible (window))
8096 gtk_widget_show (window);
8097 else
8098 gtk_widget_destroy (window);
8099 }
8100
8101 /*
8102 * GtkProgressBar
8103 */
8104
8105 typedef struct _ProgressData {
8106 GtkWidget *window;
8107 GtkWidget *pbar;
8108 GtkWidget *block_spin;
8109 GtkWidget *x_align_spin;
8110 GtkWidget *y_align_spin;
8111 GtkWidget *step_spin;
8112 GtkWidget *act_blocks_spin;
8113 GtkWidget *label;
8114 GtkWidget *omenu1;
8115 GtkWidget *elmenu;
8116 GtkWidget *omenu2;
8117 GtkWidget *entry;
8118 int timer;
8119 gboolean activity;
8120 } ProgressData;
8121
8122 gboolean
progress_timeout(gpointer data)8123 progress_timeout (gpointer data)
8124 {
8125 ProgressData *pdata = data;
8126 gdouble new_val;
8127 gchar *text;
8128
8129 if (pdata->activity)
8130 {
8131 gtk_progress_bar_pulse (GTK_PROGRESS_BAR (pdata->pbar));
8132
8133 text = g_strdup_printf ("%s", "???");
8134 }
8135 else
8136 {
8137 new_val = gtk_progress_bar_get_fraction (GTK_PROGRESS_BAR (pdata->pbar)) + 0.01;
8138 if (new_val > 1.00)
8139 new_val = 0.00;
8140 gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (pdata->pbar), new_val);
8141
8142 text = g_strdup_printf ("%.0f%%", 100 * new_val);
8143 }
8144
8145 gtk_label_set_text (GTK_LABEL (pdata->label), text);
8146 g_free (text);
8147
8148 return TRUE;
8149 }
8150
8151 static void
destroy_progress(GtkWidget * widget,ProgressData ** pdata)8152 destroy_progress (GtkWidget *widget,
8153 ProgressData **pdata)
8154 {
8155 if ((*pdata)->timer)
8156 {
8157 g_source_remove ((*pdata)->timer);
8158 (*pdata)->timer = 0;
8159 }
8160 (*pdata)->window = NULL;
8161 g_free (*pdata);
8162 *pdata = NULL;
8163 }
8164
8165 static void
progressbar_toggle_orientation(GtkWidget * widget,gpointer data)8166 progressbar_toggle_orientation (GtkWidget *widget, gpointer data)
8167 {
8168 ProgressData *pdata;
8169 gint i;
8170
8171 pdata = (ProgressData *) data;
8172
8173 if (!gtk_widget_get_mapped (widget))
8174 return;
8175
8176 i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8177
8178 if (i == 0 || i == 1)
8179 gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_HORIZONTAL);
8180 else
8181 gtk_orientable_set_orientation (GTK_ORIENTABLE (pdata->pbar), GTK_ORIENTATION_VERTICAL);
8182
8183 if (i == 1 || i == 2)
8184 gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), TRUE);
8185 else
8186 gtk_progress_bar_set_inverted (GTK_PROGRESS_BAR (pdata->pbar), FALSE);
8187 }
8188
8189 static void
toggle_show_text(GtkWidget * widget,ProgressData * pdata)8190 toggle_show_text (GtkWidget *widget, ProgressData *pdata)
8191 {
8192 gboolean active;
8193
8194 active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8195 gtk_progress_bar_set_show_text (GTK_PROGRESS_BAR (pdata->pbar), active);
8196 }
8197
8198 static void
progressbar_toggle_ellipsize(GtkWidget * widget,gpointer data)8199 progressbar_toggle_ellipsize (GtkWidget *widget,
8200 gpointer data)
8201 {
8202 ProgressData *pdata = data;
8203 if (gtk_widget_is_drawable (widget))
8204 {
8205 gint i = gtk_combo_box_get_active (GTK_COMBO_BOX (widget));
8206 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar), i);
8207 }
8208 }
8209
8210 static void
toggle_activity_mode(GtkWidget * widget,ProgressData * pdata)8211 toggle_activity_mode (GtkWidget *widget, ProgressData *pdata)
8212 {
8213 pdata->activity = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
8214 }
8215
8216 static void
toggle_running(GtkWidget * widget,ProgressData * pdata)8217 toggle_running (GtkWidget *widget, ProgressData *pdata)
8218 {
8219 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
8220 {
8221 if (pdata->timer == 0)
8222 pdata->timer = g_timeout_add (100, (GSourceFunc)progress_timeout, pdata);
8223 }
8224 else
8225 {
8226 if (pdata->timer != 0)
8227 {
8228 g_source_remove (pdata->timer);
8229 pdata->timer = 0;
8230 }
8231 }
8232 }
8233
8234 static void
entry_changed(GtkWidget * widget,ProgressData * pdata)8235 entry_changed (GtkWidget *widget, ProgressData *pdata)
8236 {
8237 gtk_progress_bar_set_text (GTK_PROGRESS_BAR (pdata->pbar),
8238 gtk_entry_get_text (GTK_ENTRY (pdata->entry)));
8239 }
8240
8241 void
create_progress_bar(GtkWidget * widget)8242 create_progress_bar (GtkWidget *widget)
8243 {
8244 GtkWidget *content_area;
8245 GtkWidget *vbox;
8246 GtkWidget *vbox2;
8247 GtkWidget *hbox;
8248 GtkWidget *check;
8249 GtkWidget *frame;
8250 GtkWidget *grid;
8251 GtkWidget *label;
8252 static ProgressData *pdata = NULL;
8253
8254 static gchar *items1[] =
8255 {
8256 "Left-Right",
8257 "Right-Left",
8258 "Bottom-Top",
8259 "Top-Bottom"
8260 };
8261
8262 static char *ellipsize_items[] = {
8263 "None", // PANGO_ELLIPSIZE_NONE,
8264 "Start", // PANGO_ELLIPSIZE_START,
8265 "Middle", // PANGO_ELLIPSIZE_MIDDLE,
8266 "End", // PANGO_ELLIPSIZE_END
8267 };
8268
8269 if (!pdata)
8270 pdata = g_new0 (ProgressData, 1);
8271
8272 if (!pdata->window)
8273 {
8274 pdata->window = gtk_dialog_new ();
8275
8276 gtk_window_set_screen (GTK_WINDOW (pdata->window),
8277 gtk_widget_get_screen (widget));
8278
8279 gtk_window_set_resizable (GTK_WINDOW (pdata->window), TRUE);
8280
8281 g_signal_connect (pdata->window, "destroy",
8282 G_CALLBACK (destroy_progress),
8283 &pdata);
8284 pdata->timer = 0;
8285
8286 content_area = gtk_dialog_get_content_area (GTK_DIALOG (pdata->window));
8287
8288 gtk_window_set_title (GTK_WINDOW (pdata->window), "GtkProgressBar");
8289 gtk_container_set_border_width (GTK_CONTAINER (pdata->window), 0);
8290
8291 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8292 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8293 gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, TRUE, 0);
8294
8295 frame = gtk_frame_new ("Progress");
8296 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8297
8298 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8299 gtk_container_add (GTK_CONTAINER (frame), vbox2);
8300
8301 pdata->pbar = gtk_progress_bar_new ();
8302 gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (pdata->pbar),
8303 PANGO_ELLIPSIZE_MIDDLE);
8304 gtk_widget_set_halign (pdata->pbar, GTK_ALIGN_CENTER);
8305 gtk_widget_set_valign (pdata->pbar, GTK_ALIGN_CENTER);
8306 gtk_box_pack_start (GTK_BOX (vbox2), pdata->pbar, FALSE, FALSE, 5);
8307
8308 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
8309 gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
8310 gtk_widget_set_valign (hbox, GTK_ALIGN_CENTER);
8311 gtk_box_pack_start (GTK_BOX (vbox2), hbox, FALSE, FALSE, 5);
8312 label = gtk_label_new ("Label updated by user :");
8313 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8314 pdata->label = gtk_label_new ("");
8315 gtk_box_pack_start (GTK_BOX (hbox), pdata->label, FALSE, TRUE, 0);
8316
8317 frame = gtk_frame_new ("Options");
8318 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, TRUE, 0);
8319
8320 vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8321 gtk_container_add (GTK_CONTAINER (frame), vbox2);
8322
8323 grid = gtk_grid_new ();
8324 gtk_grid_set_row_spacing (GTK_GRID (grid), 10);
8325 gtk_grid_set_column_spacing (GTK_GRID (grid), 10);
8326 gtk_box_pack_start (GTK_BOX (vbox2), grid, FALSE, TRUE, 0);
8327
8328 label = gtk_label_new ("Orientation :");
8329 gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
8330 gtk_widget_set_halign (label, GTK_ALIGN_START);
8331 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
8332
8333 pdata->omenu1 = build_option_menu (items1, 4, 0,
8334 progressbar_toggle_orientation,
8335 pdata);
8336 gtk_grid_attach (GTK_GRID (grid), pdata->omenu1, 1, 0, 1, 1);
8337
8338 check = gtk_check_button_new_with_label ("Running");
8339 g_signal_connect (check, "toggled",
8340 G_CALLBACK (toggle_running),
8341 pdata);
8342 gtk_grid_attach (GTK_GRID (grid), check, 0, 1, 2, 1);
8343 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE);
8344
8345 check = gtk_check_button_new_with_label ("Show text");
8346 g_signal_connect (check, "clicked",
8347 G_CALLBACK (toggle_show_text),
8348 pdata);
8349 gtk_grid_attach (GTK_GRID (grid), check, 0, 2, 1, 1);
8350
8351 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
8352 gtk_grid_attach (GTK_GRID (grid), hbox, 1, 2, 1, 1);
8353
8354 label = gtk_label_new ("Text: ");
8355 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
8356
8357 pdata->entry = gtk_entry_new ();
8358 gtk_widget_set_hexpand (pdata->entry, TRUE);
8359 g_signal_connect (pdata->entry, "changed",
8360 G_CALLBACK (entry_changed),
8361 pdata);
8362 gtk_box_pack_start (GTK_BOX (hbox), pdata->entry, TRUE, TRUE, 0);
8363 gtk_widget_set_size_request (pdata->entry, 100, -1);
8364
8365 label = gtk_label_new ("Ellipsize text :");
8366 gtk_grid_attach (GTK_GRID (grid), label, 0, 10, 1, 1);
8367
8368 gtk_widget_set_halign (label, GTK_ALIGN_START);
8369 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
8370 pdata->elmenu = build_option_menu (ellipsize_items,
8371 sizeof (ellipsize_items) / sizeof (ellipsize_items[0]),
8372 2, // PANGO_ELLIPSIZE_MIDDLE
8373 progressbar_toggle_ellipsize,
8374 pdata);
8375 gtk_grid_attach (GTK_GRID (grid), pdata->elmenu, 1, 10, 1, 1);
8376
8377 check = gtk_check_button_new_with_label ("Activity mode");
8378 g_signal_connect (check, "clicked",
8379 G_CALLBACK (toggle_activity_mode), pdata);
8380 gtk_grid_attach (GTK_GRID (grid), check, 0, 15, 1, 1);
8381
8382 gtk_dialog_add_button (GTK_DIALOG (pdata->window), "Close", GTK_RESPONSE_CLOSE);
8383 g_signal_connect (pdata->window, "response",
8384 G_CALLBACK (gtk_widget_destroy),
8385 NULL);
8386 }
8387
8388 if (!gtk_widget_get_visible (pdata->window))
8389 gtk_widget_show_all (pdata->window);
8390 else
8391 gtk_widget_destroy (pdata->window);
8392 }
8393
8394 /*
8395 * Properties
8396 */
8397
8398 typedef struct {
8399 int x;
8400 int y;
8401 gboolean found;
8402 gboolean first;
8403 GtkWidget *res_widget;
8404 } FindWidgetData;
8405
8406 static void
find_widget(GtkWidget * widget,FindWidgetData * data)8407 find_widget (GtkWidget *widget, FindWidgetData *data)
8408 {
8409 GtkAllocation new_allocation;
8410 gint x_offset = 0;
8411 gint y_offset = 0;
8412
8413 gtk_widget_get_allocation (widget, &new_allocation);
8414
8415 if (data->found || !gtk_widget_get_mapped (widget))
8416 return;
8417
8418 /* Note that in the following code, we only count the
8419 * position as being inside a WINDOW widget if it is inside
8420 * widget->window; points that are outside of widget->window
8421 * but within the allocation are not counted. This is consistent
8422 * with the way we highlight drag targets.
8423 */
8424 if (gtk_widget_get_has_window (widget))
8425 {
8426 new_allocation.x = 0;
8427 new_allocation.y = 0;
8428 }
8429
8430 if (gtk_widget_get_parent (widget) && !data->first)
8431 {
8432 GdkWindow *window = gtk_widget_get_window (widget);
8433 while (window != gtk_widget_get_window (gtk_widget_get_parent (widget)))
8434 {
8435 gint tx, ty, twidth, theight;
8436
8437 twidth = gdk_window_get_width (window);
8438 theight = gdk_window_get_height (window);
8439
8440 if (new_allocation.x < 0)
8441 {
8442 new_allocation.width += new_allocation.x;
8443 new_allocation.x = 0;
8444 }
8445 if (new_allocation.y < 0)
8446 {
8447 new_allocation.height += new_allocation.y;
8448 new_allocation.y = 0;
8449 }
8450 if (new_allocation.x + new_allocation.width > twidth)
8451 new_allocation.width = twidth - new_allocation.x;
8452 if (new_allocation.y + new_allocation.height > theight)
8453 new_allocation.height = theight - new_allocation.y;
8454
8455 gdk_window_get_position (window, &tx, &ty);
8456 new_allocation.x += tx;
8457 x_offset += tx;
8458 new_allocation.y += ty;
8459 y_offset += ty;
8460
8461 window = gdk_window_get_parent (window);
8462 }
8463 }
8464
8465 if ((data->x >= new_allocation.x) && (data->y >= new_allocation.y) &&
8466 (data->x < new_allocation.x + new_allocation.width) &&
8467 (data->y < new_allocation.y + new_allocation.height))
8468 {
8469 /* First, check if the drag is in a valid drop site in
8470 * one of our children
8471 */
8472 if (GTK_IS_CONTAINER (widget))
8473 {
8474 FindWidgetData new_data = *data;
8475
8476 new_data.x -= x_offset;
8477 new_data.y -= y_offset;
8478 new_data.found = FALSE;
8479 new_data.first = FALSE;
8480
8481 gtk_container_forall (GTK_CONTAINER (widget),
8482 (GtkCallback)find_widget,
8483 &new_data);
8484
8485 data->found = new_data.found;
8486 if (data->found)
8487 data->res_widget = new_data.res_widget;
8488 }
8489
8490 /* If not, and this widget is registered as a drop site, check to
8491 * emit "drag_motion" to check if we are actually in
8492 * a drop site.
8493 */
8494 if (!data->found)
8495 {
8496 data->found = TRUE;
8497 data->res_widget = widget;
8498 }
8499 }
8500 }
8501
8502 static GtkWidget *
find_widget_at_pointer(GdkDevice * device)8503 find_widget_at_pointer (GdkDevice *device)
8504 {
8505 GtkWidget *widget = NULL;
8506 GdkWindow *pointer_window;
8507 gint x, y;
8508 FindWidgetData data;
8509
8510 pointer_window = gdk_device_get_window_at_position (device, NULL, NULL);
8511
8512 if (pointer_window)
8513 {
8514 gpointer widget_ptr;
8515
8516 gdk_window_get_user_data (pointer_window, &widget_ptr);
8517 widget = widget_ptr;
8518 }
8519
8520 if (widget)
8521 {
8522 gdk_window_get_device_position (gtk_widget_get_window (widget),
8523 device,
8524 &x, &y, NULL);
8525
8526 data.x = x;
8527 data.y = y;
8528 data.found = FALSE;
8529 data.first = TRUE;
8530
8531 find_widget (widget, &data);
8532 if (data.found)
8533 return data.res_widget;
8534 return widget;
8535 }
8536 return NULL;
8537 }
8538
8539 struct SnapshotData {
8540 GtkWidget *toplevel_button;
8541 GtkWidget **window;
8542 GdkCursor *cursor;
8543 gboolean in_query;
8544 gboolean is_toplevel;
8545 gint handler;
8546 };
8547
8548 static void
destroy_snapshot_data(GtkWidget * widget,struct SnapshotData * data)8549 destroy_snapshot_data (GtkWidget *widget,
8550 struct SnapshotData *data)
8551 {
8552 if (*data->window)
8553 *data->window = NULL;
8554
8555 if (data->cursor)
8556 {
8557 g_object_unref (data->cursor);
8558 data->cursor = NULL;
8559 }
8560
8561 if (data->handler)
8562 {
8563 g_signal_handler_disconnect (widget, data->handler);
8564 data->handler = 0;
8565 }
8566
8567 g_free (data);
8568 }
8569
8570 static gint
snapshot_widget_event(GtkWidget * widget,GdkEvent * event,struct SnapshotData * data)8571 snapshot_widget_event (GtkWidget *widget,
8572 GdkEvent *event,
8573 struct SnapshotData *data)
8574 {
8575 GtkWidget *res_widget = NULL;
8576
8577 if (!data->in_query)
8578 return FALSE;
8579
8580 if (event->type == GDK_BUTTON_RELEASE)
8581 {
8582 gtk_grab_remove (widget);
8583 gdk_seat_ungrab (gdk_event_get_seat (event));
8584
8585 res_widget = find_widget_at_pointer (gdk_event_get_device (event));
8586 if (data->is_toplevel && res_widget)
8587 res_widget = gtk_widget_get_toplevel (res_widget);
8588 if (res_widget)
8589 {
8590 cairo_surface_t *surface;
8591 GtkWidget *window, *image;
8592 GdkPixbuf *pixbuf;
8593 int width, height;
8594 cairo_t *cr;
8595
8596 width = gtk_widget_get_allocated_width (res_widget);
8597 height = gtk_widget_get_allocated_height (res_widget);
8598
8599 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
8600
8601 cr = cairo_create (surface);
8602 gtk_widget_draw (res_widget, cr);
8603 cairo_destroy (cr);
8604
8605 pixbuf = gdk_pixbuf_get_from_surface (surface,
8606 0, 0,
8607 width, height);
8608 cairo_surface_destroy (surface);
8609
8610 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8611 image = gtk_image_new_from_pixbuf (pixbuf);
8612 g_object_unref (pixbuf);
8613
8614 gtk_container_add (GTK_CONTAINER (window), image);
8615 gtk_widget_show_all (window);
8616 }
8617
8618 data->in_query = FALSE;
8619 }
8620 return FALSE;
8621 }
8622
8623
8624 static void
snapshot_widget(GtkButton * button,struct SnapshotData * data)8625 snapshot_widget (GtkButton *button,
8626 struct SnapshotData *data)
8627 {
8628 GtkWidget *widget = GTK_WIDGET (button);
8629 GdkDevice *device;
8630
8631 device = gtk_get_current_event_device ();
8632 if (device == NULL)
8633 return;
8634
8635 data->is_toplevel = widget == data->toplevel_button;
8636
8637 if (!data->cursor)
8638 data->cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
8639 GDK_TARGET);
8640
8641 gdk_seat_grab (gdk_device_get_seat (device),
8642 gtk_widget_get_window (widget),
8643 GDK_SEAT_CAPABILITY_ALL_POINTING,
8644 TRUE, data->cursor, NULL, NULL, NULL);
8645
8646 g_signal_connect (button, "event",
8647 G_CALLBACK (snapshot_widget_event), data);
8648
8649 gtk_grab_add (widget);
8650
8651 data->in_query = TRUE;
8652 }
8653
8654 static void
create_snapshot(GtkWidget * widget)8655 create_snapshot (GtkWidget *widget)
8656 {
8657 static GtkWidget *window = NULL;
8658 GtkWidget *button;
8659 GtkWidget *vbox;
8660 struct SnapshotData *data;
8661
8662 data = g_new (struct SnapshotData, 1);
8663 data->window = &window;
8664 data->in_query = FALSE;
8665 data->cursor = NULL;
8666 data->handler = 0;
8667
8668 if (!window)
8669 {
8670 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
8671
8672 gtk_window_set_screen (GTK_WINDOW (window),
8673 gtk_widget_get_screen (widget));
8674
8675 data->handler = g_signal_connect (window, "destroy",
8676 G_CALLBACK (destroy_snapshot_data),
8677 data);
8678
8679 gtk_window_set_title (GTK_WINDOW (window), "test snapshot");
8680 gtk_container_set_border_width (GTK_CONTAINER (window), 10);
8681
8682 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 1);
8683 gtk_container_add (GTK_CONTAINER (window), vbox);
8684
8685 button = gtk_button_new_with_label ("Snapshot widget");
8686 gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8687 g_signal_connect (button, "clicked",
8688 G_CALLBACK (snapshot_widget),
8689 data);
8690
8691 button = gtk_button_new_with_label ("Snapshot toplevel");
8692 data->toplevel_button = button;
8693 gtk_box_pack_start (GTK_BOX (vbox), button, TRUE, TRUE, 0);
8694 g_signal_connect (button, "clicked",
8695 G_CALLBACK (snapshot_widget),
8696 data);
8697 }
8698
8699 if (!gtk_widget_get_visible (window))
8700 gtk_widget_show_all (window);
8701 else
8702 gtk_widget_destroy (window);
8703
8704 }
8705
8706 /*
8707 * Selection Test
8708 */
8709
8710 void
selection_test_received(GtkWidget * tree_view,GtkSelectionData * selection_data)8711 selection_test_received (GtkWidget *tree_view,
8712 GtkSelectionData *selection_data)
8713 {
8714 GtkTreeModel *model;
8715 GtkListStore *store;
8716 GdkAtom *atoms;
8717 int i, l;
8718
8719 if (gtk_selection_data_get_length (selection_data) < 0)
8720 {
8721 g_print ("Selection retrieval failed\n");
8722 return;
8723 }
8724 if (gtk_selection_data_get_data_type (selection_data) != GDK_SELECTION_TYPE_ATOM)
8725 {
8726 g_print ("Selection \"TARGETS\" was not returned as atoms!\n");
8727 return;
8728 }
8729
8730 /* Clear out any current list items */
8731
8732 model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
8733 store = GTK_LIST_STORE (model);
8734 gtk_list_store_clear (store);
8735
8736 /* Add new items to list */
8737
8738 gtk_selection_data_get_targets (selection_data,
8739 &atoms, &l);
8740
8741 for (i = 0; i < l; i++)
8742 {
8743 char *name;
8744 GtkTreeIter iter;
8745
8746 name = gdk_atom_name (atoms[i]);
8747 if (name != NULL)
8748 {
8749 gtk_list_store_insert_with_values (store, &iter, i, 0, name, -1);
8750 g_free (name);
8751 }
8752 else
8753 gtk_list_store_insert_with_values (store, &iter, i, 0, "(bad atom)", -1);
8754 }
8755
8756 return;
8757 }
8758
8759 void
selection_test_get_targets(GtkWidget * dialog,gint response,GtkWidget * tree_view)8760 selection_test_get_targets (GtkWidget *dialog, gint response, GtkWidget *tree_view)
8761 {
8762 static GdkAtom targets_atom = GDK_NONE;
8763
8764 if (response != GTK_RESPONSE_APPLY)
8765 {
8766 gtk_widget_destroy (dialog);
8767 return;
8768 }
8769
8770 if (targets_atom == GDK_NONE)
8771 targets_atom = gdk_atom_intern ("TARGETS", FALSE);
8772
8773 gtk_selection_convert (tree_view, GDK_SELECTION_PRIMARY, targets_atom,
8774 GDK_CURRENT_TIME);
8775 }
8776
8777 void
create_selection_test(GtkWidget * widget)8778 create_selection_test (GtkWidget *widget)
8779 {
8780 static GtkWidget *window = NULL;
8781 GtkWidget *content_area;
8782 GtkWidget *vbox;
8783 GtkWidget *scrolled_win;
8784 GtkListStore* store;
8785 GtkWidget *tree_view;
8786 GtkTreeViewColumn *column;
8787 GtkCellRenderer *renderer;
8788 GtkWidget *label;
8789
8790 if (!window)
8791 {
8792 window = gtk_dialog_new ();
8793
8794 gtk_window_set_screen (GTK_WINDOW (window),
8795 gtk_widget_get_screen (widget));
8796
8797 g_signal_connect (window, "destroy",
8798 G_CALLBACK (gtk_widget_destroyed),
8799 &window);
8800
8801 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
8802
8803 gtk_window_set_title (GTK_WINDOW (window), "Selection Test");
8804 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8805
8806 /* Create the list */
8807
8808 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
8809 gtk_container_set_border_width (GTK_CONTAINER (vbox), 10);
8810 gtk_box_pack_start (GTK_BOX (content_area), vbox, TRUE, TRUE, 0);
8811
8812 label = gtk_label_new ("Gets available targets for current selection");
8813 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
8814
8815 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
8816 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
8817 GTK_POLICY_AUTOMATIC,
8818 GTK_POLICY_AUTOMATIC);
8819 gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
8820 gtk_widget_set_size_request (scrolled_win, 100, 200);
8821
8822 store = gtk_list_store_new (1, G_TYPE_STRING);
8823 tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
8824 gtk_container_add (GTK_CONTAINER (scrolled_win), tree_view);
8825
8826 renderer = gtk_cell_renderer_text_new ();
8827 column = gtk_tree_view_column_new_with_attributes ("Target", renderer,
8828 "text", 0, NULL);
8829 gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
8830
8831 g_signal_connect (tree_view, "selection_received",
8832 G_CALLBACK (selection_test_received), NULL);
8833
8834 /* .. And create some buttons */
8835 gtk_dialog_add_button (GTK_DIALOG (window),
8836 "Get Targets",
8837 GTK_RESPONSE_APPLY);
8838
8839 g_signal_connect (window, "response",
8840 G_CALLBACK (selection_test_get_targets), tree_view);
8841
8842 gtk_dialog_add_button (GTK_DIALOG (window),
8843 "Quit",
8844 GTK_RESPONSE_CLOSE);
8845 }
8846
8847 if (!gtk_widget_get_visible (window))
8848 gtk_widget_show_all (window);
8849 else
8850 gtk_widget_destroy (window);
8851 }
8852
8853 /*
8854 * Test scrolling
8855 */
8856
8857 static int scroll_test_pos = 0.0;
8858
8859 static gint
scroll_test_draw(GtkWidget * widget,cairo_t * cr,GtkAdjustment * adjustment)8860 scroll_test_draw (GtkWidget *widget,
8861 cairo_t *cr,
8862 GtkAdjustment *adjustment)
8863 {
8864 gint i,j;
8865 gint imin, imax, jmin, jmax;
8866 GdkRectangle clip;
8867
8868 gdk_cairo_get_clip_rectangle (cr, &clip);
8869
8870 imin = (clip.x) / 10;
8871 imax = (clip.x + clip.width + 9) / 10;
8872
8873 jmin = ((int)gtk_adjustment_get_value (adjustment) + clip.y) / 10;
8874 jmax = ((int)gtk_adjustment_get_value (adjustment) + clip.y + clip.height + 9) / 10;
8875
8876 for (i=imin; i<imax; i++)
8877 for (j=jmin; j<jmax; j++)
8878 if ((i+j) % 2)
8879 cairo_rectangle (cr, 10*i, 10*j - (int)gtk_adjustment_get_value (adjustment), 1+i%10, 1+j%10);
8880
8881 cairo_fill (cr);
8882
8883 return TRUE;
8884 }
8885
8886 static gint
scroll_test_scroll(GtkWidget * widget,GdkEventScroll * event,GtkAdjustment * adjustment)8887 scroll_test_scroll (GtkWidget *widget, GdkEventScroll *event,
8888 GtkAdjustment *adjustment)
8889 {
8890 gdouble new_value = gtk_adjustment_get_value (adjustment) + ((event->direction == GDK_SCROLL_UP) ?
8891 -gtk_adjustment_get_page_increment (adjustment) / 2:
8892 gtk_adjustment_get_page_increment (adjustment) / 2);
8893 new_value = CLAMP (new_value, gtk_adjustment_get_lower (adjustment), gtk_adjustment_get_upper (adjustment) - gtk_adjustment_get_page_size (adjustment));
8894 gtk_adjustment_set_value (adjustment, new_value);
8895
8896 return TRUE;
8897 }
8898
8899 static void
scroll_test_configure(GtkWidget * widget,GdkEventConfigure * event,GtkAdjustment * adjustment)8900 scroll_test_configure (GtkWidget *widget, GdkEventConfigure *event,
8901 GtkAdjustment *adjustment)
8902 {
8903 GtkAllocation allocation;
8904
8905 gtk_widget_get_allocation (widget, &allocation);
8906 gtk_adjustment_configure (adjustment,
8907 gtk_adjustment_get_value (adjustment),
8908 gtk_adjustment_get_lower (adjustment),
8909 gtk_adjustment_get_upper (adjustment),
8910 0.1 * allocation.height,
8911 0.9 * allocation.height,
8912 allocation.height);
8913 }
8914
8915 static void
scroll_test_adjustment_changed(GtkAdjustment * adjustment,GtkWidget * widget)8916 scroll_test_adjustment_changed (GtkAdjustment *adjustment, GtkWidget *widget)
8917 {
8918 GdkWindow *window;
8919 gint dy;
8920
8921 dy = scroll_test_pos - (int)gtk_adjustment_get_value (adjustment);
8922 scroll_test_pos = gtk_adjustment_get_value (adjustment);
8923
8924 if (!gtk_widget_is_drawable (widget))
8925 return;
8926
8927 window = gtk_widget_get_window (widget);
8928 gdk_window_scroll (window, 0, dy);
8929 gdk_window_process_updates (window, FALSE);
8930 }
8931
8932
8933 void
create_scroll_test(GtkWidget * widget)8934 create_scroll_test (GtkWidget *widget)
8935 {
8936 static GtkWidget *window = NULL;
8937 GtkWidget *content_area;
8938 GtkWidget *hbox;
8939 GtkWidget *drawing_area;
8940 GtkWidget *scrollbar;
8941 GtkAdjustment *adjustment;
8942 GdkGeometry geometry;
8943 GdkWindowHints geometry_mask;
8944
8945 if (!window)
8946 {
8947 window = gtk_dialog_new ();
8948
8949 gtk_window_set_screen (GTK_WINDOW (window),
8950 gtk_widget_get_screen (widget));
8951
8952 g_signal_connect (window, "destroy",
8953 G_CALLBACK (gtk_widget_destroyed),
8954 &window);
8955
8956 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
8957
8958 gtk_window_set_title (GTK_WINDOW (window), "Scroll Test");
8959 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
8960
8961 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
8962 gtk_box_pack_start (GTK_BOX (content_area), hbox, TRUE, TRUE, 0);
8963 gtk_widget_show (hbox);
8964
8965 drawing_area = gtk_drawing_area_new ();
8966 gtk_widget_set_size_request (drawing_area, 200, 200);
8967 gtk_box_pack_start (GTK_BOX (hbox), drawing_area, TRUE, TRUE, 0);
8968 gtk_widget_show (drawing_area);
8969
8970 gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK | GDK_SCROLL_MASK);
8971
8972 adjustment = gtk_adjustment_new (0.0, 0.0, 1000.0, 1.0, 180.0, 200.0);
8973 scroll_test_pos = 0.0;
8974
8975 scrollbar = gtk_scrollbar_new (GTK_ORIENTATION_VERTICAL, adjustment);
8976 gtk_box_pack_start (GTK_BOX (hbox), scrollbar, FALSE, FALSE, 0);
8977 gtk_widget_show (scrollbar);
8978
8979 g_signal_connect (drawing_area, "draw",
8980 G_CALLBACK (scroll_test_draw), adjustment);
8981 g_signal_connect (drawing_area, "configure_event",
8982 G_CALLBACK (scroll_test_configure), adjustment);
8983 g_signal_connect (drawing_area, "scroll_event",
8984 G_CALLBACK (scroll_test_scroll), adjustment);
8985
8986 g_signal_connect (adjustment, "value_changed",
8987 G_CALLBACK (scroll_test_adjustment_changed),
8988 drawing_area);
8989
8990 /* .. And create some buttons */
8991
8992 gtk_dialog_add_button (GTK_DIALOG (window),
8993 "Quit",
8994 GTK_RESPONSE_CLOSE);
8995 g_signal_connect_swapped (window, "response",
8996 G_CALLBACK (gtk_widget_destroy),
8997 window);
8998
8999 /* Set up gridded geometry */
9000
9001 geometry_mask = GDK_HINT_MIN_SIZE |
9002 GDK_HINT_BASE_SIZE |
9003 GDK_HINT_RESIZE_INC;
9004
9005 geometry.min_width = 20;
9006 geometry.min_height = 20;
9007 geometry.base_width = 0;
9008 geometry.base_height = 0;
9009 geometry.width_inc = 10;
9010 geometry.height_inc = 10;
9011
9012 gtk_window_set_geometry_hints (GTK_WINDOW (window),
9013 drawing_area, &geometry, geometry_mask);
9014 }
9015
9016 if (!gtk_widget_get_visible (window))
9017 gtk_widget_show (window);
9018 else
9019 gtk_widget_destroy (window);
9020 }
9021
9022 /*
9023 * Timeout Test
9024 */
9025
9026 static int timer = 0;
9027
9028 gint
timeout_test(GtkWidget * label)9029 timeout_test (GtkWidget *label)
9030 {
9031 static int count = 0;
9032 static char buffer[32];
9033
9034 sprintf (buffer, "count: %d", ++count);
9035 gtk_label_set_text (GTK_LABEL (label), buffer);
9036
9037 return TRUE;
9038 }
9039
9040 void
start_timeout_test(GtkWidget * widget,GtkWidget * label)9041 start_timeout_test (GtkWidget *widget,
9042 GtkWidget *label)
9043 {
9044 if (!timer)
9045 {
9046 timer = g_timeout_add (100, (GSourceFunc)timeout_test, label);
9047 }
9048 }
9049
9050 void
stop_timeout_test(GtkWidget * widget,gpointer data)9051 stop_timeout_test (GtkWidget *widget,
9052 gpointer data)
9053 {
9054 if (timer)
9055 {
9056 g_source_remove (timer);
9057 timer = 0;
9058 }
9059 }
9060
9061 void
destroy_timeout_test(GtkWidget * widget,GtkWidget ** window)9062 destroy_timeout_test (GtkWidget *widget,
9063 GtkWidget **window)
9064 {
9065 stop_timeout_test (NULL, NULL);
9066
9067 *window = NULL;
9068 }
9069
9070 void
create_timeout_test(GtkWidget * widget)9071 create_timeout_test (GtkWidget *widget)
9072 {
9073 static GtkWidget *window = NULL;
9074 GtkWidget *action_area, *content_area;
9075 GtkWidget *button;
9076 GtkWidget *label;
9077
9078 if (!window)
9079 {
9080 window = gtk_dialog_new ();
9081
9082 gtk_window_set_screen (GTK_WINDOW (window),
9083 gtk_widget_get_screen (widget));
9084
9085 g_signal_connect (window, "destroy",
9086 G_CALLBACK (destroy_timeout_test),
9087 &window);
9088
9089 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9090 action_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9091
9092 gtk_window_set_title (GTK_WINDOW (window), "Timeout Test");
9093 gtk_container_set_border_width (GTK_CONTAINER (window), 0);
9094
9095 label = gtk_label_new ("count: 0");
9096 g_object_set (label, "margin", 10, NULL);
9097 gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9098 gtk_widget_show (label);
9099
9100 button = gtk_button_new_with_label ("close");
9101 g_signal_connect_swapped (button, "clicked",
9102 G_CALLBACK (gtk_widget_destroy),
9103 window);
9104 gtk_widget_set_can_default (button, TRUE);
9105 gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9106 gtk_widget_grab_default (button);
9107 gtk_widget_show (button);
9108
9109 button = gtk_button_new_with_label ("start");
9110 g_signal_connect (button, "clicked",
9111 G_CALLBACK(start_timeout_test),
9112 label);
9113 gtk_widget_set_can_default (button, TRUE);
9114 gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9115 gtk_widget_show (button);
9116
9117 button = gtk_button_new_with_label ("stop");
9118 g_signal_connect (button, "clicked",
9119 G_CALLBACK (stop_timeout_test),
9120 NULL);
9121 gtk_widget_set_can_default (button, TRUE);
9122 gtk_box_pack_start (GTK_BOX (action_area), button, TRUE, TRUE, 0);
9123 gtk_widget_show (button);
9124 }
9125
9126 if (!gtk_widget_get_visible (window))
9127 gtk_widget_show (window);
9128 else
9129 gtk_widget_destroy (window);
9130 }
9131
9132 /*
9133 * Test of recursive mainloop
9134 */
9135
9136 void
mainloop_destroyed(GtkWidget * w,GtkWidget ** window)9137 mainloop_destroyed (GtkWidget *w, GtkWidget **window)
9138 {
9139 *window = NULL;
9140 gtk_main_quit ();
9141 }
9142
9143 void
create_mainloop(GtkWidget * widget)9144 create_mainloop (GtkWidget *widget)
9145 {
9146 static GtkWidget *window = NULL;
9147 GtkWidget *content_area;
9148 GtkWidget *label;
9149
9150 if (!window)
9151 {
9152 window = gtk_dialog_new ();
9153
9154 gtk_window_set_screen (GTK_WINDOW (window),
9155 gtk_widget_get_screen (widget));
9156
9157 gtk_window_set_title (GTK_WINDOW (window), "Test Main Loop");
9158
9159 g_signal_connect (window, "destroy",
9160 G_CALLBACK (mainloop_destroyed),
9161 &window);
9162
9163 content_area = gtk_dialog_get_content_area (GTK_DIALOG (window));
9164
9165 label = gtk_label_new ("In recursive main loop...");
9166 g_object_set (label, "margin", 20, NULL);
9167
9168 gtk_box_pack_start (GTK_BOX (content_area), label, TRUE, TRUE, 0);
9169 gtk_widget_show (label);
9170
9171 gtk_dialog_add_button (GTK_DIALOG (window),
9172 "Leave",
9173 GTK_RESPONSE_OK);
9174 g_signal_connect_swapped (window, "response",
9175 G_CALLBACK (gtk_widget_destroy),
9176 window);
9177 }
9178
9179 if (!gtk_widget_get_visible (window))
9180 {
9181 gtk_widget_show (window);
9182
9183 g_print ("create_mainloop: start\n");
9184 gtk_main ();
9185 g_print ("create_mainloop: done\n");
9186 }
9187 else
9188 gtk_widget_destroy (window);
9189 }
9190
9191 static gboolean
layout_draw_handler(GtkWidget * widget,cairo_t * cr)9192 layout_draw_handler (GtkWidget *widget, cairo_t *cr)
9193 {
9194 GtkLayout *layout;
9195 GdkWindow *bin_window;
9196 GdkRectangle clip;
9197 gint i,j,x,y;
9198 gint imin, imax, jmin, jmax;
9199
9200 layout = GTK_LAYOUT (widget);
9201 bin_window = gtk_layout_get_bin_window (layout);
9202
9203 if (!gtk_cairo_should_draw_window (cr, bin_window))
9204 return FALSE;
9205
9206 gdk_window_get_position (bin_window, &x, &y);
9207 cairo_translate (cr, x, y);
9208
9209 gdk_cairo_get_clip_rectangle (cr, &clip);
9210
9211 imin = (clip.x) / 10;
9212 imax = (clip.x + clip.width + 9) / 10;
9213
9214 jmin = (clip.y) / 10;
9215 jmax = (clip.y + clip.height + 9) / 10;
9216
9217 for (i=imin; i<imax; i++)
9218 for (j=jmin; j<jmax; j++)
9219 if ((i+j) % 2)
9220 cairo_rectangle (cr,
9221 10*i, 10*j,
9222 1+i%10, 1+j%10);
9223
9224 cairo_fill (cr);
9225
9226 return FALSE;
9227 }
9228
create_layout(GtkWidget * widget)9229 void create_layout (GtkWidget *widget)
9230 {
9231 GtkAdjustment *hadjustment, *vadjustment;
9232 GtkLayout *layout;
9233 static GtkWidget *window = NULL;
9234 GtkWidget *layout_widget;
9235 GtkWidget *scrolledwindow;
9236 GtkWidget *button;
9237
9238 if (!window)
9239 {
9240 gchar buf[16];
9241
9242 gint i, j;
9243
9244 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9245 gtk_window_set_screen (GTK_WINDOW (window),
9246 gtk_widget_get_screen (widget));
9247
9248 g_signal_connect (window, "destroy",
9249 G_CALLBACK (gtk_widget_destroyed),
9250 &window);
9251
9252 gtk_window_set_title (GTK_WINDOW (window), "Layout");
9253 gtk_widget_set_size_request (window, 200, 200);
9254
9255 scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
9256 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow),
9257 GTK_SHADOW_IN);
9258 gtk_scrolled_window_set_placement (GTK_SCROLLED_WINDOW (scrolledwindow),
9259 GTK_CORNER_TOP_RIGHT);
9260
9261 gtk_container_add (GTK_CONTAINER (window), scrolledwindow);
9262
9263 layout_widget = gtk_layout_new (NULL, NULL);
9264 layout = GTK_LAYOUT (layout_widget);
9265 gtk_container_add (GTK_CONTAINER (scrolledwindow), layout_widget);
9266
9267 /* We set step sizes here since GtkLayout does not set
9268 * them itself.
9269 */
9270 hadjustment = gtk_scrollable_get_hadjustment (GTK_SCROLLABLE (layout));
9271 vadjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (layout));
9272 gtk_adjustment_set_step_increment (hadjustment, 10.0);
9273 gtk_adjustment_set_step_increment (vadjustment, 10.0);
9274 gtk_scrollable_set_hadjustment (GTK_SCROLLABLE (layout), hadjustment);
9275 gtk_scrollable_set_vadjustment (GTK_SCROLLABLE (layout), vadjustment);
9276
9277 gtk_widget_set_events (layout_widget, GDK_EXPOSURE_MASK);
9278 g_signal_connect (layout, "draw",
9279 G_CALLBACK (layout_draw_handler), NULL);
9280
9281 gtk_layout_set_size (layout, 1600, 128000);
9282
9283 for (i=0 ; i < 16 ; i++)
9284 for (j=0 ; j < 16 ; j++)
9285 {
9286 sprintf(buf, "Button %d, %d", i, j);
9287 if ((i + j) % 2)
9288 button = gtk_button_new_with_label (buf);
9289 else
9290 button = gtk_label_new (buf);
9291
9292 gtk_layout_put (layout, button, j*100, i*100);
9293 }
9294
9295 for (i=16; i < 1280; i++)
9296 {
9297 sprintf(buf, "Button %d, %d", i, 0);
9298 if (i % 2)
9299 button = gtk_button_new_with_label (buf);
9300 else
9301 button = gtk_label_new (buf);
9302
9303 gtk_layout_put (layout, button, 0, i*100);
9304 }
9305 }
9306
9307 if (!gtk_widget_get_visible (window))
9308 gtk_widget_show_all (window);
9309 else
9310 gtk_widget_destroy (window);
9311 }
9312
9313 static void
show_native(GtkWidget * button,GtkFileChooserNative * native)9314 show_native (GtkWidget *button,
9315 GtkFileChooserNative *native)
9316 {
9317 gtk_native_dialog_show (GTK_NATIVE_DIALOG (native));
9318 }
9319
9320 static void
hide_native(GtkWidget * button,GtkFileChooserNative * native)9321 hide_native (GtkWidget *button,
9322 GtkFileChooserNative *native)
9323 {
9324 gtk_native_dialog_hide (GTK_NATIVE_DIALOG (native));
9325 }
9326
9327 static void
native_response(GtkNativeDialog * self,gint response_id,GtkWidget * label)9328 native_response (GtkNativeDialog *self,
9329 gint response_id,
9330 GtkWidget *label)
9331 {
9332 static int count = 0;
9333 char *res;
9334 GSList *uris, *l;
9335 GString *s;
9336 char *response;
9337 GtkFileFilter *filter;
9338
9339 uris = gtk_file_chooser_get_uris (GTK_FILE_CHOOSER (self));
9340 filter = gtk_file_chooser_get_filter (GTK_FILE_CHOOSER (self));
9341 s = g_string_new ("");
9342 for (l = uris; l != NULL; l = l->next)
9343 {
9344 g_string_prepend (s, l->data);
9345 g_string_prepend (s, "\n");
9346 }
9347
9348 switch (response_id)
9349 {
9350 case GTK_RESPONSE_NONE:
9351 response = g_strdup ("GTK_RESPONSE_NONE");
9352 break;
9353 case GTK_RESPONSE_ACCEPT:
9354 response = g_strdup ("GTK_RESPONSE_ACCEPT");
9355 break;
9356 case GTK_RESPONSE_CANCEL:
9357 response = g_strdup ("GTK_RESPONSE_CANCEL");
9358 break;
9359 case GTK_RESPONSE_DELETE_EVENT:
9360 response = g_strdup ("GTK_RESPONSE_DELETE_EVENT");
9361 break;
9362 default:
9363 response = g_strdup_printf ("%d", response_id);
9364 break;
9365 }
9366
9367 if (filter)
9368 res = g_strdup_printf ("Response #%d: %s\n"
9369 "Filter: %s\n"
9370 "Files:\n"
9371 "%s",
9372 ++count,
9373 response,
9374 gtk_file_filter_get_name (filter),
9375 s->str);
9376 else
9377 res = g_strdup_printf ("Response #%d: %s\n"
9378 "NO Filter\n"
9379 "Files:\n"
9380 "%s",
9381 ++count,
9382 response,
9383 s->str);
9384 gtk_label_set_text (GTK_LABEL (label), res);
9385 g_free (response);
9386 g_string_free (s, TRUE);
9387 }
9388
9389 static void
native_modal_toggle(GtkWidget * checkbutton,GtkFileChooserNative * native)9390 native_modal_toggle (GtkWidget *checkbutton,
9391 GtkFileChooserNative *native)
9392 {
9393 gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (native),
9394 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
9395 }
9396
9397 static void
native_multi_select_toggle(GtkWidget * checkbutton,GtkFileChooserNative * native)9398 native_multi_select_toggle (GtkWidget *checkbutton,
9399 GtkFileChooserNative *native)
9400 {
9401 gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (native),
9402 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
9403 }
9404
9405 static void
native_overwrite_confirmation_toggle(GtkWidget * checkbutton,GtkFileChooserNative * native)9406 native_overwrite_confirmation_toggle (GtkWidget *checkbutton,
9407 GtkFileChooserNative *native)
9408 {
9409 gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (native),
9410 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton)));
9411 }
9412
9413 static void
native_extra_widget_toggle(GtkWidget * checkbutton,GtkFileChooserNative * native)9414 native_extra_widget_toggle (GtkWidget *checkbutton,
9415 GtkFileChooserNative *native)
9416 {
9417 gboolean extra_widget = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(checkbutton));
9418
9419 if (extra_widget)
9420 {
9421 GtkWidget *extra = gtk_check_button_new_with_label ("Extra toggle");
9422 gtk_widget_show (extra);
9423 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (native), extra);
9424 }
9425 else
9426 {
9427 gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (native), NULL);
9428 }
9429 }
9430
9431
9432 static void
native_visible_notify_show(GObject * object,GParamSpec * pspec,GtkWidget * show_button)9433 native_visible_notify_show (GObject *object,
9434 GParamSpec *pspec,
9435 GtkWidget *show_button)
9436 {
9437 GtkFileChooserNative *native = GTK_FILE_CHOOSER_NATIVE (object);
9438 gboolean visible;
9439
9440 visible = gtk_native_dialog_get_visible (GTK_NATIVE_DIALOG (native));
9441 gtk_widget_set_sensitive (show_button, !visible);
9442 }
9443
9444 static void
native_visible_notify_hide(GObject * object,GParamSpec * pspec,GtkWidget * hide_button)9445 native_visible_notify_hide (GObject *object,
9446 GParamSpec *pspec,
9447 GtkWidget *hide_button)
9448 {
9449 GtkFileChooserNative *native = GTK_FILE_CHOOSER_NATIVE (object);
9450 gboolean visible;
9451
9452 visible = gtk_native_dialog_get_visible (GTK_NATIVE_DIALOG (native));
9453 gtk_widget_set_sensitive (hide_button, visible);
9454 }
9455
9456 static char *
get_some_file(void)9457 get_some_file (void)
9458 {
9459 GFile *dir = g_file_new_for_path (g_get_current_dir ());
9460 GFileEnumerator *e;
9461 char *res = NULL;
9462
9463 e = g_file_enumerate_children (dir, "*", 0, NULL, NULL);
9464 if (e)
9465 {
9466 GFileInfo *info;
9467
9468 while (res == NULL)
9469 {
9470 info = g_file_enumerator_next_file (e, NULL, NULL);
9471 if (info)
9472 {
9473 if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR)
9474 {
9475 GFile *child = g_file_enumerator_get_child (e, info);
9476 res = g_file_get_path (child);
9477 g_object_unref (child);
9478 }
9479 g_object_unref (info);
9480 }
9481 else
9482 break;
9483 }
9484 }
9485
9486 return res;
9487 }
9488
9489 static void
native_action_changed(GtkWidget * combo,GtkFileChooserNative * native)9490 native_action_changed (GtkWidget *combo,
9491 GtkFileChooserNative *native)
9492 {
9493 int i;
9494 gboolean save_as = FALSE;
9495 i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
9496
9497 if (i == 4) /* Save as */
9498 {
9499 save_as = TRUE;
9500 i = GTK_FILE_CHOOSER_ACTION_SAVE;
9501 }
9502
9503 gtk_file_chooser_set_action (GTK_FILE_CHOOSER (native),
9504 (GtkFileChooserAction) i);
9505
9506
9507 if (i == GTK_FILE_CHOOSER_ACTION_SAVE ||
9508 i == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
9509 {
9510 if (save_as)
9511 {
9512 char *file = get_some_file ();
9513 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (native), file);
9514 g_free (file);
9515 }
9516 else
9517 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (native), "newname.txt");
9518 }
9519 }
9520
9521 static void
native_filter_changed(GtkWidget * combo,GtkFileChooserNative * native)9522 native_filter_changed (GtkWidget *combo,
9523 GtkFileChooserNative *native)
9524 {
9525 int i;
9526 GSList *filters, *l;
9527 GtkFileFilter *filter;
9528
9529 i = gtk_combo_box_get_active (GTK_COMBO_BOX (combo));
9530
9531 filters = gtk_file_chooser_list_filters (GTK_FILE_CHOOSER (native));
9532 for (l = filters; l != NULL; l = l->next)
9533 gtk_file_chooser_remove_filter (GTK_FILE_CHOOSER (native), l->data);
9534 g_slist_free (filters);
9535
9536 switch (i)
9537 {
9538 case 0:
9539 break;
9540 case 1: /* pattern */
9541 filter = gtk_file_filter_new ();
9542 gtk_file_filter_set_name (filter, "Text");
9543 gtk_file_filter_add_pattern (filter, "*.doc");
9544 gtk_file_filter_add_pattern (filter, "*.txt");
9545 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
9546
9547 filter = gtk_file_filter_new ();
9548 gtk_file_filter_set_name (filter, "Images");
9549 gtk_file_filter_add_pixbuf_formats (filter);
9550 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
9551 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (native), filter);
9552
9553 filter = gtk_file_filter_new ();
9554 gtk_file_filter_set_name (filter, "All");
9555 gtk_file_filter_add_pattern (filter, "*");
9556 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
9557 break;
9558
9559 case 2: /* mimetype */
9560 filter = gtk_file_filter_new ();
9561 gtk_file_filter_set_name (filter, "Text");
9562 gtk_file_filter_add_mime_type (filter, "text/plain");
9563 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
9564
9565 filter = gtk_file_filter_new ();
9566 gtk_file_filter_set_name (filter, "All");
9567 gtk_file_filter_add_pattern (filter, "*");
9568 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (native), filter);
9569 gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (native), filter);
9570 break;
9571 }
9572 }
9573
9574 static void
destroy_native(GtkFileChooserNative * native)9575 destroy_native (GtkFileChooserNative *native)
9576 {
9577 gtk_native_dialog_destroy (GTK_NATIVE_DIALOG (native));
9578 g_object_unref (native);
9579 }
9580
9581 void
create_native_dialogs(GtkWidget * widget)9582 create_native_dialogs (GtkWidget *widget)
9583 {
9584 static GtkWidget *window = NULL;
9585 GtkWidget *box, *label;
9586 GtkWidget *show_button, *hide_button, *check_button;
9587 GtkFileChooserNative *native;
9588 GtkWidget *combo;
9589
9590 if (!window)
9591 {
9592 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9593 gtk_window_set_screen (GTK_WINDOW (window),
9594 gtk_widget_get_screen (widget));
9595
9596 native = gtk_file_chooser_native_new ("Native title",
9597 GTK_WINDOW (window),
9598 GTK_FILE_CHOOSER_ACTION_OPEN,
9599 "_accept&native",
9600 "_cancel__native");
9601
9602 g_signal_connect_swapped (G_OBJECT (window), "destroy", G_CALLBACK (destroy_native), native);
9603
9604 gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (native),
9605 g_get_current_dir (),
9606 NULL);
9607
9608 gtk_window_set_title (GTK_WINDOW(window), "Native dialog parent");
9609
9610 box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 5);
9611 gtk_container_add (GTK_CONTAINER (window), box);
9612
9613 label = gtk_label_new ("");
9614 gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 4);
9615
9616 combo = gtk_combo_box_text_new ();
9617
9618 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "Open");
9619 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "Save");
9620 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "Select Folder");
9621 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "Create Folder");
9622 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "Save as");
9623
9624 g_signal_connect (combo, "changed",
9625 G_CALLBACK (native_action_changed), native);
9626 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), GTK_FILE_CHOOSER_ACTION_OPEN);
9627 gtk_box_pack_start (GTK_BOX (box), combo, FALSE, FALSE, 4);
9628
9629 combo = gtk_combo_box_text_new ();
9630
9631 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "No filters");
9632 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "Pattern filter");
9633 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "Mimetype filter");
9634
9635 g_signal_connect (combo, "changed",
9636 G_CALLBACK (native_filter_changed), native);
9637 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
9638 gtk_box_pack_start (GTK_BOX (box), combo, FALSE, FALSE, 4);
9639
9640 check_button = gtk_check_button_new_with_label ("Modal");
9641 g_signal_connect (check_button, "toggled",
9642 G_CALLBACK (native_modal_toggle), native);
9643 gtk_box_pack_start (GTK_BOX (box), check_button, FALSE, FALSE, 4);
9644
9645 check_button = gtk_check_button_new_with_label ("Multiple select");
9646 g_signal_connect (check_button, "toggled",
9647 G_CALLBACK (native_multi_select_toggle), native);
9648 gtk_box_pack_start (GTK_BOX (box), check_button, FALSE, FALSE, 4);
9649
9650 check_button = gtk_check_button_new_with_label ("Confirm overwrite");
9651 g_signal_connect (check_button, "toggled",
9652 G_CALLBACK (native_overwrite_confirmation_toggle), native);
9653 gtk_box_pack_start (GTK_BOX (box), check_button, FALSE, FALSE, 4);
9654
9655 check_button = gtk_check_button_new_with_label ("Extra widget");
9656 g_signal_connect (check_button, "toggled",
9657 G_CALLBACK (native_extra_widget_toggle), native);
9658 gtk_box_pack_start (GTK_BOX (box), check_button, FALSE, FALSE, 4);
9659
9660 show_button = gtk_button_new_with_label ("Show");
9661 hide_button = gtk_button_new_with_label ("Hide");
9662 gtk_widget_set_sensitive (hide_button, FALSE);
9663
9664 gtk_box_pack_start (GTK_BOX (box), show_button, FALSE, FALSE, 4);
9665 gtk_box_pack_start (GTK_BOX (box), hide_button, FALSE, FALSE, 4);
9666
9667 /* connect signals */
9668 g_signal_connect (native, "response",
9669 G_CALLBACK (native_response), label);
9670 g_signal_connect (show_button, "clicked",
9671 G_CALLBACK (show_native), native);
9672 g_signal_connect (hide_button, "clicked",
9673 G_CALLBACK (hide_native), native);
9674
9675 g_signal_connect (native, "notify::visible",
9676 G_CALLBACK (native_visible_notify_show), show_button);
9677 g_signal_connect (native, "notify::visible",
9678 G_CALLBACK (native_visible_notify_hide), hide_button);
9679
9680 g_signal_connect (window, "destroy",
9681 G_CALLBACK (gtk_widget_destroyed),
9682 &window);
9683 }
9684
9685 if (!gtk_widget_get_visible (window))
9686 gtk_widget_show_all (window);
9687 else
9688 gtk_widget_destroy (window);
9689 }
9690
9691 /*
9692 * Main Window and Exit
9693 */
9694
9695 void
do_exit(GtkWidget * widget,GtkWidget * window)9696 do_exit (GtkWidget *widget, GtkWidget *window)
9697 {
9698 gtk_widget_destroy (window);
9699 gtk_main_quit ();
9700 }
9701
9702 struct {
9703 char *label;
9704 void (*func) (GtkWidget *widget);
9705 gboolean do_not_benchmark;
9706 } buttons[] =
9707 {
9708 { "alpha window", create_alpha_window },
9709 { "alpha widget", create_alpha_widgets },
9710 { "big windows", create_big_windows },
9711 { "button box", create_button_box },
9712 { "buttons", create_buttons },
9713 { "check buttons", create_check_buttons },
9714 { "color selection", create_color_selection },
9715 { "composited window", create_composited_window },
9716 { "cursors", create_cursors },
9717 { "dialog", create_dialog },
9718 { "display", create_display_screen, TRUE },
9719 { "entry", create_entry },
9720 { "event box", create_event_box },
9721 { "event watcher", create_event_watcher },
9722 { "expander", create_expander },
9723 { "flipping", create_flipping },
9724 { "focus", create_focus },
9725 { "font selection", create_font_selection },
9726 { "image", create_image },
9727 { "key lookup", create_key_lookup },
9728 { "labels", create_labels },
9729 { "layout", create_layout },
9730 { "listbox", create_listbox },
9731 { "menus", create_menus },
9732 { "message dialog", create_message_dialog },
9733 { "modal window", create_modal_window, TRUE },
9734 { "native dialogs", create_native_dialogs },
9735 { "notebook", create_notebook },
9736 { "panes", create_panes },
9737 { "paned keyboard", create_paned_keyboard_navigation },
9738 { "pixbuf", create_pixbuf },
9739 { "progress bar", create_progress_bar },
9740 { "radio buttons", create_radio_buttons },
9741 { "range controls", create_range_controls },
9742 { "reparent", create_reparent },
9743 { "resize grips", create_resize_grips },
9744 { "rotated label", create_rotated_label },
9745 { "rotated text", create_rotated_text },
9746 { "saved position", create_saved_position },
9747 { "scrolled windows", create_scrolled_windows },
9748 { "shapes", create_shapes },
9749 { "size groups", create_size_groups },
9750 { "snapshot", create_snapshot },
9751 { "spinbutton", create_spins },
9752 { "statusbar", create_statusbar },
9753 { "test mainloop", create_mainloop, TRUE },
9754 { "test scrolling", create_scroll_test },
9755 { "test selection", create_selection_test },
9756 { "test timeout", create_timeout_test },
9757 { "toggle buttons", create_toggle_buttons },
9758 { "toolbar", create_toolbar },
9759 { "tooltips", create_tooltips },
9760 { "WM hints", create_wmhints },
9761 { "window sizing", create_window_sizing },
9762 { "window states", create_window_states }
9763 };
9764 int nbuttons = sizeof (buttons) / sizeof (buttons[0]);
9765
9766 void
create_main_window(void)9767 create_main_window (void)
9768 {
9769 GtkWidget *window;
9770 GtkWidget *box1;
9771 GtkWidget *box2;
9772 GtkWidget *scrolled_window;
9773 GtkWidget *button;
9774 GtkWidget *label;
9775 gchar buffer[64];
9776 GtkWidget *separator;
9777 GdkGeometry geometry;
9778 int i;
9779
9780 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9781 gtk_widget_set_name (window, "main_window");
9782 gtk_window_move (GTK_WINDOW (window), 50, 20);
9783 gtk_window_set_default_size (GTK_WINDOW (window), -1, 400);
9784
9785 geometry.min_width = -1;
9786 geometry.min_height = -1;
9787 geometry.max_width = -1;
9788 geometry.max_height = G_MAXSHORT;
9789 gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL,
9790 &geometry,
9791 GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
9792
9793 g_signal_connect (window, "destroy",
9794 G_CALLBACK (gtk_main_quit),
9795 NULL);
9796 g_signal_connect (window, "delete-event",
9797 G_CALLBACK (gtk_false),
9798 NULL);
9799
9800 box1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
9801 gtk_container_add (GTK_CONTAINER (window), box1);
9802
9803 if (gtk_micro_version > 0)
9804 sprintf (buffer,
9805 "Gtk+ v%d.%d.%d",
9806 gtk_get_major_version (),
9807 gtk_get_minor_version (),
9808 gtk_get_micro_version ());
9809 else
9810 sprintf (buffer,
9811 "Gtk+ v%d.%d",
9812 gtk_get_major_version (),
9813 gtk_get_minor_version ());
9814
9815 label = gtk_label_new (buffer);
9816 gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 0);
9817 gtk_widget_set_name (label, "testgtk-version-label");
9818
9819 scrolled_window = gtk_scrolled_window_new (NULL, NULL);
9820 gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
9821 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
9822 GTK_POLICY_NEVER,
9823 GTK_POLICY_AUTOMATIC);
9824 gtk_box_pack_start (GTK_BOX (box1), scrolled_window, TRUE, TRUE, 0);
9825
9826 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
9827 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9828 gtk_container_add (GTK_CONTAINER (scrolled_window), box2);
9829 gtk_container_set_focus_vadjustment (GTK_CONTAINER (box2),
9830 gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
9831 gtk_widget_show (box2);
9832
9833 for (i = 0; i < nbuttons; i++)
9834 {
9835 button = gtk_button_new_with_label (buttons[i].label);
9836 if (buttons[i].func)
9837 g_signal_connect (button,
9838 "clicked",
9839 G_CALLBACK(buttons[i].func),
9840 NULL);
9841 else
9842 gtk_widget_set_sensitive (button, FALSE);
9843 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9844 }
9845
9846 separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
9847 gtk_box_pack_start (GTK_BOX (box1), separator, FALSE, TRUE, 0);
9848
9849 box2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
9850 gtk_container_set_border_width (GTK_CONTAINER (box2), 10);
9851 gtk_box_pack_start (GTK_BOX (box1), box2, FALSE, TRUE, 0);
9852
9853 button = gtk_button_new_with_mnemonic ("_Close");
9854 g_signal_connect (button, "clicked",
9855 G_CALLBACK (do_exit),
9856 window);
9857 gtk_box_pack_start (GTK_BOX (box2), button, TRUE, TRUE, 0);
9858 gtk_widget_set_can_default (button, TRUE);
9859 gtk_widget_grab_default (button);
9860
9861 gtk_widget_show_all (window);
9862 }
9863
9864 static void
test_init(void)9865 test_init (void)
9866 {
9867 if (g_file_test ("../modules/input/immodules.cache", G_FILE_TEST_EXISTS))
9868 g_setenv ("GTK_IM_MODULE_FILE", "../modules/input/immodules.cache", TRUE);
9869 }
9870
9871 static char *
pad(const char * str,int to)9872 pad (const char *str, int to)
9873 {
9874 static char buf[256];
9875 int len = strlen (str);
9876 int i;
9877
9878 for (i = 0; i < to; i++)
9879 buf[i] = ' ';
9880
9881 buf[to] = '\0';
9882
9883 memcpy (buf, str, len);
9884
9885 return buf;
9886 }
9887
9888 static void
bench_iteration(GtkWidget * widget,void (* fn)(GtkWidget * widget))9889 bench_iteration (GtkWidget *widget, void (* fn) (GtkWidget *widget))
9890 {
9891 fn (widget); /* on */
9892 while (g_main_context_iteration (NULL, FALSE));
9893 fn (widget); /* off */
9894 while (g_main_context_iteration (NULL, FALSE));
9895 }
9896
9897 void
do_real_bench(GtkWidget * widget,void (* fn)(GtkWidget * widget),char * name,int num)9898 do_real_bench (GtkWidget *widget, void (* fn) (GtkWidget *widget), char *name, int num)
9899 {
9900 GTimeVal tv0, tv1;
9901 double dt_first;
9902 double dt;
9903 int n;
9904 static gboolean printed_headers = FALSE;
9905
9906 if (!printed_headers) {
9907 g_print ("Test Iters First Other\n");
9908 g_print ("-------------------- ----- ---------- ----------\n");
9909 printed_headers = TRUE;
9910 }
9911
9912 g_get_current_time (&tv0);
9913 bench_iteration (widget, fn);
9914 g_get_current_time (&tv1);
9915
9916 dt_first = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
9917 + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
9918
9919 g_get_current_time (&tv0);
9920 for (n = 0; n < num - 1; n++)
9921 bench_iteration (widget, fn);
9922 g_get_current_time (&tv1);
9923 dt = ((double)tv1.tv_sec - tv0.tv_sec) * 1000.0
9924 + (tv1.tv_usec - tv0.tv_usec) / 1000.0;
9925
9926 g_print ("%s %5d ", pad (name, 20), num);
9927 if (num > 1)
9928 g_print ("%10.1f %10.1f\n", dt_first, dt/(num-1));
9929 else
9930 g_print ("%10.1f\n", dt_first);
9931 }
9932
9933 void
do_bench(char * what,int num)9934 do_bench (char* what, int num)
9935 {
9936 int i;
9937 GtkWidget *widget;
9938 void (* fn) (GtkWidget *widget);
9939 fn = NULL;
9940 widget = gtk_window_new (GTK_WINDOW_TOPLEVEL);
9941
9942 if (g_ascii_strcasecmp (what, "ALL") == 0)
9943 {
9944 for (i = 0; i < nbuttons; i++)
9945 {
9946 if (!buttons[i].do_not_benchmark)
9947 do_real_bench (widget, buttons[i].func, buttons[i].label, num);
9948 }
9949
9950 return;
9951 }
9952 else
9953 {
9954 for (i = 0; i < nbuttons; i++)
9955 {
9956 if (strcmp (buttons[i].label, what) == 0)
9957 {
9958 fn = buttons[i].func;
9959 break;
9960 }
9961 }
9962
9963 if (!fn)
9964 g_print ("Can't bench: \"%s\" not found.\n", what);
9965 else
9966 do_real_bench (widget, fn, buttons[i].label, num);
9967 }
9968 }
9969
9970 void
usage(void)9971 usage (void)
9972 {
9973 fprintf (stderr, "Usage: testgtk [--bench ALL|<bench>[:<count>]]\n");
9974 exit (1);
9975 }
9976
9977 int
main(int argc,char * argv[])9978 main (int argc, char *argv[])
9979 {
9980 GtkCssProvider *provider, *memory_provider;
9981 GdkDisplay *display;
9982 GdkScreen *screen;
9983 GtkBindingSet *binding_set;
9984 int i;
9985 gboolean done_benchmarks = FALSE;
9986
9987 srand (time (NULL));
9988
9989 test_init ();
9990
9991 g_set_application_name ("GTK+ Test Program");
9992
9993 gtk_init (&argc, &argv);
9994
9995 provider = gtk_css_provider_new ();
9996
9997 /* Check to see if we are being run from the correct
9998 * directory.
9999 */
10000 if (file_exists ("testgtk.css"))
10001 gtk_css_provider_load_from_path (provider, "testgtk.css", NULL);
10002 else if (file_exists ("tests/testgtk.css"))
10003 gtk_css_provider_load_from_path (provider, "tests/testgtk.css", NULL);
10004 else
10005 g_warning ("Couldn't find file \"testgtk.css\".");
10006
10007 display = gdk_display_get_default ();
10008 screen = gdk_display_get_default_screen (display);
10009
10010 gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (provider),
10011 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
10012 g_object_unref (provider);
10013
10014 gtk_accelerator_set_default_mod_mask (GDK_SHIFT_MASK |
10015 GDK_CONTROL_MASK |
10016 GDK_MOD1_MASK |
10017 GDK_META_MASK |
10018 GDK_SUPER_MASK |
10019 GDK_HYPER_MASK |
10020 GDK_MOD4_MASK);
10021 /* benchmarking
10022 */
10023 for (i = 1; i < argc; i++)
10024 {
10025 if (strncmp (argv[i], "--bench", strlen("--bench")) == 0)
10026 {
10027 int num = 1;
10028 char *nextarg;
10029 char *what;
10030 char *count;
10031
10032 nextarg = strchr (argv[i], '=');
10033 if (nextarg)
10034 nextarg++;
10035 else
10036 {
10037 i++;
10038 if (i == argc)
10039 usage ();
10040 nextarg = argv[i];
10041 }
10042
10043 count = strchr (nextarg, ':');
10044 if (count)
10045 {
10046 what = g_strndup (nextarg, count - nextarg);
10047 count++;
10048 num = atoi (count);
10049 if (num <= 0)
10050 usage ();
10051 }
10052 else
10053 what = g_strdup (nextarg);
10054
10055 do_bench (what, num ? num : 1);
10056 done_benchmarks = TRUE;
10057 }
10058 else
10059 usage ();
10060 }
10061 if (done_benchmarks)
10062 return 0;
10063
10064 /* bindings test
10065 */
10066 binding_set = gtk_binding_set_by_class (g_type_class_ref (GTK_TYPE_WIDGET));
10067 gtk_binding_entry_add_signal (binding_set,
10068 '9', GDK_CONTROL_MASK | GDK_RELEASE_MASK,
10069 "debug_msg",
10070 1,
10071 G_TYPE_STRING, "GtkWidgetClass <ctrl><release>9 test");
10072
10073 memory_provider = gtk_css_provider_new ();
10074 gtk_css_provider_load_from_data (memory_provider,
10075 "#testgtk-version-label {\n"
10076 " color: #f00;\n"
10077 " font-family: Sans;\n"
10078 " font-size: 18px;\n"
10079 "}",
10080 -1, NULL);
10081 gtk_style_context_add_provider_for_screen (screen, GTK_STYLE_PROVIDER (memory_provider),
10082 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
10083
10084 create_main_window ();
10085
10086 gtk_main ();
10087
10088 if (1)
10089 {
10090 while (g_main_context_pending (NULL))
10091 g_main_context_iteration (NULL, FALSE);
10092 #if 0
10093 sleep (1);
10094 while (g_main_context_pending (NULL))
10095 g_main_context_iteration (NULL, FALSE);
10096 #endif
10097 }
10098 return 0;
10099 }
10100