]> git.sur5r.net Git - glabels/blob - glabels2/src/view-object.c
Initial revision
[glabels] / glabels2 / src / view-object.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  view_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 "view-object.h"
26
27 #include "debug.h"
28
29 /*========================================================*/
30 /* Private types.                                         */
31 /*========================================================*/
32
33 struct _glViewObjectPrivate {
34
35         glView               *view;
36         glLabelObject        *object;
37
38         GnomeCanvasItem      *group;
39         GnomeCanvasItem      *highlight;
40
41         GtkWidget            *menu;
42         GtkWidget            *property_dialog;
43 };
44
45 /*========================================================*/
46 /* Private globals.                                       */
47 /*========================================================*/
48
49 static GObjectClass *parent_class = NULL;
50
51
52 /*========================================================*/
53 /* Private function prototypes.                           */
54 /*========================================================*/
55
56 static void gl_view_object_class_init (glViewObjectClass *klass);
57 static void gl_view_object_instance_init (glViewObject *view_object);
58 static void gl_view_object_finalize (GObject *object);
59
60 static GtkMenu *new_menu (glViewObject *view_object);
61
62 static void object_moved_cb (glLabelObject *object,
63                              gdouble x, gdouble y,
64                              glViewObject *view_object);
65 static void raise_object_cb (GtkWidget * widget, glViewObject *view_object);
66 static void lower_object_cb (GtkWidget * widget, glViewObject *view_object);
67
68 \f
69 /*****************************************************************************/
70 /* Boilerplate object stuff.                                                 */
71 /*****************************************************************************/
72 GType
73 gl_view_object_get_type (void)
74 {
75         static GType type = 0;
76
77         if (!type) {
78                 GTypeInfo info = {
79                         sizeof (glViewObjectClass),
80                         NULL,
81                         NULL,
82                         (GClassInitFunc) gl_view_object_class_init,
83                         NULL,
84                         NULL,
85                         sizeof (glViewObject),
86                         0,
87                         (GInstanceInitFunc) gl_view_object_instance_init,
88                 };
89
90                 type = g_type_register_static (G_TYPE_OBJECT,
91                                                "glViewObject", &info, 0);
92         }
93
94         return type;
95 }
96
97 static void
98 gl_view_object_class_init (glViewObjectClass *klass)
99 {
100         GObjectClass *object_class = (GObjectClass *) klass;
101
102         gl_debug (DEBUG_VIEW, "START");
103
104         parent_class = g_type_class_peek_parent (klass);
105
106         object_class->finalize = gl_view_object_finalize;
107
108         gl_debug (DEBUG_VIEW, "END");
109 }
110
111 static void
112 gl_view_object_instance_init (glViewObject *view_object)
113 {
114         gl_debug (DEBUG_VIEW, "START");
115
116         view_object->private = g_new0 (glViewObjectPrivate, 1);
117
118         gl_debug (DEBUG_VIEW, "END");
119 }
120
121 static void
122 gl_view_object_finalize (GObject *object)
123 {
124         glLabel       *parent;
125         glView        *view;
126
127         gl_debug (DEBUG_VIEW, "START");
128
129         g_return_if_fail (object && GL_IS_VIEW_OBJECT (object));
130
131         view = GL_VIEW_OBJECT(object)->private->view;
132         view->object_list = g_list_remove (view->object_list, object);
133         view->selected_object_list =
134                 g_list_remove (view->selected_object_list, object);
135
136         g_object_unref (GL_VIEW_OBJECT(object)->private->object);
137         gtk_object_destroy (GTK_OBJECT(GL_VIEW_OBJECT(object)->private->group));
138         gtk_object_destroy (GTK_OBJECT(GL_VIEW_OBJECT(object)->private->highlight));
139         gtk_object_destroy (GTK_OBJECT(GL_VIEW_OBJECT(object)->private->menu));
140         gtk_object_destroy (GTK_OBJECT(GL_VIEW_OBJECT(object)->private->property_dialog));
141
142         G_OBJECT_CLASS (parent_class)->finalize (object);
143
144         gl_debug (DEBUG_VIEW, "END");
145 }
146
147 /*****************************************************************************/
148 /* NEW object view.                                                          */
149 /*****************************************************************************/
150 GObject *
151 gl_view_object_new (void)
152 {
153         glViewObject *view_object;
154
155         gl_debug (DEBUG_VIEW, "START");
156
157         view_object = g_object_new (gl_view_object_get_type(), NULL);
158
159         gl_debug (DEBUG_VIEW, "END");
160
161         return G_OBJECT (view_object);
162 }
163
164 /*****************************************************************************/
165 /* Set parent view to which this object view belongs.                        */
166 /*****************************************************************************/
167 void
168 gl_view_object_set_view       (glViewObject *view_object,
169                                glView *view)
170 {
171         gl_debug (DEBUG_VIEW, "START");
172
173         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
174         g_return_if_fail (view && GL_IS_VIEW (view));
175         
176         view_object->private->view = view;
177
178         view->object_list = g_list_prepend (view->object_list, view_object);
179
180         gl_debug (DEBUG_VIEW, "END");
181 }
182
183 /*****************************************************************************/
184 /* Set Label object to follow.                                               */
185 /*****************************************************************************/
186 void
187 gl_view_object_set_object     (glViewObject         *view_object,
188                                glLabelObject        *object,
189                                glViewHighlightStyle style)
190 {
191         GnomeCanvas        *canvas;
192         GnomeCanvasGroup   *root;
193         gdouble            x, y;
194
195         gl_debug (DEBUG_VIEW, "START");
196
197         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
198         g_return_if_fail (object && GL_IS_LABEL_OBJECT (object));
199         
200         view_object->private->object = object;
201
202         gl_label_object_get_position (GL_LABEL_OBJECT(object), &x, &y);
203
204         /* create canvas group to contain items representing object */
205         canvas = GNOME_CANVAS (view_object->private->view->canvas);
206         root = gnome_canvas_root (canvas);
207         view_object->private->group =
208                 gnome_canvas_item_new (root, gnome_canvas_group_get_type (),
209                                        "x", x,
210                                        "y", y,
211                                        NULL);
212
213         /* Create appropriate selection highlight canvas item. */
214         view_object->private->highlight =
215                 gl_view_highlight_new (view_object, style);
216
217         view_object->private->menu = GTK_WIDGET(new_menu (view_object));
218
219         g_signal_connect (G_OBJECT (object), "moved",
220                           G_CALLBACK (object_moved_cb),
221                           view_object);
222
223         g_signal_connect (G_OBJECT (object), "top",
224                           G_CALLBACK (raise_object_cb),
225                           view_object);
226
227         g_signal_connect (G_OBJECT (object), "bottom",
228                           G_CALLBACK (lower_object_cb),
229                           view_object);
230
231         g_signal_connect (G_OBJECT (view_object->private->group), "event",
232                           G_CALLBACK (gl_view_item_event_handler),
233                           view_object);
234
235         gl_debug (DEBUG_VIEW, "END");
236 }
237
238 /*****************************************************************************/
239 /* Set dialog for controlling/viewing object properties.                     */
240 /*****************************************************************************/
241 void
242 gl_view_object_set_dialog     (glViewObject *view_object,
243                                GtkWidget *dialog)
244
245 {
246         gl_debug (DEBUG_VIEW, "START");
247
248         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
249         g_return_if_fail (dialog && GTK_IS_WIDGET (dialog));
250         
251         view_object->private->property_dialog = dialog;
252
253         gl_debug (DEBUG_VIEW, "END");
254 }
255
256 /*****************************************************************************/
257 /* Return parent view associated with this view.                             */
258 /*****************************************************************************/
259 glView *
260 gl_view_object_get_view   (glViewObject *view_object)
261 {
262         gl_debug (DEBUG_VIEW, "START");
263
264         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
265
266         gl_debug (DEBUG_VIEW, "END");
267
268         return view_object->private->view;
269 }
270
271 /*****************************************************************************/
272 /* Return label object that we are following.                                */
273 /*****************************************************************************/
274 glLabelObject *
275 gl_view_object_get_object (glViewObject *view_object)
276 {
277         gl_debug (DEBUG_VIEW, "START");
278
279         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
280         
281         gl_debug (DEBUG_VIEW, "END");
282
283         return view_object->private->object;
284 }
285
286 /*****************************************************************************/
287 /* Return canvas item representing our object in this view.                  */
288 /*****************************************************************************/
289 GnomeCanvasItem *
290 gl_view_object_get_group   (glViewObject *view_object)
291 {
292         gl_debug (DEBUG_VIEW, "START");
293
294         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
295         
296         gl_debug (DEBUG_VIEW, "END");
297
298         return view_object->private->group;
299 }
300
301 /*****************************************************************************/
302 /* Return dialog for controlling/viewing object properties.                  */
303 /*****************************************************************************/
304 GtkWidget *
305 gl_view_object_get_dialog (glViewObject *view_object)
306 {
307         gl_debug (DEBUG_VIEW, "START");
308
309         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
310         
311         gl_debug (DEBUG_VIEW, "END");
312
313         return view_object->private->property_dialog;
314 }
315
316 /*****************************************************************************/
317 /* Popup menu for this object.                                               */
318 /*****************************************************************************/
319 GtkMenu *
320 gl_view_object_get_menu (glViewObject *view_object)
321 {
322         gl_debug (DEBUG_VIEW, "START");
323
324         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
325
326         gl_debug (DEBUG_VIEW, "END");
327
328         return GTK_MENU(view_object->private->menu);
329 }
330
331 /*****************************************************************************/
332 /* Update Highlight of object.                                               */
333 /*****************************************************************************/
334 void
335 gl_view_object_update_highlight     (glViewObject *view_object)
336 {
337         gl_debug (DEBUG_VIEW, "START");
338
339         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
340         g_return_if_fail (view_object->private->highlight);
341         
342         gl_view_highlight_update (view_object->private->highlight);
343
344         gl_debug (DEBUG_VIEW, "END");
345 }
346
347 /*****************************************************************************/
348 /* Highlight view of object.                                                 */
349 /*****************************************************************************/
350 void
351 gl_view_object_show_highlight     (glViewObject *view_object)
352 {
353         gl_debug (DEBUG_VIEW, "START");
354
355         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
356         g_return_if_fail (view_object->private->highlight);
357         
358         gnome_canvas_item_show (view_object->private->highlight);
359         gnome_canvas_item_raise_to_top (view_object->private->highlight);
360
361         gl_debug (DEBUG_VIEW, "END");
362 }
363
364 /*****************************************************************************/
365 /* Remove highlight from view of object.                                     */
366 /*****************************************************************************/
367 void
368 gl_view_object_hide_highlight   (glViewObject *view_object)
369 {
370         gl_debug (DEBUG_VIEW, "START");
371
372         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
373         g_return_if_fail (view_object->private->highlight);
374         
375         gnome_canvas_item_hide (view_object->private->highlight);
376
377         gl_debug (DEBUG_VIEW, "END");
378 }
379
380
381 /*---------------------------------------------------------------------------*/
382 /* Create a popup menu for this object view.                                 */
383 /*---------------------------------------------------------------------------*/
384 static GtkMenu *
385 new_menu (glViewObject *view_object)
386 {
387         GtkWidget *menu, *menuitem;
388
389         gl_debug (DEBUG_VIEW, "START");
390
391         g_return_val_if_fail (view_object && GL_VIEW_OBJECT(view_object), NULL);
392
393         menu = gtk_menu_new ();
394
395         menuitem = gtk_menu_item_new_with_label (_("Edit properties..."));
396         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
397         gtk_widget_show (menuitem);
398         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
399                                   G_CALLBACK (gl_view_object_show_dialog),
400                                   view_object);
401
402         menuitem = gtk_menu_item_new ();
403         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
404         gtk_widget_show (menuitem);
405
406         menuitem = gtk_menu_item_new_with_label (_("Delete"));
407         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
408         gtk_widget_show (menuitem);
409         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
410                                   G_CALLBACK (g_object_unref), view_object);
411
412         menuitem = gtk_menu_item_new ();
413         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
414         gtk_widget_show (menuitem);
415
416         menuitem = gtk_menu_item_new_with_label (_("Bring to front"));
417         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
418         gtk_widget_show (menuitem);
419         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
420                                   G_CALLBACK (gl_label_object_raise_to_top),
421                                   view_object->private->object);
422
423         menuitem = gtk_menu_item_new_with_label (_("Send to back"));
424         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
425         gtk_widget_show (menuitem);
426         g_signal_connect_swapped (G_OBJECT (menuitem), "activate",
427                                   G_CALLBACK (gl_label_object_lower_to_bottom),
428                                   view_object->private->object);
429
430         gl_debug (DEBUG_VIEW, "END");
431
432         return GTK_MENU(menu);
433 }
434
435 /*****************************************************************************/
436 /* Show property dialog.                                                     */
437 /*****************************************************************************/
438 void
439 gl_view_object_show_dialog (glViewObject *view_object)
440 {
441         gl_debug (DEBUG_VIEW, "START");
442
443         g_return_if_fail (view_object && GL_IS_VIEW_OBJECT (view_object));
444
445         gtk_widget_show_all (view_object->private->property_dialog);
446
447         gl_debug (DEBUG_VIEW, "END");
448 }
449
450
451 /*---------------------------------------------------------------------------*/
452 /* PRIVATE.  Object moved callback.                                          */
453 /*---------------------------------------------------------------------------*/
454 static void
455 object_moved_cb (glLabelObject *object,
456                  gdouble dx,
457                  gdouble dy,
458                  glViewObject *view_object)
459 {
460         GnomeCanvasItem    *item, *highlight;
461
462         gl_debug (DEBUG_VIEW, "START");
463
464         /* Adjust location of analogous canvas group. */
465         gnome_canvas_item_move (view_object->private->group, dx, dy);
466
467         /* Adjust location of highlight group */
468         gnome_canvas_item_move (view_object->private->highlight, dx, dy);
469
470         gl_debug (DEBUG_VIEW, "END");
471 }
472
473 /*---------------------------------------------------------------------------*/
474 /* PRIVATE.  raise item to front callback.                                   */
475 /*---------------------------------------------------------------------------*/
476 static void
477 raise_object_cb (GtkWidget * widget,
478                  glViewObject *view_object)
479 {
480         glLabelObject *object;
481
482         gl_debug (DEBUG_VIEW, "START");
483
484         gnome_canvas_item_raise_to_top (view_object->private->group);
485         gnome_canvas_item_raise_to_top (view_object->private->highlight);
486
487         gl_debug (DEBUG_VIEW, "END");
488 }
489
490 /*---------------------------------------------------------------------------*/
491 /* PRIVATE.  lower item to back callback.                                    */
492 /*---------------------------------------------------------------------------*/
493 static void
494 lower_object_cb (GtkWidget * widget,
495                  glViewObject *view_object)
496 {
497         glLabelObject *object;
498         glView *view;
499
500         gl_debug (DEBUG_VIEW, "START");
501
502         /* Send to bottom */
503         gnome_canvas_item_lower_to_bottom (view_object->private->group);
504
505         /* now raise it above all items that form the backgound */
506         gnome_canvas_item_raise (view_object->private->group,
507                                  view_object->private->view->n_bg_items);
508
509         gl_debug (DEBUG_VIEW, "END");
510 }
511
512 /*****************************************************************************/
513 /* Select object.                                                            */
514 /*****************************************************************************/
515 void
516 gl_view_object_select (glViewObject *view_object)
517 {
518         gl_debug (DEBUG_VIEW, "START");
519
520         gl_view_select_object(view_object->private->view, view_object);
521
522         gl_debug (DEBUG_VIEW, "END");
523 }
524