]> git.sur5r.net Git - glabels/blob - glabels2/src/label-object.c
view_text and view_barcode dialogs now track changes to label's merge properties.
[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 };
39
40 enum {
41         CHANGED,
42         MOVED,
43         TOP,
44         BOTTOM,
45         LAST_SIGNAL
46 };
47
48 /*========================================================*/
49 /* Private globals.                                       */
50 /*========================================================*/
51
52 static GObjectClass *parent_class = NULL;
53
54 static guint signals[LAST_SIGNAL] = {0};
55
56 static guint instance = 0;
57
58 /*========================================================*/
59 /* Private function prototypes.                           */
60 /*========================================================*/
61
62 static void gl_label_object_class_init    (glLabelObjectClass *klass);
63 static void gl_label_object_instance_init (glLabelObject      *object);
64 static void gl_label_object_finalize      (GObject            *object);
65
66 static void merge_changed_cb              (glLabel            *label,
67                                            glLabelObject      *object);
68
69 \f
70 /*****************************************************************************/
71 /* Boilerplate object stuff.                                                 */
72 /*****************************************************************************/
73 GType
74 gl_label_object_get_type (void)
75 {
76         static GType type = 0;
77
78         if (!type) {
79                 GTypeInfo info = {
80                         sizeof (glLabelObjectClass),
81                         NULL,
82                         NULL,
83                         (GClassInitFunc) gl_label_object_class_init,
84                         NULL,
85                         NULL,
86                         sizeof (glLabelObject),
87                         0,
88                         (GInstanceInitFunc) gl_label_object_instance_init,
89                 };
90
91                 type = g_type_register_static (G_TYPE_OBJECT,
92                                                "glLabelObject", &info, 0);
93         }
94
95         return type;
96 }
97
98 static void
99 gl_label_object_class_init (glLabelObjectClass *klass)
100 {
101         GObjectClass *object_class = (GObjectClass *) klass;
102
103         gl_debug (DEBUG_LABEL, "START");
104
105         parent_class = g_type_class_peek_parent (klass);
106
107         object_class->finalize = gl_label_object_finalize;
108
109         signals[CHANGED] =
110                 g_signal_new ("changed",
111                               G_OBJECT_CLASS_TYPE (object_class),
112                               G_SIGNAL_RUN_LAST,
113                               G_STRUCT_OFFSET (glLabelObjectClass, changed),
114                               NULL, NULL,
115                               gl_marshal_VOID__VOID,
116                               G_TYPE_NONE,
117                               0);
118
119         signals[MOVED] =
120                 g_signal_new ("moved",
121                               G_OBJECT_CLASS_TYPE (object_class),
122                               G_SIGNAL_RUN_LAST,
123                               G_STRUCT_OFFSET (glLabelObjectClass, moved),
124                               NULL, NULL,
125                               gl_marshal_VOID__DOUBLE_DOUBLE,
126                               G_TYPE_NONE,
127                               2, G_TYPE_DOUBLE, G_TYPE_DOUBLE);
128         signals[TOP] =
129                 g_signal_new ("top",
130                               G_OBJECT_CLASS_TYPE (object_class),
131                               G_SIGNAL_RUN_LAST,
132                               G_STRUCT_OFFSET (glLabelObjectClass, top),
133                               NULL, NULL,
134                               gl_marshal_VOID__VOID,
135                               G_TYPE_NONE,
136                               0);
137
138         signals[BOTTOM] =
139                 g_signal_new ("bottom",
140                               G_OBJECT_CLASS_TYPE (object_class),
141                               G_SIGNAL_RUN_LAST,
142                               G_STRUCT_OFFSET (glLabelObjectClass, bottom),
143                               NULL, NULL,
144                               gl_marshal_VOID__VOID,
145                               G_TYPE_NONE,
146                               0);
147
148         gl_debug (DEBUG_LABEL, "END");
149 }
150
151 static void
152 gl_label_object_instance_init (glLabelObject *object)
153 {
154         gl_debug (DEBUG_LABEL, "START");
155
156         object->private = g_new0 (glLabelObjectPrivate, 1);
157
158         object->private->name = g_strdup_printf ("object%d", instance++);
159
160         gl_debug (DEBUG_LABEL, "END");
161 }
162
163 static void
164 gl_label_object_finalize (GObject *object)
165 {
166         glLabel       *parent;
167
168         gl_debug (DEBUG_LABEL, "START");
169
170         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
171
172         parent = GL_LABEL_OBJECT(object)->parent;
173         gl_label_remove_object (parent, GL_LABEL_OBJECT(object));
174
175         g_free (GL_LABEL_OBJECT(object)->private);
176
177         G_OBJECT_CLASS (parent_class)->finalize (object);
178
179         gl_debug (DEBUG_LABEL, "END");
180 }
181
182 GObject *
183 gl_label_object_new (glLabel *label)
184 {
185         glLabelObject *object;
186
187         gl_debug (DEBUG_LABEL, "START");
188
189         object = g_object_new (gl_label_object_get_type(), NULL);
190
191         gl_label_object_set_parent (object, label);
192
193         gl_debug (DEBUG_LABEL, "END");
194
195         return G_OBJECT (object);
196 }
197
198 /*****************************************************************************/
199 /* Emit "changed" signal (for derived objects).                              */
200 /*****************************************************************************/
201 void
202 gl_label_object_emit_changed (glLabelObject *object)
203 {
204         gl_debug (DEBUG_LABEL, "START");
205
206         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
207
208         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
209
210         gl_debug (DEBUG_LABEL, "END");
211 }
212
213 /*****************************************************************************/
214 /* Set parent label of object.                                               */
215 /*****************************************************************************/
216 void
217 gl_label_object_set_parent (glLabelObject *object,
218                             glLabel       *label)
219 {
220         glLabel *old_parent;
221
222         gl_debug (DEBUG_LABEL, "START");
223
224         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
225         g_return_if_fail (label && GL_IS_LABEL (label));
226
227         old_parent = object->parent;
228         if ( old_parent != NULL ) {
229                 g_signal_handlers_disconnect_by_func (old_parent,
230                                                       G_CALLBACK(merge_changed_cb),
231                                                       object);
232                 gl_label_remove_object( old_parent, object );
233         }
234         gl_label_add_object( label, object );
235
236         g_signal_connect (G_OBJECT(label), "merge_changed",
237                           G_CALLBACK(merge_changed_cb), object);
238
239         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
240
241         gl_debug (DEBUG_LABEL, "END");
242 }
243
244 /*****************************************************************************/
245 /* Get parent label of object.                                               */
246 /*****************************************************************************/
247 glLabel *
248 gl_label_object_get_parent (glLabelObject *object)
249 {
250         gl_debug (DEBUG_LABEL, "START");
251
252         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
253
254         gl_debug (DEBUG_LABEL, "END");
255
256         return object->parent;
257 }
258
259 /*****************************************************************************/
260 /* Set name of object.                                                       */
261 /*****************************************************************************/
262 void
263 gl_label_object_set_name (glLabelObject *object,
264                           gchar         *name)
265 {
266         gl_debug (DEBUG_LABEL, "START");
267
268         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
269
270         g_free(object->private->name);
271         object->private->name = name;
272
273         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
274
275         gl_debug (DEBUG_LABEL, "END");
276 }
277
278 /*****************************************************************************/
279 /* Get name of object.                                                       */
280 /*****************************************************************************/
281 gchar *
282 gl_label_object_get_name (glLabelObject *object)
283 {
284         gl_debug (DEBUG_LABEL, "START");
285
286         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
287
288         gl_debug (DEBUG_LABEL, "END");
289
290         return g_strdup(object->private->name);
291 }
292
293 /*****************************************************************************/
294 /* Set position of object.                                                   */
295 /*****************************************************************************/
296 void
297 gl_label_object_set_position (glLabelObject *object,
298                               gdouble        x,
299                               gdouble        y)
300 {
301         gdouble dx, dy;
302
303         gl_debug (DEBUG_LABEL, "START");
304
305         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
306
307         dx = x - object->private->x;
308         dy = y - object->private->y;
309
310         object->private->x = x;
311         object->private->y = y;
312
313         g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
314
315         gl_debug (DEBUG_LABEL, "END");
316 }
317
318 /*****************************************************************************/
319 /* Set position of object relative to old position.                          */
320 /*****************************************************************************/
321 void
322 gl_label_object_set_position_relative (glLabelObject *object,
323                                        gdouble        dx,
324                                        gdouble        dy)
325 {
326         gl_debug (DEBUG_LABEL, "START");
327
328         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
329
330         object->private->x += dx;
331         object->private->y += dy;
332
333         gl_debug (DEBUG_LABEL, "       x = %f, y= %f",
334                   object->private->x,
335                   object->private->y);
336
337         g_signal_emit (G_OBJECT(object), signals[MOVED], 0, dx, dy);
338
339         gl_debug (DEBUG_LABEL, "END");
340 }
341
342 /*****************************************************************************/
343 /* Get position of object.                                                   */
344 /*****************************************************************************/
345 void
346 gl_label_object_get_position (glLabelObject *object,
347                               gdouble       *x,
348                               gdouble       *y)
349 {
350         gl_debug (DEBUG_LABEL, "START");
351
352         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
353
354         *x = object->private->x;
355         *y = object->private->y;
356
357         gl_debug (DEBUG_LABEL, "END");
358 }
359
360 /*****************************************************************************/
361 /* Set size of object.                                                       */
362 /*****************************************************************************/
363 void
364 gl_label_object_set_size (glLabelObject *object,
365                           gdouble        w,
366                           gdouble        h)
367 {
368         gl_debug (DEBUG_LABEL, "START");
369
370         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
371
372         object->private->w = w;
373         object->private->h = h;
374
375         g_signal_emit (G_OBJECT(object), signals[CHANGED], 0);
376
377         gl_debug (DEBUG_LABEL, "END");
378 }
379
380 /*****************************************************************************/
381 /* Get size of object.                                                       */
382 /*****************************************************************************/
383 void
384 gl_label_object_get_size (glLabelObject *object,
385                           gdouble       *w,
386                           gdouble       *h)
387 {
388         gl_debug (DEBUG_LABEL, "START");
389
390         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
391
392         *w = object->private->w;
393         *h = object->private->h;
394
395         gl_debug (DEBUG_LABEL, "END");
396 }
397
398 /****************************************************************************/
399 /* Bring label object to front/top.                                         */
400 /****************************************************************************/
401 void
402 gl_label_object_raise_to_top (glLabelObject *object)
403 {
404         glLabel *label;
405
406         gl_debug (DEBUG_LABEL, "START");
407
408         label = object->parent;
409
410         gl_label_raise_object_to_top (label, object);
411
412         g_signal_emit (G_OBJECT(object), signals[TOP], 0);
413
414         gl_debug (DEBUG_LABEL, "END");
415 }
416
417 /****************************************************************************/
418 /* Send label object to rear/bottom.                                        */
419 /****************************************************************************/
420 void
421 gl_label_object_lower_to_bottom (glLabelObject *object)
422 {
423         glLabel *label;
424
425         gl_debug (DEBUG_LABEL, "START");
426
427         label = object->parent;
428
429         gl_label_lower_object_to_bottom (label, object);
430
431         g_signal_emit (G_OBJECT(object), signals[BOTTOM], 0);
432
433         gl_debug (DEBUG_LABEL, "END");
434 }
435
436 /*--------------------------------------------------------------------------*/
437 /* PRIVATE.  Label's merge data changed callback.                           */
438 /*--------------------------------------------------------------------------*/
439 static void
440 merge_changed_cb (glLabel       *label,
441                   glLabelObject *object)
442 {
443         gl_label_object_emit_changed (object);
444 }
445