1#include <gtk/gtk.h>
2
3
4static void
5horizontal_policy_changed (GtkComboBox *combo_box,
6 GtkViewport *viewport)
7{
8 GtkScrollablePolicy policy = gtk_combo_box_get_active (combo_box);
9
10 gtk_scrollable_set_hscroll_policy (GTK_SCROLLABLE (viewport), policy);
11}
12
13static void
14vertical_policy_changed (GtkComboBox *combo_box,
15 GtkViewport *viewport)
16{
17 GtkScrollablePolicy policy = gtk_combo_box_get_active (combo_box);
18
19 gtk_scrollable_set_vscroll_policy (GTK_SCROLLABLE (viewport), policy);
20}
21
22static void
23content_width_changed (GtkSpinButton *spin_button,
24 gpointer data)
25{
26 GtkScrolledWindow *swindow = data;
27 double value;
28
29 value = gtk_spin_button_get_value (spin_button);
30 gtk_scrolled_window_set_min_content_width (scrolled_window: swindow, width: (int)value);
31}
32
33static void
34content_height_changed (GtkSpinButton *spin_button,
35 gpointer data)
36{
37 GtkScrolledWindow *swindow = data;
38 double value;
39
40 value = gtk_spin_button_get_value (spin_button);
41 gtk_scrolled_window_set_min_content_height (scrolled_window: swindow, height: (int)value);
42}
43
44static void
45kinetic_scrolling_changed (GtkToggleButton *toggle_button,
46 gpointer data)
47{
48 GtkScrolledWindow *swindow = data;
49 gboolean enabled = gtk_toggle_button_get_active (toggle_button);
50
51 gtk_scrolled_window_set_kinetic_scrolling (scrolled_window: swindow, kinetic_scrolling: enabled);
52}
53
54static void
55add_row (GtkButton *button,
56 GtkListBox *listbox)
57{
58 GtkWidget *row;
59
60 row = g_object_new (GTK_TYPE_LIST_BOX_ROW, NULL);
61 gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), child: gtk_label_new (str: "test"));
62 gtk_list_box_insert (GTK_LIST_BOX (listbox), child: row, position: -1);
63}
64
65static void
66remove_row (GtkButton *button,
67 GtkListBox *listbox)
68{
69 GtkWidget *last;
70
71 last = gtk_widget_get_last_child (GTK_WIDGET (listbox));
72 if (last)
73 gtk_list_box_remove (GTK_LIST_BOX (listbox), child: last);
74}
75
76static void
77scrollable_policy (void)
78{
79 GtkWidget *window, *swindow, *hbox, *vbox, *frame, *cntl, *listbox;
80 GtkWidget *viewport, *label, *expander, *widget, *popover;
81
82 window = gtk_window_new ();
83 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
84 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 6);
85
86 gtk_window_set_child (GTK_WINDOW (window), child: hbox);
87 gtk_box_append (GTK_BOX (hbox), child: vbox);
88
89 frame = gtk_frame_new (label: "Scrolled Window");
90 gtk_widget_set_hexpand (widget: frame, TRUE);
91 gtk_box_append (GTK_BOX (hbox), child: frame);
92
93 swindow = gtk_scrolled_window_new ();
94 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
95 hscrollbar_policy: GTK_POLICY_AUTOMATIC, vscrollbar_policy: GTK_POLICY_AUTOMATIC);
96
97 gtk_frame_set_child (GTK_FRAME (frame), child: swindow);
98
99 viewport = gtk_viewport_new (NULL, NULL);
100 label = gtk_label_new (str: "Here is a wrapping label with a minimum width-chars of 40 and "
101 "a natural max-width-chars of 100 to demonstrate the usage of "
102 "scrollable widgets \"hscroll-policy\" and \"vscroll-policy\" "
103 "properties. Note also that when playing with the window height, "
104 "one can observe that the vscrollbar disappears as soon as there "
105 "is enough height to fit the content vertically if the window were "
106 "to be allocated a width without a vscrollbar present");
107
108 gtk_label_set_wrap (GTK_LABEL (label), TRUE);
109 gtk_label_set_width_chars (GTK_LABEL (label), n_chars: 40);
110 gtk_label_set_max_width_chars (GTK_LABEL (label), n_chars: 100);
111
112 gtk_viewport_set_child (GTK_VIEWPORT (viewport), child: label);
113 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (swindow), child: viewport);
114
115 /* Add controls here */
116 expander = gtk_expander_new (label: "Controls");
117 gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
118 cntl = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 2);
119 gtk_expander_set_child (GTK_EXPANDER (expander), child: cntl);
120 gtk_box_append (GTK_BOX (vbox), child: expander);
121
122 /* Add Horizontal policy control here */
123 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
124
125 widget = gtk_label_new (str: "hscroll-policy");
126 gtk_widget_set_hexpand (widget, TRUE);
127 gtk_box_append (GTK_BOX (hbox), child: widget);
128
129 widget = gtk_combo_box_text_new ();
130 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Minimum");
131 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Natural");
132 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), index_: 0);
133 gtk_widget_set_hexpand (widget, TRUE);
134
135 gtk_box_append (GTK_BOX (hbox), child: widget);
136 gtk_box_append (GTK_BOX (cntl), child: hbox);
137
138 g_signal_connect (G_OBJECT (widget), "changed",
139 G_CALLBACK (horizontal_policy_changed), viewport);
140
141 /* Add Vertical policy control here */
142 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
143
144 widget = gtk_label_new (str: "vscroll-policy");
145 gtk_widget_set_hexpand (widget, TRUE);
146 gtk_box_append (GTK_BOX (hbox), child: widget);
147
148 widget = gtk_combo_box_text_new ();
149 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Minimum");
150 gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), text: "Natural");
151 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), index_: 0);
152 gtk_widget_set_hexpand (widget, TRUE);
153
154 gtk_box_append (GTK_BOX (hbox), child: widget);
155 gtk_box_append (GTK_BOX (cntl), child: hbox);
156
157 g_signal_connect (G_OBJECT (widget), "changed",
158 G_CALLBACK (vertical_policy_changed), viewport);
159
160 /* Content size controls */
161 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
162
163 widget = gtk_label_new (str: "min-content-width");
164 gtk_widget_set_hexpand (widget, TRUE);
165 gtk_box_append (GTK_BOX (hbox), child: widget);
166
167 widget = gtk_spin_button_new_with_range (min: 100.0, max: 1000.0, step: 10.0);
168 gtk_widget_set_hexpand (widget, TRUE);
169 gtk_box_append (GTK_BOX (hbox), child: widget);
170 gtk_box_append (GTK_BOX (cntl), child: hbox);
171
172 g_signal_connect (G_OBJECT (widget), "value-changed",
173 G_CALLBACK (content_width_changed), swindow);
174
175 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
176
177 widget = gtk_label_new (str: "min-content-height");
178 gtk_widget_set_hexpand (widget, TRUE);
179 gtk_box_append (GTK_BOX (hbox), child: widget);
180
181 widget = gtk_spin_button_new_with_range (min: 100.0, max: 1000.0, step: 10.0);
182 gtk_widget_set_hexpand (widget, TRUE);
183 gtk_box_append (GTK_BOX (hbox), child: widget);
184 gtk_box_append (GTK_BOX (cntl), child: hbox);
185
186 g_signal_connect (G_OBJECT (widget), "value-changed",
187 G_CALLBACK (content_height_changed), swindow);
188
189 /* Add Kinetic scrolling control here */
190 widget = gtk_check_button_new_with_label (label: "Kinetic scrolling");
191 gtk_widget_set_hexpand (widget, TRUE);
192 gtk_box_append (GTK_BOX (cntl), child: widget);
193 g_signal_connect (G_OBJECT (widget), "toggled",
194 G_CALLBACK (kinetic_scrolling_changed), swindow);
195
196 gtk_widget_show (widget: window);
197
198 /* Popover */
199 popover = gtk_popover_new ();
200
201 widget = gtk_menu_button_new ();
202 gtk_menu_button_set_popover (GTK_MENU_BUTTON (widget), popover);
203 gtk_menu_button_set_label (GTK_MENU_BUTTON (widget), label: "Popover");
204 gtk_box_append (GTK_BOX (cntl), child: widget);
205
206 vbox = gtk_box_new (orientation: GTK_ORIENTATION_VERTICAL, spacing: 6);
207 gtk_popover_set_child (GTK_POPOVER (popover), child: vbox);
208
209 /* Popover's scrolled window */
210 swindow = gtk_scrolled_window_new ();
211 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
212 hscrollbar_policy: GTK_POLICY_AUTOMATIC, vscrollbar_policy: GTK_POLICY_AUTOMATIC);
213
214 gtk_box_append (GTK_BOX (vbox), child: swindow);
215
216 /* Listbox */
217 listbox = gtk_list_box_new ();
218 gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (swindow), child: listbox);
219
220 /* Min content */
221 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
222
223 widget = gtk_label_new (str: "min-content-width");
224 gtk_widget_set_hexpand (widget, TRUE);
225 gtk_box_append (GTK_BOX (hbox), child: widget);
226
227 widget = gtk_spin_button_new_with_range (min: 0.0, max: 150.0, step: 10.0);
228 gtk_widget_set_hexpand (widget, TRUE);
229 gtk_box_append (GTK_BOX (hbox), child: widget);
230
231 g_object_bind_property (source: gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
232 source_property: "value",
233 target: swindow,
234 target_property: "min-content-width",
235 flags: G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
236
237 widget = gtk_label_new (str: "min-content-height");
238 gtk_widget_set_hexpand (widget, TRUE);
239 gtk_box_append (GTK_BOX (hbox), child: widget);
240
241
242 widget = gtk_spin_button_new_with_range (min: 0.0, max: 150.0, step: 10.0);
243 gtk_widget_set_hexpand (widget, TRUE);
244 gtk_box_append (GTK_BOX (hbox), child: widget);
245 gtk_box_append (GTK_BOX (vbox), child: hbox);
246
247 g_object_bind_property (source: gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
248 source_property: "value",
249 target: swindow,
250 target_property: "min-content-height",
251 flags: G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
252
253 /* Max content */
254 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
255
256 widget = gtk_label_new (str: "max-content-width");
257 gtk_widget_set_hexpand (widget, TRUE);
258 gtk_box_append (GTK_BOX (hbox), child: widget);
259
260 widget = gtk_spin_button_new_with_range (min: 250.0, max: 1000.0, step: 10.0);
261 gtk_widget_set_hexpand (widget, TRUE);
262 gtk_box_append (GTK_BOX (hbox), child: widget);
263
264 g_object_bind_property (source: gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
265 source_property: "value",
266 target: swindow,
267 target_property: "max-content-width",
268 flags: G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
269
270 widget = gtk_label_new (str: "max-content-height");
271 gtk_widget_set_hexpand (widget, TRUE);
272 gtk_box_append (GTK_BOX (hbox), child: widget);
273
274 widget = gtk_spin_button_new_with_range (min: 250.0, max: 1000.0, step: 10.0);
275 gtk_widget_set_hexpand (widget, TRUE);
276 gtk_box_append (GTK_BOX (hbox), child: widget);
277 gtk_box_append (GTK_BOX (vbox), child: hbox);
278
279 g_object_bind_property (source: gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
280 source_property: "value",
281 target: swindow,
282 target_property: "max-content-height",
283 flags: G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
284
285 /* Add and Remove buttons */
286 hbox = gtk_box_new (orientation: GTK_ORIENTATION_HORIZONTAL, spacing: 2);
287
288 widget = gtk_button_new_with_label (label: "Remove");
289 gtk_widget_set_hexpand (widget, TRUE);
290 gtk_box_append (GTK_BOX (hbox), child: widget);
291
292 g_signal_connect (widget, "clicked",
293 G_CALLBACK (remove_row), listbox);
294
295 widget = gtk_button_new_with_label (label: "Add");
296 gtk_widget_set_hexpand (widget, TRUE);
297 gtk_box_append (GTK_BOX (hbox), child: widget);
298 gtk_box_append (GTK_BOX (vbox), child: hbox);
299
300 g_signal_connect (widget, "clicked",
301 G_CALLBACK (add_row), listbox);
302}
303
304
305int
306main (int argc, char *argv[])
307{
308 gtk_init ();
309
310 scrollable_policy ();
311
312 while (TRUE)
313 g_main_context_iteration (NULL, TRUE);
314
315 return 0;
316}
317

source code of gtk/tests/testscrolledwindow.c