2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * item_barcode.c: GLabels Barcode 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
28 #include "item_barcode.h"
31 #include "highlight.h"
34 #include "propertybox.h"
35 #include "prop_bc_data.h"
37 #include "prop_bc_style.h"
38 #include "prop_position.h"
40 #include "pixmaps/cursor_barcode.xbm"
41 #include "pixmaps/cursor_barcode_mask.xbm"
44 #include "gnome-canvas-hacktext.h"
45 #include <libgnomeprint/gnome-glyphlist.h>
50 #define Y_FONT_ADJUST (-1.0) /* Adjust font vertical position */
52 /*===========================================*/
53 /* Private data types */
54 /*===========================================*/
57 GnomeCanvasItem *item;
60 GtkWidget *data_entry;
68 } PropertyDialogPassback;
70 /*===========================================*/
72 /*===========================================*/
74 /*===========================================*/
75 /* Local function prototypes */
76 /*===========================================*/
78 static void item_barcode_update (GnomeCanvasItem * item);
80 static void changed_cb (glPropertyBox * propertybox);
81 static void apply_cb (glPropertyBox * propertybox, gint page,
82 PropertyDialogPassback * data);
84 static void draw_barcode (GnomeCanvasItem * item,
90 gdouble canvas_scale);
92 /*****************************************************************************/
93 /* Create a barcode object */
94 /*****************************************************************************/
96 gl_item_barcode_new (glLabelObject * object,
99 GnomeCanvasGroup *group;
100 GnomeCanvasItem *item;
103 group = gnome_canvas_root (GNOME_CANVAS (display->canvas));
104 item = gnome_canvas_item_new (group, gnome_canvas_group_get_type (),
105 "x", object->x, "y", object->y, NULL);
107 if (object->arg.barcode.text_node->field_flag) {
108 text = gl_barcode_default_digits (object->arg.barcode.style);
111 gl_text_node_expand (object->arg.barcode.text_node, NULL);
114 object->arg.barcode.style,
115 object->arg.barcode.color,
116 object->arg.barcode.text_flag,
117 object->arg.barcode.scale, text, display->scale);
120 /* Squirrel away pointers to object and display in the canvas item. */
121 gtk_object_set_data (GTK_OBJECT (item), "label_object", object);
122 gtk_object_set_data (GTK_OBJECT (item), "display", display);
123 gtk_object_set_data (GTK_OBJECT (item), "highlight", NULL);
125 gtk_signal_connect (GTK_OBJECT (item), "event",
126 GTK_SIGNAL_FUNC (gl_display_item_event_handler),
129 gl_display_new_item_menu (item);
131 gl_display_set_modified (display);
136 /*---------------------------------------------------------------------------*/
137 /* PRIVATE. Update a barcode object */
138 /*---------------------------------------------------------------------------*/
140 item_barcode_update (GnomeCanvasItem * item)
142 glLabelObject *object;
144 GList *item_list, *li;
148 display = gtk_object_get_data (GTK_OBJECT (item), "display");
149 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
151 item_list = gtk_object_get_data (GTK_OBJECT (item), "item_list");
152 for (li = item_list; li != NULL; li = li->next) {
153 gtk_object_destroy (GTK_OBJECT (li->data));
155 g_list_free (item_list);
156 gtk_object_set_data (GTK_OBJECT (item), "item_list", NULL);
158 if (object->arg.barcode.text_node->field_flag) {
159 text = gl_barcode_default_digits (object->arg.barcode.style);
162 gl_text_node_expand (object->arg.barcode.text_node, NULL);
165 object->arg.barcode.style,
166 object->arg.barcode.color,
167 object->arg.barcode.text_flag,
168 object->arg.barcode.scale, text, display->scale);
171 art_affine_identity (affine);
172 gnome_canvas_item_affine_absolute (item, affine);
173 gnome_canvas_item_set (item, "x", object->x, "y", object->y, NULL);
175 gl_display_set_modified (display);
178 /*****************************************************************************/
179 /* Highlight given canvas item. */
180 /*****************************************************************************/
182 gl_item_barcode_highlight (GnomeCanvasItem * item)
184 gl_highlight (item, GL_HIGHLIGHT_SIMPLE);
187 /*****************************************************************************/
188 /* Get position and size of object. */
189 /*****************************************************************************/
191 gl_item_barcode_get_position_size (GnomeCanvasItem * item,
197 glLabelObject *object;
200 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
205 gbc = gtk_object_get_data (GTK_OBJECT (item), "bc");
211 /*****************************************************************************/
212 /* Get position and size of object. */
213 /*****************************************************************************/
215 gl_item_barcode_set_position_size (GnomeCanvasItem * item,
221 glLabelObject *object;
223 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
228 /* Currently ignore w, h */
230 item_barcode_update (item);
233 /*****************************************************************************/
234 /* Get barcode item bounds. */
235 /*****************************************************************************/
237 gl_item_barcode_get_bounds (GnomeCanvasItem * item,
244 glLabelObject *object;
246 gbc = gtk_object_get_data (GTK_OBJECT (item), "bc");
247 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
250 gnome_canvas_item_get_bounds (item, x1, y1, x2, y2);
254 *x2 = *x1 + gbc->width;
255 *y2 = *y1 + gbc->height;
259 /*****************************************************************************/
260 /* Create and run an edit dialog on a barcode object. */
261 /*****************************************************************************/
263 gl_item_barcode_edit_dialog (GnomeCanvasItem * item)
266 static PropertyDialogPassback *data = NULL;
267 glLabelObject *object;
271 object = gtk_object_get_data (GTK_OBJECT (item), "label_object");
272 display = gtk_object_get_data (GTK_OBJECT (item), "display");
274 /*-----------------------------------------------------------------*/
275 /* Build dialog with notebook. */
276 /*-----------------------------------------------------------------*/
278 data = g_new0 (PropertyDialogPassback, 1);
282 dialog = gl_property_box_new ();
283 gtk_window_set_modal (GTK_WINDOW (dialog), TRUE);
284 gtk_window_set_transient_for (GTK_WINDOW (dialog),
285 GTK_WINDOW (gl_mdi_get_active_window ()));
286 gtk_window_set_title (GTK_WINDOW (dialog),
287 _("Edit barcode object properties"));
288 gtk_signal_connect (GTK_OBJECT (dialog), "apply",
289 GTK_SIGNAL_FUNC (apply_cb), data);
291 /*---------------------------*/
292 /* Data Notebook Tab */
293 /*---------------------------*/
294 wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
295 gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
296 gl_property_box_append_page (GL_PROPERTY_BOX (dialog),
297 wvbox, gtk_label_new (_("Data")));
299 data->data_entry = gl_prop_bc_data_new (_("Barcode data"),
300 object->parent->merge_fields);
301 gl_prop_bc_data_set_data (GL_PROP_BC_DATA (data->data_entry),
302 (object->parent->merge_type != GL_MERGE_NONE),
303 object->arg.barcode.text_node->field_flag,
304 object->arg.barcode.text_node->data,
305 object->arg.barcode.text_node->data);
306 gtk_box_pack_start (GTK_BOX (wvbox), data->data_entry, FALSE, FALSE, 0);
307 gtk_signal_connect_object (GTK_OBJECT (data->data_entry), "changed",
308 GTK_SIGNAL_FUNC (changed_cb),
309 GTK_OBJECT (dialog));
311 /*---------------------------*/
312 /* Appearance Notebook Tab */
313 /*---------------------------*/
314 wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
315 gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
316 gl_property_box_append_page (GL_PROPERTY_BOX (dialog),
317 wvbox, gtk_label_new (_("Appearance")));
319 /* ------ Begin Barcode Properties Frame ------ */
320 data->bcprop = gl_prop_bc_new (_("General"));
321 gl_prop_bc_set_params (GL_PROP_BC (data->bcprop),
322 object->arg.barcode.scale,
323 object->arg.barcode.color);
324 gtk_box_pack_start (GTK_BOX (wvbox), data->bcprop, FALSE, FALSE, 0);
325 gtk_signal_connect_object (GTK_OBJECT (data->bcprop), "changed",
326 GTK_SIGNAL_FUNC (changed_cb),
327 GTK_OBJECT (dialog));
329 /* ------ Barcode Style Frame ------ */
330 data->style = gl_prop_bc_style_new (_("Style"));
331 gl_prop_bc_style_set_params (GL_PROP_BC_STYLE (data->style),
332 object->arg.barcode.style,
333 object->arg.barcode.text_flag);
334 gtk_box_pack_start (GTK_BOX (wvbox), data->style, FALSE, FALSE, 0);
335 gtk_signal_connect_object (GTK_OBJECT (data->style), "changed",
336 GTK_SIGNAL_FUNC (changed_cb),
337 GTK_OBJECT (dialog));
339 /*----------------------------*/
340 /* Position Notebook Tab */
341 /*----------------------------*/
342 wvbox = gtk_vbox_new (FALSE, GNOME_PAD);
343 gtk_container_set_border_width (GTK_CONTAINER (wvbox), 10);
344 gl_property_box_append_page (GL_PROPERTY_BOX (dialog),
345 wvbox, gtk_label_new (_("Position")));
347 /* ------ Position Frame ------ */
348 data->position = gl_prop_position_new (_("Position"));
349 gl_prop_position_set_params (GL_PROP_POSITION (data->position),
350 object->x, object->y,
351 display->label->width,
352 display->label->height);
353 gtk_box_pack_start (GTK_BOX (wvbox), data->position, FALSE, FALSE, 0);
354 gtk_signal_connect_object (GTK_OBJECT (data->position), "changed",
355 GTK_SIGNAL_FUNC (changed_cb),
356 GTK_OBJECT (dialog));
358 /*-----------------------------------------------------------------*/
359 /* Run dialog, and update state of object if "Applied." */
360 /*-----------------------------------------------------------------*/
361 gtk_widget_show_all (GTK_WIDGET (dialog));
364 /*---------------------------------------------------------------------------*/
365 /* PRIVATE. Callback for when any control in the dialog has changed. */
366 /*---------------------------------------------------------------------------*/
368 changed_cb (glPropertyBox * propertybox)
370 gl_property_box_changed (propertybox);
373 /*---------------------------------------------------------------------------*/
374 /* PRIVATE. "Apply" callback. */
375 /*---------------------------------------------------------------------------*/
377 apply_cb (glPropertyBox * propertybox,
379 PropertyDialogPassback * data)
381 glLabelObject *object;
386 object = gtk_object_get_data (GTK_OBJECT (data->item), "label_object");
387 display = gtk_object_get_data (GTK_OBJECT (data->item), "display");
392 /* ------- Get updated digit data ------ */
393 gl_prop_bc_data_get_data (GL_PROP_BC_DATA (data->data_entry),
394 &flag, &tmp1, &tmp2);
395 object->arg.barcode.text_node->field_flag = flag;
397 object->arg.barcode.text_node->data = tmp1;
400 object->arg.barcode.text_node->data = tmp2;
406 /* ------- Get updated scale/color ------ */
407 gl_prop_bc_get_params (GL_PROP_BC (data->bcprop),
408 &object->arg.barcode.scale,
409 &object->arg.barcode.color);
410 /* ------ Get updated style ------ */
411 gl_prop_bc_style_get_params (GL_PROP_BC_STYLE (data->style),
412 &object->arg.barcode.style,
413 &object->arg.barcode.text_flag);
417 /* ------ get updated position ------ */
418 gl_prop_position_get_position (GL_PROP_POSITION
419 (data->position), &object->x,
427 /* ------ Udate state of object ------ */
428 item_barcode_update (data->item);
429 gl_display_select_item (display, data->item);
433 /*****************************************************************************/
434 /* Return apropos cursor for create object mode. */
435 /*****************************************************************************/
437 gl_item_barcode_get_create_cursor (void)
439 static GdkCursor *cursor = NULL;
440 GdkPixmap *pixmap_data, *pixmap_mask;
441 GdkColor fg = { 0, 0, 0, 0 };
442 GdkColor bg = { 0, 65535, 65535, 65535 };
445 pixmap_data = gdk_bitmap_create_from_data (NULL,
447 cursor_barcode_width,
448 cursor_barcode_height);
449 pixmap_mask = gdk_bitmap_create_from_data (NULL,
450 cursor_barcode_mask_bits,
451 cursor_barcode_mask_width,
452 cursor_barcode_mask_height);
454 gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
455 &bg, cursor_barcode_x_hot,
456 cursor_barcode_y_hot);
462 /*****************************************************************************/
463 /* Canvas event handler (barcode mode) */
464 /*****************************************************************************/
466 gl_item_barcode_create_event_handler (GnomeCanvas * canvas,
470 glDisplay *display = GL_DISPLAY (data);
472 glLabelObject *object;
473 GnomeCanvasItem *item;
475 switch (event->type) {
477 case GDK_BUTTON_PRESS:
478 switch (event->button.button) {
480 gnome_canvas_window_to_world (canvas,
482 event->button.y, &x, &y);
484 gl_label_object_new (display->label,
485 GL_LABEL_OBJECT_BARCODE);
488 object->arg.barcode.text_node =
489 gl_text_node_new_from_text ("123456789");
490 object->arg.barcode.style = GL_BARCODE_STYLE_POSTNET;
491 object->arg.barcode.color =
492 GNOME_CANVAS_COLOR_A (0, 0, 0, 255);
493 object->arg.barcode.text_flag = TRUE;
494 object->arg.barcode.scale = 1.0;
495 item = gl_item_barcode_new (object, display);
496 gl_display_add_item (display, item);
497 gl_display_unselect_all (display);
498 gl_display_select_item (display, item);
499 gl_display_arrow_mode (display);
512 /*---------------------------------------------------------------------------*/
513 /* PRIVATE. Draw barcode to canvas item (group). */
514 /*---------------------------------------------------------------------------*/
516 draw_barcode (GnomeCanvasItem * group,
517 glBarcodeStyle style,
522 gdouble canvas_scale)
525 glBarcodeChar *bchar;
528 GnomeCanvasItem *item;
529 GList *item_list = NULL;
530 GnomeCanvasPoints *points;
534 GnomeGlyphList *glyphlist;
538 GnomeDisplayFont *display_font;
541 gbc = gtk_object_get_data (GTK_OBJECT (group), "bc");
542 gl_barcode_free (&gbc);
543 gbc = gl_barcode (style, text_flag, scale, digits);
546 font = gnome_font_new_closest (GL_BARCODE_FONT_FAMILY,
547 GL_BARCODE_FONT_WEIGHT,
549 cstring = _("Invalid barcode");
550 glyphlist = gnome_glyphlist_from_text_sized_dumb (font,
556 y_offset = 10.0 - gnome_font_get_descender (font);
557 item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (group),
558 gnome_canvas_hacktext_get_type (),
561 "glyphlist", glyphlist, NULL);
563 display_font = gnome_get_display_font (GL_BARCODE_FONT_FAMILY,
564 GL_BARCODE_FONT_WEIGHT,
567 gdk_font = gnome_display_font_get_gdk_font (display_font);
568 item = gnome_canvas_item_new (GNOME_CANVAS_GROUP (group),
569 gnome_canvas_text_get_type (),
572 "text", _("Invalid barcode"),
573 "font_gdk", gdk_font,
574 "anchor", GTK_ANCHOR_NW,
575 "fill_color_rgba", color, NULL);
577 item_list = g_list_prepend (item_list, item);
580 points = gnome_canvas_points_new (2);
581 for (li = gbc->lines; li != NULL; li = li->next) {
582 line = (glBarcodeLine *) li->data;
584 points->coords[0] = line->x;
585 points->coords[1] = line->y;
586 points->coords[2] = line->x;
587 points->coords[3] = line->y + line->length;
590 gnome_canvas_item_new (GNOME_CANVAS_GROUP (group),
591 gnome_canvas_line_get_type
592 (), "points", points,
593 "width_units", line->width,
594 "fill_color_rgba", color,
596 item_list = g_list_prepend (item_list, item);
598 gnome_canvas_points_free (points);
600 for (li = gbc->chars; li != NULL; li = li->next) {
601 bchar = (glBarcodeChar *) li->data;
604 font = gnome_font_new_closest (GL_BARCODE_FONT_FAMILY,
605 GL_BARCODE_FONT_WEIGHT,
606 FALSE, bchar->fsize);
607 glyphlist = gnome_glyphlist_from_text_sized_dumb (font,
616 bchar->fsize - gnome_font_get_descender (font);
618 gnome_canvas_item_new (GNOME_CANVAS_GROUP (group),
619 gnome_canvas_hacktext_get_type
620 (), "x", bchar->x, "y",
622 "glyphlist", glyphlist,
626 gnome_get_display_font (GL_BARCODE_FONT_FAMILY,
627 GL_BARCODE_FONT_WEIGHT,
631 gnome_display_font_get_gdk_font (display_font);
632 cstring = g_strdup_printf ("%c", bchar->c);
634 gnome_canvas_item_new (GNOME_CANVAS_GROUP (group),
635 gnome_canvas_text_get_type
636 (), "x", bchar->x, "y",
637 bchar->y + Y_FONT_ADJUST,
638 "text", cstring, "font_gdk",
641 "fill_color_rgba", color,
645 item_list = g_list_prepend (item_list, item);
651 /* attach item list to group, so we can get at these again */
652 gtk_object_set_data (GTK_OBJECT (group), "item_list", item_list);
654 gtk_object_set_data (GTK_OBJECT (group), "bc", gbc);