]> git.sur5r.net Git - glabels/blob - glabels2/src/label-object.c
Includes support for flipping.
[glabels] / glabels2 / src / label-object.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  label_object.c:  GLabels label object base class
5  *
6  *  Copyright (C) 2001-2002  Jim Evins <evins@snaught.com>.
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
21  */
22
23 #include <glib.h>
24
25 #include "label-object.h"
26 #include "marshal.h"
27
28 #include "debug.h"
29
30 /*========================================================*/
31 /* Private types.                                         */
32 /*========================================================*/
33
34 struct _glLabelObjectPrivate {
35         gchar             *name;
36         gdouble            x, y;
37         gdouble            w, h;
38         glLabelObjectFlip  flip;
39         gdouble            rotate_degs;
40 };
41
42 enum {
43         CHANGED,
44         MOVED,
45         FLIP_ROTATE,
46         TOP,
47         BOTTOM,
48         LAST_SIGNAL
49 };
50
51 /*========================================================*/
52 /* Private globals.                                       */
53 /*========================================================*/
54
55 static GObjectClass *parent_class = NULL;
56
57 static guint signals[LAST_SIGNAL] = {0};
58
59 static guint instance = 0;
60
61 /*========================================================*/
62 /* Private function prototypes.                           */
63 /*========================================================*/
64
65 static void gl_label_object_class_init    (glLabelObjectClass *klass);
66 static void gl_label_object_instance_init (glLabelObject      *object);
67 static void gl_label_object_finalize      (GObject            *object);
68
69 static void merge_changed_cb              (glLabel            *label,
70                                            glLabelObject      *object);
71
72 \f
73 /*****************************************************************************/
74 /* Boilerplate object stuff.                                                 */
75 /*****************************************************************************/
76 GType
77 gl_label_object_get_type (void)
78 {
79         static GType type = 0;
80
81         if (!type) {
82                 GTypeInfo info = {
83                         sizeof (glLabelObjectClass),
84                         NULL,
85                         NULL,
86                         (GClassInitFunc) gl_label_object_class_init,
87                         NULL,
88                         NULL,
89                         sizeof (glLabelObject),
90                         0,
91                         (GInstanceInitFunc) gl_label_object_instance_init,
92                 };
93
94                 type = g_type_register_static (G_TYPE_OBJECT,
95                                                "glLabelObject", &info, 0);
96         }
97
98         return type;
99 }
100
101 static void
102 gl_label_object_class_init (glLabelObjectClass *klass)
103 {
104         GObjectClass *object_class = (GObjectClass *) klass;
105
106         gl_debug (DEBUG_LABEL, "START");
107
108         parent_class = g_type_class_peek_parent (klass);
109
110         object_class->finalize = gl_label_object_finalize;
111
112         signals[CHANGED] =
113                 g_signal_new ("changed",
114                               G_OBJECT_CLASS_TYPE (object_class),
115                               G_SIGNAL_RUN_LAST,
116                               G_STRUCT_OFFSET (glLabelObjectClass, changed),
117                               NULL, NULL,
118                               gl_marshal_VOID__VOID,
119                               G_TYPE_NONE,
120                               0);
121
122         signals[MOVED] =
123                 g_signal_new ("moved",
124                               G_OBJECT_CLASS_TYPE (object_class),
125                               G_SIGNAL_RUN_LAST,
126                               G_STRUCT_OFFSET (glLabelObjectClass, moved),
127                               NULL, NULL,
128                               gl_marshal_VOID__DOUBLE_DOUBLE,
129                               G_TYPE_NONE,
130                               2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
131         signals[FLIP_ROTATE] =
132                 g_signal_new ("flip_rotate",
133                               G_OBJECT_CLASS_TYPE (object_class),
134                               G_SIGNAL_RUN_LAST,
135                               G_STRUCT_OFFSET (glLabelObjectClass, flip_rotate),
136                               NULL, NULL,
137                               gl_marshal_VOID__INT_DOUBLE,
138                               G_TYPE_NONE,
139                               2, G_TYPE_INT, G_TYPE_DOUBLE);
140         signals[TOP] =
141                 g_signal_new ("top",
142                               G_OBJECT_CLASS_TYPE (object_class),
143                               G_SIGNAL_RUN_LAST,
144                               G_STRUCT_OFFSET (glLabelObjectClass, top),
145                               NULL, NULL,
146                               gl_marshal_VOID__VOID,
147                               G_TYPE_NONE,
148                               0);
149
150         signals[BOTTOM] =
151                 g_signal_new ("bottom",
152                               G_OBJECT_CLASS_TYPE (object_class),
153                               G_SIGNAL_RUN_LAST,
154                               G_STRUCT_OFFSET (glLabelObjectClass, bottom),
155                               NULL, NULL,
156                               gl_marshal_VOID__VOID,
157                               G_TYPE_NONE,
158                               0);
159
160         gl_debug (DEBUG_LABEL, "END");
161 }
162
163 static void
164 gl_label_object_instance_init (glLabelObject *object)
165 {
166         gl_debug (DEBUG_LABEL, "START");
167
168         object->private = g_new0 (glLabelObjectPrivate, 1);
169
170         object->private->name = g_strdup_printf ("object%d", instance++);
171
172         gl_debug (DEBUG_LABEL, "END");
173 }
174
175 static void
176 gl_label_object_finalize (GObject *object)
177 {
178         glLabel       *parent;
179
180         gl_debug (DEBUG_LABEL, "START");
181
182         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
183
184         parent = GL_LABEL_OBJECT(object)->parent;
185         gl_label_remove_object (parent, GL_LABEL_OBJECT(object));
186
187         g_free (GL_LABEL_OBJECT(object)->private);
188
189         G_OBJECT_CLASS (parent_class)->finalize (object);
190
191         gl_debug (DEBUG_LABEL, "END");
192 }
193
194 /*****************************************************************************/
195 /* New label object.                                                         */
196 /*****************************************************************************/
197 GObject *
198 gl_label_object_new (glLabel *label)
199 {
200         glLabelObject *object;
201
202         gl_debug (DEBUG_LABEL, "START");
203
204         object = g_object_new (gl_label_object_get_type(), NULL);
205
206         gl_label_object_set_parent (object, label);
207
208         gl_debug (DEBUG_LABEL, "END");
209
210         return G_OBJECT (object);
211 }
212
213 /*****************************************************************************/
214 /* Copy properties of one label object to another.                           */
215 /*****************************************************************************/
216 void
217 gl_label_object_copy_props (glLabelObject *dst_object,
218                             glLabelObject *src_object)
219 {
220         gdouble           x, y, w, h;
221         glLabelObjectFlip flip;
222
223         g_return_if_fail (src_object && GL_IS_LABEL_OBJECT (src_object));
224         g_return_if_fail (dst_object && GL_IS_LABEL_OBJECT (dst_object));
225
226         gl_label_object_get_position    (src_object, &x, &y);
227         gl_label_object_get_size        (src_object, &w, &h);
228         flip = gl_label_object_get_flip (src_object);
229
230         gl_label_object_set_position (dst_object,  x,  y);
231         gl_label_object_set_size     (dst_object,  w,  h);
232         gl_label_object_set_flip     (dst_object,  flip);
233 }
234
235 /*****************************************************************************/
236 /* Emit "changed" signal (for derived objects).                              */
237 /*****************************************************************************/
238 void
239 gl_label_object_emit_changed (glLabelObject *object)
240 {
241         gl_debug (DEBUG_LABEL, "START");
242
243         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
244
245         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
246
247         gl_debug (DEBUG_LABEL, "END");
248 }
249
250 /*****************************************************************************/
251 /* Set parent label of object.                                               */
252 /*****************************************************************************/
253 void
254 gl_label_object_set_parent (glLabelObject *object,
255                             glLabel       *label)
256 {
257         glLabel *old_parent;
258
259         gl_debug (DEBUG_LABEL, "START");
260
261         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
262         g_return_if_fail (label && GL_IS_LABEL (label));
263
264         old_parent = object->parent;
265         if ( old_parent != NULL ) {
266                 g_signal_handlers_disconnect_by_func (old_parent,
267                                                       G_CALLBACK(merge_changed_cb),
268                                                       object);
269                 gl_label_remove_object( old_parent, object );
270         }
271         gl_label_add_object( label, object );
272
273         g_signal_connect (G_OBJECT(label), "merge_changed",
274                           G_CALLBACK(merge_changed_cb), object);
275
276         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
277
278         gl_debug (DEBUG_LABEL, "END");
279 }
280
281 /*****************************************************************************/
282 /* Get parent label of object.                                               */
283 /*****************************************************************************/
284 glLabel *
285 gl_label_object_get_parent (glLabelObject *object)
286 {
287         gl_debug (DEBUG_LABEL, "START");
288
289         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
290
291         gl_debug (DEBUG_LABEL, "END");
292
293         return object->parent;
294 }
295
296 /*****************************************************************************/
297 /* Set name of object.                                                       */
298 /*****************************************************************************/
299 void
300 gl_label_object_set_name (glLabelObject *object,
301                           gchar         *name)
302 {
303         gl_debug (DEBUG_LABEL, "START");
304
305         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
306
307         g_free(object->private->name);
308         object->private->name = name;
309
310         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
311
312         gl_debug (DEBUG_LABEL, "END");
313 }
314
315 /*****************************************************************************/
316 /* Get name of object.                                                       */
317 /*****************************************************************************/
318 gchar *
319 gl_label_object_get_name (glLabelObject *object)
320 {
321         gl_debug (DEBUG_LABEL, "START");
322
323         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
324
325         gl_debug (DEBUG_LABEL, "END");
326
327         return g_strdup(object->private->name);
328 }
329
330 /*****************************************************************************/
331 /* Set position of object.                                                   */
332 /*****************************************************************************/
333 void
334 gl_label_object_set_position (glLabelObject *object,
335                               gdouble        x,
336                               gdouble        y)
337 {
338         gdouble dx, dy;
339
340         gl_debug (DEBUG_LABEL, "START");
341
342         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
343
344         dx = x - object->private->x;
345         dy = y - object->private->y;
346
347         object->private->x = x;
348         object->private->y = y;
349
350         g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
351
352         gl_debug (DEBUG_LABEL, "END");
353 }
354
355 /*****************************************************************************/
356 /* Set position of object relative to old position.                          */
357 /*****************************************************************************/
358 void
359 gl_label_object_set_position_relative (glLabelObject *object,
360                                        gdouble        dx,
361                                        gdouble        dy)
362 {
363         gl_debug (DEBUG_LABEL, "START");
364
365         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
366
367         object->private->x += dx;
368         object->private->y += dy;
369
370         gl_debug (DEBUG_LABEL, "       x = %f, y= %f",
371                   object->private->x,
372                   object->private->y);
373
374         g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
375
376         gl_debug (DEBUG_LABEL, "END");
377 }
378
379 /*****************************************************************************/
380 /* Get position of object.                                                   */
381 /*****************************************************************************/
382 void
383 gl_label_object_get_position (glLabelObject *object,
384                               gdouble       *x,
385                               gdouble       *y)
386 {
387         gl_debug (DEBUG_LABEL, "START");
388
389         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
390
391         *x = object->private->x;
392         *y = object->private->y;
393
394         gl_debug (DEBUG_LABEL, "END");
395 }
396
397 /*****************************************************************************/
398 /* Set size of object.                                                       */
399 /*****************************************************************************/
400 void
401 gl_label_object_set_size (glLabelObject *object,
402                           gdouble        w,
403                           gdouble        h)
404 {
405         gl_debug (DEBUG_LABEL, "START");
406
407         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
408
409         object->private->w = w;
410         object->private->h = h;
411
412         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
413
414         gl_debug (DEBUG_LABEL, "END");
415 }
416
417 /*****************************************************************************/
418 /* Get size of object.                                                       */
419 /*****************************************************************************/
420 void
421 gl_label_object_get_size (glLabelObject *object,
422                           gdouble       *w,
423                           gdouble       *h)
424 {
425         gl_debug (DEBUG_LABEL, "START");
426
427         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
428
429         *w = object->private->w;
430         *h = object->private->h;
431
432         gl_debug (DEBUG_LABEL, "END");
433 }
434
435 /****************************************************************************/
436 /* Set flip state of object.                                                */
437 /****************************************************************************/
438 void
439 gl_label_object_set_flip (glLabelObject     *object,
440                           glLabelObjectFlip  flip)
441 {
442         gl_debug (DEBUG_LABEL, "START");
443
444         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
445
446         object->private->flip = flip;
447
448         g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0,
449                        flip, object->private->rotate_degs);
450
451         gl_debug (DEBUG_LABEL, "END");
452 }
453
454 /****************************************************************************/
455 /* Flip object horizontally.                                                */
456 /****************************************************************************/
457 void
458 gl_label_object_flip_horiz (glLabelObject *object)
459 {
460         gl_debug (DEBUG_LABEL, "START");
461
462         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
463
464         object->private->flip ^= GL_LABEL_OBJECT_FLIP_HORIZ;
465
466         g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0,
467                        object->private->flip, object->private->rotate_degs);
468
469         gl_debug (DEBUG_LABEL, "END");
470 }
471
472 /****************************************************************************/
473 /* Flip object vertically.                                                  */
474 /****************************************************************************/
475 void
476 gl_label_object_flip_vert (glLabelObject *object)
477 {
478         gl_debug (DEBUG_LABEL, "START");
479
480         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
481
482         object->private->flip ^= GL_LABEL_OBJECT_FLIP_VERT;
483
484         g_signal_emit (G_OBJECT(object), signals[FLIP_ROTATE], 0,
485                        object->private->flip, object->private->rotate_degs);
486
487         gl_debug (DEBUG_LABEL, "END");
488 }
489
490 /****************************************************************************/
491 /* Get flip state of object.                                                */
492 /****************************************************************************/
493 glLabelObjectFlip
494 gl_label_object_get_flip (glLabelObject      *object)
495 {
496         gl_debug (DEBUG_LABEL, "");
497
498         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
499
500         return object->private->flip;
501 }
502
503 /****************************************************************************/
504 /* Bring label object to front/top.                                         */
505 /****************************************************************************/
506 void
507 gl_label_object_raise_to_top (glLabelObject *object)
508 {
509         glLabel *label;
510
511         gl_debug (DEBUG_LABEL, "START");
512
513         label = object->parent;
514
515         gl_label_raise_object_to_top (label, object);
516
517         g_signal_emit (G_OBJECT(object), signals[TOP], 0);
518
519         gl_debug (DEBUG_LABEL, "END");
520 }
521
522 /****************************************************************************/
523 /* Send label object to rear/bottom.                                        */
524 /****************************************************************************/
525 void
526 gl_label_object_lower_to_bottom (glLabelObject *object)
527 {
528         glLabel *label;
529
530         gl_debug (DEBUG_LABEL, "START");
531
532         label = object->parent;
533
534         gl_label_lower_object_to_bottom (label, object);
535
536         g_signal_emit (G_OBJECT(object), signals[BOTTOM], 0);
537
538         gl_debug (DEBUG_LABEL, "END");
539 }
540
541 /*--------------------------------------------------------------------------*/
542 /* PRIVATE.  Label's merge data changed callback.                           */
543 /*--------------------------------------------------------------------------*/
544 static void
545 merge_changed_cb (glLabel       *label,
546                   glLabelObject *object)
547 {
548         gl_label_object_emit_changed (object);
549 }
550