]> git.sur5r.net Git - glabels/blob - glabels2/src/wdgt-mini-preview.c
2004-01-06 Jim Evins <evins@snaught.com>
[glabels] / glabels2 / src / wdgt-mini-preview.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  wdgt_mini_preview.c:  mini preview widget module
5  *
6  *  Copyright (C) 2001  Jim Evins <evins@snaught.com>.
7  *
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.
12  *
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.
17  *
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
21  */
22
23 #include <config.h>
24
25 #include <math.h>
26
27 #include "wdgt-mini-preview.h"
28 #include "marshal.h"
29 #include "color.h"
30
31 #include "debug.h"
32
33 #define WDGT_MINI_PREVIEW_MAX_PIXELS 175
34 #define SHADOW_X_OFFSET 5
35 #define SHADOW_Y_OFFSET 5
36
37 #define RES 5 /* Resolution in degrees for Business Card CD outlines */
38
39 /*===========================================*/
40 /* Private types                             */
41 /*===========================================*/
42
43 enum {
44         CLICKED,
45         PRESSED,
46         LAST_SIGNAL
47 };
48
49
50 /*===========================================*/
51 /* Private globals                           */
52 /*===========================================*/
53
54 static GtkContainerClass *parent_class;
55
56 static gint wdgt_mini_preview_signals[LAST_SIGNAL] = { 0 };
57
58 /*===========================================*/
59 /* Local function prototypes                 */
60 /*===========================================*/
61
62 static void gl_wdgt_mini_preview_class_init    (glWdgtMiniPreviewClass * class);
63 static void gl_wdgt_mini_preview_instance_init (glWdgtMiniPreview * preview);
64 static void gl_wdgt_mini_preview_finalize      (GObject * object);
65
66 static void gl_wdgt_mini_preview_construct     (glWdgtMiniPreview * preview,
67                                                 gint height, gint width);
68
69 static GList *mini_outline_list_new            (GnomeCanvas      *canvas,
70                                                 const glTemplate *template);
71 static void mini_outline_list_free             (GList ** list);
72
73 static gint canvas_event_cb                    (GnomeCanvas * canvas,
74                                                 GdkEvent * event,
75                                                 gpointer data);
76
77 static GnomeCanvasItem *cdbc_item              (GnomeCanvasGroup *group,
78                                                 gdouble           x1,
79                                                 gdouble           y1,
80                                                 const glTemplate *template);
81
82 static void style_set_cb                       (GtkWidget        *widget,
83                                                 GtkStyle         *previous_style,
84                                                 gpointer data);
85
86
87
88 \f
89 /****************************************************************************/
90 /* Boilerplate Object stuff.                                                */
91 /****************************************************************************/
92 guint
93 gl_wdgt_mini_preview_get_type (void)
94 {
95         static guint wdgt_mini_preview_type = 0;
96
97         if (!wdgt_mini_preview_type) {
98                 GTypeInfo wdgt_mini_preview_info = {
99                         sizeof (glWdgtMiniPreviewClass),
100                         NULL,
101                         NULL,
102                         (GClassInitFunc) gl_wdgt_mini_preview_class_init,
103                         NULL,
104                         NULL,
105                         sizeof (glWdgtMiniPreview),
106                         0,
107                         (GInstanceInitFunc) gl_wdgt_mini_preview_instance_init,
108                 };
109
110                 wdgt_mini_preview_type =
111                         g_type_register_static (gtk_hbox_get_type (),
112                                                 "glWdgtMiniPreview",
113                                                 &wdgt_mini_preview_info, 0);
114         }
115
116         return wdgt_mini_preview_type;
117 }
118
119 static void
120 gl_wdgt_mini_preview_class_init (glWdgtMiniPreviewClass * class)
121 {
122         GObjectClass *object_class;
123
124         gl_debug (DEBUG_MINI_PREVIEW, "START");
125
126         object_class = (GObjectClass *) class;
127
128         parent_class = gtk_type_class (gtk_hbox_get_type ());
129
130         object_class->finalize = gl_wdgt_mini_preview_finalize;
131
132         wdgt_mini_preview_signals[CLICKED] =
133             g_signal_new ("clicked",
134                           G_OBJECT_CLASS_TYPE(object_class),
135                           G_SIGNAL_RUN_LAST,
136                           G_STRUCT_OFFSET (glWdgtMiniPreviewClass, clicked),
137                           NULL, NULL,
138                           gl_marshal_VOID__INT,
139                           G_TYPE_NONE, 1, G_TYPE_INT);
140
141         wdgt_mini_preview_signals[PRESSED] =
142             g_signal_new ("pressed",
143                           G_OBJECT_CLASS_TYPE(object_class),
144                           G_SIGNAL_RUN_LAST,
145                           G_STRUCT_OFFSET (glWdgtMiniPreviewClass, pressed),
146                           NULL, NULL,
147                           gl_marshal_VOID__INT_INT,
148                           G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
149
150         gl_debug (DEBUG_MINI_PREVIEW, "END");
151 }
152
153 static void
154 gl_wdgt_mini_preview_instance_init (glWdgtMiniPreview * preview)
155 {
156         gl_debug (DEBUG_MINI_PREVIEW, "START");
157
158         preview->canvas = NULL;
159         preview->label_items = NULL;
160
161         gl_debug (DEBUG_MINI_PREVIEW, "END");
162 }
163
164 static void
165 gl_wdgt_mini_preview_finalize (GObject * object)
166 {
167         glWdgtMiniPreview *preview;
168         glWdgtMiniPreviewClass *class;
169
170         gl_debug (DEBUG_MINI_PREVIEW, "START");
171
172         g_return_if_fail (object != NULL);
173         g_return_if_fail (GL_IS_WDGT_MINI_PREVIEW (object));
174
175         preview = GL_WDGT_MINI_PREVIEW (object);
176
177         G_OBJECT_CLASS (parent_class)->finalize (object);
178
179         gl_debug (DEBUG_MINI_PREVIEW, "END");
180 }
181
182 GtkWidget *
183 gl_wdgt_mini_preview_new (gint height,
184                           gint width)
185 {
186         glWdgtMiniPreview *preview;
187
188         gl_debug (DEBUG_MINI_PREVIEW, "START");
189
190         preview = g_object_new (gl_wdgt_mini_preview_get_type (), NULL);
191
192         gl_wdgt_mini_preview_construct (preview, height, width);
193
194         gl_debug (DEBUG_MINI_PREVIEW, "END");
195
196         return GTK_WIDGET (preview);
197 }
198
199 /*--------------------------------------------------------------------------*/
200 /* Construct composite widget.                                              */
201 /*--------------------------------------------------------------------------*/
202 static void
203 gl_wdgt_mini_preview_construct (glWdgtMiniPreview * preview,
204                                 gint height,
205                                 gint width)
206 {
207         GtkWidget        *whbox;
208         GnomeCanvasGroup *group;
209         GtkStyle         *style;
210         guint             shadow_color;
211
212         gl_debug (DEBUG_MINI_PREVIEW, "START");
213
214         whbox = GTK_WIDGET (preview);
215
216         preview->height = height;
217         preview->width  = width;
218
219         /* create canvas */
220         gtk_widget_push_colormap (gdk_rgb_get_colormap ());
221         preview->canvas = gnome_canvas_new_aa ();
222         gtk_widget_pop_colormap ();
223         gtk_box_pack_start (GTK_BOX (whbox), preview->canvas, TRUE, TRUE, 0);
224         gtk_widget_set_size_request (preview->canvas, width, height);
225         gnome_canvas_set_scroll_region (GNOME_CANVAS (preview->canvas),
226                                         0.0, 0.0, width, height);
227
228         gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (preview->canvas), 1.0);
229         group = gnome_canvas_root (GNOME_CANVAS (preview->canvas));
230
231         /* draw shadow */
232         style = gtk_widget_get_style (GTK_WIDGET(preview));
233         shadow_color = gl_color_from_gdk_color (&style->bg[GTK_STATE_ACTIVE]);
234         preview->shadow_item =
235                 gnome_canvas_item_new (group,
236                                        gnome_canvas_rect_get_type (),
237                                        "x1", (gdouble)SHADOW_X_OFFSET,
238                                        "y1", (gdouble)SHADOW_Y_OFFSET,
239                                        "x2", (gdouble)(SHADOW_X_OFFSET + width),
240                                        "y2", (gdouble)(SHADOW_Y_OFFSET + height),
241                                        "fill_color_rgba", shadow_color,
242                                        NULL);
243
244         /* draw an initial paper outline */
245         preview->paper_item =
246                 gnome_canvas_item_new (group,
247                                        gnome_canvas_rect_get_type (),
248                                        "x1", 0.0,
249                                        "y1", 0.0,
250                                        "x2", (gdouble)width,
251                                        "y2", (gdouble)height,
252                                        "width_pixels", 1,
253                                        "outline_color", "black",
254                                        "fill_color", "white",
255                                        NULL);
256
257         /* create empty list of label canvas items */
258         preview->label_items = NULL;
259         preview->labels_per_sheet = 0;
260
261         /* Event handler */
262         g_signal_connect (G_OBJECT (preview->canvas), "event",
263                           G_CALLBACK (canvas_event_cb), preview);
264
265
266         /* Style changed handler */
267         g_signal_connect (G_OBJECT (preview), "style_set",
268                           G_CALLBACK (style_set_cb), NULL);
269
270         gl_debug (DEBUG_MINI_PREVIEW, "END");
271 }
272
273 /****************************************************************************/
274 /* Set label for mini-preview to determine geometry.                        */
275 /****************************************************************************/
276 void gl_wdgt_mini_preview_set_label_by_name (glWdgtMiniPreview *preview,
277                                              const gchar       *name)
278 {
279         glTemplate *template;
280
281         gl_debug (DEBUG_MINI_PREVIEW, "START");
282
283         /* Fetch template */
284         template = gl_template_from_name (name);
285
286         gl_wdgt_mini_preview_set_template (preview, template);
287
288         gl_template_free (template);
289
290         gl_debug (DEBUG_MINI_PREVIEW, "END");
291 }
292
293 /****************************************************************************/
294 /* Set label for mini-preview to determine geometry.                        */
295 /****************************************************************************/
296 void gl_wdgt_mini_preview_set_template (glWdgtMiniPreview *preview,
297                                         const glTemplate  *template)
298 {
299         gchar      *page_size;
300         gdouble     canvas_scale;
301         gdouble     w, h;
302         gdouble     offset_x, offset_y;
303         gdouble     shadow_x, shadow_y;
304
305         gl_debug (DEBUG_MINI_PREVIEW, "START");
306
307         gl_debug (DEBUG_MINI_PREVIEW, "page_size = %s, page_width = %g, page_height = %g",
308                   template->page_size, template->page_width, template->page_height);
309
310         /* get paper size and set scale */
311         w = preview->width - 4 - 2*SHADOW_X_OFFSET;
312         h = preview->height - 4 - 2*SHADOW_Y_OFFSET;
313         if ( (w/template->page_width) > (h/template->page_height) ) {
314                 canvas_scale = h / template->page_height;
315         } else {
316                 canvas_scale = w / template->page_width;
317         }
318         gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (preview->canvas),
319                                           canvas_scale);
320         offset_x = (preview->width/canvas_scale - template->page_width) / 2.0;
321         offset_y = (preview->height/canvas_scale - template->page_height) / 2.0;
322
323         gnome_canvas_set_scroll_region (GNOME_CANVAS (preview->canvas),
324                                         -offset_x, -offset_y,
325                                         preview->width/canvas_scale - offset_x,
326                                         preview->height/canvas_scale - offset_y);
327
328         /* update shadow */
329         shadow_x = SHADOW_X_OFFSET/canvas_scale;
330         shadow_y = SHADOW_Y_OFFSET/canvas_scale;
331         gnome_canvas_item_set (preview->shadow_item,
332                                "x1", shadow_x,
333                                "y1", shadow_y,
334                                "x2", shadow_x + template->page_width,
335                                "y2", shadow_y + template->page_height,
336                                NULL);
337
338         /* update paper outline */
339         gnome_canvas_item_set (preview->paper_item,
340                                "x2", template->page_width,
341                                "y2", template->page_height,
342                                NULL);
343
344         /* update label items */
345         mini_outline_list_free (&preview->label_items);
346         preview->label_items =
347                 mini_outline_list_new (GNOME_CANVAS(preview->canvas),
348                                        template);
349
350         gl_debug (DEBUG_MINI_PREVIEW, "END");
351 }
352
353 /*--------------------------------------------------------------------------*/
354 /* PRIVATE.  Draw label outlines and return canvas item list.               */
355 /*--------------------------------------------------------------------------*/
356 static GList *
357 mini_outline_list_new (GnomeCanvas       *canvas,
358                        const glTemplate  *template)
359 {
360         GnomeCanvasGroup          *group = NULL;
361         const glTemplateLabelType *label_type;
362         GnomeCanvasItem           *item = NULL;
363         GList                     *list = NULL;
364         gint                       i, n_labels;
365         glTemplateOrigin          *origins;
366         gdouble                    x1, y1, x2, y2, w, h;
367
368         gl_debug (DEBUG_MINI_PREVIEW, "START");
369
370         group = gnome_canvas_root (canvas);
371
372         label_type = gl_template_get_first_label_type (template);
373
374         /* draw mini label outlines */
375         n_labels = gl_template_get_n_labels (label_type);
376         origins  = gl_template_get_origins (label_type);
377         gl_template_get_label_size (label_type, &w, &h);
378         for ( i=0; i < n_labels; i++ ) {
379
380                 x1 = origins[i].x;
381                 y1 = origins[i].y;
382                 x2 = x1 + w;
383                 y2 = y1 + h;
384
385                 switch (label_type->shape) {
386                 case GL_TEMPLATE_SHAPE_RECT:
387                         item = gnome_canvas_item_new (group,
388                                                       gnome_canvas_rect_get_type(),
389                                                       "x1", x1,
390                                                       "y1", y1,
391                                                       "x2", x2,
392                                                       "y2", y2,
393                                                       "width_pixels", 1,
394                                                       "outline_color", "black",
395                                                       "fill_color", "white",
396                                                       NULL);
397                         break;
398                 case GL_TEMPLATE_SHAPE_ROUND:
399                         item = gnome_canvas_item_new (group,
400                                                       gnome_canvas_ellipse_get_type(),
401                                                       "x1", x1,
402                                                       "y1", y1,
403                                                       "x2", x2,
404                                                       "y2", y2,
405                                                       "width_pixels", 1,
406                                                       "outline_color", "black",
407                                                       "fill_color", "white",
408                                                       NULL);
409                         break;
410                 case GL_TEMPLATE_SHAPE_CD:
411                         if ( w == h ) {
412                                 item = gnome_canvas_item_new (group,
413                                                               gnome_canvas_ellipse_get_type(),
414                                                               "x1", x1,
415                                                               "y1", y1,
416                                                               "x2", x2,
417                                                               "y2", y2,
418                                                               "width_pixels", 1,
419                                                               "outline_color", "black",
420                                                               "fill_color", "white",
421                                                               NULL);
422                         } else {
423                                 item = cdbc_item (group, x1, y1, template);
424                         }
425                         break;
426                 default:
427                         g_warning ("Unknown label style");
428                         return list;
429                         break;
430                 }
431                 g_object_set_data (G_OBJECT (item), "i",
432                                    GINT_TO_POINTER (i+1));
433                 
434                 list = g_list_append (list, item);
435         }
436
437         gl_debug (DEBUG_MINI_PREVIEW, "END");
438         return list;
439 }
440
441 /*--------------------------------------------------------------------------*/
442 /* PRIVATE.  Draw label outlines and return canvas item list.               */
443 /*--------------------------------------------------------------------------*/
444 static void
445 mini_outline_list_free (GList ** list)
446 {
447         GnomeCanvasItem *item;
448         GList *p;
449
450         gl_debug (DEBUG_MINI_PREVIEW, "START");
451
452         if ( *list != NULL ) {
453
454                 for (p = *list; p != NULL; p = p->next) {
455                         item = GNOME_CANVAS_ITEM (p->data);
456                         gtk_object_destroy (GTK_OBJECT (item));
457                 }
458
459                 g_list_free (*list);
460                 *list = NULL;
461
462         }
463
464         gl_debug (DEBUG_MINI_PREVIEW, "END");
465 }
466
467 /*--------------------------------------------------------------------------*/
468 /* PRIVATE.  Canvas event handler, select first and last items.             */
469 /*--------------------------------------------------------------------------*/
470 static gint
471 canvas_event_cb (GnomeCanvas * canvas,
472                  GdkEvent * event,
473                  gpointer data)
474 {
475         glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (data);
476         GnomeCanvasItem *item;
477         static gboolean dragging = FALSE;
478         static gint prev_i = 0, first, last;
479         gint i;
480         gdouble x, y;
481
482         gl_debug (DEBUG_MINI_PREVIEW, "START");
483
484         switch (event->type) {
485
486         case GDK_BUTTON_PRESS:
487                 gnome_canvas_window_to_world (canvas,
488                                               event->button.x, event->button.y,
489                                               &x, &y);
490                 switch (event->button.button) {
491                 case 1:
492                         /* Get item at cursor and make sure
493                            it's a label object ("i" is valid) */
494                         item = gnome_canvas_get_item_at (GNOME_CANVAS (canvas),
495                                                          x, y);
496                         if (item == NULL)
497                                 break;
498                         i = GPOINTER_TO_INT (g_object_get_data
499                                              (G_OBJECT (item), "i"));
500                         if (i == 0)
501                                 break;
502                         /* Go into dragging mode while remains pressed. */
503                         dragging = TRUE;
504                         gnome_canvas_item_grab (canvas->root,
505                                                 GDK_POINTER_MOTION_MASK |
506                                                 GDK_BUTTON_RELEASE_MASK |
507                                                 GDK_BUTTON_PRESS_MASK,
508                                                 NULL, event->button.time);
509                         g_signal_emit (G_OBJECT(preview),
510                                        wdgt_mini_preview_signals[CLICKED],
511                                        0, i);
512                         first = i;
513                         last = i;
514                         g_signal_emit (G_OBJECT(preview),
515                                        wdgt_mini_preview_signals[PRESSED],
516                                        0, first, last);
517                         prev_i = i;
518                         break;
519
520                 default:
521                         break;
522                 }
523                 break;
524
525         case GDK_BUTTON_RELEASE:
526                 gnome_canvas_window_to_world (canvas,
527                                               event->button.x, event->button.y,
528                                               &x, &y);
529                 switch (event->button.button) {
530                 case 1:
531                         /* Exit dragging mode */
532                         dragging = FALSE;
533                         gnome_canvas_item_ungrab (canvas->root, event->button.time);
534                         break;
535
536                 default:
537                         break;
538                 }
539                 break;
540
541         case GDK_MOTION_NOTIFY:
542                 gnome_canvas_window_to_world (canvas,
543                                               event->motion.x, event->motion.y,
544                                               &x, &y);
545                 if (dragging && (event->motion.state & GDK_BUTTON1_MASK)) {
546                         /* Get item at cursor and
547                            make sure it's a label object ("i" is valid) */
548                         item = gnome_canvas_get_item_at (GNOME_CANVAS (canvas),
549                                                          x, y);
550                         if (item == NULL)
551                                 break;
552                         i = GPOINTER_TO_INT (g_object_get_data
553                                              (G_OBJECT (item), "i"));
554                         if (i == 0)
555                                 break;
556                         if (prev_i != i) {
557                                 /* Entered into a new item */
558                                 last = i;
559                                 g_signal_emit (G_OBJECT(preview),
560                                                wdgt_mini_preview_signals[PRESSED],
561                                                0,
562                                                MIN (first, last),
563                                                MAX (first, last));
564                                 prev_i = i;
565                         }
566                 }
567                 break;
568
569         default:
570                 break;
571         }
572
573         gl_debug (DEBUG_MINI_PREVIEW, "END");
574
575         return FALSE;
576 }
577
578 /****************************************************************************/
579 /* Highlight given label outlines.                                          */
580 /****************************************************************************/
581 void
582 gl_wdgt_mini_preview_highlight_range (glWdgtMiniPreview *preview,
583                                       gint               first_label,
584                                       gint               last_label)
585 {
586         GtkStyle         *style;
587         guint             select_color;
588         GnomeCanvasItem  *item = NULL;
589         GList            *p = NULL;
590         gint              i;
591
592         gl_debug (DEBUG_MINI_PREVIEW, "START");
593
594         style = gtk_widget_get_style (GTK_WIDGET(preview));
595         select_color = gl_color_from_gdk_color (&style->base[GTK_STATE_SELECTED]);
596         gl_debug (DEBUG_MINI_PREVIEW, "select color = 0x%08x", select_color);
597
598         for (p = preview->label_items, i = 1; p != NULL; i++, p = p->next) {
599
600                 item = GNOME_CANVAS_ITEM (p->data);
601
602                 if ((i >= first_label) && (i <= last_label)) {
603                         gnome_canvas_item_set (item,
604                                                "fill_color_rgba", select_color,
605                                                NULL);
606                 } else {
607                         gnome_canvas_item_set (item,
608                                                "fill_color", "white", NULL);
609                 }
610
611         }
612
613         preview->highlight_first = first_label;
614         preview->highlight_last =  last_label;
615
616         gl_debug (DEBUG_MINI_PREVIEW, "END");
617 }
618
619 /*--------------------------------------------------------------------------*/
620 /* PRIVATE.  Refresh colors, if style changed.                              */
621 /*--------------------------------------------------------------------------*/
622 static void
623 style_set_cb (GtkWidget        *widget,
624               GtkStyle         *previous_style,
625               gpointer          data)
626 {
627         glWdgtMiniPreview *preview = GL_WDGT_MINI_PREVIEW (widget);
628         GtkStyle         *style;
629         guint             shadow_color;
630
631         style = gtk_widget_get_style (GTK_WIDGET(preview));
632
633         shadow_color = gl_color_from_gdk_color (&style->bg[GTK_STATE_ACTIVE]);
634         gnome_canvas_item_set (preview->shadow_item,
635                                "fill_color_rgba", shadow_color,
636                                NULL);
637
638         gl_wdgt_mini_preview_highlight_range (preview,
639                                               preview->highlight_first,
640                                               preview->highlight_last);
641 }
642
643 /*--------------------------------------------------------------------------*/
644 /* PRIVATE.  Draw CD business card item (cut-off in w and/or h).            */
645 /*--------------------------------------------------------------------------*/
646 static GnomeCanvasItem *
647 cdbc_item (GnomeCanvasGroup *group,
648            gdouble           x1,
649            gdouble           y1,
650            const glTemplate *template)
651 {
652         const glTemplateLabelType *label_type;
653         GnomeCanvasPoints         *points;
654         gint                       i_coords, i_theta;
655         gdouble                    theta1, theta2;
656         gdouble                    x0, y0, w, h, r;
657         GnomeCanvasItem           *item;
658
659         label_type = gl_template_get_first_label_type (template);
660
661         gl_template_get_label_size (label_type, &w, &h);
662         r = label_type->size.cd.r1;
663         x0 = x1 + (w/2.0);
664         y0 = y1 + (h/2.0);
665
666         theta1 = (180.0/G_PI) * acos (w / (2.0*r));
667         theta2 = (180.0/G_PI) * asin (h / (2.0*r));
668
669         points = gnome_canvas_points_new (360/RES + 1);
670         i_coords = 0;
671
672         points->coords[i_coords++] = x0 + r * cos (theta1 * G_PI / 180.0);
673         points->coords[i_coords++] = y0 + r * sin (theta1 * G_PI / 180.0);
674
675         for ( i_theta = theta1 + RES; i_theta < theta2; i_theta +=RES ) {
676                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
677                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
678         }
679
680         points->coords[i_coords++] = x0 + r * cos (theta2 * G_PI / 180.0);
681         points->coords[i_coords++] = y0 + r * sin (theta2 * G_PI / 180.0);
682
683
684         if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
685                 points->coords[i_coords++] = x0 + r * cos ((180-theta2) * G_PI / 180.0);
686                 points->coords[i_coords++] = y0 + r * sin ((180-theta2) * G_PI / 180.0);
687         }
688
689         for ( i_theta = 180-theta2+RES; i_theta < (180-theta1); i_theta +=RES ) {
690                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
691                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
692         }
693
694         points->coords[i_coords++] = x0 + r * cos ((180-theta1) * G_PI / 180.0);
695         points->coords[i_coords++] = y0 + r * sin ((180-theta1) * G_PI / 180.0);
696
697         if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
698                 points->coords[i_coords++] = x0 + r * cos ((180+theta1) * G_PI / 180.0);
699                 points->coords[i_coords++] = y0 + r * sin ((180+theta1) * G_PI / 180.0);
700         }
701
702         for ( i_theta = 180+theta1+RES; i_theta < (180+theta2); i_theta +=RES ) {
703                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
704                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
705         }
706
707         points->coords[i_coords++] = x0 + r * cos ((180+theta2) * G_PI / 180.0);
708         points->coords[i_coords++] = y0 + r * sin ((180+theta2) * G_PI / 180.0);
709
710         if ( fabs (theta2 - 90.0) > GNOME_CANVAS_EPSILON ) {
711                 points->coords[i_coords++] = x0 + r * cos ((360-theta2) * G_PI / 180.0);
712                 points->coords[i_coords++] = y0 + r * sin ((360-theta2) * G_PI / 180.0);
713         }
714
715         for ( i_theta = 360-theta2+RES; i_theta < (360-theta1); i_theta +=RES ) {
716                 points->coords[i_coords++] = x0 + r * cos (i_theta * G_PI / 180.0);
717                 points->coords[i_coords++] = y0 + r * sin (i_theta * G_PI / 180.0);
718         }
719
720         if ( fabs (theta1) > GNOME_CANVAS_EPSILON ) {
721                 points->coords[i_coords++] = x0 + r * cos ((360-theta1) * G_PI / 180.0);
722                 points->coords[i_coords++] = y0 + r * sin ((360-theta1) * G_PI / 180.0);
723         }
724
725         points->num_points = i_coords / 2;
726
727
728         item = gnome_canvas_item_new (group,
729                                       gnome_canvas_polygon_get_type (),
730                                       "points", points,
731                                       "width_pixels", 1,
732                                       "outline_color", "black",
733                                       "fill_color", "white",
734                                       NULL);
735
736         gnome_canvas_points_free (points);
737
738         return item;
739 }
740
741 /****************************************************************************/
742 /* Change/set background color of preview.                                  */
743 /****************************************************************************/
744 void
745 gl_wdgt_mini_preview_set_bg_color (glWdgtMiniPreview *preview,
746                                    guint              color)
747 {
748         GdkColor *gdk_color;
749
750         gdk_color = gl_color_to_gdk_color (color);
751         gtk_widget_modify_bg (GTK_WIDGET(preview->canvas), GTK_STATE_NORMAL, gdk_color);
752         g_free (gdk_color);
753 }
754