2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * item_box.c: GLabels Box Object (canvas item) module
6 * Copyright (C) 2001-2002 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
30 #include "highlight.h"
33 #include "propertybox.h"
34 #include "prop_line.h"
35 #include "prop_fill.h"
36 #include "prop_size.h"
37 #include "prop_position.h"
39 #include "pixmaps/cursor_box.xbm"
40 #include "pixmaps/cursor_box_mask.xbm"
44 /*===========================================*/
45 /* Private data types */
46 /*===========================================*/
49 GnomeCanvasItem *item;
50 gboolean keep_aspect_ratio_flag;
59 } PropertyDialogPassback;
61 /*===========================================*/
63 /*===========================================*/
65 /*===========================================*/
66 /* Local function prototypes */
67 /*===========================================*/
69 static void item_box_update (GnomeCanvasItem * item);
71 static void changed_cb (glPropertyBox * propertybox);
72 static void apply_cb (glPropertyBox * propertybox,
73 gint page, PropertyDialogPassback * data);
75 /*****************************************************************************/
76 /* Create a box object */
77 /*****************************************************************************/
79 gl_item_box_new (glLabelObject * object,
82 GnomeCanvasGroup *group;
83 GnomeCanvasItem *item;
85 group = gnome_canvas_root (GNOME_CANVAS (display->canvas));
86 item = gnome_canvas_item_new (group, gnome_canvas_rect_get_type (),
89 "x2", object->x + object->arg.box.w,
90 "y2", object->y + object->arg.box.h,
91 "width_units", object->arg.box.line_width,
93 object->arg.box.line_color,
95 object->arg.box.fill_color, NULL);
97 /* Squirrel away pointers to object and display in the canvas item. */
98 gtk_object_set_data (GTK_OBJECT (item), "label_object", object);
99 gtk_object_set_data (GTK_OBJECT (item), "display", display);
100 gtk_object_set_data (GTK_OBJECT (item), "highlight", NULL);
102 gtk_signal_connect (GTK_OBJECT (item), "event",
103 GTK_SIGNAL_FUNC (gl_display_item_event_handler),
106 gl_display_new_item_menu (item);
108 gl_display_set_modified (display);
113 /*---------------------------------------------------------------------------*/
114 /* PRIVATE. Update a box object */
115 /*---------------------------------------------------------------------------*/
117 item_box_update (GnomeCanvasItem * item)
119 glLabelObject *object;
123 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
125 art_affine_identity (affine);
126 gnome_canvas_item_affine_absolute (item, affine);
127 gnome_canvas_item_set (item,
130 "x2", object->x + object->arg.box.w,
131 "y2", object->y + object->arg.box.h,
132 "width_units", object->arg.box.line_width,
133 "outline_color_rgba", object->arg.box.line_color,
134 "fill_color_rgba", object->arg.box.fill_color,
137 display = gtk_object_get_data (GTK_OBJECT (item), "display");
138 gl_display_set_modified (display);
141 /*****************************************************************************/
142 /* Return a selection canvas item/group for given item */
143 /*****************************************************************************/
145 gl_item_box_highlight (GnomeCanvasItem * item)
147 gl_highlight (item, GL_HIGHLIGHT_BOX_RESIZABLE);
150 /*****************************************************************************/
151 /* Get position and size of object. */
152 /*****************************************************************************/
154 gl_item_box_get_position_size (GnomeCanvasItem * item,
160 glLabelObject *object;
162 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
167 *w = object->arg.box.w;
168 *h = object->arg.box.h;
171 /*****************************************************************************/
172 /* Get position and size of object. */
173 /*****************************************************************************/
175 gl_item_box_set_position_size (GnomeCanvasItem * item,
181 glLabelObject *object;
183 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
188 object->arg.box.w = w;
189 object->arg.box.h = h;
191 item_box_update (item);
194 /*****************************************************************************/
195 /* Get box item bounds. */
196 /*****************************************************************************/
198 gl_item_box_get_bounds (GnomeCanvasItem * item,
204 gnome_canvas_item_get_bounds (item, x1, y1, x2, y2);
207 /*****************************************************************************/
208 /* Create and run an edit dialog on a box object. */
209 /*****************************************************************************/
211 gl_item_box_edit_dialog (GnomeCanvasItem * item)
214 static PropertyDialogPassback *data = NULL;
215 glLabelObject *object;
219 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
220 display = gtk_object_get_data (GTK_OBJECT (item), "display");
222 /*-----------------------------------------------------------------*/
223 /* Build dialog with notebook. */
224 /*-----------------------------------------------------------------*/
226 data = g_new0 (PropertyDialogPassback, 1);
230 dialog = gl_property_box_new ();
231 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
232 gtk_window_set_transient_for (GTK_WINDOW (dialog),
233 GTK_WINDOW (gl_mdi_get_active_window ()));
234 gtk_window_set_title (GTK_WINDOW (dialog),
235 _("Edit box object properties"));
236 gtk_signal_connect (GTK_OBJECT (dialog), "apply",
237 GTK_SIGNAL_FUNC (apply_cb), data);
239 /*---------------------------*/
240 /* Appearance Notebook Tab */
241 /*---------------------------*/
242 wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
243 gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
244 gl_property_box_append_page (GL_PROPERTY_BOX (dialog), wvbox,
245 gtk_label_new (_("Appearance")));
247 /* ------ Line box ------ */
248 data->line = gl_prop_line_new (_("Outline"));
249 gl_prop_line_set_params (GL_PROP_LINE (data->line),
250 object->arg.box.line_width,
251 object->arg.box.line_color);
252 gtk_box_pack_start (GTK_BOX (wvbox), data->line, FALSE, FALSE, 0);
253 gtk_signal_connect_object (GTK_OBJECT (data->line), "changed",
254 GTK_SIGNAL_FUNC (changed_cb),
255 GTK_OBJECT (dialog));
257 /* ------ Fill box ------ */
258 data->fill = gl_prop_fill_new (_("Fill"));
259 gl_prop_fill_set_params (GL_PROP_FILL (data->fill),
260 object->arg.box.fill_color);
261 gtk_box_pack_start (GTK_BOX (wvbox), data->fill, FALSE, FALSE, 0);
262 gtk_signal_connect_object (GTK_OBJECT (data->fill), "changed",
263 GTK_SIGNAL_FUNC (changed_cb),
264 GTK_OBJECT (dialog));
266 /*----------------------------*/
267 /* Position/Size Notebook Tab */
268 /*----------------------------*/
269 wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
270 gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
271 gl_property_box_append_page (GL_PROPERTY_BOX (dialog), wvbox,
272 gtk_label_new (_("Position/Size")));
274 /* ------ Position Frame ------ */
275 data->position = gl_prop_position_new (_("Position"));
276 gl_prop_position_set_params (GL_PROP_POSITION (data->position),
277 object->x, object->y,
278 display->label->width,
279 display->label->height);
280 gtk_box_pack_start (GTK_BOX (wvbox), data->position, FALSE, FALSE, 0);
281 gtk_signal_connect_object (GTK_OBJECT (data->position), "changed",
282 GTK_SIGNAL_FUNC (changed_cb),
283 GTK_OBJECT (dialog));
285 /* ------ Size Frame ------ */
286 data->size = gl_prop_size_new (_("Size"));
287 gl_prop_size_set_params (GL_PROP_SIZE (data->size),
288 object->arg.box.w, object->arg.box.h,
289 data->keep_aspect_ratio_flag,
290 display->label->width, display->label->height);
291 gtk_box_pack_start (GTK_BOX (wvbox), data->size, FALSE, FALSE, 0);
292 gtk_signal_connect_object (GTK_OBJECT (data->size), "changed",
293 GTK_SIGNAL_FUNC (changed_cb),
294 GTK_OBJECT (dialog));
296 /*-----------------------------------------------------------------*/
297 /* Run dialog, and update state of object if "Applied." */
298 /*-----------------------------------------------------------------*/
299 gtk_widget_show_all (GTK_WIDGET (dialog));
302 /*---------------------------------------------------------------------------*/
303 /* PRIVATE. Callback for when any control in the dialog has changed. */
304 /*---------------------------------------------------------------------------*/
306 changed_cb (glPropertyBox * propertybox)
308 gl_property_box_changed (propertybox);
311 /*---------------------------------------------------------------------------*/
312 /* PRIVATE. "Apply" callback. */
313 /*---------------------------------------------------------------------------*/
315 apply_cb (glPropertyBox * propertybox,
317 PropertyDialogPassback * data)
319 glLabelObject *object;
322 object = gtk_object_get_data (GTK_OBJECT (data->item), "label_object");
323 display = gtk_object_get_data (GTK_OBJECT (data->item), "display");
328 /* ------- Get updated line width & color ------ */
329 gl_prop_line_get_params (GL_PROP_LINE (data->line),
330 &object->arg.box.line_width,
331 &object->arg.box.line_color);
332 /* ------- Get updated fill color ------ */
333 gl_prop_fill_get_params (GL_PROP_FILL (data->fill),
334 &object->arg.box.fill_color);
338 /* ------ get updated position ------ */
339 gl_prop_position_get_position (GL_PROP_POSITION
340 (data->position), &object->x,
343 /* ------ get updated size ------ */
344 gl_prop_size_get_size (GL_PROP_SIZE (data->size),
345 &object->arg.box.w, &object->arg.box.h,
346 &data->keep_aspect_ratio_flag);
353 /* ------ Udate state of object ------ */
354 item_box_update (data->item);
355 gl_display_select_item (display, data->item);
359 /*****************************************************************************/
360 /* Return apropos cursor for create object mode. */
361 /*****************************************************************************/
363 gl_item_box_get_create_cursor (void)
365 static GdkCursor *cursor = NULL;
366 GdkPixmap *pixmap_data, *pixmap_mask;
367 GdkColor fg = { 0, 0, 0, 0 };
368 GdkColor bg = { 0, 65535, 65535, 65535 };
371 pixmap_data = gdk_bitmap_create_from_data (NULL,
375 pixmap_mask = gdk_bitmap_create_from_data (NULL,
376 cursor_box_mask_bits,
377 cursor_box_mask_width,
378 cursor_box_mask_height);
380 gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
381 &bg, cursor_box_x_hot,
388 /*****************************************************************************/
389 /* Canvas event handler (box mode) */
390 /*****************************************************************************/
392 gl_item_box_create_event_handler (GnomeCanvas * canvas,
396 static gdouble x0, y0;
397 static gboolean dragging = FALSE;
398 static GnomeCanvasItem *item;
399 static glLabelObject *object;
400 glDisplay *display = GL_DISPLAY (data);
403 switch (event->type) {
405 case GDK_BUTTON_PRESS:
406 switch (event->button.button) {
409 gdk_pointer_grab (GTK_WIDGET (display->canvas)->window,
411 GDK_POINTER_MOTION_MASK |
412 GDK_BUTTON_RELEASE_MASK |
413 GDK_BUTTON_PRESS_MASK,
414 NULL, NULL, event->button.time);
415 gnome_canvas_window_to_world (canvas,
417 event->button.y, &x, &y);
419 gl_label_object_new (display->label,
420 GL_LABEL_OBJECT_BOX);
423 object->arg.box.w = 0.0;
424 object->arg.box.h = 0.0;
425 object->arg.box.line_width = 1.0;
426 object->arg.box.line_color =
427 GNOME_CANVAS_COLOR_A (0, 0, 255, 128);
428 object->arg.box.fill_color =
429 GNOME_CANVAS_COLOR_A (128, 128, 128, 128);
430 item = gl_item_box_new (object, display);
439 case GDK_BUTTON_RELEASE:
440 switch (event->button.button) {
443 gdk_pointer_ungrab (event->button.time);
444 gnome_canvas_window_to_world (canvas,
446 event->button.y, &x, &y);
447 if ((x0 == x) && (y0 == y)) {
451 object->x = MIN (x, x0);
452 object->y = MIN (y, y0);
453 object->arg.box.w = MAX (x, x0) - MIN (x, x0);
454 object->arg.box.h = MAX (y, y0) - MIN (y, y0);
455 object->arg.box.line_color =
456 GNOME_CANVAS_COLOR_A (0, 0, 0, 255);
457 object->arg.box.fill_color =
458 GNOME_CANVAS_COLOR_A (0, 255, 0, 255);
459 item_box_update (item);
460 gl_display_add_item (display, item);
461 gl_display_unselect_all (display);
462 gl_display_select_item (display, item);
463 gl_display_arrow_mode (display);
470 case GDK_MOTION_NOTIFY:
471 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
472 gnome_canvas_window_to_world (canvas,
474 event->motion.y, &x, &y);
475 object->x = MIN (x, x0);
476 object->y = MIN (y, y0);
477 object->arg.box.w = MAX (x, x0) - MIN (x, x0);
478 object->arg.box.h = MAX (y, y0) - MIN (y, y0);
479 item_box_update (item);