1 | #include <gtk/gtk.h> |
2 | |
3 | |
4 | static void |
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 |
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 |
23 | content_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 | |
33 | static void |
34 | content_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 | |
44 | static void |
45 | kinetic_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 | |
54 | static void |
55 | add_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 | |
65 | static void |
66 | remove_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 | |
76 | static void |
77 | scrollable_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 | |
305 | int |
306 | main (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 | |