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"
33 #define WDGT_MINI_PREVIEW_MAX_PIXELS 175
34 #define SHADOW_X_OFFSET 3
35 #define SHADOW_Y_OFFSET 3
36 #define SHADOW_COLOR GL_COLOR_A (33, 33, 33, 192)
38 /*===========================================*/
40 /*===========================================*/
49 /*===========================================*/
51 /*===========================================*/
53 static GtkContainerClass *parent_class;
55 static gint wdgt_mini_preview_signals[LAST_SIGNAL] = { 0 };
57 /*===========================================*/
58 /* Local function prototypes */
59 /*===========================================*/
61 static void gl_wdgt_mini_preview_class_init (glWdgtMiniPreviewClass * class);
62 static void gl_wdgt_mini_preview_instance_init (glWdgtMiniPreview * preview);
63 static void gl_wdgt_mini_preview_finalize (GObject * object);
65 static void gl_wdgt_mini_preview_construct (glWdgtMiniPreview * preview,
66 gint height, gint width);
68 static GList *mini_outline_list_new (GnomeCanvas *canvas,
69 glTemplate *template);
70 static void mini_outline_list_free (GList ** list);
72 static gint canvas_event_cb (GnomeCanvas * canvas,
76 /****************************************************************************/
77 /* Boilerplate Object stuff. */
78 /****************************************************************************/
80 gl_wdgt_mini_preview_get_type (void)
82 static guint wdgt_mini_preview_type = 0;
84 if (!wdgt_mini_preview_type) {
85 GTypeInfo wdgt_mini_preview_info = {
86 sizeof (glWdgtMiniPreviewClass),
89 (GClassInitFunc) gl_wdgt_mini_preview_class_init,
92 sizeof (glWdgtMiniPreview),
94 (GInstanceInitFunc) gl_wdgt_mini_preview_instance_init,
97 wdgt_mini_preview_type =
98 g_type_register_static (gtk_hbox_get_type (),
100 &wdgt_mini_preview_info, 0);
103 return wdgt_mini_preview_type;
107 gl_wdgt_mini_preview_class_init (glWdgtMiniPreviewClass * class)
109 GObjectClass *object_class;
111 gl_debug (DEBUG_MINI_PREVIEW, "START");
113 object_class = (GObjectClass *) class;
115 parent_class = gtk_type_class (gtk_hbox_get_type ());
117 object_class->finalize = gl_wdgt_mini_preview_finalize;
119 wdgt_mini_preview_signals[CLICKED] =
120 g_signal_new ("clicked",
121 G_OBJECT_CLASS_TYPE(object_class),
123 G_STRUCT_OFFSET (glWdgtMiniPreviewClass, clicked),
125 gl_marshal_VOID__INT,
126 G_TYPE_NONE, 1, G_TYPE_INT);
128 wdgt_mini_preview_signals[PRESSED] =
129 g_signal_new ("pressed",
130 G_OBJECT_CLASS_TYPE(object_class),
132 G_STRUCT_OFFSET (glWdgtMiniPreviewClass, pressed),
134 gl_marshal_VOID__INT_INT,
135 G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
137 gl_debug (DEBUG_MINI_PREVIEW, "END");
141 gl_wdgt_mini_preview_instance_init (glWdgtMiniPreview * preview)
143 gl_debug (DEBUG_MINI_PREVIEW, "START");
145 preview->canvas = NULL;
146 preview->label_items = NULL;
148 gl_debug (DEBUG_MINI_PREVIEW, "END");
152 gl_wdgt_mini_preview_finalize (GObject * object)
154 glWdgtMiniPreview *preview;
155 glWdgtMiniPreviewClass *class;
157 gl_debug (DEBUG_MINI_PREVIEW, "START");
159 g_return_if_fail (object != NULL);
160 g_return_if_fail (GL_IS_WDGT_MINI_PREVIEW (object));
162 preview = GL_WDGT_MINI_PREVIEW (object);
164 G_OBJECT_CLASS (parent_class)->finalize (object);
166 gl_debug (DEBUG_MINI_PREVIEW, "END");
170 gl_wdgt_mini_preview_new (gint height,
173 glWdgtMiniPreview *preview;
175 gl_debug (DEBUG_MINI_PREVIEW, "START");
177 preview = g_object_new (gl_wdgt_mini_preview_get_type (), NULL);
179 gl_wdgt_mini_preview_construct (preview, height, width);
181 gl_debug (DEBUG_MINI_PREVIEW, "END");
183 return GTK_WIDGET (preview);
186 /*--------------------------------------------------------------------------*/
187 /* Construct composite widget. */
188 /*--------------------------------------------------------------------------*/
190 gl_wdgt_mini_preview_construct (glWdgtMiniPreview * preview,
195 GnomeCanvasGroup *group;
197 gl_debug (DEBUG_MINI_PREVIEW, "START");
199 whbox = GTK_WIDGET (preview);
201 preview->height = height;
202 preview->width = width;
205 gtk_widget_push_colormap (gdk_rgb_get_colormap ());
206 preview->canvas = gnome_canvas_new_aa ();
207 gtk_widget_pop_colormap ();
208 gtk_box_pack_start (GTK_BOX (whbox), preview->canvas, TRUE, TRUE, 0);
209 gtk_widget_set_size_request (preview->canvas, width, height);
210 gnome_canvas_set_scroll_region (GNOME_CANVAS (preview->canvas),
211 0.0, 0.0, width, height);
213 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (preview->canvas), 1.0);
214 group = gnome_canvas_root (GNOME_CANVAS (preview->canvas));
217 preview->shadow_item =
218 gnome_canvas_item_new (group,
219 gnome_canvas_rect_get_type (),
220 "x1", (gdouble)SHADOW_X_OFFSET,
221 "y1", (gdouble)SHADOW_Y_OFFSET,
222 "x2", (gdouble)(SHADOW_X_OFFSET + width),
223 "y2", (gdouble)(SHADOW_Y_OFFSET + height),
224 "fill_color_rgba", SHADOW_COLOR,
227 /* draw an initial paper outline */
228 preview->paper_item =
229 gnome_canvas_item_new (group,
230 gnome_canvas_rect_get_type (),
233 "x2", (gdouble)width,
234 "y2", (gdouble)height,
236 "outline_color", "black",
237 "fill_color", "white",
240 /* create empty list of label canvas items */
241 preview->label_items = NULL;
242 preview->labels_per_sheet = 0;
245 g_signal_connect (G_OBJECT (preview->canvas), "event",
246 G_CALLBACK (canvas_event_cb), preview);
248 gl_debug (DEBUG_MINI_PREVIEW, "END");
251 /****************************************************************************/
252 /* Set label for mini-preview to determine geometry. */
253 /****************************************************************************/
254 void gl_wdgt_mini_preview_set_label (glWdgtMiniPreview * preview,
257 glTemplate *template;
259 const GnomePrintPaper *paper = NULL;
260 gdouble paper_width, paper_height;
261 gdouble canvas_scale;
263 gdouble shadow_x, shadow_y;
265 gl_debug (DEBUG_MINI_PREVIEW, "START");
268 template = gl_template_from_name (name);
270 /* get paper size and set scale */
271 paper = gnome_print_paper_get_by_name (template->page_size);
272 paper_width = paper->width;
273 paper_height = paper->height;
274 w = preview->width - 4 - 2*SHADOW_X_OFFSET;
275 h = preview->height - 4 - 2*SHADOW_Y_OFFSET;
276 if ( (w/paper_width) > (h/paper_height) ) {
277 canvas_scale = h / paper_height;
279 canvas_scale = w / paper_width;
281 gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (preview->canvas),
283 gnome_canvas_set_scroll_region (GNOME_CANVAS (preview->canvas),
284 0.0, 0.0, paper_width, paper_height);
287 shadow_x = SHADOW_X_OFFSET/canvas_scale;
288 shadow_y = SHADOW_Y_OFFSET/canvas_scale;
289 gnome_canvas_item_set (preview->shadow_item,
292 "x2", shadow_x + paper_width,
293 "y2", shadow_y + paper_height,
296 /* update paper outline */
297 gnome_canvas_item_set (preview->paper_item,
302 /* update label items */
303 mini_outline_list_free (&preview->label_items);
304 preview->label_items =
305 mini_outline_list_new (GNOME_CANVAS(preview->canvas),
308 gl_template_free( &template );
310 gl_debug (DEBUG_MINI_PREVIEW, "END");
313 /*--------------------------------------------------------------------------*/
314 /* PRIVATE. Draw label outlines and return canvas item list. */
315 /*--------------------------------------------------------------------------*/
317 mini_outline_list_new (GnomeCanvas *canvas,
318 glTemplate *template)
320 GnomeCanvasGroup *group = NULL;
321 GnomeCanvasItem *item = NULL;
324 glTemplateOrigin *origins;
325 gdouble x1, y1, x2, y2, y_temp, w, h;
326 const GnomePrintPaper *paper = NULL;
327 gdouble paper_height;
329 gl_debug (DEBUG_MINI_PREVIEW, "START");
331 /* get paper height */
332 paper = gnome_print_paper_get_by_name (template->page_size);
333 paper_height = paper->height;
335 group = gnome_canvas_root (canvas);
337 /* draw mini label outlines */
338 n_labels = gl_template_get_n_labels (template);
339 origins = gl_template_get_origins (template);
340 gl_template_get_label_size (template, &w, &h);
341 for ( i=0; i < n_labels; i++ ) {
348 /* transform origin from lower left to upper left */
349 /* and swap y's so that (y1 < y2) */
351 y2 = paper_height - y1;
352 y1 = paper_height - y_temp;
354 switch (template->label.style) {
355 case GL_TEMPLATE_STYLE_RECT:
356 item = gnome_canvas_item_new (group,
357 gnome_canvas_rect_get_type(),
363 "outline_color", "black",
364 "fill_color", "white",
367 case GL_TEMPLATE_STYLE_ROUND:
368 case GL_TEMPLATE_STYLE_CD:
369 item = gnome_canvas_item_new (group,
370 gnome_canvas_ellipse_get_type(),
376 "outline_color", "black",
377 "fill_color", "white",
381 g_warning ("Unknown label style");
385 g_object_set_data (G_OBJECT (item), "i",
386 GINT_TO_POINTER (i));
388 list = g_list_append (list, item);
391 gl_debug (DEBUG_MINI_PREVIEW, "END");
395 /*--------------------------------------------------------------------------*/
396 /* PRIVATE. Draw label outlines and return canvas item list. */
397 /*--------------------------------------------------------------------------*/
399 mini_outline_list_free (GList ** list)
401 GnomeCanvasItem *item;
404 gl_debug (DEBUG_MINI_PREVIEW, "START");
406 if ( *list != NULL ) {
408 for (p = *list; p != NULL; p = p->next) {
409 item = GNOME_CANVAS_ITEM (p->data);
410 gtk_object_destroy (GTK_OBJECT (item));
418 gl_debug (DEBUG_MINI_PREVIEW, "END");
421 /*--------------------------------------------------------------------------*/
422 /* PRIVATE. Canvas event handler, select first and last items. */
423 /*--------------------------------------------------------------------------*/
425 canvas_event_cb (GnomeCanvas * canvas,
429 glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (data);
430 GnomeCanvasItem *item;
431 static gboolean dragging = FALSE;
432 static gint prev_i = 0, first, last;
436 gl_debug (DEBUG_MINI_PREVIEW, "START");
438 switch (event->type) {
440 case GDK_BUTTON_PRESS:
441 gnome_canvas_window_to_world (canvas,
442 event->button.x, event->button.y,
444 switch (event->button.button) {
446 /* Get item at cursor and make sure
447 it's a label object ("i" is valid) */
448 item = gnome_canvas_get_item_at (GNOME_CANVAS (canvas),
452 i = GPOINTER_TO_INT (g_object_get_data
453 (G_OBJECT (item), "i"));
456 /* Go into dragging mode while remains pressed. */
458 gdk_pointer_grab (GTK_WIDGET (canvas)->window,
460 GDK_POINTER_MOTION_MASK |
461 GDK_BUTTON_RELEASE_MASK |
462 GDK_BUTTON_PRESS_MASK, NULL, NULL,
464 g_signal_emit (G_OBJECT(preview),
465 wdgt_mini_preview_signals[CLICKED],
469 g_signal_emit (G_OBJECT(preview),
470 wdgt_mini_preview_signals[PRESSED],
480 case GDK_BUTTON_RELEASE:
481 gnome_canvas_window_to_world (canvas,
482 event->button.x, event->button.y,
484 switch (event->button.button) {
486 /* Exit dragging mode */
488 gdk_pointer_ungrab (event->button.time);
496 case GDK_MOTION_NOTIFY:
497 gnome_canvas_window_to_world (canvas,
498 event->motion.x, event->motion.y,
500 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
501 /* Get item at cursor and
502 make sure it's a label object ("i" is valid) */
503 item = gnome_canvas_get_item_at (GNOME_CANVAS (canvas),
507 i = GPOINTER_TO_INT (g_object_get_data
508 (G_OBJECT (item), "i"));
512 /* Entered into a new item */
514 g_signal_emit (G_OBJECT(preview),
515 wdgt_mini_preview_signals[PRESSED],
528 gl_debug (DEBUG_MINI_PREVIEW, "END");
533 /****************************************************************************/
534 /* Highlight given label outlines. */
535 /****************************************************************************/
537 gl_wdgt_mini_preview_highlight_range (glWdgtMiniPreview * preview,
541 GnomeCanvasItem *item = NULL;
545 gl_debug (DEBUG_MINI_PREVIEW, "START");
547 for (p = preview->label_items, i = 1; p != NULL; i++, p = p->next) {
549 item = GNOME_CANVAS_ITEM (p->data);
551 if ((i >= first_label) && (i <= last_label)) {
552 gnome_canvas_item_set (item,
553 "fill_color", "light blue",
556 gnome_canvas_item_set (item,
557 "fill_color", "white", NULL);
562 gl_debug (DEBUG_MINI_PREVIEW, "END");