2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * view_line.c: GLabels label line object widget
6 * Copyright (C) 2001-2003 Jim Evins <evins@snaught.com>.
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.
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.
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
25 #include "view-line.h"
27 #include "view-highlight.h"
30 #include "object-editor.h"
33 #include "pixmaps/cursor_line.xbm"
34 #include "pixmaps/cursor_line_mask.xbm"
38 /*========================================================*/
39 /* Private macros and constants. */
40 /*========================================================*/
42 /*========================================================*/
44 /*========================================================*/
46 struct _glViewLinePrivate {
47 GnomeCanvasItem *item;
50 /*========================================================*/
51 /* Private globals. */
52 /*========================================================*/
54 static glViewObjectClass *parent_class = NULL;
57 /*========================================================*/
58 /* Private function prototypes. */
59 /*========================================================*/
61 static void gl_view_line_class_init (glViewLineClass *klass);
62 static void gl_view_line_instance_init (glViewLine *view_line);
63 static void gl_view_line_finalize (GObject *object);
65 static GtkWidget *construct_properties_editor (glViewObject *view_object);
67 static void update_canvas_item_from_object_cb (glLabelObject *object,
68 glViewLine *view_line);
70 static void update_object_from_editor_cb (glObjectEditor *editor,
71 glLabelObject *object);
73 static void update_editor_from_object_cb (glLabelObject *object,
74 glObjectEditor *editor);
76 static void update_editor_from_move_cb (glLabelObject *object,
79 glObjectEditor *editor);
81 static void update_editor_from_label_cb (glLabel *label,
82 glObjectEditor *editor);
86 /*****************************************************************************/
87 /* Boilerplate object stuff. */
88 /*****************************************************************************/
90 gl_view_line_get_type (void)
92 static GType type = 0;
96 sizeof (glViewLineClass),
99 (GClassInitFunc) gl_view_line_class_init,
104 (GInstanceInitFunc) gl_view_line_instance_init,
107 type = g_type_register_static (GL_TYPE_VIEW_OBJECT,
108 "glViewLine", &info, 0);
115 gl_view_line_class_init (glViewLineClass *klass)
117 GObjectClass *object_class = (GObjectClass *) klass;
118 glViewObjectClass *view_object_class = (glViewObjectClass *) klass;
120 gl_debug (DEBUG_VIEW, "START");
122 parent_class = g_type_class_peek_parent (klass);
124 object_class->finalize = gl_view_line_finalize;
126 view_object_class->construct_editor = construct_properties_editor;
128 gl_debug (DEBUG_VIEW, "END");
132 gl_view_line_instance_init (glViewLine *view_line)
134 gl_debug (DEBUG_VIEW, "START");
136 view_line->private = g_new0 (glViewLinePrivate, 1);
138 gl_debug (DEBUG_VIEW, "END");
142 gl_view_line_finalize (GObject *object)
146 gl_debug (DEBUG_VIEW, "START");
148 g_return_if_fail (object && GL_IS_VIEW_LINE (object));
150 G_OBJECT_CLASS (parent_class)->finalize (object);
152 gl_debug (DEBUG_VIEW, "END");
155 /*****************************************************************************/
156 /* NEW line object view. */
157 /*****************************************************************************/
159 gl_view_line_new (glLabelLine *object,
162 glViewLine *view_line;
166 GnomeCanvasPoints *points;
168 gl_debug (DEBUG_VIEW, "START");
169 g_return_if_fail (object && GL_IS_LABEL_LINE (object));
170 g_return_if_fail (view && GL_IS_VIEW (view));
172 view_line = g_object_new (gl_view_line_get_type(), NULL);
174 gl_view_object_set_view (GL_VIEW_OBJECT(view_line), view);
175 gl_view_object_set_object (GL_VIEW_OBJECT(view_line),
176 GL_LABEL_OBJECT(object),
177 GL_VIEW_HIGHLIGHT_LINE_RESIZABLE);
179 /* Query properties of object. */
180 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
181 line_width = gl_label_object_get_line_width(GL_LABEL_OBJECT(object));
182 line_color = gl_label_object_get_line_color(GL_LABEL_OBJECT(object));
184 /* Create analogous canvas item. */
185 points = gnome_canvas_points_new (2);
186 points->coords[0] = 0.0;
187 points->coords[1] = 0.0;
188 points->coords[2] = w;
189 points->coords[3] = h;
190 view_line->private->item =
191 gl_view_object_item_new (GL_VIEW_OBJECT(view_line),
192 gnome_canvas_line_get_type (),
194 "width_units", line_width,
195 "fill_color_rgba", line_color,
197 gnome_canvas_points_free (points);
199 g_signal_connect (G_OBJECT (object), "changed",
200 G_CALLBACK (update_canvas_item_from_object_cb), view_line);
202 gl_debug (DEBUG_VIEW, "END");
204 return GL_VIEW_OBJECT (view_line);
207 /*****************************************************************************/
208 /* Create a properties editor for a line object. */
209 /*****************************************************************************/
211 construct_properties_editor (glViewObject *view_object)
214 glViewLine *view_line = (glViewLine *)view_object;
215 glLabelObject *object;
217 gl_debug (DEBUG_VIEW, "START");
219 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_line));
222 editor = gl_object_editor_new (GL_STOCK_LINE, _("Line object properties"),
223 GL_OBJECT_EDITOR_POSITION_PAGE,
224 GL_OBJECT_EDITOR_SIZE_LINE_PAGE,
225 GL_OBJECT_EDITOR_LINE_PAGE,
229 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
230 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
231 update_editor_from_label_cb (object->parent, GL_OBJECT_EDITOR(editor));
233 /* Connect signals. */
234 g_signal_connect (G_OBJECT (editor), "changed",
235 G_CALLBACK(update_object_from_editor_cb), object);
236 g_signal_connect (G_OBJECT (object), "changed",
237 G_CALLBACK (update_editor_from_object_cb), editor);
238 g_signal_connect (G_OBJECT (object), "moved",
239 G_CALLBACK (update_editor_from_move_cb), editor);
240 g_signal_connect (G_OBJECT (object->parent), "size_changed",
241 G_CALLBACK (update_editor_from_label_cb), editor);
243 gl_debug (DEBUG_VIEW, "END");
248 /*---------------------------------------------------------------------------*/
249 /* PRIVATE. label object "changed" callback. */
250 /*---------------------------------------------------------------------------*/
252 update_canvas_item_from_object_cb (glLabelObject *object,
253 glViewLine *view_line)
258 GnomeCanvasPoints *points;
260 gl_debug (DEBUG_VIEW, "START");
262 /* Query properties of object. */
263 gl_label_object_get_size (GL_LABEL_OBJECT(object), &w, &h);
264 line_width = gl_label_object_get_line_width(GL_LABEL_OBJECT(object));
265 line_color = gl_label_object_get_line_color(GL_LABEL_OBJECT(object));
267 /* Adjust appearance of analogous canvas item. */
268 points = gnome_canvas_points_new (2);
269 points->coords[0] = 0.0;
270 points->coords[1] = 0.0;
271 points->coords[2] = w;
272 points->coords[3] = h;
273 gnome_canvas_item_set (view_line->private->item,
275 "width_units", line_width,
276 "fill_color_rgba", line_color,
278 gnome_canvas_points_free (points);
280 gl_debug (DEBUG_VIEW, "END");
283 /*---------------------------------------------------------------------------*/
284 /* PRIVATE. editor "changed" callback. */
285 /*---------------------------------------------------------------------------*/
287 update_object_from_editor_cb (glObjectEditor *editor,
288 glLabelObject *object)
294 gl_debug (DEBUG_VIEW, "START");
296 g_signal_handlers_block_by_func (G_OBJECT(object),
297 update_editor_from_object_cb,
299 g_signal_handlers_block_by_func (G_OBJECT(object),
300 update_editor_from_move_cb,
304 gl_object_editor_get_position (editor, &x, &y);
305 gl_label_object_set_position (object, x, y);
307 gl_object_editor_get_lsize (editor, &w, &h);
308 gl_label_object_set_size (object, w, h);
310 line_color = gl_object_editor_get_line_color (editor);
311 gl_label_object_set_line_color (object, line_color);
313 line_width = gl_object_editor_get_line_width (editor);
314 gl_label_object_set_line_width (object, line_width);
317 g_signal_handlers_unblock_by_func (G_OBJECT(object),
318 update_editor_from_object_cb,
320 g_signal_handlers_unblock_by_func (G_OBJECT(object),
321 update_editor_from_move_cb,
324 gl_debug (DEBUG_VIEW, "END");
327 /*---------------------------------------------------------------------------*/
328 /* PRIVATE. label object "changed" callback. */
329 /*---------------------------------------------------------------------------*/
331 update_editor_from_object_cb (glLabelObject *object,
332 glObjectEditor *editor)
338 gl_debug (DEBUG_VIEW, "START");
340 gl_label_object_get_size (object, &w, &h);
341 gl_object_editor_set_lsize (editor, w, h);
343 line_color = gl_label_object_get_line_color (GL_LABEL_OBJECT(object));
344 gl_object_editor_set_line_color (editor, line_color);
346 line_width = gl_label_object_get_line_width (GL_LABEL_OBJECT(object));
347 gl_object_editor_set_line_width (editor, line_width);
349 gl_debug (DEBUG_VIEW, "END");
352 /*---------------------------------------------------------------------------*/
353 /* PRIVATE. label object "moved" callback. */
354 /*---------------------------------------------------------------------------*/
356 update_editor_from_move_cb (glLabelObject *object,
359 glObjectEditor *editor)
363 gl_debug (DEBUG_VIEW, "START");
365 gl_label_object_get_position (object, &x, &y);
366 gl_object_editor_set_position (editor, x, y);
368 gl_debug (DEBUG_VIEW, "END");
371 /*---------------------------------------------------------------------------*/
372 /* PRIVATE. label "changed" callback. */
373 /*---------------------------------------------------------------------------*/
375 update_editor_from_label_cb (glLabel *label,
376 glObjectEditor *editor)
378 gdouble label_width, label_height;
380 gl_debug (DEBUG_VIEW, "START");
382 gl_label_get_size (label, &label_width, &label_height);
383 gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
384 label_width, label_height);
385 gl_object_editor_set_max_lsize (GL_OBJECT_EDITOR (editor),
386 label_width, label_height);
388 gl_debug (DEBUG_VIEW, "END");
391 /*****************************************************************************/
392 /* Return apropos cursor for create object mode. */
393 /*****************************************************************************/
395 gl_view_line_get_create_cursor (void)
397 static GdkCursor *cursor = NULL;
398 GdkPixmap *pixmap_data, *pixmap_mask;
399 GdkColor fg = { 0, 0, 0, 0 };
400 GdkColor bg = { 0, 65535, 65535, 65535 };
402 gl_debug (DEBUG_VIEW, "START");
405 pixmap_data = gdk_bitmap_create_from_data (NULL,
409 pixmap_mask = gdk_bitmap_create_from_data (NULL,
410 cursor_line_mask_bits,
411 cursor_line_mask_width,
412 cursor_line_mask_height);
414 gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
415 &bg, cursor_line_x_hot,
419 gl_debug (DEBUG_VIEW, "END");
424 /*****************************************************************************/
425 /* Canvas event handler for creating line objects. */
426 /*****************************************************************************/
428 gl_view_line_create_event_handler (GnomeCanvas *canvas,
432 static gdouble x0, y0;
433 static gboolean dragging = FALSE;
434 static glViewObject *view_line;
435 static GObject *object;
438 gl_debug (DEBUG_VIEW, "");
440 switch (event->type) {
442 case GDK_BUTTON_PRESS:
443 switch (event->button.button) {
446 gnome_canvas_item_grab (canvas->root,
447 GDK_POINTER_MOTION_MASK |
448 GDK_BUTTON_RELEASE_MASK |
449 GDK_BUTTON_PRESS_MASK,
450 NULL, event->button.time);
451 gnome_canvas_window_to_world (canvas,
453 event->button.y, &x, &y);
454 object = gl_label_line_new (view->label);
455 gl_label_object_set_position (GL_LABEL_OBJECT(object),
457 gl_label_object_set_size (GL_LABEL_OBJECT(object),
459 gl_label_object_set_line_width (GL_LABEL_OBJECT(object),
460 gl_view_get_default_line_width(view));
461 gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
462 gl_color_set_opacity (gl_view_get_default_line_color(view), 0.5));
463 view_line = gl_view_line_new (GL_LABEL_LINE(object),
473 case GDK_BUTTON_RELEASE:
474 switch (event->button.button) {
477 gnome_canvas_item_ungrab (canvas->root, event->button.time);
478 gnome_canvas_window_to_world (canvas,
480 event->button.y, &x, &y);
481 if ((x0 == x) && (y0 == y)) {
487 gl_label_object_set_size (GL_LABEL_OBJECT(object),
489 gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
490 gl_view_get_default_line_color(view));
491 gl_view_unselect_all (view);
492 gl_view_object_select (GL_VIEW_OBJECT(view_line));
493 gl_view_arrow_mode (view);
500 case GDK_MOTION_NOTIFY:
501 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
502 gnome_canvas_window_to_world (canvas,
504 event->motion.y, &x, &y);
507 gl_label_object_set_size (GL_LABEL_OBJECT(object),