]> git.sur5r.net Git - glabels/blob - glabels2/src/wdgt-rotate-label.c
Restructured template module to ultimately support multiple layouts and markups.
[glabels] / glabels2 / src / wdgt-rotate-label.c
1 /*
2  *  (GLABELS) Label and Business Card Creation program for GNOME
3  *
4  *  wdgt_rotate_label.c:  label rotate selection widget module
5  *
6  *  Copyright (C) 2001-2002  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 "wdgt-rotate-label.h"
26 #include "template.h"
27 #include "marshal.h"
28
29 #include "debug.h"
30
31 #define MINI_PREVIEW_MAX_PIXELS 48
32
33 /*===========================================*/
34 /* Private types                             */
35 /*===========================================*/
36
37 enum {
38         CHANGED,
39         LAST_SIGNAL
40 };
41
42 typedef void (*glWdgtRotateLabelSignal) (GObject * object, gpointer data);
43
44 /*===========================================*/
45 /* Private globals                           */
46 /*===========================================*/
47
48 static GObjectClass *parent_class;
49
50 static gint wdgt_rotate_label_signals[LAST_SIGNAL] = { 0 };
51
52 /*===========================================*/
53 /* Local function prototypes                 */
54 /*===========================================*/
55
56 static void gl_wdgt_rotate_label_class_init    (glWdgtRotateLabelClass * class);
57 static void gl_wdgt_rotate_label_instance_init (glWdgtRotateLabel * rotate_select);
58 static void gl_wdgt_rotate_label_finalize      (GObject * object);
59
60 static void gl_wdgt_rotate_label_construct     (glWdgtRotateLabel * rotate_select);
61
62 static void entry_changed_cb                   (GtkToggleButton * toggle,
63                                                 gpointer user_data);
64
65 static GtkWidget *mini_preview_canvas_new      (void);
66
67 static void mini_preview_canvas_update         (GnomeCanvas * canvas,
68                                                 glTemplate * template,
69                                                 gboolean rotate_flag);
70
71 /****************************************************************************/
72 /* Boilerplate Object stuff.                                                */
73 /****************************************************************************/
74 guint
75 gl_wdgt_rotate_label_get_type (void)
76 {
77         static guint wdgt_rotate_label_type = 0;
78
79         if (!wdgt_rotate_label_type) {
80                 GTypeInfo wdgt_rotate_label_info = {
81                         sizeof (glWdgtRotateLabelClass),
82                         NULL,
83                         NULL,
84                         (GClassInitFunc) gl_wdgt_rotate_label_class_init,
85                         NULL,
86                         NULL,
87                         sizeof (glWdgtRotateLabel),
88                         0,
89                         (GInstanceInitFunc) gl_wdgt_rotate_label_instance_init,
90
91                 };
92
93                 wdgt_rotate_label_type =
94                         g_type_register_static (gtk_hbox_get_type (),
95                                                 "glWdgtRotateLabel",
96                                                 &wdgt_rotate_label_info, 0);
97         }
98
99         return wdgt_rotate_label_type;
100 }
101
102 static void
103 gl_wdgt_rotate_label_class_init (glWdgtRotateLabelClass * class)
104 {
105         GObjectClass *object_class;
106
107         object_class = (GObjectClass *) class;
108
109         parent_class = gtk_type_class (gtk_hbox_get_type ());
110
111         object_class->finalize = gl_wdgt_rotate_label_finalize;
112
113         wdgt_rotate_label_signals[CHANGED] =
114             g_signal_new ("changed",
115                           G_OBJECT_CLASS_TYPE(object_class),
116                           G_SIGNAL_RUN_LAST,
117                           G_STRUCT_OFFSET (glWdgtRotateLabelClass, changed),
118                           NULL, NULL,
119                           gl_marshal_VOID__VOID,
120                           G_TYPE_NONE, 0);
121
122 }
123
124 static void
125 gl_wdgt_rotate_label_instance_init (glWdgtRotateLabel * rotate_select)
126 {
127         rotate_select->rotate_check = NULL;
128
129         rotate_select->canvas = NULL;
130
131         rotate_select->template = NULL;
132 }
133
134 static void
135 gl_wdgt_rotate_label_finalize (GObject * object)
136 {
137         glWdgtRotateLabel *rotate_select;
138         glWdgtRotateLabelClass *class;
139
140         g_return_if_fail (object != NULL);
141         g_return_if_fail (GL_IS_WDGT_ROTATE_LABEL (object));
142
143         rotate_select = GL_WDGT_ROTATE_LABEL (object);
144
145 #if 0
146         gl_template_free (&rotate_select->template);
147 #endif
148
149         G_OBJECT_CLASS (parent_class)->finalize (object);
150 }
151
152 GtkWidget *
153 gl_wdgt_rotate_label_new (void)
154 {
155         glWdgtRotateLabel *rotate_select;
156
157         rotate_select = g_object_new (gl_wdgt_rotate_label_get_type (), NULL);
158
159         gl_wdgt_rotate_label_construct (rotate_select);
160
161         return GTK_WIDGET (rotate_select);
162 }
163
164 /*--------------------------------------------------------------------------*/
165 /* Construct composite widget.                                              */
166 /*--------------------------------------------------------------------------*/
167 static void
168 gl_wdgt_rotate_label_construct (glWdgtRotateLabel * rotate_select)
169 {
170         GtkWidget *whbox;
171
172         whbox = GTK_WIDGET (rotate_select);
173
174         /* Actual selection control */
175         rotate_select->rotate_check =
176             gtk_check_button_new_with_label (_("Rotate"));
177         gtk_box_pack_start (GTK_BOX (whbox), rotate_select->rotate_check, TRUE,
178                             TRUE, GNOME_PAD);
179
180         /* mini_preview canvas */
181         rotate_select->canvas = mini_preview_canvas_new ();
182         gtk_box_pack_start (GTK_BOX (whbox), rotate_select->canvas,
183                             TRUE, TRUE, GNOME_PAD);
184
185         /* Connect signals to controls */
186         g_signal_connect (G_OBJECT (rotate_select->rotate_check), "toggled",
187                           G_CALLBACK (entry_changed_cb), rotate_select);
188 }
189
190 /*--------------------------------------------------------------------------*/
191 /* PRIVATE.  modify widget due to change of check button                    */
192 /*--------------------------------------------------------------------------*/
193 static void
194 entry_changed_cb (GtkToggleButton * toggle,
195                   gpointer user_data)
196 {
197         glWdgtRotateLabel *rotate_select = GL_WDGT_ROTATE_LABEL (user_data);
198
199         if (rotate_select->template != NULL) {
200                 /* Update mini_preview canvas & details with template */
201                 mini_preview_canvas_update (GNOME_CANVAS
202                                             (rotate_select->canvas),
203                                             rotate_select->template,
204                                             gtk_toggle_button_get_active
205                                             (toggle));
206         }
207
208         /* Emit our "changed" signal */
209         g_signal_emit (G_OBJECT (user_data),
210                        wdgt_rotate_label_signals[CHANGED], 0);
211
212 }
213
214 /*--------------------------------------------------------------------------*/
215 /* PRIVATE.  Draw a mini-preview canvas.                                    */
216 /*--------------------------------------------------------------------------*/
217 static GtkWidget *
218 mini_preview_canvas_new (void)
219 {
220         GtkWidget *wcanvas = NULL;
221
222         /* Create a canvas */
223         gtk_widget_push_colormap (gdk_rgb_get_colormap ());
224         wcanvas = gnome_canvas_new_aa ();
225         gtk_widget_pop_colormap ();
226
227         gtk_widget_set_size_request (GTK_WIDGET (wcanvas),
228                                      MINI_PREVIEW_MAX_PIXELS + 8,
229                                      MINI_PREVIEW_MAX_PIXELS + 8);
230
231         gtk_object_set_data (GTK_OBJECT (wcanvas), "label_item", NULL);
232
233         return wcanvas;
234 }
235
236 /*--------------------------------------------------------------------------*/
237 /* PRIVATE.  Update mini-preview canvas from new template.                  */
238 /*--------------------------------------------------------------------------*/
239 static void
240 mini_preview_canvas_update (GnomeCanvas * canvas,
241                             glTemplate * template,
242                             gboolean rotate_flag)
243 {
244         gdouble canvas_scale;
245         GnomeCanvasGroup *group = NULL;
246         GnomeCanvasItem *label_item = NULL;
247         gdouble m, raw_w, raw_h, w, h;
248
249         /* Fetch our data from canvas */
250         label_item = g_object_get_data (G_OBJECT (canvas), "label_item");
251
252         gl_template_get_label_size (template, &raw_w, &raw_h);
253         m = MAX (raw_w, raw_h);
254         canvas_scale = (MINI_PREVIEW_MAX_PIXELS) / m;
255
256         /* FIXME: Stupid hack to eliminate canvas artifacts. */
257         if (rotate_flag) {
258                 canvas_scale *= 1.02;
259         }
260
261         /* scale and size canvas */
262         gnome_canvas_set_pixels_per_unit (GNOME_CANVAS (canvas), canvas_scale);
263         group = gnome_canvas_root (GNOME_CANVAS (canvas));
264         gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas),
265                                         -m / 2.0, -m / 2.0,
266                                         +m / 2.0, +m / 2.0);
267
268         /* remove old label outline */
269         if (label_item != NULL) {
270                 gtk_object_destroy (GTK_OBJECT (label_item));
271         }
272
273         /* draw mini label outline */
274         if (!rotate_flag) {
275                 w = raw_w;
276                 h = raw_h;
277         } else {
278                 w = raw_h;
279                 h = raw_w;
280         }
281         switch (template->label.style) {
282         case GL_TEMPLATE_STYLE_RECT:
283                 label_item = gnome_canvas_item_new (group,
284                                                     gnome_canvas_rect_get_type(),
285                                                     "x1", -w / 2.0,
286                                                     "y1", -h / 2.0,
287                                                     "x2", +w / 2.0,
288                                                     "y2", +h / 2.0,
289                                                     "width_pixels", 1,
290                                                     "outline_color", "black",
291                                                     "fill_color", "white",
292                                                     NULL);
293                 break;
294         case GL_TEMPLATE_STYLE_ROUND:
295         case GL_TEMPLATE_STYLE_CD:
296                 label_item = gnome_canvas_item_new (group,
297                                                     gnome_canvas_ellipse_get_type(),
298                                                     "x1", -w / 2.0,
299                                                     "y1", -h / 2.0,
300                                                     "x2", +w / 2.0,
301                                                     "y2", +h / 2.0,
302                                                     "width_pixels", 2,
303                                                     "outline_color", "black",
304                                                     "fill_color", "white",
305                                                     NULL);
306                 break;
307         default:
308                 g_warning ("Unknown label style");
309                 break;
310         }
311
312         gtk_object_set_data (GTK_OBJECT (canvas), "label_item", label_item);
313
314 }
315
316 /****************************************************************************/
317 /* query state of widget.                                                   */
318 /****************************************************************************/
319 gboolean
320 gl_wdgt_rotate_label_get_state (glWdgtRotateLabel * rotate_select)
321 {
322         return
323             gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
324                                           (rotate_select->rotate_check));
325 }
326
327 /****************************************************************************/
328 /* set state of widget.                                                     */
329 /****************************************************************************/
330 void
331 gl_wdgt_rotate_label_set_state (glWdgtRotateLabel * rotate_select,
332                                 gboolean state)
333 {
334         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
335                                       (rotate_select->rotate_check), state);
336 }
337
338 /****************************************************************************/
339 /* set template for widget.                                                 */
340 /****************************************************************************/
341 void
342 gl_wdgt_rotate_label_set_template_name (glWdgtRotateLabel * rotate_select,
343                                         gchar * name)
344 {
345         glTemplate *template;
346         gdouble raw_w, raw_h;
347
348         template = gl_template_from_name (name);
349         rotate_select->template = template;
350         gl_template_get_label_size (template, &raw_w, &raw_h);
351
352         if (raw_w != raw_h) {
353                 gtk_widget_set_sensitive (rotate_select->rotate_check, TRUE);
354         } else {
355                 gtk_widget_set_sensitive (rotate_select->rotate_check, FALSE);
356         }
357
358         mini_preview_canvas_update (GNOME_CANVAS (rotate_select->canvas),
359                                     template, FALSE);
360         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
361                                       (rotate_select->rotate_check), FALSE);
362 }