New implementation of ModestScrollable based on GtkScrolledWindow
[modest] / src / widgets / modest-scrolled-window-scrollable.c
1 /* Copyright (c) 2009, Igalia
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  *   notice, this list of conditions and the following disclaimer in the
12  *   documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Nokia Corporation nor the names of its
14  *   contributors may be used to endorse or promote products derived from
15  *   this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
18  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <glib/gi18n.h>
31 #include "modest-scrolled-window-scrollable.h"
32
33 static void modest_scrolled_window_scrollable_class_init (ModestScrolledWindowScrollableClass *klass);
34 static void modest_scrolled_window_scrollable_init (ModestScrolledWindowScrollable *self);
35 static void modest_scrollable_iface_init (gpointer g, gpointer iface_data);
36
37 /* GObject interface */
38 static void modest_scrolled_window_scrollable_finalize (GObject *obj);
39 static void modest_scrolled_window_scrollable_get_property (GObject *obj,
40                                                                  guint prop_id, 
41                                                                  GValue *value, 
42                                                                  GParamSpec *pspec);
43 static void modest_scrolled_window_scrollable_set_property (GObject *obj,
44                                                                  guint prop_id, 
45                                                                  const GValue *value, 
46                                                                  GParamSpec *pspec);
47
48 /* Modest scrollable interface */
49 static void modest_scrolled_window_scrollable_add_with_viewport (ModestScrollable *self, GtkWidget *widget);
50 static void modest_scrolled_window_scrollable_add_with_viewport_default (ModestScrollable *self, GtkWidget *widget);
51 static GtkAdjustment *modest_scrolled_window_scrollable_get_vadjustment (ModestScrollable *self);
52 static GtkAdjustment *modest_scrolled_window_scrollable_get_vadjustment_default (ModestScrollable *self);
53 static GtkAdjustment *modest_scrolled_window_scrollable_get_hadjustment (ModestScrollable *self);
54 static GtkAdjustment *modest_scrolled_window_scrollable_get_hadjustment_default (ModestScrollable *self);
55 static void modest_scrolled_window_scrollable_scroll_to (ModestScrollable *self, const gint x, const gint y);
56 static void modest_scrolled_window_scrollable_scroll_to_default (ModestScrollable *self, const gint x, const gint y);
57 static void modest_scrolled_window_scrollable_jump_to (ModestScrollable *self, const gint x, const gint y);
58 static void modest_scrolled_window_scrollable_jump_to_default (ModestScrollable *self, const gint x, const gint y);
59 static GtkPolicyType modest_scrolled_window_scrollable_get_vertical_policy (ModestScrollable *self);
60 static GtkPolicyType modest_scrolled_window_scrollable_get_vertical_policy_default (ModestScrollable *self);
61 static GtkPolicyType modest_scrolled_window_scrollable_get_horizontal_policy (ModestScrollable *self);
62 static GtkPolicyType modest_scrolled_window_scrollable_get_horizontal_policy_default (ModestScrollable *self);
63 static void modest_scrolled_window_scrollable_set_horizontal_policy (ModestScrollable *self, GtkPolicyType policy);
64 static void modest_scrolled_window_scrollable_set_horizontal_policy_default (ModestScrollable *self, GtkPolicyType policy);
65 static void modest_scrolled_window_scrollable_set_vertical_policy (ModestScrollable *self, GtkPolicyType policy);
66 static void modest_scrolled_window_scrollable_set_vertical_policy_default (ModestScrollable *self, GtkPolicyType policy);
67
68 /* list properties */
69 enum {
70         PROP_0,
71         PROP_HORIZONTAL_POLICY,
72         PROP_VERTICAL_POLICY,
73         PROP_MOVEMENT_MODE,
74         PROP_HORIZONTAL_MAX_OVERSHOOT,
75         PROP_VERTICAL_MAX_OVERSHOOT,
76 };
77
78 /* globals */
79 static GtkScrolledWindowClass *parent_class = NULL;
80
81 G_DEFINE_TYPE_EXTENDED    (ModestScrolledWindowScrollable,
82                            modest_scrolled_window_scrollable,
83                            GTK_TYPE_SCROLLED_WINDOW,
84                            0,
85                            {
86                              G_IMPLEMENT_INTERFACE (MODEST_TYPE_SCROLLABLE, modest_scrollable_iface_init);
87                              g_type_interface_add_prerequisite (g_define_type_id, GTK_TYPE_BIN);
88                            }
89                            );
90
91 GtkWidget *
92 modest_scrolled_window_scrollable_new                            (void)
93 {
94         GtkWidget *scrollable = g_object_new (MODEST_TYPE_SCROLLED_WINDOW_SCROLLABLE, 
95                                               NULL);
96
97     return scrollable;
98 }
99
100 static void
101 modest_scrolled_window_scrollable_class_init (ModestScrolledWindowScrollableClass *klass)
102 {
103         GObjectClass *gobject_class;
104
105         parent_class = g_type_class_peek_parent (klass);
106         gobject_class->finalize = modest_scrolled_window_scrollable_finalize;
107         gobject_class->set_property = modest_scrolled_window_scrollable_set_property;
108         gobject_class->get_property = modest_scrolled_window_scrollable_get_property;
109
110         klass->add_with_viewport_func = modest_scrolled_window_scrollable_add_with_viewport_default;
111         klass->get_vadjustment_func = modest_scrolled_window_scrollable_get_vadjustment_default;
112         klass->get_hadjustment_func = modest_scrolled_window_scrollable_get_hadjustment_default;
113         klass->scroll_to_func = modest_scrolled_window_scrollable_scroll_to_default;
114         klass->jump_to_func = modest_scrolled_window_scrollable_jump_to_default;
115         klass->get_vertical_policy_func = modest_scrolled_window_scrollable_get_vertical_policy_default;
116         klass->get_horizontal_policy_func = modest_scrolled_window_scrollable_get_horizontal_policy_default;
117         klass->set_vertical_policy_func = modest_scrolled_window_scrollable_set_vertical_policy_default;
118         klass->set_horizontal_policy_func = modest_scrolled_window_scrollable_set_horizontal_policy_default;
119
120         g_object_class_install_property (gobject_class,
121                                          PROP_HORIZONTAL_POLICY,
122                                          g_param_spec_enum ("horizontal_policy", 
123                                                             _("Horizontal scrollbar policy"),
124                                                             _("Visual policy of the horizontal scrollbar"),
125                                                             GTK_TYPE_POLICY_TYPE,
126                                                             GTK_POLICY_AUTOMATIC,
127                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
128
129         g_object_class_install_property (gobject_class,
130                                          PROP_VERTICAL_POLICY,
131                                          g_param_spec_enum ("vertical_policy", 
132                                                             _("Vertical scrollbar policy"),
133                                                             _("Visual policy of the vertical scrollbar"),
134                                                             GTK_TYPE_POLICY_TYPE,
135                                                             GTK_POLICY_AUTOMATIC,
136                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
137
138         g_object_class_install_property (gobject_class,
139                                          PROP_MOVEMENT_MODE,
140                                          g_param_spec_enum ("movement_mode",
141                                                             "Directions scroll is allowed",
142                                                             "Movements allowed in the scrollable",
143                                                             MODEST_TYPE_MOVEMENT_MODE,
144                                                             MODEST_MOVEMENT_MODE_VERTICAL,
145                                                             G_PARAM_READWRITE |
146                                                             G_PARAM_CONSTRUCT));
147
148         g_object_class_install_property (gobject_class,
149                                          PROP_HORIZONTAL_MAX_OVERSHOOT,
150                                          g_param_spec_int ("horizontal-max-overshoot",
151                                                            "Horizontal max overshoot",
152                                                            "Horizontal maximum overshoot (0 disables)",
153                                                            0, G_MAXINT, 150,
154                                                            G_PARAM_READWRITE |G_PARAM_CONSTRUCT));
155
156         g_object_class_install_property (gobject_class,
157                                          PROP_VERTICAL_MAX_OVERSHOOT,
158                                          g_param_spec_int ("vertical-max-overshoot",
159                                                            "Vertical max overshoot",
160                                                            "Vertical maximum overshoot (0 disables)",
161                                                            0, G_MAXINT, 150,
162                                                            G_PARAM_READWRITE |G_PARAM_CONSTRUCT));
163 }
164
165 static void
166 modest_scrolled_window_scrollable_init (ModestScrolledWindowScrollable *self)
167 {
168 }
169
170 static void
171 modest_scrollable_iface_init (gpointer g, gpointer iface_data)
172 {
173         ModestScrollableIface *iface = (ModestScrollableIface *) g;
174
175         iface->jump_to = modest_scrolled_window_scrollable_jump_to;
176         iface->scroll_to = modest_scrolled_window_scrollable_scroll_to;
177         iface->add_with_viewport = modest_scrolled_window_scrollable_add_with_viewport;
178         iface->get_vadjustment = modest_scrolled_window_scrollable_get_vadjustment;
179         iface->get_hadjustment = modest_scrolled_window_scrollable_get_hadjustment;
180         iface->get_vertical_policy = modest_scrolled_window_scrollable_get_vertical_policy;
181         iface->set_vertical_policy = modest_scrolled_window_scrollable_set_vertical_policy;
182         iface->get_horizontal_policy = modest_scrolled_window_scrollable_get_horizontal_policy;
183         iface->set_horizontal_policy = modest_scrolled_window_scrollable_set_horizontal_policy;
184 }
185
186 static void 
187 modest_scrolled_window_scrollable_finalize (GObject *obj)
188 {
189         G_OBJECT_CLASS(parent_class)->finalize (obj);           
190 }
191
192 static void
193 modest_scrolled_window_scrollable_get_property (GObject *obj,
194                                                 guint prop_id, 
195                                                 GValue *value, 
196                                                 GParamSpec *pspec)
197 {
198         GtkPolicyType policy;
199
200         switch (prop_id) {
201         case PROP_VERTICAL_POLICY:
202                 gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (obj), NULL, &policy);
203                 g_value_set_enum (value, policy);
204                 break;
205         case PROP_HORIZONTAL_POLICY:
206                 gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (obj), &policy, NULL);
207                 g_value_set_enum (value, policy);
208                 break;
209         case PROP_MOVEMENT_MODE:
210                 g_value_set_enum (value, MODEST_MOVEMENT_MODE_BOTH);
211                 break;
212         case PROP_HORIZONTAL_MAX_OVERSHOOT:
213                 g_value_set_int (value, 0);
214                 break;
215         case PROP_VERTICAL_MAX_OVERSHOOT:
216                 g_value_set_int (value, 0);
217                 break;
218         default:
219                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
220                 break;
221         }
222 }
223
224 static void
225 modest_scrolled_window_scrollable_set_property (GObject *obj,
226                                                      guint prop_id, 
227                                                      const GValue *value, 
228                                                      GParamSpec *pspec)
229 {
230         GtkPolicyType hpolicy, vpolicy;
231
232         gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (obj), &hpolicy, &vpolicy);
233         switch (prop_id) {
234         case PROP_VERTICAL_POLICY:
235                 vpolicy = g_value_get_enum (value);
236                 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (obj), hpolicy, vpolicy);
237                 break;
238         case PROP_HORIZONTAL_POLICY:
239                 hpolicy = g_value_get_enum (value);
240                 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (obj), hpolicy, vpolicy);
241                 break;
242         case PROP_MOVEMENT_MODE:
243         case PROP_HORIZONTAL_MAX_OVERSHOOT:
244         case PROP_VERTICAL_MAX_OVERSHOOT:
245                 /* these three parameters are not supported in scrolled window */
246                 break;
247         default:
248                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
249                 break;
250         }
251 }
252
253 static void
254 modest_scrolled_window_scrollable_add_with_viewport (ModestScrollable *self,
255                                                           GtkWidget *widget)
256 {
257         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->add_with_viewport_func (self, widget);
258 }
259
260 static void
261 modest_scrolled_window_scrollable_add_with_viewport_default (ModestScrollable *self,
262                                                                   GtkWidget *widget)
263 {
264         gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (self), widget);
265 }
266
267 static GtkAdjustment *
268 modest_scrolled_window_scrollable_get_vadjustment (ModestScrollable *self)
269 {
270         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_vadjustment_func (self);
271 }
272
273 static GtkAdjustment *
274 modest_scrolled_window_scrollable_get_vadjustment_default (ModestScrollable *self)
275 {
276         return gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self));
277 }
278
279 static GtkAdjustment *
280 modest_scrolled_window_scrollable_get_hadjustment (ModestScrollable *self)
281 {
282         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_hadjustment_func (self);
283 }
284
285 static GtkAdjustment *
286 modest_scrolled_window_scrollable_get_hadjustment_default (ModestScrollable *self)
287 {
288         return gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (self));
289 }
290
291 static void
292 modest_scrolled_window_scrollable_scroll_to (ModestScrollable *self, 
293                                              const gint x, const gint y)
294 {
295         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->scroll_to_func (self, x, y);
296 }
297
298 static void
299 modest_scrolled_window_scrollable_scroll_to_default (ModestScrollable *self,
300                                                      const gint x, const gint y)
301 {
302         GtkAdjustment *vadj, *hadj;
303         hadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self));
304         gtk_adjustment_set_value (hadj, (gdouble) y);
305         vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self));
306 }
307
308 static void
309 modest_scrolled_window_scrollable_jump_to (ModestScrollable *self, 
310                                                 const gint x, const gint y)
311 {
312         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->jump_to_func (self, x, y);
313 }
314
315 static void
316 modest_scrolled_window_scrollable_jump_to_default (ModestScrollable *self,
317                                                         const gint x, const gint y)
318 {
319         modest_scrollable_scroll_to (MODEST_SCROLLABLE (self), x, y);
320 }
321
322 static GtkPolicyType
323 modest_scrolled_window_scrollable_get_vertical_policy (ModestScrollable *self)
324 {
325         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_vertical_policy_func (self);
326 }
327
328 static GtkPolicyType
329 modest_scrolled_window_scrollable_get_vertical_policy_default (ModestScrollable *self)
330 {
331         GtkPolicyType policy;
332
333         g_object_get (G_OBJECT (self), "vertical-policy", &policy, NULL);
334         return policy;
335 }
336
337 static GtkPolicyType
338 modest_scrolled_window_scrollable_get_horizontal_policy (ModestScrollable *self)
339 {
340         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_horizontal_policy_func (self);
341 }
342
343 static GtkPolicyType
344 modest_scrolled_window_scrollable_get_horizontal_policy_default (ModestScrollable *self)
345 {
346         GtkPolicyType policy;
347
348         g_object_get (G_OBJECT (self), "horizontal-policy", &policy, NULL);
349         return policy;
350 }
351
352 static void
353 modest_scrolled_window_scrollable_set_horizontal_policy (ModestScrollable *self,
354                                                               GtkPolicyType policy)
355 {
356         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->set_horizontal_policy_func (self, policy);
357 }
358
359 static void
360 modest_scrolled_window_scrollable_set_horizontal_policy_default (ModestScrollable *self,
361                                                                       GtkPolicyType policy)
362 {
363         g_object_set (G_OBJECT (self), "horizontal-policy", policy, NULL);
364 }
365
366 static void
367 modest_scrolled_window_scrollable_set_vertical_policy (ModestScrollable *self,
368                                                             GtkPolicyType policy)
369 {
370         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->set_vertical_policy_func (self, policy);
371 }
372
373 static void
374 modest_scrolled_window_scrollable_set_vertical_policy_default (ModestScrollable *self,
375                                                                     GtkPolicyType policy)
376 {
377         g_object_set (G_OBJECT (self), "vertical-policy", policy, NULL);
378 }