2 * (GLABELS) Label and Business Card Creation program for GNOME
4 * wdgt_mini_preview.c: mini preview widget module
6 * Copyright (C) 2001 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-print-paper.h"
27 #include "wdgt-mini-preview.h"
32 #define WDGT_MINI_PREVIEW_MAX_PIXELS 175
33 #define SHADOW_X_OFFSET 3
34 #define SHADOW_Y_OFFSET 3
35 #define SHADOW_COLOR GNOME_CANVAS_COLOR_A (33, 33, 33, 192)
37 /*===========================================*/
39 /*===========================================*/
48 /*===========================================*/
50 /*===========================================*/
52 static GtkContainerClass *parent_class;
54 static gint wdgt_mini_preview_signals[LAST_SIGNAL] = { 0 };
56 /*===========================================*/
57 /* Local function prototypes */
58 /*===========================================*/
60 static void gl_wdgt_mini_preview_class_init (glWdgtMiniPreviewClass * class);
61 static void gl_wdgt_mini_preview_instance_init (glWdgtMiniPreview * preview);
62 static void gl_wdgt_mini_preview_finalize (GObject * object);
64 static void gl_wdgt_mini_preview_construct (glWdgtMiniPreview * preview,
65 gint height, gint width);
67 static GList *mini_outline_list_new (GnomeCanvas *canvas,
68 glTemplate *template);
69 static void mini_outline_list_free (GList ** list);
71 static gint canvas_event_cb (GnomeCanvas * canvas,
75 /****************************************************************************/
76 /* Boilerplate Object stuff. */
77 /****************************************************************************/
79 gl_wdgt_mini_preview_get_type (void)
81 static guint wdgt_mini_preview_type = 0;
83 if (!wdgt_mini_preview_type) {
84 GTypeInfo wdgt_mini_preview_info = {
85 sizeof (glWdgtMiniPreviewClass),
88 (GClassInitFunc) gl_wdgt_mini_preview_class_init,
91 sizeof (glWdgtMiniPreview),
93 (GInstanceInitFunc) gl_wdgt_mini_preview_instance_init,
96 wdgt_mini_preview_type =
97 g_type_register_static (gtk_hbox_get_type (),
99 &wdgt_mini_preview_info, 0);
102 return wdgt_mini_preview_type;
106 gl_wdgt_mini_preview_class_init (glWdgtMiniPreviewClass * class)
108 GObjectClass *object_class;
110 gl_debug (DEBUG_MINI_PREVIEW, "START");
112 object_class = (GObjectClass *) class;
114 parent_class = gtk_type_class (gtk_hbox_get_type ());
116 object_class->finalize = gl_wdgt_mini_preview_finalize;
118 wdgt_mini_preview_signals[CLICKED] =
119 g_signal_new ("clicked",
120 G_OBJECT_CLASS_TYPE(object_class),
122 G_STRUCT_OFFSET (glWdgtMiniPreviewClass, clicked),
124 gl_marshal_VOID__INT,
125 G_TYPE_NONE, 1, G_TYPE_INT);
127 wdgt_mini_preview_signals[PRESSED] =
128 g_signal_new ("pressed",
129 G_OBJECT_CLASS_TYPE(object_class),
131 G_STRUCT_OFFSET (glWdgtMiniPreviewClass, pressed),
133 gl_marshal_VOID__INT_INT,
134 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
136 gl_debug (DEBUG_MINI_PREVIEW, "END");
140 gl_wdgt_mini_preview_instance_init (glWdgtMiniPreview * preview)
142 gl_debug (DEBUG_MINI_PREVIEW, "START");
144 preview->canvas = NULL;
145 preview->label_items = NULL;
147 gl_debug (DEBUG_MINI_PREVIEW, "END");
151 gl_wdgt_mini_preview_finalize (GObject * object)
153 glWdgtMiniPreview *preview;
154 glWdgtMiniPreviewClass *class;
156 gl_debug (DEBUG_MINI_PREVIEW, "START");
158 g_return_if_fail (object != NULL);
159 g_return_if_fail (GL_IS_WDGT_MINI_PREVIEW (object));
161 preview = GL_WDGT_MINI_PREVIEW (object);
163 G_OBJECT_CLASS (parent_class)->finalize (object);
165 gl_debug (DEBUG_MINI_PREVIEW, "END");
169 gl_wdgt_mini_preview_new (gint height,
172 glWdgtMiniPreview *preview;
174 gl_debug (DEBUG_MINI_PREVIEW, "START");
176 preview = g_object_new (gl_wdgt_mini_preview_get_type (), NULL);
178 gl_wdgt_mini_preview_construct (preview, height, width);
180 gl_debug (DEBUG_MINI_PREVIEW, "END");
182 return GTK_WIDGET (preview);
185 /*--------------------------------------------------------------------------*/
186 /* Construct composite widget. */
187 /*--------------------------------------------------------------------------*/
189 gl_wdgt_mini_preview_construct (glWdgtMiniPreview * preview,
194 GnomeCanvasGroup *group;
196 gl_debug (DEBUG_MINI_PREVIEW, "START");
198 whbox = GTK_WIDGET (preview);
200 preview->height = height;
201 preview->width = width;
204 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
205 preview->canvas = gnome_canvas_new_aa ();
206 gtk_widget_pop_colormap ();
207 gtk_box_pack_start (GTK_BOX (whbox), preview->canvas, TRUE, TRUE, 0);
208 gtk_widget_set_size_request (preview->canvas, width, height);
209 gnome_canvas_set_scroll_region (GNOME_CANVAS (preview->canvas),
210 0.0, 0.0, width, height);
212 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (preview->canvas), 1.0);
213 group = gnome_canvas_root (GNOME_CANVAS (preview->canvas));
216 preview->shadow_item =
217 gnome_canvas_item_new (group,
218 gnome_canvas_rect_get_type (),
219 "x1", (gdouble)SHADOW_X_OFFSET,
220 "y1", (gdouble)SHADOW_Y_OFFSET,
221 "x2", (gdouble)(SHADOW_X_OFFSET + width),
222 "y2", (gdouble)(SHADOW_Y_OFFSET + height),
223 "fill_color_rgba", SHADOW_COLOR,
226 /* draw an initial paper outline */
227 preview->paper_item =
228 gnome_canvas_item_new (group,
229 gnome_canvas_rect_get_type (),
232 "x2", (gdouble)width,
233 "y2", (gdouble)height,
235 "outline_color", "black",
236 "fill_color", "white",
239 /* create empty list of label canvas items */
240 preview->label_items = NULL;
241 preview->labels_per_sheet = 0;
244 g_signal_connect (G_OBJECT (preview->canvas), "event",
245 G_CALLBACK (canvas_event_cb), preview);
247 gl_debug (DEBUG_MINI_PREVIEW, "END");
250 /****************************************************************************/
251 /* Set label for mini-preview to determine geometry. */
252 /****************************************************************************/
253 void gl_wdgt_mini_preview_set_label (glWdgtMiniPreview * preview,
256 glTemplate *template;
258 const GnomePrintPaper *paper = NULL;
259 gdouble paper_width, paper_height;
260 gdouble canvas_scale;
262 gdouble shadow_x, shadow_y;
264 gl_debug (DEBUG_MINI_PREVIEW, "START");
267 template = gl_template_from_name (name);
269 /* get paper size and set scale */
270 paper = gnome_print_paper_get_by_name (template->page_size);
271 paper_width = paper->width;
272 paper_height = paper->height;
273 w = preview->width - 4 - 2*SHADOW_X_OFFSET;
274 h = preview->height - 4 - 2*SHADOW_Y_OFFSET;
275 if ( (w/paper_width) > (h/paper_height) ) {
276 canvas_scale = h / paper_height;
278 canvas_scale = w / paper_width;
280 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (preview->canvas),
282 gnome_canvas_set_scroll_region (GNOME_CANVAS (preview->canvas),
283 0.0, 0.0, paper_width, paper_height);
286 shadow_x = SHADOW_X_OFFSET/canvas_scale;
287 shadow_y = SHADOW_Y_OFFSET/canvas_scale;
288 gnome_canvas_item_set (preview->shadow_item,
291 "x2", shadow_x + paper_width,
292 "y2", shadow_y + paper_height,
295 /* update paper outline */
296 gnome_canvas_item_set (preview->paper_item,
301 /* update label items */
302 mini_outline_list_free (&preview->label_items);
303 preview->label_items =
304 mini_outline_list_new (GNOME_CANVAS(preview->canvas),
307 gl_template_free( &template );
309 gl_debug (DEBUG_MINI_PREVIEW, "END");
312 /*--------------------------------------------------------------------------*/
313 /* PRIVATE. Draw label outlines and return canvas item list. */
314 /*--------------------------------------------------------------------------*/
316 mini_outline_list_new (GnomeCanvas * canvas,
317 glTemplate * template)
319 GnomeCanvasGroup *group = NULL;
320 GnomeCanvasItem *item = NULL;
323 gdouble x1, y1, x2, y2, y_temp;
324 const GnomePrintPaper *paper = NULL;
325 gdouble paper_height;
327 gl_debug (DEBUG_MINI_PREVIEW, "START");
329 /* get paper height */
330 paper = gnome_print_paper_get_by_name (template->page_size);
331 paper_height = paper->height;
333 group = gnome_canvas_root (canvas);
335 /* draw mini label outlines */
337 for (iy = (template->ny - 1); iy >= 0; iy--) {
338 for (ix = 0; ix < template->nx; ix++, i++) {
340 x1 = ix * (template->dx) + template->x0;
341 y1 = iy * (template->dy) + template->y0;
342 x2 = x1 + template->label_width;
343 y2 = y1 + template->label_height;
345 /* transform origin from lower left to upper left */
346 /* and swap y's so that (y1 < y2) */
348 y2 = paper_height - y1;
349 y1 = paper_height - y_temp;
351 switch (template->style) {
352 case GL_TEMPLATE_STYLE_RECT:
353 item = gnome_canvas_item_new (group,
354 gnome_canvas_rect_get_type(),
360 "outline_color", "black",
361 "fill_color", "white",
364 case GL_TEMPLATE_STYLE_ROUND:
365 case GL_TEMPLATE_STYLE_CD:
366 item = gnome_canvas_item_new (group,
367 gnome_canvas_ellipse_get_type(),
373 "outline_color", "black",
374 "fill_color", "white",
378 g_warning ("Unknown label style");
382 g_object_set_data (G_OBJECT (item), "i",
383 GINT_TO_POINTER (i));
385 list = g_list_append (list, item);
389 gl_debug (DEBUG_MINI_PREVIEW, "END");
393 /*--------------------------------------------------------------------------*/
394 /* PRIVATE. Draw label outlines and return canvas item list. */
395 /*--------------------------------------------------------------------------*/
397 mini_outline_list_free (GList ** list)
399 GnomeCanvasItem *item;
402 gl_debug (DEBUG_MINI_PREVIEW, "START");
404 if ( *list != NULL ) {
406 for (p = *list; p != NULL; p = p->next) {
407 item = GNOME_CANVAS_ITEM (p->data);
408 gtk_object_destroy (GTK_OBJECT (item));
416 gl_debug (DEBUG_MINI_PREVIEW, "END");
419 /*--------------------------------------------------------------------------*/
420 /* PRIVATE. Canvas event handler, select first and last items. */
421 /*--------------------------------------------------------------------------*/
423 canvas_event_cb (GnomeCanvas * canvas,
427 glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (data);
428 GnomeCanvasItem *item;
429 static gboolean dragging = FALSE;
430 static gint prev_i = 0, first, last;
434 gl_debug (DEBUG_MINI_PREVIEW, "START");
436 switch (event->type) {
438 case GDK_BUTTON_PRESS:
439 gnome_canvas_window_to_world (canvas,
440 event->button.x, event->button.y,
442 switch (event->button.button) {
444 /* Get item at cursor and make sure
445 it's a label object ("i" is valid) */
446 item = gnome_canvas_get_item_at (GNOME_CANVAS (canvas),
450 i = GPOINTER_TO_INT (g_object_get_data
451 (G_OBJECT (item), "i"));
454 /* Go into dragging mode while remains pressed. */
456 gdk_pointer_grab (GTK_WIDGET (canvas)->window,
458 GDK_POINTER_MOTION_MASK |
459 GDK_BUTTON_RELEASE_MASK |
460 GDK_BUTTON_PRESS_MASK, NULL, NULL,
462 g_signal_emit (G_OBJECT(preview),
463 wdgt_mini_preview_signals[CLICKED],
467 g_signal_emit (G_OBJECT(preview),
468 wdgt_mini_preview_signals[PRESSED],
478 case GDK_BUTTON_RELEASE:
479 gnome_canvas_window_to_world (canvas,
480 event->button.x, event->button.y,
482 switch (event->button.button) {
484 /* Exit dragging mode */
486 gdk_pointer_ungrab (event->button.time);
494 case GDK_MOTION_NOTIFY:
495 gnome_canvas_window_to_world (canvas,
496 event->motion.x, event->motion.y,
498 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
499 /* Get item at cursor and
500 make sure it's a label object ("i" is valid) */
501 item = gnome_canvas_get_item_at (GNOME_CANVAS (canvas),
505 i = GPOINTER_TO_INT (g_object_get_data
506 (G_OBJECT (item), "i"));
510 /* Entered into a new item */
512 g_signal_emit (G_OBJECT(preview),
513 wdgt_mini_preview_signals[PRESSED],
526 gl_debug (DEBUG_MINI_PREVIEW, "END");
531 /****************************************************************************/
532 /* Highlight given label outlines. */
533 /****************************************************************************/
535 gl_wdgt_mini_preview_highlight_range (glWdgtMiniPreview * preview,
539 GnomeCanvasItem *item = NULL;
543 gl_debug (DEBUG_MINI_PREVIEW, "START");
545 for (p = preview->label_items, i = 1; p != NULL; i++, p = p->next) {
547 item = GNOME_CANVAS_ITEM (p->data);
549 if ((i >= first_label) && (i <= last_label)) {
550 gnome_canvas_item_set (item,
551 "fill_color", "light blue",
554 gnome_canvas_item_set (item,
555 "fill_color", "white", NULL);
560 gl_debug (DEBUG_MINI_PREVIEW, "END");