1 | /* Expander |
2 | * |
3 | * GtkExpander allows to provide additional content that is initially hidden. |
4 | * This is also known as "disclosure triangle". |
5 | * |
6 | * This example also shows how to make the window resizable only if the expander |
7 | * is expanded. |
8 | */ |
9 | |
10 | #include <glib/gi18n.h> |
11 | #include <gtk/gtk.h> |
12 | |
13 | static GtkWidget *window = NULL; |
14 | |
15 | static void |
16 | response_cb (GtkDialog *dialog, int response_id) |
17 | { |
18 | gtk_window_destroy (GTK_WINDOW (window)); |
19 | window = NULL; |
20 | } |
21 | |
22 | static void |
23 | expander_cb (GtkExpander *expander, GParamSpec *pspec, GtkWindow *dialog) |
24 | { |
25 | gtk_window_set_resizable (window: dialog, resizable: gtk_expander_get_expanded (expander)); |
26 | } |
27 | |
28 | GtkWidget * |
29 | do_expander (GtkWidget *do_widget) |
30 | { |
31 | GtkWidget *toplevel; |
32 | GtkWidget *area; |
33 | GtkWidget *expander; |
34 | GtkWidget *label; |
35 | GtkWidget *sw; |
36 | GtkWidget *tv; |
37 | GtkTextBuffer *buffer; |
38 | GtkTextIter start; |
39 | GtkTextIter end; |
40 | GtkTextTag *tag; |
41 | GdkPaintable *paintable; |
42 | |
43 | if (!window) |
44 | { |
45 | toplevel = GTK_WIDGET (gtk_widget_get_root (do_widget)); |
46 | window = gtk_message_dialog_new_with_markup (GTK_WINDOW (toplevel), |
47 | flags: 0, |
48 | type: GTK_MESSAGE_ERROR, |
49 | buttons: GTK_BUTTONS_CLOSE, |
50 | message_format: "<big><b>%s</b></big>" , |
51 | "Something went wrong" ); |
52 | gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (window), |
53 | message_format: "Here are some more details " |
54 | "but not the full story." ); |
55 | |
56 | area = gtk_message_dialog_get_message_area (GTK_MESSAGE_DIALOG (window)); |
57 | |
58 | label = gtk_widget_get_last_child (widget: area); |
59 | gtk_label_set_wrap (GTK_LABEL (label), FALSE); |
60 | gtk_widget_set_vexpand (widget: label, FALSE); |
61 | |
62 | expander = gtk_expander_new (label: "Details:" ); |
63 | gtk_widget_set_vexpand (widget: expander, TRUE); |
64 | sw = gtk_scrolled_window_new (); |
65 | gtk_scrolled_window_set_min_content_height (GTK_SCROLLED_WINDOW (sw), height: 100); |
66 | gtk_scrolled_window_set_has_frame (GTK_SCROLLED_WINDOW (sw), TRUE); |
67 | gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), |
68 | hscrollbar_policy: GTK_POLICY_NEVER, |
69 | vscrollbar_policy: GTK_POLICY_AUTOMATIC); |
70 | gtk_scrolled_window_set_propagate_natural_height (GTK_SCROLLED_WINDOW (sw), TRUE); |
71 | gtk_widget_set_vexpand (widget: sw, TRUE); |
72 | |
73 | tv = gtk_text_view_new (); |
74 | |
75 | g_object_set (object: tv, |
76 | first_property_name: "left-margin" , 10, |
77 | "right-margin" , 10, |
78 | "top-margin" , 10, |
79 | "bottom-margin" , 10, |
80 | NULL); |
81 | |
82 | buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); |
83 | gtk_text_view_set_editable (GTK_TEXT_VIEW (tv), FALSE); |
84 | gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (tv), FALSE); |
85 | gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (tv), wrap_mode: GTK_WRAP_WORD); |
86 | gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW (tv), pixels_above_lines: 2); |
87 | gtk_text_view_set_pixels_below_lines (GTK_TEXT_VIEW (tv), pixels_below_lines: 2); |
88 | |
89 | gtk_text_buffer_set_text (buffer, |
90 | text: "Finally, the full story with all details. " |
91 | "And all the inside information, including " |
92 | "error codes, etc etc. Pages of information, " |
93 | "you might have to scroll down to read it all, " |
94 | "or even resize the window - it works !\n" |
95 | "A second paragraph will contain even more " |
96 | "innuendo, just to make you scroll down or " |
97 | "resize the window.\n" |
98 | "Do it already!\n" , len: -1); |
99 | |
100 | gtk_text_buffer_get_end_iter (buffer, iter: &start); |
101 | paintable = GDK_PAINTABLE (ptr: gdk_texture_new_from_resource (resource_path: "/cursors/images/gtk_logo_cursor.png" )); |
102 | gtk_text_buffer_insert_paintable (buffer, iter: &start, paintable); |
103 | g_object_unref (object: paintable); |
104 | gtk_text_iter_backward_char (iter: &start); |
105 | |
106 | gtk_text_buffer_get_end_iter (buffer, iter: &end); |
107 | tag = gtk_text_buffer_create_tag (buffer, NULL, |
108 | first_property_name: "pixels-above-lines" , 200, |
109 | "justification" , GTK_JUSTIFY_RIGHT, |
110 | NULL); |
111 | gtk_text_buffer_apply_tag (buffer, tag, start: &start, end: &end); |
112 | |
113 | gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (sw), child: tv); |
114 | gtk_expander_set_child (GTK_EXPANDER (expander), child: sw); |
115 | gtk_box_append (GTK_BOX (area), child: expander); |
116 | g_signal_connect (expander, "notify::expanded" , |
117 | G_CALLBACK (expander_cb), window); |
118 | |
119 | g_signal_connect (window, "response" , G_CALLBACK (response_cb), NULL); |
120 | } |
121 | |
122 | if (!gtk_widget_get_visible (widget: window)) |
123 | gtk_widget_show (widget: window); |
124 | else |
125 | gtk_window_destroy (GTK_WINDOW (window)); |
126 | |
127 | return window; |
128 | } |
129 | |