db40d0bcb66f5707a2cb3a83e3fca67a23caa555
[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                            }
88                            );
89
90 GtkWidget *
91 modest_scrolled_window_scrollable_new                            (void)
92 {
93         GtkWidget *scrollable = g_object_new (MODEST_TYPE_SCROLLED_WINDOW_SCROLLABLE,
94                                               "hscrollbar-policy", GTK_POLICY_NEVER,
95                                               "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
96                                               NULL);
97
98     return scrollable;
99 }
100
101 static void
102 modest_scrolled_window_scrollable_class_init (ModestScrolledWindowScrollableClass *klass)
103 {
104         GObjectClass *gobject_class;
105
106         parent_class = g_type_class_peek_parent (klass);
107         gobject_class = (GObjectClass *) klass;
108         gobject_class->finalize = modest_scrolled_window_scrollable_finalize;
109         gobject_class->set_property = modest_scrolled_window_scrollable_set_property;
110         gobject_class->get_property = modest_scrolled_window_scrollable_get_property;
111
112         klass->add_with_viewport_func = modest_scrolled_window_scrollable_add_with_viewport_default;
113         klass->get_vadjustment_func = modest_scrolled_window_scrollable_get_vadjustment_default;
114         klass->get_hadjustment_func = modest_scrolled_window_scrollable_get_hadjustment_default;
115         klass->scroll_to_func = modest_scrolled_window_scrollable_scroll_to_default;
116         klass->jump_to_func = modest_scrolled_window_scrollable_jump_to_default;
117         klass->get_vertical_policy_func = modest_scrolled_window_scrollable_get_vertical_policy_default;
118         klass->get_horizontal_policy_func = modest_scrolled_window_scrollable_get_horizontal_policy_default;
119         klass->set_vertical_policy_func = modest_scrolled_window_scrollable_set_vertical_policy_default;
120         klass->set_horizontal_policy_func = modest_scrolled_window_scrollable_set_horizontal_policy_default;
121
122         g_object_class_install_property (gobject_class,
123                                          PROP_HORIZONTAL_POLICY,
124                                          g_param_spec_enum ("horizontal_policy", 
125                                                             _("Horizontal scrollbar policy"),
126                                                             _("Visual policy of the horizontal scrollbar"),
127                                                             GTK_TYPE_POLICY_TYPE,
128                                                             GTK_POLICY_AUTOMATIC,
129                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
130
131         g_object_class_install_property (gobject_class,
132                                          PROP_VERTICAL_POLICY,
133                                          g_param_spec_enum ("vertical_policy", 
134                                                             _("Vertical scrollbar policy"),
135                                                             _("Visual policy of the vertical scrollbar"),
136                                                             GTK_TYPE_POLICY_TYPE,
137                                                             GTK_POLICY_AUTOMATIC,
138                                                             G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
139
140         g_object_class_install_property (gobject_class,
141                                          PROP_MOVEMENT_MODE,
142                                          g_param_spec_flags ("movement_mode",
143                                                              "Directions scroll is allowed",
144                                                              "Movements allowed in the scrollable",
145                                                              MODEST_TYPE_MOVEMENT_MODE,
146                                                              MODEST_MOVEMENT_MODE_VERTICAL,
147                                                              G_PARAM_READWRITE |
148                                                              G_PARAM_CONSTRUCT));
149
150         g_object_class_install_property (gobject_class,
151                                          PROP_HORIZONTAL_MAX_OVERSHOOT,
152                                          g_param_spec_int ("horizontal-max-overshoot",
153                                                            "Horizontal max overshoot",
154                                                            "Horizontal maximum overshoot (0 disables)",
155                                                            0, G_MAXINT, 150,
156                                                            G_PARAM_READWRITE |G_PARAM_CONSTRUCT));
157
158         g_object_class_install_property (gobject_class,
159                                          PROP_VERTICAL_MAX_OVERSHOOT,
160                                          g_param_spec_int ("vertical-max-overshoot",
161                                                            "Vertical max overshoot",
162                                                            "Vertical maximum overshoot (0 disables)",
163                                                            0, G_MAXINT, 150,
164                                                            G_PARAM_READWRITE |G_PARAM_CONSTRUCT));
165 }
166
167 static void
168 modest_scrolled_window_scrollable_init (ModestScrolledWindowScrollable *self)
169 {
170         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (self), GTK_SHADOW_NONE);
171 }
172
173 static void
174 modest_scrollable_iface_init (gpointer g, gpointer iface_data)
175 {
176         ModestScrollableIface *iface = (ModestScrollableIface *) g;
177
178         iface->jump_to = modest_scrolled_window_scrollable_jump_to;
179         iface->scroll_to = modest_scrolled_window_scrollable_scroll_to;
180         iface->add_with_viewport = modest_scrolled_window_scrollable_add_with_viewport;
181         iface->get_vadjustment = modest_scrolled_window_scrollable_get_vadjustment;
182         iface->get_hadjustment = modest_scrolled_window_scrollable_get_hadjustment;
183         iface->get_vertical_policy = modest_scrolled_window_scrollable_get_vertical_policy;
184         iface->set_vertical_policy = modest_scrolled_window_scrollable_set_vertical_policy;
185         iface->get_horizontal_policy = modest_scrolled_window_scrollable_get_horizontal_policy;
186         iface->set_horizontal_policy = modest_scrolled_window_scrollable_set_horizontal_policy;
187 }
188
189 static void 
190 modest_scrolled_window_scrollable_finalize (GObject *obj)
191 {
192         G_OBJECT_CLASS(parent_class)->finalize (obj);           
193 }
194
195 static void
196 modest_scrolled_window_scrollable_get_property (GObject *obj,
197                                                 guint prop_id, 
198                                                 GValue *value, 
199                                                 GParamSpec *pspec)
200 {
201         GtkPolicyType policy;
202
203         switch (prop_id) {
204         case PROP_VERTICAL_POLICY:
205                 gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (obj), NULL, &policy);
206                 g_value_set_enum (value, policy);
207                 break;
208         case PROP_HORIZONTAL_POLICY:
209                 gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (obj), &policy, NULL);
210                 g_value_set_enum (value, policy);
211                 break;
212         case PROP_MOVEMENT_MODE:
213                 g_value_set_enum (value, MODEST_MOVEMENT_MODE_BOTH);
214                 break;
215         case PROP_HORIZONTAL_MAX_OVERSHOOT:
216                 g_value_set_int (value, 0);
217                 break;
218         case PROP_VERTICAL_MAX_OVERSHOOT:
219                 g_value_set_int (value, 0);
220                 break;
221         default:
222                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
223                 break;
224         }
225 }
226
227 static void
228 modest_scrolled_window_scrollable_set_property (GObject *obj,
229                                                      guint prop_id, 
230                                                      const GValue *value, 
231                                                      GParamSpec *pspec)
232 {
233         GtkPolicyType hpolicy, vpolicy;
234
235         gtk_scrolled_window_get_policy (GTK_SCROLLED_WINDOW (obj), &hpolicy, &vpolicy);
236         switch (prop_id) {
237         case PROP_VERTICAL_POLICY:
238                 vpolicy = g_value_get_enum (value);
239                 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (obj), hpolicy, vpolicy);
240                 break;
241         case PROP_HORIZONTAL_POLICY:
242                 hpolicy = g_value_get_enum (value);
243                 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (obj), hpolicy, vpolicy);
244                 break;
245         case PROP_MOVEMENT_MODE:
246         case PROP_HORIZONTAL_MAX_OVERSHOOT:
247         case PROP_VERTICAL_MAX_OVERSHOOT:
248                 /* these three parameters are not supported in scrolled window */
249                 break;
250         default:
251                 G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
252                 break;
253         }
254 }
255
256 static void
257 modest_scrolled_window_scrollable_add_with_viewport (ModestScrollable *self,
258                                                           GtkWidget *widget)
259 {
260         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->add_with_viewport_func (self, widget);
261 }
262
263 static void
264 modest_scrolled_window_scrollable_add_with_viewport_default (ModestScrollable *self,
265                                                                   GtkWidget *widget)
266 {
267         gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (self), widget);
268 }
269
270 static GtkAdjustment *
271 modest_scrolled_window_scrollable_get_vadjustment (ModestScrollable *self)
272 {
273         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_vadjustment_func (self);
274 }
275
276 static GtkAdjustment *
277 modest_scrolled_window_scrollable_get_vadjustment_default (ModestScrollable *self)
278 {
279         return gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self));
280 }
281
282 static GtkAdjustment *
283 modest_scrolled_window_scrollable_get_hadjustment (ModestScrollable *self)
284 {
285         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_hadjustment_func (self);
286 }
287
288 static GtkAdjustment *
289 modest_scrolled_window_scrollable_get_hadjustment_default (ModestScrollable *self)
290 {
291         return gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (self));
292 }
293
294 static void
295 modest_scrolled_window_scrollable_scroll_to (ModestScrollable *self, 
296                                              const gint x, const gint y)
297 {
298         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->scroll_to_func (self, x, y);
299 }
300
301 static void
302 modest_scrolled_window_scrollable_scroll_to_default (ModestScrollable *self,
303                                                      const gint x, const gint y)
304 {
305         GtkAdjustment *vadj, *hadj;
306         hadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self));
307         gtk_adjustment_set_value (hadj, (gdouble) y);
308         vadj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self));
309 }
310
311 static void
312 modest_scrolled_window_scrollable_jump_to (ModestScrollable *self, 
313                                                 const gint x, const gint y)
314 {
315         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->jump_to_func (self, x, y);
316 }
317
318 static void
319 modest_scrolled_window_scrollable_jump_to_default (ModestScrollable *self,
320                                                         const gint x, const gint y)
321 {
322         modest_scrollable_scroll_to (MODEST_SCROLLABLE (self), x, y);
323 }
324
325 static GtkPolicyType
326 modest_scrolled_window_scrollable_get_vertical_policy (ModestScrollable *self)
327 {
328         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_vertical_policy_func (self);
329 }
330
331 static GtkPolicyType
332 modest_scrolled_window_scrollable_get_vertical_policy_default (ModestScrollable *self)
333 {
334         GtkPolicyType policy;
335
336         g_object_get (G_OBJECT (self), "vertical-policy", &policy, NULL);
337         return policy;
338 }
339
340 static GtkPolicyType
341 modest_scrolled_window_scrollable_get_horizontal_policy (ModestScrollable *self)
342 {
343         return MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->get_horizontal_policy_func (self);
344 }
345
346 static GtkPolicyType
347 modest_scrolled_window_scrollable_get_horizontal_policy_default (ModestScrollable *self)
348 {
349         GtkPolicyType policy;
350
351         g_object_get (G_OBJECT (self), "horizontal-policy", &policy, NULL);
352         return policy;
353 }
354
355 static void
356 modest_scrolled_window_scrollable_set_horizontal_policy (ModestScrollable *self,
357                                                               GtkPolicyType policy)
358 {
359         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->set_horizontal_policy_func (self, policy);
360 }
361
362 static void
363 modest_scrolled_window_scrollable_set_horizontal_policy_default (ModestScrollable *self,
364                                                                       GtkPolicyType policy)
365 {
366         g_object_set (G_OBJECT (self), "horizontal-policy", policy, NULL);
367 }
368
369 static void
370 modest_scrolled_window_scrollable_set_vertical_policy (ModestScrollable *self,
371                                                             GtkPolicyType policy)
372 {
373         MODEST_SCROLLED_WINDOW_SCROLLABLE_GET_CLASS (self)->set_vertical_policy_func (self, policy);
374 }
375
376 static void
377 modest_scrolled_window_scrollable_set_vertical_policy_default (ModestScrollable *self,
378                                                                     GtkPolicyType policy)
379 {
380         g_object_set (G_OBJECT (self), "vertical-policy", policy, NULL);
381 }