]> git.sur5r.net Git - glabels/blob - src/view-ellipse.c
Imported Upstream version 2.2.8
[glabels] / src / view-ellipse.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
3 /*
4  *  (GLABELS) Label and Business Card Creation program for GNOME
5  *
6  *  view_ellipse.c:  GLabels label ellipse object view
7  *
8  *  Copyright (C) 2001-2007  Jim Evins <evins@snaught.com>.
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
23  */
24 #include <config.h>
25
26 #include "view-ellipse.h"
27
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
30 #include <math.h>
31
32 #include "cairo-ellipse-path.h"
33 #include "color.h"
34 #include "object-editor.h"
35 #include "stock.h"
36
37 #include "pixmaps/cursor_ellipse.xbm"
38 #include "pixmaps/cursor_ellipse_mask.xbm"
39
40 #include "debug.h"
41
42 /*========================================================*/
43 /* Private macros and constants.                          */
44 /*========================================================*/
45
46 /*========================================================*/
47 /* Private types.                                         */
48 /*========================================================*/
49
50 struct _glViewEllipsePrivate {
51         int place_holder; /* Place holder for future private data. */
52 };
53
54 /*========================================================*/
55 /* Private globals.                                       */
56 /*========================================================*/
57
58
59 /*========================================================*/
60 /* Private function prototypes.                           */
61 /*========================================================*/
62
63 static void       gl_view_ellipse_finalize          (GObject          *object);
64
65 static GtkWidget *construct_properties_editor       (glViewObject     *view_object);
66
67 static void       update_object_from_editor_cb      (glObjectEditor   *editor,
68                                                      glLabelObject    *object);
69
70 static void       update_editor_from_object_cb      (glLabelObject    *object,
71                                                      glObjectEditor   *editor);
72
73 static void       update_editor_from_move_cb        (glLabelObject    *object,
74                                                      gdouble           dx,
75                                                      gdouble           dy,
76                                                      glObjectEditor   *editor);
77
78 static gboolean   object_at                         (glViewObject     *view_object,
79                                                      cairo_t          *cr,
80                                                      gdouble           x,
81                                                      gdouble           y);
82
83
84 \f
85 /*****************************************************************************/
86 /* Boilerplate object stuff.                                                 */
87 /*****************************************************************************/
88 G_DEFINE_TYPE (glViewEllipse, gl_view_ellipse, GL_TYPE_VIEW_OBJECT);
89
90
91 static void
92 gl_view_ellipse_class_init (glViewEllipseClass *class)
93 {
94         GObjectClass      *object_class      = G_OBJECT_CLASS (class);
95         glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
96
97         gl_debug (DEBUG_VIEW, "START");
98
99         gl_view_ellipse_parent_class = g_type_class_peek_parent (class);
100
101         object_class->finalize = gl_view_ellipse_finalize;
102
103         view_object_class->construct_editor = construct_properties_editor;
104         view_object_class->object_at        = object_at;
105
106         gl_debug (DEBUG_VIEW, "END");
107 }
108
109 static void
110 gl_view_ellipse_init (glViewEllipse *view_ellipse)
111 {
112         gl_debug (DEBUG_VIEW, "START");
113
114         view_ellipse->priv = g_new0 (glViewEllipsePrivate, 1);
115
116         gl_debug (DEBUG_VIEW, "END");
117 }
118
119 static void
120 gl_view_ellipse_finalize (GObject *object)
121 {
122         glViewEllipse *view_ellipse = GL_VIEW_ELLIPSE (object);
123
124         gl_debug (DEBUG_VIEW, "START");
125
126         g_return_if_fail (object && GL_IS_VIEW_ELLIPSE (object));
127
128         g_free (view_ellipse->priv);
129
130         G_OBJECT_CLASS (gl_view_ellipse_parent_class)->finalize (object);
131
132         gl_debug (DEBUG_VIEW, "END");
133 }
134
135 /*****************************************************************************/
136 /* NEW ellipse object view.                                                  */
137 /*****************************************************************************/
138 glViewObject *
139 gl_view_ellipse_new (glLabelEllipse *object,
140                      glView         *view)
141 {
142         glViewEllipse         *view_ellipse;
143
144         gl_debug (DEBUG_VIEW, "START");
145
146         g_return_val_if_fail (object && GL_IS_LABEL_ELLIPSE (object), NULL);
147         g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
148         
149         view_ellipse = g_object_new (gl_view_ellipse_get_type(), NULL);
150
151         gl_view_object_set_object (GL_VIEW_OBJECT(view_ellipse),
152                                    GL_LABEL_OBJECT(object),
153                                    GL_VIEW_OBJECT_HANDLES_BOX);
154         gl_view_object_set_view (GL_VIEW_OBJECT(view_ellipse), view);
155
156         gl_debug (DEBUG_VIEW, "END");
157
158         return GL_VIEW_OBJECT (view_ellipse);
159 }
160
161 /*****************************************************************************/
162 /* Create a properties dialog for a ellipse object.                          */
163 /*****************************************************************************/
164 static GtkWidget *
165 construct_properties_editor (glViewObject *view_object)
166 {
167         GtkWidget          *editor;
168         glViewEllipse      *view_ellipse = (glViewEllipse *)view_object;
169         glLabelObject      *object;
170
171         gl_debug (DEBUG_VIEW, "START");
172
173         object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
174
175         /* Build editor. */
176         editor = gl_object_editor_new (GL_STOCK_ELLIPSE, _("Ellipse object properties"),
177                                        object->parent,
178                                        GL_OBJECT_EDITOR_SHADOW_PAGE,
179                                        GL_OBJECT_EDITOR_POSITION_PAGE,
180                                        GL_OBJECT_EDITOR_SIZE_PAGE,
181                                        GL_OBJECT_EDITOR_FILL_PAGE,
182                                        GL_OBJECT_EDITOR_LINE_PAGE,
183                                        0);
184         
185         /* Update */
186         update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
187         update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
188
189         /* Connect signals. */
190         g_signal_connect (G_OBJECT (editor), "changed",
191                           G_CALLBACK(update_object_from_editor_cb), object);
192         g_signal_connect (G_OBJECT (object), "changed",
193                           G_CALLBACK (update_editor_from_object_cb), editor);
194         g_signal_connect (G_OBJECT (object), "moved",
195                           G_CALLBACK (update_editor_from_move_cb), editor);
196
197         gl_debug (DEBUG_VIEW, "END");
198
199         return editor;
200 }
201
202 /*---------------------------------------------------------------------------*/
203 /* PRIVATE.  editor "changed" callback.                                      */
204 /*---------------------------------------------------------------------------*/
205 static void
206 update_object_from_editor_cb (glObjectEditor *editor,
207                               glLabelObject  *object)
208 {
209         gdouble            x, y, w, h;
210         glColorNode       *line_color_node;
211         gdouble            line_width;
212         glColorNode       *fill_color_node;
213         gboolean           shadow_state;
214         gdouble            shadow_x, shadow_y;
215         glColorNode       *shadow_color_node;
216         gdouble            shadow_opacity;
217         
218
219         gl_debug (DEBUG_VIEW, "START");
220
221         g_signal_handlers_block_by_func (G_OBJECT(object),
222                                          update_editor_from_object_cb,
223                                          editor);
224         g_signal_handlers_block_by_func (G_OBJECT(object),
225                                          update_editor_from_move_cb,
226                                          editor);
227
228         gl_object_editor_get_position (editor, &x, &y);
229         gl_label_object_set_position (object, x, y);
230
231         gl_object_editor_get_size (editor, &w, &h);
232         gl_label_object_set_size (object, w, h);
233
234         fill_color_node = gl_object_editor_get_fill_color (editor);
235         gl_label_object_set_fill_color (object, fill_color_node);
236         gl_color_node_free (&fill_color_node);
237
238         line_color_node = gl_object_editor_get_line_color (editor);
239         gl_label_object_set_line_color (object, line_color_node);
240         gl_color_node_free (&line_color_node);
241
242         line_width = gl_object_editor_get_line_width (editor);
243         gl_label_object_set_line_width (object, line_width);
244
245         shadow_state = gl_object_editor_get_shadow_state (editor);
246         gl_label_object_set_shadow_state (object, shadow_state);
247
248         gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
249         gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
250
251         shadow_color_node = gl_object_editor_get_shadow_color (editor);
252         gl_label_object_set_shadow_color (object, shadow_color_node);
253         gl_color_node_free (&shadow_color_node);
254
255         shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
256         gl_label_object_set_shadow_opacity (object, shadow_opacity);
257
258         g_signal_handlers_unblock_by_func (G_OBJECT(object),
259                                            update_editor_from_object_cb,
260                                            editor);
261         g_signal_handlers_unblock_by_func (G_OBJECT(object),
262                                            update_editor_from_move_cb,
263                                            editor);
264
265         gl_debug (DEBUG_VIEW, "END");
266 }
267
268 /*---------------------------------------------------------------------------*/
269 /* PRIVATE. label object "changed" callback.                                 */
270 /*---------------------------------------------------------------------------*/
271 static void
272 update_editor_from_object_cb (glLabelObject  *object,
273                               glObjectEditor *editor)
274 {
275         gdouble            w, h;
276         glColorNode       *line_color_node;
277         gdouble            line_width;
278         glColorNode       *fill_color_node;
279         gboolean           shadow_state;
280         gdouble            shadow_x, shadow_y;
281         glColorNode       *shadow_color_node;
282         gdouble            shadow_opacity;
283         glMerge           *merge;
284
285         gl_debug (DEBUG_VIEW, "START");
286
287         gl_label_object_get_size (object, &w, &h);
288         gl_object_editor_set_size (editor, w, h);
289         merge = gl_label_get_merge (GL_LABEL(object->parent));
290         
291         fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
292         gl_object_editor_set_fill_color (editor, (merge != NULL), fill_color_node);
293         gl_color_node_free (&fill_color_node);
294
295         line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
296         gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
297         gl_color_node_free (&line_color_node);
298
299         line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
300         gl_object_editor_set_line_width (editor, line_width);
301
302         shadow_state = gl_label_object_get_shadow_state (object);
303         gl_object_editor_set_shadow_state (editor, shadow_state);
304
305         gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
306         gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
307
308         shadow_color_node = gl_label_object_get_shadow_color (object);
309         gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
310         gl_color_node_free (&shadow_color_node);
311
312         shadow_opacity = gl_label_object_get_shadow_opacity (object);
313         gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
314
315         gl_debug (DEBUG_VIEW, "END");
316 }
317
318 /*---------------------------------------------------------------------------*/
319 /* PRIVATE. label object "moved" callback.                                   */
320 /*---------------------------------------------------------------------------*/
321 static void
322 update_editor_from_move_cb (glLabelObject    *object,
323                             gdouble           dx,
324                             gdouble           dy,
325                             glObjectEditor   *editor)
326 {
327         gdouble            x, y;
328
329         gl_debug (DEBUG_VIEW, "START");
330
331         gl_label_object_get_position (object, &x, &y);
332         gl_object_editor_set_position (editor, x, y);
333
334         gl_debug (DEBUG_VIEW, "END");
335 }
336
337 /*****************************************************************************/
338 /* Is object at (x,y)?                                                       */
339 /*****************************************************************************/
340 static gboolean
341 object_at (glViewObject  *view_object,
342            cairo_t       *cr,
343            gdouble        x,
344            gdouble        y)
345 {
346         glLabelObject    *object;
347         gdouble           w, h;
348         gdouble           line_width;
349
350         object = gl_view_object_get_object (view_object);
351
352         gl_label_object_get_size (object, &w, &h);
353
354         gl_cairo_ellipse_path (cr, w/2, h/2);
355
356         if (cairo_in_fill (cr, x, y))
357         {
358                 return TRUE;
359         }
360
361         line_width = gl_label_object_get_line_width (object);
362         cairo_set_line_width (cr, line_width);
363         if (cairo_in_stroke (cr, x, y))
364         {
365                 return TRUE;
366         }
367
368         return FALSE;
369 }
370
371
372 /*****************************************************************************/
373 /* Return apropos cursor for create object mode.                             */
374 /*****************************************************************************/
375 GdkCursor *
376 gl_view_ellipse_get_create_cursor (void)
377 {
378         GdkCursor       *cursor = NULL;
379         GdkPixmap       *pixmap_data, *pixmap_mask;
380         GdkColor         fg = { 0, 0, 0, 0 };
381         GdkColor         bg = { 0, 65535, 65535, 65535 };
382
383         gl_debug (DEBUG_VIEW, "START");
384
385         pixmap_data = gdk_bitmap_create_from_data (NULL,
386                                                    (gchar *)cursor_ellipse_bits,
387                                                    cursor_ellipse_width,
388                                                    cursor_ellipse_height);
389         pixmap_mask = gdk_bitmap_create_from_data (NULL,
390                                                    (gchar *)cursor_ellipse_mask_bits,
391                                                    cursor_ellipse_mask_width,
392                                                    cursor_ellipse_mask_height);
393         cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
394                                              &bg, cursor_ellipse_x_hot,
395                                              cursor_ellipse_y_hot);
396
397         gl_debug (DEBUG_VIEW, "END");
398
399         return cursor;
400 }
401
402 /*****************************************************************************/
403 /* Object creation handler: button press event.                              */
404 /*****************************************************************************/
405 void
406 gl_view_ellipse_create_button_press_event   (glView *view,
407                                              gdouble x,
408                                              gdouble y)
409 {
410         GObject             *object;
411         glColorNode         *fill_color_node;
412         glColorNode         *line_color_node;
413
414         gl_view_unselect_all (view);
415
416         fill_color_node = gl_color_node_new_default ();
417         line_color_node = gl_color_node_new_default ();
418                 
419         object = gl_label_ellipse_new (view->label);
420         gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
421         gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
422         line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
423         fill_color_node->color = gl_color_set_opacity (gl_view_get_default_fill_color(view), 0.5);
424         gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
425                                         gl_view_get_default_line_width(view));
426         gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
427                                         line_color_node);
428         gl_label_object_set_fill_color (GL_LABEL_OBJECT(object),
429                                         fill_color_node);
430
431         gl_color_node_free (&fill_color_node);
432         gl_color_node_free (&line_color_node);
433
434         view->create_object = GL_LABEL_OBJECT (object);
435         view->create_x0 = x;
436         view->create_y0 = y;
437 }
438
439 /*****************************************************************************/
440 /* Object creation handler: motion event.                                    */
441 /*****************************************************************************/
442 void
443 gl_view_ellipse_create_motion_event     (glView *view,
444                                          gdouble x,
445                                          gdouble y)
446 {
447         gdouble w, h;
448
449         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
450                                       MIN (x, view->create_x0), MIN (y, view->create_y0));
451         w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
452         h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
453         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
454 }
455
456 /*****************************************************************************/
457 /* Object creation handler: button relesase event.                           */
458 /*****************************************************************************/
459 void
460 gl_view_ellipse_create_button_release_event (glView *view,
461                                              gdouble x,
462                                              gdouble y)
463 {
464         glColorNode         *fill_color_node;
465         glColorNode         *line_color_node;
466         gdouble              w, h;
467
468         fill_color_node = gl_color_node_new_default ();
469         line_color_node = gl_color_node_new_default ();
470                 
471         if ((view->create_x0 == x) && (view->create_y0 == y)) {
472                 x = view->create_x0 + 36.0;
473                 y = view->create_y0 + 36.0;
474         }
475         gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
476                                       MIN (x, view->create_x0), MIN (y, view->create_y0));
477         w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
478         h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
479         gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
480         line_color_node->color = gl_view_get_default_line_color(view);
481         gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
482         fill_color_node->color = gl_view_get_default_fill_color(view);
483         gl_label_object_set_fill_color (GL_LABEL_OBJECT(view->create_object), fill_color_node);
484         gl_color_node_free (&fill_color_node);
485         gl_color_node_free (&line_color_node);
486 }
487