1 #include <gtk/gtk.h>
2 
3 
4 static void
horizontal_policy_changed(GtkComboBox * combo_box,GtkViewport * viewport)5 horizontal_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 
13 static void
vertical_policy_changed(GtkComboBox * combo_box,GtkViewport * viewport)14 vertical_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 
22 static void
label_flip_changed(GtkComboBox * combo_box,GtkLabel * label)23 label_flip_changed (GtkComboBox *combo_box,
24 		    GtkLabel    *label)
25 {
26   gint active = gtk_combo_box_get_active (combo_box);
27 
28   if (active == 0)
29     gtk_label_set_angle (label, 0.0);
30   else
31     gtk_label_set_angle (label, 90.0);
32 }
33 
34 static void
content_width_changed(GtkSpinButton * spin_button,gpointer data)35 content_width_changed (GtkSpinButton *spin_button,
36                        gpointer       data)
37 {
38   GtkScrolledWindow *swindow = data;
39   gdouble value;
40 
41   value = gtk_spin_button_get_value (spin_button);
42   gtk_scrolled_window_set_min_content_width (swindow, (gint)value);
43 }
44 
45 static void
content_height_changed(GtkSpinButton * spin_button,gpointer data)46 content_height_changed (GtkSpinButton *spin_button,
47                         gpointer       data)
48 {
49   GtkScrolledWindow *swindow = data;
50   gdouble value;
51 
52   value = gtk_spin_button_get_value (spin_button);
53   gtk_scrolled_window_set_min_content_height (swindow, (gint)value);
54 }
55 
56 static void
kinetic_scrolling_changed(GtkToggleButton * toggle_button,gpointer data)57 kinetic_scrolling_changed (GtkToggleButton *toggle_button,
58                            gpointer         data)
59 {
60   GtkScrolledWindow *swindow = data;
61   gboolean enabled = gtk_toggle_button_get_active (toggle_button);
62 
63   gtk_scrolled_window_set_kinetic_scrolling (swindow, enabled);
64 }
65 
66 static void
add_row(GtkButton * button,GtkListBox * listbox)67 add_row (GtkButton  *button,
68          GtkListBox *listbox)
69 {
70   GtkWidget *row;
71 
72   row = g_object_new (GTK_TYPE_LIST_BOX_ROW, "border-width", 12, NULL);
73   gtk_container_add (GTK_CONTAINER (row), gtk_label_new ("test"));
74   gtk_container_add (GTK_CONTAINER (listbox), row);
75 
76   gtk_widget_show_all (row);
77 }
78 
79 static void
remove_row(GtkButton * button,GtkListBox * listbox)80 remove_row (GtkButton  *button,
81             GtkListBox *listbox)
82 {
83   GList *children, *last;
84 
85   children = gtk_container_get_children (GTK_CONTAINER (listbox));
86   last = g_list_last (children);
87 
88   if (last)
89     gtk_container_remove (GTK_CONTAINER (listbox), last->data);
90 
91   g_list_free (children);
92 }
93 
94 static void
scrollable_policy(void)95 scrollable_policy (void)
96 {
97   GtkWidget *window, *swindow, *hbox, *vbox, *frame, *cntl, *listbox;
98   GtkWidget *viewport, *label, *expander, *widget, *popover;
99 
100   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
101   hbox   = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
102   vbox   = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
103 
104   gtk_container_set_border_width (GTK_CONTAINER (window), 8);
105 
106   gtk_widget_show (vbox);
107   gtk_widget_show (hbox);
108   gtk_container_add (GTK_CONTAINER (window), hbox);
109   gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, FALSE, 0);
110 
111   frame = gtk_frame_new ("Scrolled Window");
112   gtk_widget_show (frame);
113   gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
114 
115   swindow = gtk_scrolled_window_new (NULL, NULL);
116   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
117                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
118 
119   gtk_widget_show (swindow);
120   gtk_container_add (GTK_CONTAINER (frame), swindow);
121 
122   viewport = gtk_viewport_new (NULL, NULL);
123   label = gtk_label_new ("Here is a wrapping label with a minimum width-chars of 40 and "
124 			 "a natural max-width-chars of 100 to demonstrate the usage of "
125 			 "scrollable widgets \"hscroll-policy\" and \"vscroll-policy\" "
126 			 "properties. Note also that when playing with the window height, "
127 			 "one can observe that the vscrollbar disappears as soon as there "
128 			 "is enough height to fit the content vertically if the window were "
129 			 "to be allocated a width without a vscrollbar present");
130 
131   gtk_label_set_line_wrap  (GTK_LABEL (label), TRUE);
132   gtk_label_set_width_chars  (GTK_LABEL (label), 40);
133   gtk_label_set_max_width_chars  (GTK_LABEL (label), 100);
134 
135   gtk_widget_show (label);
136   gtk_widget_show (viewport);
137   gtk_container_add (GTK_CONTAINER (viewport), label);
138   gtk_container_add (GTK_CONTAINER (swindow), viewport);
139 
140   /* Add controls here */
141   expander = gtk_expander_new ("Controls");
142   gtk_expander_set_expanded (GTK_EXPANDER (expander), TRUE);
143   cntl = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
144   gtk_widget_show (cntl);
145   gtk_widget_show (expander);
146   gtk_container_add (GTK_CONTAINER (expander), cntl);
147   gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, FALSE, 0);
148 
149   /* Add Horizontal policy control here */
150   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
151   gtk_widget_show (hbox);
152 
153   widget = gtk_label_new ("hscroll-policy");
154   gtk_widget_show (widget);
155   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
156 
157   widget = gtk_combo_box_text_new ();
158   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Minimum");
159   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Natural");
160   gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
161   gtk_widget_show (widget);
162 
163   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
164   gtk_box_pack_start (GTK_BOX (cntl), hbox, FALSE, FALSE, 0);
165 
166   g_signal_connect (G_OBJECT (widget), "changed",
167                     G_CALLBACK (horizontal_policy_changed), viewport);
168 
169   /* Add Vertical policy control here */
170   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
171   gtk_widget_show (hbox);
172 
173   widget = gtk_label_new ("vscroll-policy");
174   gtk_widget_show (widget);
175   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
176 
177   widget = gtk_combo_box_text_new ();
178   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Minimum");
179   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Natural");
180   gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
181   gtk_widget_show (widget);
182 
183   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
184   gtk_box_pack_start (GTK_BOX (cntl), hbox, FALSE, FALSE, 0);
185 
186   g_signal_connect (G_OBJECT (widget), "changed",
187                     G_CALLBACK (vertical_policy_changed), viewport);
188 
189   /* Content size controls */
190   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
191 
192   widget = gtk_label_new ("min-content-width");
193   gtk_widget_show (widget);
194   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
195 
196   widget = gtk_spin_button_new_with_range (100.0, 1000.0, 10.0);
197   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
198   gtk_box_pack_start (GTK_BOX (cntl), hbox, FALSE, FALSE, 0);
199   gtk_widget_show (widget);
200   gtk_widget_show (hbox);
201 
202   g_signal_connect (G_OBJECT (widget), "value-changed",
203                     G_CALLBACK (content_width_changed), swindow);
204 
205   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
206 
207   widget = gtk_label_new ("min-content-height");
208   gtk_widget_show (widget);
209   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
210 
211   widget = gtk_spin_button_new_with_range (100.0, 1000.0, 10.0);
212   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
213   gtk_box_pack_start (GTK_BOX (cntl), hbox, FALSE, FALSE, 0);
214   gtk_widget_show (widget);
215   gtk_widget_show (hbox);
216 
217   g_signal_connect (G_OBJECT (widget), "value-changed",
218                     G_CALLBACK (content_height_changed), swindow);
219 
220   /* Add Label orientation control here */
221   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
222   gtk_widget_show (hbox);
223 
224   widget = gtk_label_new ("label-flip");
225   gtk_widget_show (widget);
226   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
227 
228   widget = gtk_combo_box_text_new ();
229   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Horizontal");
230   gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), "Vertical");
231   gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);
232   gtk_widget_show (widget);
233 
234   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
235   gtk_box_pack_start (GTK_BOX (cntl), hbox, FALSE, FALSE, 0);
236 
237   g_signal_connect (G_OBJECT (widget), "changed",
238                     G_CALLBACK (label_flip_changed), label);
239 
240   /* Add Kinetic scrolling control here */
241   widget = gtk_check_button_new_with_label ("Kinetic scrolling");
242   gtk_widget_show (widget);
243   gtk_box_pack_start (GTK_BOX (cntl), widget, TRUE, TRUE, 0);
244   g_signal_connect (G_OBJECT (widget), "toggled",
245                     G_CALLBACK (kinetic_scrolling_changed), swindow);
246 
247   gtk_widget_show (window);
248 
249   /* Popover */
250   popover = gtk_popover_new (NULL);
251 
252   widget = gtk_menu_button_new ();
253   gtk_menu_button_set_popover (GTK_MENU_BUTTON (widget), popover);
254   gtk_container_add (GTK_CONTAINER (widget), gtk_label_new ("Popover"));
255   gtk_box_pack_start (GTK_BOX (cntl), widget, FALSE, FALSE, 0);
256   gtk_widget_show_all (widget);
257 
258   vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
259   gtk_container_add (GTK_CONTAINER (popover), vbox);
260   gtk_widget_show (vbox);
261 
262   /* Popover's scrolled window */
263   swindow = gtk_scrolled_window_new (NULL, NULL);
264   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
265                                   GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
266 
267   gtk_box_pack_end (GTK_BOX (vbox), swindow, FALSE, FALSE, 0);
268   gtk_widget_show (swindow);
269   gtk_widget_show (hbox);
270 
271   /* Listbox */
272   listbox = gtk_list_box_new ();
273   gtk_container_add (GTK_CONTAINER (swindow), listbox);
274   gtk_widget_show (listbox);
275 
276   /* Min content */
277   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
278 
279   widget = gtk_label_new ("min-content-width");
280   gtk_widget_show (widget);
281   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
282 
283   widget = gtk_spin_button_new_with_range (0.0, 150.0, 10.0);
284   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
285   gtk_widget_show (widget);
286   gtk_widget_show (hbox);
287 
288   g_object_bind_property (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
289                           "value",
290                           swindow,
291                           "min-content-width",
292                           G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
293 
294   widget = gtk_label_new ("min-content-height");
295   gtk_widget_show (widget);
296   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
297 
298 
299   widget = gtk_spin_button_new_with_range (0.0, 150.0, 10.0);
300   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
301   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
302   gtk_widget_show (widget);
303   gtk_widget_show (hbox);
304 
305   g_object_bind_property (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
306                           "value",
307                           swindow,
308                           "min-content-height",
309                           G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
310 
311   /* Max content */
312   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
313 
314   widget = gtk_label_new ("max-content-width");
315   gtk_widget_show (widget);
316   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
317 
318   widget = gtk_spin_button_new_with_range (250.0, 1000.0, 10.0);
319   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
320   gtk_widget_show (widget);
321   gtk_widget_show (hbox);
322 
323   g_object_bind_property (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
324                           "value",
325                           swindow,
326                           "max-content-width",
327                           G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
328 
329   widget = gtk_label_new ("max-content-height");
330   gtk_widget_show (widget);
331   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
332 
333   widget = gtk_spin_button_new_with_range (250.0, 1000.0, 10.0);
334   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
335   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
336   gtk_widget_show (widget);
337   gtk_widget_show (hbox);
338 
339   g_object_bind_property (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (widget)),
340                           "value",
341                           swindow,
342                           "max-content-height",
343                           G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
344 
345   /* Add and Remove buttons */
346   hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
347 
348   widget = gtk_button_new_with_label ("Remove");
349   gtk_widget_show (widget);
350   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
351 
352   g_signal_connect (widget, "clicked",
353                     G_CALLBACK (remove_row), listbox);
354 
355   widget = gtk_button_new_with_label ("Add");
356   gtk_box_pack_start (GTK_BOX (hbox), widget, TRUE, TRUE, 0);
357   gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
358   gtk_widget_show (widget);
359   gtk_widget_show (hbox);
360 
361   g_signal_connect (widget, "clicked",
362                     G_CALLBACK (add_row), listbox);
363 }
364 
365 
366 int
main(int argc,char * argv[])367 main (int argc, char *argv[])
368 {
369   gtk_init (NULL, NULL);
370 
371   scrollable_policy ();
372 
373   gtk_main ();
374 
375   return 0;
376 }
377