1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * view_ellipse.c: GLabels label ellipse object view
8 * Copyright (C) 2001-2007 Jim Evins <evins@snaught.com>.
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.
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.
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
26 #include "view-ellipse.h"
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
32 #include "cairo-ellipse-path.h"
34 #include "object-editor.h"
37 #include "pixmaps/cursor_ellipse.xbm"
38 #include "pixmaps/cursor_ellipse_mask.xbm"
42 /*========================================================*/
43 /* Private macros and constants. */
44 /*========================================================*/
46 /*========================================================*/
48 /*========================================================*/
50 struct _glViewEllipsePrivate {
53 /*========================================================*/
54 /* Private globals. */
55 /*========================================================*/
58 /*========================================================*/
59 /* Private function prototypes. */
60 /*========================================================*/
62 static void gl_view_ellipse_finalize (GObject *object);
64 static GtkWidget *construct_properties_editor (glViewObject *view_object);
66 static void update_object_from_editor_cb (glObjectEditor *editor,
67 glLabelObject *object);
69 static void update_editor_from_object_cb (glLabelObject *object,
70 glObjectEditor *editor);
72 static void update_editor_from_move_cb (glLabelObject *object,
75 glObjectEditor *editor);
77 static void update_editor_from_label_cb (glLabel *label,
78 glObjectEditor *editor);
80 static gboolean object_at (glViewObject *view_object,
87 /*****************************************************************************/
88 /* Boilerplate object stuff. */
89 /*****************************************************************************/
90 G_DEFINE_TYPE (glViewEllipse, gl_view_ellipse, GL_TYPE_VIEW_OBJECT);
94 gl_view_ellipse_class_init (glViewEllipseClass *class)
96 GObjectClass *object_class = G_OBJECT_CLASS (class);
97 glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
99 gl_debug (DEBUG_VIEW, "START");
101 gl_view_ellipse_parent_class = g_type_class_peek_parent (class);
103 object_class->finalize = gl_view_ellipse_finalize;
105 view_object_class->construct_editor = construct_properties_editor;
106 view_object_class->object_at = object_at;
108 gl_debug (DEBUG_VIEW, "END");
112 gl_view_ellipse_init (glViewEllipse *view_ellipse)
114 gl_debug (DEBUG_VIEW, "START");
116 view_ellipse->priv = g_new0 (glViewEllipsePrivate, 1);
118 gl_debug (DEBUG_VIEW, "END");
122 gl_view_ellipse_finalize (GObject *object)
124 glViewEllipse *view_ellipse = GL_VIEW_ELLIPSE (object);
126 gl_debug (DEBUG_VIEW, "START");
128 g_return_if_fail (object && GL_IS_VIEW_ELLIPSE (object));
130 g_free (view_ellipse->priv);
132 G_OBJECT_CLASS (gl_view_ellipse_parent_class)->finalize (object);
134 gl_debug (DEBUG_VIEW, "END");
137 /*****************************************************************************/
138 /* NEW ellipse object view. */
139 /*****************************************************************************/
141 gl_view_ellipse_new (glLabelEllipse *object,
144 glViewEllipse *view_ellipse;
146 gl_debug (DEBUG_VIEW, "START");
148 g_return_val_if_fail (object && GL_IS_LABEL_ELLIPSE (object), NULL);
149 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
151 view_ellipse = g_object_new (gl_view_ellipse_get_type(), NULL);
153 gl_view_object_set_object (GL_VIEW_OBJECT(view_ellipse),
154 GL_LABEL_OBJECT(object),
155 GL_VIEW_OBJECT_HANDLES_BOX);
156 gl_view_object_set_view (GL_VIEW_OBJECT(view_ellipse), view);
158 gl_debug (DEBUG_VIEW, "END");
160 return GL_VIEW_OBJECT (view_ellipse);
163 /*****************************************************************************/
164 /* Create a properties dialog for a ellipse object. */
165 /*****************************************************************************/
167 construct_properties_editor (glViewObject *view_object)
170 glViewEllipse *view_ellipse = (glViewEllipse *)view_object;
171 glLabelObject *object;
173 gl_debug (DEBUG_VIEW, "START");
175 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_ellipse));
178 editor = gl_object_editor_new (GL_STOCK_ELLIPSE, _("Ellipse object properties"),
179 GL_OBJECT_EDITOR_SHADOW_PAGE,
180 GL_OBJECT_EDITOR_POSITION_PAGE,
181 GL_OBJECT_EDITOR_SIZE_PAGE,
182 GL_OBJECT_EDITOR_FILL_PAGE,
183 GL_OBJECT_EDITOR_LINE_PAGE,
187 update_editor_from_label_cb (object->parent, GL_OBJECT_EDITOR(editor));
188 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
189 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
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 g_signal_connect (G_OBJECT (object->parent), "size_changed",
199 G_CALLBACK (update_editor_from_label_cb), editor);
200 g_signal_connect (G_OBJECT (object->parent), "merge_changed",
201 G_CALLBACK (update_editor_from_label_cb), editor);
203 gl_debug (DEBUG_VIEW, "END");
208 /*---------------------------------------------------------------------------*/
209 /* PRIVATE. editor "changed" callback. */
210 /*---------------------------------------------------------------------------*/
212 update_object_from_editor_cb (glObjectEditor *editor,
213 glLabelObject *object)
216 glColorNode *line_color_node;
218 glColorNode *fill_color_node;
219 gboolean shadow_state;
220 gdouble shadow_x, shadow_y;
221 glColorNode *shadow_color_node;
222 gdouble shadow_opacity;
225 gl_debug (DEBUG_VIEW, "START");
227 g_signal_handlers_block_by_func (G_OBJECT(object),
228 update_editor_from_object_cb,
230 g_signal_handlers_block_by_func (G_OBJECT(object),
231 update_editor_from_move_cb,
234 gl_object_editor_get_position (editor, &x, &y);
235 gl_label_object_set_position (object, x, y);
237 gl_object_editor_get_size (editor, &w, &h);
238 gl_label_object_set_size (object, w, h);
240 fill_color_node = gl_object_editor_get_fill_color (editor);
241 gl_label_object_set_fill_color (object, fill_color_node);
242 gl_color_node_free (&fill_color_node);
244 line_color_node = gl_object_editor_get_line_color (editor);
245 gl_label_object_set_line_color (object, line_color_node);
246 gl_color_node_free (&line_color_node);
248 line_width = gl_object_editor_get_line_width (editor);
249 gl_label_object_set_line_width (object, line_width);
251 shadow_state = gl_object_editor_get_shadow_state (editor);
252 gl_label_object_set_shadow_state (object, shadow_state);
254 gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
255 gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
257 shadow_color_node = gl_object_editor_get_shadow_color (editor);
258 gl_label_object_set_shadow_color (object, shadow_color_node);
259 gl_color_node_free (&shadow_color_node);
261 shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
262 gl_label_object_set_shadow_opacity (object, shadow_opacity);
264 g_signal_handlers_unblock_by_func (G_OBJECT(object),
265 update_editor_from_object_cb,
267 g_signal_handlers_unblock_by_func (G_OBJECT(object),
268 update_editor_from_move_cb,
271 gl_debug (DEBUG_VIEW, "END");
274 /*---------------------------------------------------------------------------*/
275 /* PRIVATE. label object "changed" callback. */
276 /*---------------------------------------------------------------------------*/
278 update_editor_from_object_cb (glLabelObject *object,
279 glObjectEditor *editor)
282 glColorNode *line_color_node;
284 glColorNode *fill_color_node;
285 gboolean shadow_state;
286 gdouble shadow_x, shadow_y;
287 glColorNode *shadow_color_node;
288 gdouble shadow_opacity;
291 gl_debug (DEBUG_VIEW, "START");
293 gl_label_object_get_size (object, &w, &h);
294 gl_object_editor_set_size (editor, w, h);
295 merge = gl_label_get_merge (GL_LABEL(object->parent));
297 fill_color_node = gl_label_object_get_fill_color (GL_LABEL_OBJECT(object));
298 gl_object_editor_set_fill_color (editor, (merge != NULL), fill_color_node);
299 gl_color_node_free (&fill_color_node);
301 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
302 gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
303 gl_color_node_free (&line_color_node);
305 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
306 gl_object_editor_set_line_width (editor, line_width);
308 shadow_state = gl_label_object_get_shadow_state (object);
309 gl_object_editor_set_shadow_state (editor, shadow_state);
311 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
312 gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
314 shadow_color_node = gl_label_object_get_shadow_color (object);
315 gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
316 gl_color_node_free (&shadow_color_node);
318 shadow_opacity = gl_label_object_get_shadow_opacity (object);
319 gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
321 gl_debug (DEBUG_VIEW, "END");
324 /*---------------------------------------------------------------------------*/
325 /* PRIVATE. label object "moved" callback. */
326 /*---------------------------------------------------------------------------*/
328 update_editor_from_move_cb (glLabelObject *object,
331 glObjectEditor *editor)
335 gl_debug (DEBUG_VIEW, "START");
337 gl_label_object_get_position (object, &x, &y);
338 gl_object_editor_set_position (editor, x, y);
340 gl_debug (DEBUG_VIEW, "END");
343 /*---------------------------------------------------------------------------*/
344 /* PRIVATE. label "changed" callback. */
345 /*---------------------------------------------------------------------------*/
347 update_editor_from_label_cb (glLabel *label,
348 glObjectEditor *editor)
350 gdouble label_width, label_height;
353 gl_debug (DEBUG_VIEW, "START");
355 gl_label_get_size (label, &label_width, &label_height);
356 gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
357 label_width, label_height);
358 gl_object_editor_set_max_size (GL_OBJECT_EDITOR (editor),
359 label_width, label_height);
360 gl_object_editor_set_max_shadow_offset (GL_OBJECT_EDITOR (editor),
361 label_width, label_height);
363 merge = gl_label_get_merge (label);
364 gl_object_editor_set_key_names (editor, merge);
366 gl_debug (DEBUG_VIEW, "END");
369 /*****************************************************************************/
370 /* Is object at (x,y)? */
371 /*****************************************************************************/
373 object_at (glViewObject *view_object,
378 glLabelObject *object;
382 object = gl_view_object_get_object (view_object);
384 gl_label_object_get_size (object, &w, &h);
386 gl_cairo_ellipse_path (cr, w/2, h/2);
388 if (cairo_in_fill (cr, x, y))
393 line_width = gl_label_object_get_line_width (object);
394 cairo_set_line_width (cr, line_width);
395 if (cairo_in_stroke (cr, x, y))
404 /*****************************************************************************/
405 /* Return apropos cursor for create object mode. */
406 /*****************************************************************************/
408 gl_view_ellipse_get_create_cursor (void)
410 GdkCursor *cursor = NULL;
411 GdkPixmap *pixmap_data, *pixmap_mask;
412 GdkColor fg = { 0, 0, 0, 0 };
413 GdkColor bg = { 0, 65535, 65535, 65535 };
415 gl_debug (DEBUG_VIEW, "START");
417 pixmap_data = gdk_bitmap_create_from_data (NULL,
418 (gchar *)cursor_ellipse_bits,
419 cursor_ellipse_width,
420 cursor_ellipse_height);
421 pixmap_mask = gdk_bitmap_create_from_data (NULL,
422 (gchar *)cursor_ellipse_mask_bits,
423 cursor_ellipse_mask_width,
424 cursor_ellipse_mask_height);
425 cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
426 &bg, cursor_ellipse_x_hot,
427 cursor_ellipse_y_hot);
429 gl_debug (DEBUG_VIEW, "END");
434 /*****************************************************************************/
435 /* Object creation handler: button press event. */
436 /*****************************************************************************/
438 gl_view_ellipse_create_button_press_event (glView *view,
443 glColorNode *fill_color_node;
444 glColorNode *line_color_node;
446 gl_view_unselect_all (view);
448 fill_color_node = gl_color_node_new_default ();
449 line_color_node = gl_color_node_new_default ();
451 object = gl_label_ellipse_new (view->label);
452 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
453 gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
454 line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
455 fill_color_node->color = gl_color_set_opacity (gl_view_get_default_fill_color(view), 0.5);
456 gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
457 gl_view_get_default_line_width(view));
458 gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
460 gl_label_object_set_fill_color (GL_LABEL_OBJECT(object),
463 gl_color_node_free (&fill_color_node);
464 gl_color_node_free (&line_color_node);
466 view->create_object = GL_LABEL_OBJECT (object);
471 /*****************************************************************************/
472 /* Object creation handler: motion event. */
473 /*****************************************************************************/
475 gl_view_ellipse_create_motion_event (glView *view,
481 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
482 MIN (x, view->create_x0), MIN (y, view->create_y0));
483 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
484 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
485 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
488 /*****************************************************************************/
489 /* Object creation handler: button relesase event. */
490 /*****************************************************************************/
492 gl_view_ellipse_create_button_release_event (glView *view,
496 glColorNode *fill_color_node;
497 glColorNode *line_color_node;
500 fill_color_node = gl_color_node_new_default ();
501 line_color_node = gl_color_node_new_default ();
503 if ((view->create_x0 == x) && (view->create_y0 == y)) {
504 x = view->create_x0 + 36.0;
505 y = view->create_y0 + 36.0;
507 gl_label_object_set_position (GL_LABEL_OBJECT(view->create_object),
508 MIN (x, view->create_x0), MIN (y, view->create_y0));
509 w = MAX (x, view->create_x0) - MIN (x, view->create_x0);
510 h = MAX (y, view->create_y0) - MIN (y, view->create_y0);
511 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
512 line_color_node->color = gl_view_get_default_line_color(view);
513 gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
514 fill_color_node->color = gl_view_get_default_fill_color(view);
515 gl_label_object_set_fill_color (GL_LABEL_OBJECT(view->create_object), fill_color_node);
516 gl_color_node_free (&fill_color_node);
517 gl_color_node_free (&line_color_node);