1 /* gtkscrollable.c
2 * Copyright (C) 2008 Tadej Borovšak <tadeboro@gmail.com>
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 * SECTION:gtkscrollable
20 * @Short_Description: An interface for scrollable widgets
21 * @Title: GtkScrollable
22 *
23 * #GtkScrollable is an interface that is implemented by widgets with native
24 * scrolling ability.
25 *
26 * To implement this interface you should override the
27 * #GtkScrollable:hadjustment and #GtkScrollable:vadjustment properties.
28 *
29 * ## Creating a scrollable widget
30 *
31 * All scrollable widgets should do the following.
32 *
33 * - When a parent widget sets the scrollable child widget’s adjustments,
34 * the widget should populate the adjustments’
35 * #GtkAdjustment:lower, #GtkAdjustment:upper,
36 * #GtkAdjustment:step-increment, #GtkAdjustment:page-increment and
37 * #GtkAdjustment:page-size properties and connect to the
38 * #GtkAdjustment::value-changed signal.
39 *
40 * - Because its preferred size is the size for a fully expanded widget,
41 * the scrollable widget must be able to cope with underallocations.
42 * This means that it must accept any value passed to its
43 * #GtkWidgetClass.size_allocate() function.
44 *
45 * - When the parent allocates space to the scrollable child widget,
46 * the widget should update the adjustments’ properties with new values.
47 *
48 * - When any of the adjustments emits the #GtkAdjustment::value-changed signal,
49 * the scrollable widget should scroll its contents.
50 */
51
52 #include "config.h"
53
54 #include "gtkscrollable.h"
55
56 #include "gtkadjustment.h"
57 #include "gtkprivate.h"
58 #include "gtktypebuiltins.h"
59 #include "gtkintl.h"
60
G_DEFINE_INTERFACE(GtkScrollable,gtk_scrollable,G_TYPE_OBJECT)61 G_DEFINE_INTERFACE (GtkScrollable, gtk_scrollable, G_TYPE_OBJECT)
62
63 static void
64 gtk_scrollable_default_init (GtkScrollableInterface *iface)
65 {
66 GParamSpec *pspec;
67
68 /**
69 * GtkScrollable:hadjustment:
70 *
71 * Horizontal #GtkAdjustment of the scrollable widget. This adjustment is
72 * shared between the scrollable widget and its parent.
73 *
74 * Since: 3.0
75 */
76 pspec = g_param_spec_object ("hadjustment",
77 P_("Horizontal adjustment"),
78 P_("Horizontal adjustment that is shared "
79 "between the scrollable widget and its "
80 "controller"),
81 GTK_TYPE_ADJUSTMENT,
82 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT);
83 g_object_interface_install_property (iface, pspec);
84
85 /**
86 * GtkScrollable:vadjustment:
87 *
88 * Verical #GtkAdjustment of the scrollable widget. This adjustment is shared
89 * between the scrollable widget and its parent.
90 *
91 * Since: 3.0
92 */
93 pspec = g_param_spec_object ("vadjustment",
94 P_("Vertical adjustment"),
95 P_("Vertical adjustment that is shared "
96 "between the scrollable widget and its "
97 "controller"),
98 GTK_TYPE_ADJUSTMENT,
99 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT);
100 g_object_interface_install_property (iface, pspec);
101
102 /**
103 * GtkScrollable:hscroll-policy:
104 *
105 * Determines whether horizontal scrolling should start once the scrollable
106 * widget is allocated less than its minimum width or less than its natural width.
107 *
108 * Since: 3.0
109 */
110 pspec = g_param_spec_enum ("hscroll-policy",
111 P_("Horizontal Scrollable Policy"),
112 P_("How the size of the content should be determined"),
113 GTK_TYPE_SCROLLABLE_POLICY,
114 GTK_SCROLL_MINIMUM,
115 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
116 g_object_interface_install_property (iface, pspec);
117
118 /**
119 * GtkScrollable:vscroll-policy:
120 *
121 * Determines whether vertical scrolling should start once the scrollable
122 * widget is allocated less than its minimum height or less than its natural height.
123 *
124 * Since: 3.0
125 */
126 pspec = g_param_spec_enum ("vscroll-policy",
127 P_("Vertical Scrollable Policy"),
128 P_("How the size of the content should be determined"),
129 GTK_TYPE_SCROLLABLE_POLICY,
130 GTK_SCROLL_MINIMUM,
131 GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
132 g_object_interface_install_property (iface, pspec);
133 }
134
135 /**
136 * gtk_scrollable_get_hadjustment:
137 * @scrollable: a #GtkScrollable
138 *
139 * Retrieves the #GtkAdjustment used for horizontal scrolling.
140 *
141 * Returns: (transfer none): horizontal #GtkAdjustment.
142 *
143 * Since: 3.0
144 **/
145 GtkAdjustment *
gtk_scrollable_get_hadjustment(GtkScrollable * scrollable)146 gtk_scrollable_get_hadjustment (GtkScrollable *scrollable)
147 {
148 GtkAdjustment *adj = NULL;
149
150 g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), NULL);
151
152 g_object_get (scrollable, "hadjustment", &adj, NULL);
153
154 /* Horrid hack; g_object_get() returns a new reference but
155 * that contradicts the memory management conventions
156 * for accessors.
157 */
158 if (adj)
159 g_object_unref (adj);
160
161 return adj;
162 }
163
164 /**
165 * gtk_scrollable_set_hadjustment:
166 * @scrollable: a #GtkScrollable
167 * @hadjustment: (allow-none): a #GtkAdjustment
168 *
169 * Sets the horizontal adjustment of the #GtkScrollable.
170 *
171 * Since: 3.0
172 **/
173 void
gtk_scrollable_set_hadjustment(GtkScrollable * scrollable,GtkAdjustment * hadjustment)174 gtk_scrollable_set_hadjustment (GtkScrollable *scrollable,
175 GtkAdjustment *hadjustment)
176 {
177 g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
178 g_return_if_fail (hadjustment == NULL || GTK_IS_ADJUSTMENT (hadjustment));
179
180 g_object_set (scrollable, "hadjustment", hadjustment, NULL);
181 }
182
183 /**
184 * gtk_scrollable_get_vadjustment:
185 * @scrollable: a #GtkScrollable
186 *
187 * Retrieves the #GtkAdjustment used for vertical scrolling.
188 *
189 * Returns: (transfer none): vertical #GtkAdjustment.
190 *
191 * Since: 3.0
192 **/
193 GtkAdjustment *
gtk_scrollable_get_vadjustment(GtkScrollable * scrollable)194 gtk_scrollable_get_vadjustment (GtkScrollable *scrollable)
195 {
196 GtkAdjustment *adj = NULL;
197
198 g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), NULL);
199
200 g_object_get (scrollable, "vadjustment", &adj, NULL);
201
202 /* Horrid hack; g_object_get() returns a new reference but
203 * that contradicts the memory management conventions
204 * for accessors.
205 */
206 if (adj)
207 g_object_unref (adj);
208
209 return adj;
210 }
211
212 /**
213 * gtk_scrollable_set_vadjustment:
214 * @scrollable: a #GtkScrollable
215 * @vadjustment: (allow-none): a #GtkAdjustment
216 *
217 * Sets the vertical adjustment of the #GtkScrollable.
218 *
219 * Since: 3.0
220 **/
221 void
gtk_scrollable_set_vadjustment(GtkScrollable * scrollable,GtkAdjustment * vadjustment)222 gtk_scrollable_set_vadjustment (GtkScrollable *scrollable,
223 GtkAdjustment *vadjustment)
224 {
225 g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
226 g_return_if_fail (vadjustment == NULL || GTK_IS_ADJUSTMENT (vadjustment));
227
228 g_object_set (scrollable, "vadjustment", vadjustment, NULL);
229 }
230
231
232 /**
233 * gtk_scrollable_get_hscroll_policy:
234 * @scrollable: a #GtkScrollable
235 *
236 * Gets the horizontal #GtkScrollablePolicy.
237 *
238 * Returns: The horizontal #GtkScrollablePolicy.
239 *
240 * Since: 3.0
241 **/
242 GtkScrollablePolicy
gtk_scrollable_get_hscroll_policy(GtkScrollable * scrollable)243 gtk_scrollable_get_hscroll_policy (GtkScrollable *scrollable)
244 {
245 GtkScrollablePolicy policy;
246
247 g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), GTK_SCROLL_MINIMUM);
248
249 g_object_get (scrollable, "hscroll-policy", &policy, NULL);
250
251 return policy;
252 }
253
254 /**
255 * gtk_scrollable_set_hscroll_policy:
256 * @scrollable: a #GtkScrollable
257 * @policy: the horizontal #GtkScrollablePolicy
258 *
259 * Sets the #GtkScrollablePolicy to determine whether
260 * horizontal scrolling should start below the minimum width or
261 * below the natural width.
262 *
263 * Since: 3.0
264 **/
265 void
gtk_scrollable_set_hscroll_policy(GtkScrollable * scrollable,GtkScrollablePolicy policy)266 gtk_scrollable_set_hscroll_policy (GtkScrollable *scrollable,
267 GtkScrollablePolicy policy)
268 {
269 g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
270
271 g_object_set (scrollable, "hscroll-policy", policy, NULL);
272 }
273
274 /**
275 * gtk_scrollable_get_vscroll_policy:
276 * @scrollable: a #GtkScrollable
277 *
278 * Gets the vertical #GtkScrollablePolicy.
279 *
280 * Returns: The vertical #GtkScrollablePolicy.
281 *
282 * Since: 3.0
283 **/
284 GtkScrollablePolicy
gtk_scrollable_get_vscroll_policy(GtkScrollable * scrollable)285 gtk_scrollable_get_vscroll_policy (GtkScrollable *scrollable)
286 {
287 GtkScrollablePolicy policy;
288
289 g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), GTK_SCROLL_MINIMUM);
290
291 g_object_get (scrollable, "vscroll-policy", &policy, NULL);
292
293 return policy;
294 }
295
296 /**
297 * gtk_scrollable_set_vscroll_policy:
298 * @scrollable: a #GtkScrollable
299 * @policy: the vertical #GtkScrollablePolicy
300 *
301 * Sets the #GtkScrollablePolicy to determine whether
302 * vertical scrolling should start below the minimum height or
303 * below the natural height.
304 *
305 * Since: 3.0
306 **/
307 void
gtk_scrollable_set_vscroll_policy(GtkScrollable * scrollable,GtkScrollablePolicy policy)308 gtk_scrollable_set_vscroll_policy (GtkScrollable *scrollable,
309 GtkScrollablePolicy policy)
310 {
311 g_return_if_fail (GTK_IS_SCROLLABLE (scrollable));
312
313 g_object_set (scrollable, "vscroll-policy", policy, NULL);
314 }
315
316 /**
317 * gtk_scrollable_get_border:
318 * @scrollable: a #GtkScrollable
319 * @border: (out caller-allocates): return location for the results
320 *
321 * Returns the size of a non-scrolling border around the
322 * outside of the scrollable. An example for this would
323 * be treeview headers. GTK+ can use this information to
324 * display overlayed graphics, like the overshoot indication,
325 * at the right position.
326 *
327 * Returns: %TRUE if @border has been set
328 *
329 * Since: 3.16
330 */
331 gboolean
gtk_scrollable_get_border(GtkScrollable * scrollable,GtkBorder * border)332 gtk_scrollable_get_border (GtkScrollable *scrollable,
333 GtkBorder *border)
334 {
335 g_return_val_if_fail (GTK_IS_SCROLLABLE (scrollable), FALSE);
336 g_return_val_if_fail (border != NULL, FALSE);
337
338 if (GTK_SCROLLABLE_GET_IFACE (scrollable)->get_border)
339 return GTK_SCROLLABLE_GET_IFACE (scrollable)->get_border (scrollable, border);
340
341 return FALSE;
342 }
343