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