Code

tpdfv-ctl: Added controller module used to manage multiple GtkTPDFV widgets.
[tpdfview.git] / src / tpdfv-ctl.c
1 /*
2  * tpdfview - src/tpdfvctl.c
3  * Copyright (C) 2011 Sebastian 'tokkee' Harl <sh@tokkee.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
28 /*
29  * This module provides a controller use to manage multiple GtkTPDFV widgets.
30  */
32 #include "tpdfv-ctl.h"
34 #include <assert.h>
35 #include <errno.h>
37 #include <stdlib.h>
39 typedef struct {
40         GtkWidget *widget;
41         gint factor;
42         gint offset;
43 } slave_t;
45 typedef struct {
46         GtkWidget *main;
47         slave_t   *slaves;
48         gint slaves_num;
49 } tpdfv_ctl_t;
51 GType tpdfv_ctl_get_type(void);
52 G_DEFINE_TYPE(TPDFVCtl, tpdfv_ctl, G_TYPE_OBJECT);
54 #define TPDFV_CTL_GET_PRIVATE(obj) \
55         (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TPDFV_TYPE_CTL, tpdfv_ctl_t))
57 /*
58  * Private helper functions.
59  */
61 static void
62 update_slave_page(tpdfv_ctl_t *ctl)
63 {
64         gint current_page;
65         gint i;
67         current_page = gtk_tpdfv_get_current_page(ctl->main);
69         for (i = 0; i < ctl->slaves_num; ++i) {
70                 slave_t *slave = ctl->slaves + i;
72                 gtk_tpdfv_goto_page(slave->widget,
73                                 current_page * slave->factor + slave->offset);
74         }
75 } /* update_slave_page */
77 /*
78  * GObject definition.
79  */
81 static void
82 tpdfv_ctl_dispose(GObject *obj)
83 {
84         G_OBJECT_CLASS(tpdfv_ctl_parent_class)->dispose(obj);
85 } /* tpdfv_ctl_dispose */
87 static void
88 tpdfv_ctl_finalize(GObject *obj)
89 {
90         tpdfv_ctl_t *ctl = TPDFV_CTL_GET_PRIVATE(obj);
92         if (ctl->slaves)
93                 free(ctl->slaves);
94         ctl->slaves = NULL;
95         ctl->slaves_num = 0;
97         G_OBJECT_CLASS(tpdfv_ctl_parent_class)->finalize(obj);
98 } /* tpdfv_ctl_finalize */
100 static void
101 tpdfv_ctl_class_init(TPDFVCtlClass *class)
103         GObjectClass *goclass;
105         goclass = G_OBJECT_CLASS(class);
106         g_type_class_add_private(goclass, sizeof(tpdfv_ctl_t));
108         goclass->dispose  = tpdfv_ctl_dispose;
109         goclass->finalize = tpdfv_ctl_finalize;
110 } /* tpdfv_ctl_class_init */
112 static void
113 tpdfv_ctl_init(TPDFVCtl __attribute__((unused)) *ctl)
115         /* nothing to do for now */
116 } /* tpdfv_ctl_init */
118 /*
119  * Public API.
120  */
122 GObject *
123 tpdfv_ctl_new(GtkTPDFV *main)
125         TPDFVCtl *g_ctl;
126         tpdfv_ctl_t *ctl;
128         g_ctl = g_object_new(TPDFV_TYPE_CTL, NULL);
129         ctl   = TPDFV_CTL_GET_PRIVATE(g_ctl);
131         ctl->main = GTK_WIDGET(main);
132         ctl->slaves = NULL;
133         ctl->slaves_num = 0;
134         return G_OBJECT(g_ctl);
135 } /* tpdfv_ctl_new */
137 gboolean
138 tpdfv_ctl_add_slave(GObject *obj, GtkTPDFV *slave,
139                 gint factor, gint offset)
141         tpdfv_ctl_t *ctl;
142         slave_t *s;
144         ctl = TPDFV_CTL_GET_PRIVATE(obj);
145         s = (slave_t *)realloc(ctl->slaves,
146                         (size_t)(ctl->slaves_num + 1) * sizeof(*s));
147         if (! s)
148                 return FALSE;
150         ctl->slaves = s;
151         s = ctl->slaves + ctl->slaves_num;
152         ++ctl->slaves_num;
154         s->widget = GTK_WIDGET(slave);
155         s->factor = factor;
156         s->offset = offset;
158         update_slave_page(ctl);
159         return TRUE;
160 } /* tpdfv_ctl_add_slave */
162 void
163 tpdfv_ctl_reload(GObject *obj)
165         tpdfv_ctl_t *ctl;
167         gint i;
169         if (GTK_IS_TPDFV(obj))
170                 return gtk_tpdfv_reload(GTK_WIDGET(obj));
172         ctl = TPDFV_CTL_GET_PRIVATE(obj);
174         gtk_tpdfv_reload(ctl->main);
175         for (i = 0; i < ctl->slaves_num; ++i)
176                 gtk_tpdfv_reload(ctl->slaves[i].widget);
177 } /* tpdfv_ctl_reload */
179 void
180 tpdfv_ctl_page_up(GObject *obj)
182         tpdfv_ctl_t *ctl;
184         if (GTK_IS_TPDFV(obj))
185                 return gtk_tpdfv_page_up(GTK_WIDGET(obj));
187         ctl = TPDFV_CTL_GET_PRIVATE(obj);
189         gtk_tpdfv_page_up(ctl->main);
190         update_slave_page(ctl);
191 } /* tpdfv_ctl_page_up */
193 void
194 tpdfv_ctl_page_down(GObject *obj)
196         tpdfv_ctl_t *ctl;
198         if (GTK_IS_TPDFV(obj))
199                 return gtk_tpdfv_page_down(GTK_WIDGET(obj));
201         ctl = TPDFV_CTL_GET_PRIVATE(obj);
203         gtk_tpdfv_page_down(ctl->main);
204         update_slave_page(ctl);
205 } /* tpdfv_ctl_page_down */
207 void
208 tpdfv_ctl_first_page(GObject *obj)
210         tpdfv_ctl_t *ctl;
212         if (GTK_IS_TPDFV(obj))
213                 return gtk_tpdfv_first_page(GTK_WIDGET(obj));
215         ctl = TPDFV_CTL_GET_PRIVATE(obj);
217         gtk_tpdfv_first_page(ctl->main);
218         update_slave_page(ctl);
219 } /* tpdfv_ctl_first_page */
221 void
222 tpdfv_ctl_last_page(GObject *obj)
224         tpdfv_ctl_t *ctl;
226         if (GTK_IS_TPDFV(obj))
227                 return gtk_tpdfv_last_page(GTK_WIDGET(obj));
229         ctl = TPDFV_CTL_GET_PRIVATE(obj);
231         gtk_tpdfv_last_page(ctl->main);
232         update_slave_page(ctl);
233 } /* tpdfv_ctl_last_page */
235 void
236 tpdfv_ctl_goto_page(GObject *obj, gint page)
238         tpdfv_ctl_t *ctl;
240         if (GTK_IS_TPDFV(obj))
241                 return gtk_tpdfv_goto_page(GTK_WIDGET(obj), page);
243         ctl = TPDFV_CTL_GET_PRIVATE(obj);
245         gtk_tpdfv_goto_page(ctl->main, page);
246         update_slave_page(ctl);
247 } /* tpdfv_ctl_goto_page */
249 void
250 tpdfv_ctl_zoom_in(GObject *obj)
252         tpdfv_ctl_t *ctl;
254         gint i;
256         if (GTK_IS_TPDFV(obj))
257                 return gtk_tpdfv_zoom_in(GTK_WIDGET(obj));
259         ctl = TPDFV_CTL_GET_PRIVATE(obj);
261         gtk_tpdfv_zoom_in(ctl->main);
262         for (i = 0; i < ctl->slaves_num; ++i)
263                 gtk_tpdfv_zoom_in(ctl->slaves[i].widget);
264 } /* tpdfv_ctl_zoom_in */
266 void
267 tpdfv_ctl_zoom_out(GObject *obj)
269         tpdfv_ctl_t *ctl;
271         gint i;
273         if (GTK_IS_TPDFV(obj))
274                 return gtk_tpdfv_zoom_out(GTK_WIDGET(obj));
276         ctl = TPDFV_CTL_GET_PRIVATE(obj);
278         gtk_tpdfv_zoom_out(ctl->main);
279         for (i = 0; i < ctl->slaves_num; ++i)
280                 gtk_tpdfv_zoom_out(ctl->slaves[i].widget);
281 } /* tpdfv_ctl_zoom_out */
283 void
284 tpdfv_ctl_zoom_1(GObject *obj)
286         tpdfv_ctl_t *ctl;
288         gint i;
290         if (GTK_IS_TPDFV(obj))
291                 return gtk_tpdfv_zoom_1(GTK_WIDGET(obj));
293         ctl = TPDFV_CTL_GET_PRIVATE(obj);
295         gtk_tpdfv_zoom_1(ctl->main);
296         for (i = 0; i < ctl->slaves_num; ++i)
297                 gtk_tpdfv_zoom_1(ctl->slaves[i].widget);
298 } /* tpdfv_ctl_zoom_1 */
300 void
301 tpdfv_ctl_zoom_width(GObject *obj)
303         tpdfv_ctl_t *ctl;
305         gint i;
307         if (GTK_IS_TPDFV(obj))
308                 return gtk_tpdfv_zoom_width(GTK_WIDGET(obj));
310         ctl = TPDFV_CTL_GET_PRIVATE(obj);
312         gtk_tpdfv_zoom_width(ctl->main);
313         for (i = 0; i < ctl->slaves_num; ++i)
314                 gtk_tpdfv_zoom_width(ctl->slaves[i].widget);
315 } /* tpdfv_ctl_zoom_width */
317 void
318 tpdfv_ctl_zoom_height(GObject *obj)
320         tpdfv_ctl_t *ctl;
322         gint i;
324         if (GTK_IS_TPDFV(obj))
325                 return gtk_tpdfv_zoom_height(GTK_WIDGET(obj));
327         ctl = TPDFV_CTL_GET_PRIVATE(obj);
329         gtk_tpdfv_zoom_height(ctl->main);
330         for (i = 0; i < ctl->slaves_num; ++i)
331                 gtk_tpdfv_zoom_height(ctl->slaves[i].widget);
332 } /* tpdfv_ctl_zoom_height */
334 void
335 tpdfv_ctl_zoom_fit(GObject *obj)
337         tpdfv_ctl_t *ctl;
339         gint i;
341         if (GTK_IS_TPDFV(obj))
342                 return gtk_tpdfv_zoom_fit(GTK_WIDGET(obj));
344         ctl = TPDFV_CTL_GET_PRIVATE(obj);
346         gtk_tpdfv_zoom_fit(ctl->main);
347         for (i = 0; i < ctl->slaves_num; ++i)
348                 gtk_tpdfv_zoom_fit(ctl->slaves[i].widget);
349 } /* tpdfv_ctl_zoom_fit */
351 void
352 tpdfv_ctl_scroll_up(GObject *obj)
354         tpdfv_ctl_t *ctl;
356         gint i;
358         if (GTK_IS_TPDFV(obj))
359                 return gtk_tpdfv_scroll_up(GTK_WIDGET(obj));
361         ctl = TPDFV_CTL_GET_PRIVATE(obj);
363         gtk_tpdfv_scroll_up(ctl->main);
364         for (i = 0; i < ctl->slaves_num; ++i)
365                 gtk_tpdfv_scroll_up(ctl->slaves[i].widget);
366 } /* tpdfv_ctl_scroll_up */
368 void
369 tpdfv_ctl_scroll_down(GObject *obj)
371         tpdfv_ctl_t *ctl;
373         gint i;
375         if (GTK_IS_TPDFV(obj))
376                 return gtk_tpdfv_scroll_down(GTK_WIDGET(obj));
378         ctl = TPDFV_CTL_GET_PRIVATE(obj);
380         gtk_tpdfv_scroll_down(ctl->main);
381         for (i = 0; i < ctl->slaves_num; ++i)
382                 gtk_tpdfv_scroll_down(ctl->slaves[i].widget);
383 } /* tpdfv_ctl_scroll_down */
385 void
386 tpdfv_ctl_scroll_left(GObject *obj)
388         tpdfv_ctl_t *ctl;
390         gint i;
392         if (GTK_IS_TPDFV(obj))
393                 return gtk_tpdfv_scroll_left(GTK_WIDGET(obj));
395         ctl = TPDFV_CTL_GET_PRIVATE(obj);
397         gtk_tpdfv_scroll_left(ctl->main);
398         for (i = 0; i < ctl->slaves_num; ++i)
399                 gtk_tpdfv_scroll_left(ctl->slaves[i].widget);
400 } /* tpdfv_ctl_scroll_left */
402 void
403 tpdfv_ctl_scroll_right(GObject *obj)
405         tpdfv_ctl_t *ctl;
407         gint i;
409         if (GTK_IS_TPDFV(obj))
410                 return gtk_tpdfv_scroll_right(GTK_WIDGET(obj));
412         ctl = TPDFV_CTL_GET_PRIVATE(obj);
414         gtk_tpdfv_scroll_right(ctl->main);
415         for (i = 0; i < ctl->slaves_num; ++i)
416                 gtk_tpdfv_scroll_right(ctl->slaves[i].widget);
417 } /* tpdfv_ctl_scroll_right */
419 /* vim: set tw=78 sw=4 ts=4 noexpandtab : */