2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * view_text.c: GLabels label text 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 <libgnomeprint/gnome-glyphlist.h>
27 #include "view-barcode.h"
28 #include "canvas-hacktext.h"
29 #include "view-highlight.h"
32 #include "object-editor.h"
35 #include "pixmaps/cursor_barcode.xbm"
36 #include "pixmaps/cursor_barcode_mask.xbm"
40 /*========================================================*/
41 /* Private macros and constants. */
42 /*========================================================*/
44 /*========================================================*/
46 /*========================================================*/
48 struct _glViewBarcodePrivate {
54 /*========================================================*/
55 /* Private globals. */
56 /*========================================================*/
58 static glViewObjectClass *parent_class = NULL;
61 /*========================================================*/
62 /* Private function prototypes. */
63 /*========================================================*/
65 static void gl_view_barcode_class_init (glViewBarcodeClass *klass);
66 static void gl_view_barcode_instance_init (glViewBarcode *view_bc);
67 static void gl_view_barcode_finalize (GObject *object);
69 static GtkWidget *construct_properties_editor (glViewObject *view_object);
71 static void update_canvas_item_from_object_cb (glLabelObject *object,
72 glViewBarcode *view_bc);
74 static void update_object_from_editor_cb (glObjectEditor *editor,
75 glLabelObject *object);
77 static void update_editor_from_object_cb (glLabelObject *object,
78 glObjectEditor *editor);
80 static void update_editor_from_move_cb (glLabelObject *object,
83 glObjectEditor *editor);
85 static void update_editor_from_label_cb (glLabel *label,
86 glObjectEditor *editor);
88 static void draw_barcode (glViewBarcode *view_bc);
92 /*****************************************************************************/
93 /* Boilerplate object stuff. */
94 /*****************************************************************************/
96 gl_view_barcode_get_type (void)
98 static GType type = 0;
102 sizeof (glViewBarcodeClass),
105 (GClassInitFunc) gl_view_barcode_class_init,
108 sizeof (glViewBarcode),
110 (GInstanceInitFunc) gl_view_barcode_instance_init,
113 type = g_type_register_static (GL_TYPE_VIEW_OBJECT,
114 "glViewBarcode", &info, 0);
121 gl_view_barcode_class_init (glViewBarcodeClass *klass)
123 GObjectClass *object_class = (GObjectClass *) klass;
124 glViewObjectClass *view_object_class = (glViewObjectClass *) klass;
126 gl_debug (DEBUG_VIEW, "START");
128 parent_class = g_type_class_peek_parent (klass);
130 object_class->finalize = gl_view_barcode_finalize;
132 view_object_class->construct_editor = construct_properties_editor;
134 gl_debug (DEBUG_VIEW, "END");
138 gl_view_barcode_instance_init (glViewBarcode *view_bc)
140 gl_debug (DEBUG_VIEW, "START");
142 view_bc->private = g_new0 (glViewBarcodePrivate, 1);
144 gl_debug (DEBUG_VIEW, "END");
148 gl_view_barcode_finalize (GObject *object)
152 gl_debug (DEBUG_VIEW, "START");
154 g_return_if_fail (object && GL_IS_VIEW_BARCODE (object));
156 G_OBJECT_CLASS (parent_class)->finalize (object);
158 gl_debug (DEBUG_VIEW, "END");
161 /*****************************************************************************/
162 /* NEW barcode object view. */
163 /*****************************************************************************/
165 gl_view_barcode_new (glLabelBarcode *object,
168 glViewBarcode *view_bc;
171 gl_debug (DEBUG_VIEW, "START");
172 g_return_if_fail (object && GL_IS_LABEL_BARCODE (object));
173 g_return_if_fail (view && GL_IS_VIEW (view));
175 view_bc = g_object_new (gl_view_barcode_get_type(), NULL);
177 gl_view_object_set_view (GL_VIEW_OBJECT(view_bc), view);
178 gl_view_object_set_object (GL_VIEW_OBJECT(view_bc),
179 GL_LABEL_OBJECT(object),
180 GL_VIEW_HIGHLIGHT_BOX_RESIZABLE);
182 /* Create analogous canvas items. */
183 draw_barcode (view_bc);
185 g_signal_connect (G_OBJECT (object), "changed",
186 G_CALLBACK (update_canvas_item_from_object_cb), view_bc);
188 gl_debug (DEBUG_VIEW, "END");
190 return GL_VIEW_OBJECT (view_bc);
193 /*****************************************************************************/
194 /* Create a properties editor for a barcode object. */
195 /*****************************************************************************/
197 construct_properties_editor (glViewObject *view_object)
200 glViewBarcode *view_bc = (glViewBarcode *)view_object;
201 glLabelObject *object;
203 gl_debug (DEBUG_VIEW, "START");
205 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_bc));
208 editor = gl_object_editor_new (GL_STOCK_BARCODE, _("Barcode object properties"),
209 GL_OBJECT_EDITOR_POSITION_PAGE,
210 GL_OBJECT_EDITOR_SIZE_PAGE,
211 GL_OBJECT_EDITOR_BC_PAGE,
212 GL_OBJECT_EDITOR_DATA_PAGE,
216 update_editor_from_object_cb (object, GL_OBJECT_EDITOR(editor));
217 update_editor_from_move_cb (object, 0, 0, GL_OBJECT_EDITOR(editor));
218 update_editor_from_label_cb (object->parent, GL_OBJECT_EDITOR(editor));
220 /* Connect signals. */
221 g_signal_connect (G_OBJECT (editor), "changed",
222 G_CALLBACK(update_object_from_editor_cb), object);
223 g_signal_connect (G_OBJECT (object), "changed",
224 G_CALLBACK (update_editor_from_object_cb), editor);
225 g_signal_connect (G_OBJECT (object), "moved",
226 G_CALLBACK (update_editor_from_move_cb), editor);
227 g_signal_connect (G_OBJECT (object->parent), "size_changed",
228 G_CALLBACK (update_editor_from_label_cb), editor);
229 g_signal_connect (G_OBJECT (object->parent), "merge_changed",
230 G_CALLBACK (update_editor_from_label_cb), editor);
232 gl_debug (DEBUG_VIEW, "END");
237 /*---------------------------------------------------------------------------*/
238 /* PRIVATE. label object "changed" callback. */
239 /*---------------------------------------------------------------------------*/
241 update_canvas_item_from_object_cb (glLabelObject *object,
242 glViewBarcode *view_bc)
244 gl_debug (DEBUG_VIEW, "START");
246 /* Adjust appearance of analogous canvas item. */
247 draw_barcode (view_bc);
249 gl_debug (DEBUG_VIEW, "END");
252 /*---------------------------------------------------------------------------*/
253 /* PRIVATE. editor "changed" callback. */
254 /*---------------------------------------------------------------------------*/
256 update_object_from_editor_cb (glObjectEditor *editor,
257 glLabelObject *object)
260 glTextNode *text_node;
261 glBarcodeStyle style;
262 gboolean text_flag, cs_flag;
265 gl_debug (DEBUG_VIEW, "START");
267 g_signal_handlers_block_by_func (G_OBJECT(object),
268 update_editor_from_object_cb,
270 g_signal_handlers_block_by_func (G_OBJECT(object),
271 update_editor_from_move_cb,
275 gl_object_editor_get_position (editor, &x, &y);
276 gl_label_object_set_position (object, x, y);
278 gl_object_editor_get_size (editor, &w, &h);
279 gl_label_object_set_size (object, w, h);
281 text_node = gl_object_editor_get_data (editor);
282 gl_label_barcode_set_data (GL_LABEL_BARCODE(object), text_node);
283 gl_text_node_free (&text_node);
285 gl_object_editor_get_bc_style (editor, &style, &text_flag, &cs_flag);
286 color = gl_object_editor_get_bc_color (editor);
287 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
288 style, text_flag, cs_flag);
289 gl_label_object_set_line_color (object, color);
291 g_signal_handlers_unblock_by_func (G_OBJECT(object),
292 update_editor_from_object_cb,
294 g_signal_handlers_unblock_by_func (G_OBJECT(object),
295 update_editor_from_move_cb,
298 gl_debug (DEBUG_VIEW, "END");
301 /*---------------------------------------------------------------------------*/
302 /* PRIVATE. label object "changed" callback. */
303 /*---------------------------------------------------------------------------*/
305 update_editor_from_object_cb (glLabelObject *object,
306 glObjectEditor *editor)
309 glTextNode *text_node;
310 glBarcodeStyle style;
311 gboolean text_flag, cs_flag;
315 gl_debug (DEBUG_VIEW, "START");
317 gl_label_object_get_size (object, &w, &h);
318 gl_object_editor_set_size (editor, w, h);
320 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
321 &style, &text_flag, &cs_flag);
322 color = gl_label_object_get_line_color (object);
323 gl_object_editor_set_bc_style (editor, style, text_flag, cs_flag);
324 gl_object_editor_set_bc_color (editor, color);
326 text_node = gl_label_barcode_get_data (GL_LABEL_BARCODE(object));
327 merge = gl_label_get_merge (GL_LABEL(object->parent));
328 gl_object_editor_set_data (editor, (merge != NULL), text_node);
329 gl_text_node_free (&text_node);
332 gl_debug (DEBUG_VIEW, "END");
335 /*---------------------------------------------------------------------------*/
336 /* PRIVATE. label object "moved" callback. */
337 /*---------------------------------------------------------------------------*/
339 update_editor_from_move_cb (glLabelObject *object,
342 glObjectEditor *editor)
346 gl_debug (DEBUG_VIEW, "START");
348 gl_label_object_get_position (object, &x, &y);
349 gl_object_editor_set_position (editor, x, y);
351 gl_debug (DEBUG_VIEW, "END");
354 /*---------------------------------------------------------------------------*/
355 /* PRIVATE. label "changed" callback. */
356 /*---------------------------------------------------------------------------*/
358 update_editor_from_label_cb (glLabel *label,
359 glObjectEditor *editor)
361 gdouble label_width, label_height;
364 gl_debug (DEBUG_VIEW, "START");
366 gl_label_get_size (label, &label_width, &label_height);
367 gl_object_editor_set_max_position (GL_OBJECT_EDITOR (editor),
368 label_width, label_height);
369 gl_object_editor_set_max_size (GL_OBJECT_EDITOR (editor),
370 label_width, label_height);
372 merge = gl_label_get_merge (label);
373 gl_object_editor_set_key_names (editor, merge);
375 gl_debug (DEBUG_VIEW, "END");
378 /*****************************************************************************/
379 /* Return apropos cursor for create object mode. */
380 /*****************************************************************************/
382 gl_view_barcode_get_create_cursor (void)
384 static GdkCursor *cursor = NULL;
385 GdkPixmap *pixmap_data, *pixmap_mask;
386 GdkColor fg = { 0, 0, 0, 0 };
387 GdkColor bg = { 0, 65535, 65535, 65535 };
389 gl_debug (DEBUG_VIEW, "START");
392 pixmap_data = gdk_bitmap_create_from_data (NULL,
394 cursor_barcode_width,
395 cursor_barcode_height);
396 pixmap_mask = gdk_bitmap_create_from_data (NULL,
397 cursor_barcode_mask_bits,
398 cursor_barcode_mask_width,
399 cursor_barcode_mask_height);
401 gdk_cursor_new_from_pixmap (pixmap_data, pixmap_mask, &fg,
402 &bg, cursor_barcode_x_hot,
403 cursor_barcode_y_hot);
406 gl_debug (DEBUG_VIEW, "END");
411 /*****************************************************************************/
412 /* Canvas event handler for creating barcode objects. */
413 /*****************************************************************************/
415 gl_view_barcode_create_event_handler (GnomeCanvas *canvas,
419 static gdouble x0, y0;
420 static gboolean dragging = FALSE;
421 static glViewObject *view_barcode;
422 static GObject *object;
424 glTextNode *text_node;
426 gl_debug (DEBUG_VIEW, "");
428 switch (event->type) {
430 case GDK_BUTTON_PRESS:
431 gl_debug (DEBUG_VIEW, "BUTTON_PRESS");
432 switch (event->button.button) {
435 gnome_canvas_item_grab (canvas->root,
436 GDK_POINTER_MOTION_MASK |
437 GDK_BUTTON_RELEASE_MASK |
438 GDK_BUTTON_PRESS_MASK,
439 NULL, event->button.time);
440 gnome_canvas_window_to_world (canvas,
442 event->button.y, &x, &y);
443 object = gl_label_barcode_new (view->label);
444 gl_label_object_set_position (GL_LABEL_OBJECT(object),
446 text_node = gl_text_node_new_from_text ("123456789");
447 gl_label_barcode_set_data (GL_LABEL_BARCODE(object),
449 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
450 GL_BARCODE_STYLE_POSTNET,
453 gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
454 gl_color_set_opacity (
455 gl_view_get_default_line_color(view),
457 view_barcode = gl_view_barcode_new (GL_LABEL_BARCODE(object),
467 case GDK_BUTTON_RELEASE:
468 gl_debug (DEBUG_VIEW, "BUTTON_RELEASE");
469 switch (event->button.button) {
472 gnome_canvas_item_ungrab (canvas->root, event->button.time);
473 gnome_canvas_window_to_world (canvas,
475 event->button.y, &x, &y);
476 gl_label_object_set_position (GL_LABEL_OBJECT(object),
478 gl_label_barcode_set_props (GL_LABEL_BARCODE(object),
479 GL_BARCODE_STYLE_POSTNET,
482 gl_label_object_set_line_color (GL_LABEL_OBJECT(object),
483 gl_view_get_default_line_color(view));
484 gl_view_unselect_all (view);
485 gl_view_object_select (GL_VIEW_OBJECT(view_barcode));
486 gl_view_arrow_mode (view);
493 case GDK_MOTION_NOTIFY:
494 gl_debug (DEBUG_VIEW, "MOTION_NOTIFY");
495 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
496 gnome_canvas_window_to_world (canvas,
498 event->motion.y, &x, &y);
499 gl_label_object_set_position (GL_LABEL_OBJECT(object),
512 /*--------------------------------------------------------------------------*/
513 /* PRIVATE. Draw barcode to item (group). */
514 /*--------------------------------------------------------------------------*/
516 draw_barcode (glViewBarcode *view_barcode)
518 glLabelObject *object;
519 GnomeCanvasItem *item;
520 glTextNode *text_node;
521 glBarcodeStyle style;
523 gboolean checksum_flag;
527 glBarcodeChar *bchar;
530 GList *item_list = NULL;
531 GnomeCanvasPoints *points;
532 gchar *digits, *cstring;
534 GnomeGlyphList *glyphlist;
537 gl_debug (DEBUG_VIEW, "START");
539 /* Query label object and properties */
540 object = gl_view_object_get_object (GL_VIEW_OBJECT(view_barcode));
541 gl_label_barcode_get_props (GL_LABEL_BARCODE(object),
542 &style, &text_flag, &checksum_flag);
543 color = gl_label_object_get_line_color (object);
544 gl_label_object_get_size (object, &w, &h);
545 text_node = gl_label_barcode_get_data(GL_LABEL_BARCODE(object));
546 if (text_node->field_flag) {
547 digits = gl_barcode_default_digits (style);
549 digits = gl_text_node_expand (text_node, NULL);
552 /* remove previous items from group. */
553 for (li = view_barcode->private->item_list; li!=NULL; li = li->next) {
554 gl_debug (DEBUG_VIEW, "in loop");
555 gtk_object_destroy (GTK_OBJECT (li->data));
557 gl_debug (DEBUG_VIEW, "1");
558 g_list_free (view_barcode->private->item_list);
559 view_barcode->private->item_list = NULL;
560 gl_debug (DEBUG_VIEW, "2");
563 font = gnome_font_find_closest_from_weight_slant (GL_BARCODE_FONT_FAMILY,
564 GL_BARCODE_FONT_WEIGHT,
568 gbc = gl_barcode_new (style, text_flag, checksum_flag, w, h, digits);
571 cstring = _("Invalid barcode");
572 glyphlist = gnome_glyphlist_from_text_sized_dumb (font,
578 y_offset = 10.0 - gnome_font_get_descender (font);
579 item = gl_view_object_item_new (GL_VIEW_OBJECT(view_barcode),
580 gl_canvas_hacktext_get_type (),
583 "glyphlist", glyphlist, NULL);
585 view_barcode->private->item_list =
586 g_list_prepend (view_barcode->private->item_list, item);
589 points = gnome_canvas_points_new (2);
590 for (li = gbc->lines; li != NULL; li = li->next) {
591 line = (glBarcodeLine *) li->data;
593 points->coords[0] = line->x;
594 points->coords[1] = line->y;
595 points->coords[2] = line->x;
596 points->coords[3] = line->y + line->length;
598 item = gl_view_object_item_new (GL_VIEW_OBJECT(view_barcode),
599 gnome_canvas_line_get_type (),
601 "width_units", line->width,
602 "fill_color_rgba", color,
604 view_barcode->private->item_list =
605 g_list_prepend (view_barcode->private->item_list, item);
607 gnome_canvas_points_free (points);
609 for (li = gbc->chars; li != NULL; li = li->next) {
610 bchar = (glBarcodeChar *) li->data;
612 font = gnome_font_find_closest_from_weight_slant (
613 GL_BARCODE_FONT_FAMILY,
614 GL_BARCODE_FONT_WEIGHT,
615 FALSE, bchar->fsize);
616 glyphlist = gnome_glyphlist_from_text_sized_dumb (font,
625 bchar->fsize - gnome_font_get_descender (font);
626 item = gl_view_object_item_new (GL_VIEW_OBJECT(view_barcode),
627 gl_canvas_hacktext_get_type (),
629 "y", bchar->y + y_offset,
630 "glyphlist", glyphlist,
633 view_barcode->private->item_list =
634 g_list_prepend (view_barcode->private->item_list, item);
641 gl_barcode_free (&gbc);
644 gl_debug (DEBUG_VIEW, "END");