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_line.c: GLabels label line 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-line.h"
28 #include <glib/gi18n.h>
29 #include <glib/gmem.h>
32 #include "object-editor.h"
35 #include "pixmaps/cursor_line.xbm"
36 #include "pixmaps/cursor_line_mask.xbm"
40 /*========================================================*/
41 /* Private macros and constants. */
42 /*========================================================*/
45 /*========================================================*/
47 /*========================================================*/
49 struct _glViewLinePrivate {
52 /*========================================================*/
53 /* Private globals. */
54 /*========================================================*/
57 /*========================================================*/
58 /* Private function prototypes. */
59 /*========================================================*/
61 static void gl_view_line_finalize (GObject *object);
63 static GtkWidget *construct_properties_editor (glViewObject *view_object);
65 static void update_object_from_editor_cb (glObjectEditor *editor,
66 glLabelObject *object);
68 static void update_editor_from_object_cb (glLabelObject *object,
69 glObjectEditor *editor);
71 static void update_editor_from_move_cb (glLabelObject *object,
74 glObjectEditor *editor);
76 static void update_editor_from_label_cb (glLabel *label,
77 glObjectEditor *editor);
79 static gboolean object_at (glViewObject *view_object,
86 /*****************************************************************************/
87 /* Boilerplate object stuff. */
88 /*****************************************************************************/
89 G_DEFINE_TYPE (glViewLine, gl_view_line, GL_TYPE_VIEW_OBJECT);
93 gl_view_line_class_init (glViewLineClass *class)
95 GObjectClass *object_class = G_OBJECT_CLASS (class);
96 glViewObjectClass *view_object_class = GL_VIEW_OBJECT_CLASS (class);
98 gl_debug (DEBUG_VIEW, "START");
100 gl_view_line_parent_class = g_type_class_peek_parent (class);
102 object_class->finalize = gl_view_line_finalize;
104 view_object_class->construct_editor = construct_properties_editor;
105 view_object_class->object_at = object_at;
107 gl_debug (DEBUG_VIEW, "END");
111 gl_view_line_init (glViewLine *view_line)
113 gl_debug (DEBUG_VIEW, "START");
115 view_line->priv = g_new0 (glViewLinePrivate, 1);
117 gl_debug (DEBUG_VIEW, "END");
121 gl_view_line_finalize (GObject *object)
123 glViewLine *view_line = GL_VIEW_LINE (object);
125 gl_debug (DEBUG_VIEW, "START");
127 g_return_if_fail (object && GL_IS_VIEW_LINE (object));
129 g_free (view_line->priv);
131 G_OBJECT_CLASS (gl_view_line_parent_class)->finalize (object);
133 gl_debug (DEBUG_VIEW, "END");
136 /*****************************************************************************/
137 /* NEW line object view. */
138 /*****************************************************************************/
140 gl_view_line_new (glLabelLine *object,
143 glViewLine *view_line;
145 gl_debug (DEBUG_VIEW, "START");
147 g_return_val_if_fail (object && GL_IS_LABEL_LINE (object), NULL);
148 g_return_val_if_fail (view && GL_IS_VIEW (view), NULL);
150 view_line = g_object_new (gl_view_line_get_type(), NULL);
152 gl_view_object_set_object (GL_VIEW_OBJECT(view_line),
153 GL_LABEL_OBJECT(object),
154 GL_VIEW_OBJECT_HANDLES_LINE);
155 gl_view_object_set_view (GL_VIEW_OBJECT(view_line), view);
157 gl_debug (DEBUG_VIEW, "END");
159 return GL_VIEW_OBJECT (view_line);
162 /*****************************************************************************/
163 /* Create a properties dialog for a line object. */
164 /*****************************************************************************/
166 construct_properties_editor (glViewObject *view_object)
169 glViewLine *view_line = (glViewLine *)view_object;
170 glLabelObject *object;
172 gl_debug (DEBUG_VIEW, "START");
174 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_line));
177 editor = gl_object_editor_new (GL_STOCK_LINE, _("Line object properties"),
178 GL_OBJECT_EDITOR_SHADOW_PAGE,
179 GL_OBJECT_EDITOR_POSITION_PAGE,
180 GL_OBJECT_EDITOR_SIZE_LINE_PAGE,
181 GL_OBJECT_EDITOR_LINE_PAGE,
185 update_editor_from_label_cb (object->parent, GL_OBJECT_EDITOR(editor));
186 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
187 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
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 g_signal_connect (G_OBJECT (object->parent), "size_changed",
197 G_CALLBACK (update_editor_from_label_cb), editor);
198 g_signal_connect (G_OBJECT (object->parent), "merge_changed",
199 G_CALLBACK (update_editor_from_label_cb), editor);
201 gl_debug (DEBUG_VIEW, "END");
206 /*---------------------------------------------------------------------------*/
207 /* PRIVATE. editor "changed" callback. */
208 /*---------------------------------------------------------------------------*/
210 update_object_from_editor_cb (glObjectEditor *editor,
211 glLabelObject *object)
214 glColorNode *line_color_node;
216 gboolean shadow_state;
217 gdouble shadow_x, shadow_y;
218 glColorNode *shadow_color_node;
219 gdouble shadow_opacity;
222 gl_debug (DEBUG_VIEW, "START");
224 g_signal_handlers_block_by_func (G_OBJECT(object),
225 update_editor_from_object_cb,
227 g_signal_handlers_block_by_func (G_OBJECT(object),
228 update_editor_from_move_cb,
231 gl_object_editor_get_position (editor, &x, &y);
232 gl_label_object_set_position (object, x, y);
234 gl_object_editor_get_lsize (editor, &w, &h);
235 gl_label_object_set_size (object, w, h);
237 line_color_node = gl_object_editor_get_line_color (editor);
238 gl_label_object_set_line_color (object, line_color_node);
239 gl_color_node_free (&line_color_node);
241 line_width = gl_object_editor_get_line_width (editor);
242 gl_label_object_set_line_width (object, line_width);
244 shadow_state = gl_object_editor_get_shadow_state (editor);
245 gl_label_object_set_shadow_state (object, shadow_state);
247 gl_object_editor_get_shadow_offset (editor, &shadow_x, &shadow_y);
248 gl_label_object_set_shadow_offset (object, shadow_x, shadow_y);
250 shadow_color_node = gl_object_editor_get_shadow_color (editor);
251 gl_label_object_set_shadow_color (object, shadow_color_node);
252 gl_color_node_free (&shadow_color_node);
254 shadow_opacity = gl_object_editor_get_shadow_opacity (editor);
255 gl_label_object_set_shadow_opacity (object, shadow_opacity);
257 g_signal_handlers_unblock_by_func (G_OBJECT(object),
258 update_editor_from_object_cb,
260 g_signal_handlers_unblock_by_func (G_OBJECT(object),
261 update_editor_from_move_cb,
264 gl_debug (DEBUG_VIEW, "END");
267 /*---------------------------------------------------------------------------*/
268 /* PRIVATE. label object "changed" callback. */
269 /*---------------------------------------------------------------------------*/
271 update_editor_from_object_cb (glLabelObject *object,
272 glObjectEditor *editor)
275 glColorNode *line_color_node;
277 gboolean shadow_state;
278 gdouble shadow_x, shadow_y;
279 glColorNode *shadow_color_node;
280 gdouble shadow_opacity;
283 gl_debug (DEBUG_VIEW, "START");
285 gl_label_object_get_size (object, &w, &h);
286 gl_object_editor_set_lsize (editor, w, h);
287 merge = gl_label_get_merge (GL_LABEL(object->parent));
289 line_color_node = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
290 gl_object_editor_set_line_color (editor, (merge != NULL), line_color_node);
291 gl_color_node_free (&line_color_node);
293 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
294 gl_object_editor_set_line_width (editor, line_width);
296 shadow_state = gl_label_object_get_shadow_state (object);
297 gl_object_editor_set_shadow_state (editor, shadow_state);
299 gl_label_object_get_shadow_offset (object, &shadow_x, &shadow_y);
300 gl_object_editor_set_shadow_offset (editor, shadow_x, shadow_y);
302 shadow_color_node = gl_label_object_get_shadow_color (object);
303 gl_object_editor_set_shadow_color (editor, (merge != NULL), shadow_color_node);
304 gl_color_node_free (&shadow_color_node);
306 shadow_opacity = gl_label_object_get_shadow_opacity (object);
307 gl_object_editor_set_shadow_opacity (editor, shadow_opacity);
309 gl_debug (DEBUG_VIEW, "END");
312 /*---------------------------------------------------------------------------*/
313 /* PRIVATE. label object "moved" callback. */
314 /*---------------------------------------------------------------------------*/
316 update_editor_from_move_cb (glLabelObject *object,
319 glObjectEditor *editor)
323 gl_debug (DEBUG_VIEW, "START");
325 gl_label_object_get_position (object, &x, &y);
326 gl_object_editor_set_position (editor, x, y);
328 gl_debug (DEBUG_VIEW, "END");
331 /*---------------------------------------------------------------------------*/
332 /* PRIVATE. label "changed" callback. */
333 /*---------------------------------------------------------------------------*/
335 update_editor_from_label_cb (glLabel *label,
336 glObjectEditor *editor)
338 gdouble label_width, label_height;
341 gl_debug (DEBUG_VIEW, "START");
343 gl_label_get_size (label, &label_width, &label_height);
344 gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
345 label_width, label_height);
346 gl_object_editor_set_max_lsize (GL_OBJECT_EDITOR (editor),
347 label_width, label_height);
348 gl_object_editor_set_max_shadow_offset (GL_OBJECT_EDITOR (editor),
349 label_width, label_height);
351 merge = gl_label_get_merge (label);
352 gl_object_editor_set_key_names (editor, merge);
354 gl_debug (DEBUG_VIEW, "END");
357 /*****************************************************************************/
358 /* Is object at (x,y)? */
359 /*****************************************************************************/
361 object_at (glViewObject *view_object,
366 glLabelObject *object;
370 object = gl_view_object_get_object (view_object);
372 gl_label_object_get_size (object, &w, &h);
374 cairo_move_to (cr, 0.0, 0.0);
375 cairo_line_to (cr, w, h);
377 line_width = gl_label_object_get_line_width (object);
378 cairo_set_line_width (cr, line_width);
379 if (cairo_in_stroke (cr, x, y))
388 /*****************************************************************************/
389 /* Return apropos cursor for create object mode. */
390 /*****************************************************************************/
392 gl_view_line_get_create_cursor (void)
394 GdkCursor *cursor = NULL;
395 GdkPixmap *pixmap_data, *pixmap_mask;
396 GdkColor fg = { 0, 0, 0, 0 };
397 GdkColor bg = { 0, 65535, 65535, 65535 };
399 gl_debug (DEBUG_VIEW, "START");
401 pixmap_data = gdk_bitmap_create_from_data (NULL,
402 (gchar *)cursor_line_bits,
405 pixmap_mask = gdk_bitmap_create_from_data (NULL,
406 (gchar *)cursor_line_mask_bits,
407 cursor_line_mask_width,
408 cursor_line_mask_height);
409 cursor = gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
410 &bg, cursor_line_x_hot,
413 gl_debug (DEBUG_VIEW, "END");
418 /*****************************************************************************/
419 /* Object creation handler: button press event. */
420 /*****************************************************************************/
422 gl_view_line_create_button_press_event (glView *view,
427 glColorNode *line_color_node;
428 glViewObject *view_line;
430 gl_view_unselect_all (view);
432 line_color_node = gl_color_node_new_default ();
434 object = gl_label_line_new (view->label);
435 gl_label_object_set_position (GL_LABEL_OBJECT(object), x, y);
436 gl_label_object_set_size (GL_LABEL_OBJECT(object), 0.0, 0.0);
437 line_color_node->color = gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5);
438 gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
439 gl_view_get_default_line_width(view));
440 gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
443 gl_color_node_free (&line_color_node);
445 view->create_object = GL_LABEL_OBJECT (object);
450 /*****************************************************************************/
451 /* Object creation handler: motion event. */
452 /*****************************************************************************/
454 gl_view_line_create_motion_event (glView *view,
460 w = x - view->create_x0;
461 h = y - view->create_y0;
462 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
465 /*****************************************************************************/
466 /* Object creation handler: button relesase event. */
467 /*****************************************************************************/
469 gl_view_line_create_button_release_event (glView *view,
473 glColorNode *line_color_node;
476 line_color_node = gl_color_node_new_default ();
478 if ((view->create_x0 == x) && (view->create_y0 == y)) {
479 x = view->create_x0 + 36.0;
480 y = view->create_y0 + 36.0;
482 w = x - view->create_x0;
483 h = y - view->create_y0;
484 gl_label_object_set_size (GL_LABEL_OBJECT(view->create_object), w, h);
485 line_color_node->color = gl_view_get_default_line_color(view);
486 gl_label_object_set_line_color (GL_LABEL_OBJECT(view->create_object), line_color_node);
487 gl_color_node_free (&line_color_node);