1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
4 * (GLABELS) Label and Business Card Creation program for GNOME
6 * wdgt_rotate_label.c: label rotate selection widget module
8 * Copyright (C) 2001-2006 Jim Evins <evins@snaught.com>.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "wdgt-rotate-label.h"
29 #include <glib/gi18n.h>
30 #include <glade/glade-xml.h>
31 #include <gtk/gtktogglebutton.h>
32 #include <gtk/gtkcheckbutton.h>
33 #include <gtk/gtkdrawingarea.h>
38 #include <libglabels/db.h>
39 #include "cairo-label-path.h"
43 /*========================================================*/
44 /* Private macros and constants. */
45 /*========================================================*/
46 #define MINI_PREVIEW_MAX_PIXELS 48
47 #define MINI_PREVIEW_CANVAS_PIXELS (MINI_PREVIEW_MAX_PIXELS + 8)
49 #define LINE_COLOR GL_COLOR(0,0,0)
50 #define FILL_COLOR GL_COLOR(255,255,255)
52 #define LINE_WIDTH_PIXELS 1.0
54 #define SHADOW_X_OFFSET 3
55 #define SHADOW_Y_OFFSET 3
58 /*===========================================*/
60 /*===========================================*/
62 struct _glWdgtRotateLabelPrivate {
64 GtkWidget *rotate_check;
65 GtkWidget *rotate_drawingarea;
67 lglTemplate *template;
75 /*===========================================*/
77 /*===========================================*/
79 static gint wdgt_rotate_label_signals[LAST_SIGNAL] = { 0 };
81 /*===========================================*/
82 /* Local function prototypes */
83 /*===========================================*/
85 static void gl_wdgt_rotate_label_finalize (GObject *object);
87 static void gl_wdgt_rotate_label_construct (glWdgtRotateLabel *rotate_label);
89 static void entry_changed_cb (GtkToggleButton *toggle,
92 static void drawingarea_update (GtkDrawingArea *drawing_area,
93 lglTemplate *template,
94 gboolean rotate_flag);
96 static gboolean expose_cb (GtkWidget *drawingarea,
97 GdkEventExpose *event,
101 /****************************************************************************/
102 /* Boilerplate Object stuff. */
103 /****************************************************************************/
104 G_DEFINE_TYPE (glWdgtRotateLabel, gl_wdgt_rotate_label, GTK_TYPE_VBOX);
108 gl_wdgt_rotate_label_class_init (glWdgtRotateLabelClass *class)
110 GObjectClass *object_class = G_OBJECT_CLASS (class);
112 gl_wdgt_rotate_label_parent_class = g_type_class_peek_parent (class);
114 object_class->finalize = gl_wdgt_rotate_label_finalize;
116 wdgt_rotate_label_signals[CHANGED] =
117 g_signal_new ("changed",
118 G_OBJECT_CLASS_TYPE(object_class),
120 G_STRUCT_OFFSET (glWdgtRotateLabelClass, changed),
122 gl_marshal_VOID__VOID,
128 gl_wdgt_rotate_label_init (glWdgtRotateLabel *rotate_label)
130 rotate_label->priv = g_new0 (glWdgtRotateLabelPrivate, 1);
134 gl_wdgt_rotate_label_finalize (GObject *object)
136 glWdgtRotateLabel *rotate_label = GL_WDGT_ROTATE_LABEL (object);
138 g_return_if_fail (object != NULL);
139 g_return_if_fail (GL_IS_WDGT_ROTATE_LABEL (object));
141 if (rotate_label->priv->template) {
142 lgl_template_free (rotate_label->priv->template);
143 rotate_label->priv->template = NULL;
145 g_free (rotate_label->priv);
147 G_OBJECT_CLASS (gl_wdgt_rotate_label_parent_class)->finalize (object);
151 gl_wdgt_rotate_label_new (void)
153 glWdgtRotateLabel *rotate_label;
155 rotate_label = g_object_new (gl_wdgt_rotate_label_get_type (), NULL);
157 gl_wdgt_rotate_label_construct (rotate_label);
159 return GTK_WIDGET (rotate_label);
162 /*--------------------------------------------------------------------------*/
163 /* Construct composite widget. */
164 /*--------------------------------------------------------------------------*/
166 gl_wdgt_rotate_label_construct (glWdgtRotateLabel *rotate_label)
171 g_return_if_fail (GL_IS_WDGT_ROTATE_LABEL (rotate_label));
172 g_return_if_fail (rotate_label->priv != NULL);
174 gui = glade_xml_new (GLABELS_GLADE_DIR "wdgt-rotate-label.glade",
175 "rotate_hbox", NULL);
178 g_critical ("Could not open wdgt-media-select.glade. gLabels may not be installed correctly!");
182 hbox = glade_xml_get_widget (gui, "rotate_hbox");
183 gtk_container_add (GTK_CONTAINER (rotate_label), hbox);
185 rotate_label->priv->rotate_check = glade_xml_get_widget (gui, "rotate_check");
186 rotate_label->priv->rotate_drawingarea = glade_xml_get_widget (gui, "rotate_drawingarea");
188 g_object_unref (gui);
191 gtk_widget_set_size_request (rotate_label->priv->rotate_drawingarea,
192 MINI_PREVIEW_CANVAS_PIXELS,
193 MINI_PREVIEW_CANVAS_PIXELS);
195 /* Connect signals to controls */
196 g_signal_connect (G_OBJECT (rotate_label->priv->rotate_check),
198 G_CALLBACK (entry_changed_cb), rotate_label);
199 g_signal_connect (G_OBJECT (rotate_label->priv->rotate_drawingarea),
201 G_CALLBACK (expose_cb), rotate_label);
204 /*--------------------------------------------------------------------------*/
205 /* PRIVATE. modify widget due to change of check button */
206 /*--------------------------------------------------------------------------*/
208 entry_changed_cb (GtkToggleButton *toggle,
211 glWdgtRotateLabel *rotate_label = GL_WDGT_ROTATE_LABEL (user_data);
213 if (rotate_label->priv->template != NULL) {
214 /* Update mini_preview canvas & details with template */
215 drawingarea_update (GTK_DRAWING_AREA (rotate_label->priv->rotate_drawingarea),
216 rotate_label->priv->template,
217 gtk_toggle_button_get_active (toggle));
220 /* Emit our "changed" signal */
221 g_signal_emit (G_OBJECT (user_data),
222 wdgt_rotate_label_signals[CHANGED], 0);
226 /*--------------------------------------------------------------------------*/
227 /* PRIVATE. Update mini-preview from template . */
228 /*--------------------------------------------------------------------------*/
230 drawingarea_update (GtkDrawingArea *drawing_area,
231 lglTemplate *template,
232 gboolean rotate_flag)
234 const lglTemplateFrame *frame;
235 gdouble m, m_canvas, w, h, scale;
237 guint line_color, fill_color, shadow_color;
240 if (!GTK_WIDGET_DRAWABLE (GTK_WIDGET (drawing_area)))
246 gdk_window_clear (GTK_WIDGET (drawing_area)->window);
248 if (template == NULL)
253 frame = (lglTemplateFrame *)template->frames->data;
257 lgl_template_frame_get_size (frame, &h, &w);
261 lgl_template_frame_get_size (frame, &w, &h);
264 scale = MINI_PREVIEW_MAX_PIXELS / m;
265 m_canvas = MINI_PREVIEW_CANVAS_PIXELS / scale;
267 style = gtk_widget_get_style (GTK_WIDGET (drawing_area));
269 /* Adjust sensitivity (should the canvas be grayed?) */
271 line_color = LINE_COLOR;
272 fill_color = FILL_COLOR;
274 line_color = gl_color_from_gdk_color (&style->text[GTK_STATE_INSENSITIVE]);
275 fill_color = gl_color_from_gdk_color (&style->base[GTK_STATE_INSENSITIVE]);
278 shadow_color = gl_color_from_gdk_color (&style->bg[GTK_STATE_ACTIVE]);
281 cr = gdk_cairo_create (GTK_WIDGET (drawing_area)->window);
283 cairo_identity_matrix (cr);
284 cairo_translate (cr, MINI_PREVIEW_CANVAS_PIXELS/2, MINI_PREVIEW_CANVAS_PIXELS/2);
285 cairo_scale (cr, scale, scale);
286 cairo_translate (cr, -w/2.0, -h/2.0);
292 cairo_translate (cr, SHADOW_X_OFFSET/scale, SHADOW_Y_OFFSET/scale);
293 gl_cairo_label_path (cr, template, rotate_flag, FALSE);
295 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (shadow_color));
296 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
303 gl_cairo_label_path (cr, template, rotate_flag, FALSE);
305 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (fill_color));
306 cairo_set_fill_rule (cr, CAIRO_FILL_RULE_EVEN_ODD);
307 cairo_fill_preserve (cr);
309 cairo_set_line_width (cr, LINE_WIDTH_PIXELS/scale);
310 cairo_set_source_rgb (cr, GL_COLOR_RGB_ARGS (line_color));
318 /*--------------------------------------------------------------------------*/
319 /* PRIVATE. Expose handler. */
320 /*--------------------------------------------------------------------------*/
322 expose_cb (GtkWidget *drawingarea, GdkEventExpose *event, gpointer user_data)
324 glWdgtRotateLabel *rotate_label = GL_WDGT_ROTATE_LABEL (user_data);
326 drawingarea_update (GTK_DRAWING_AREA (drawingarea),
327 rotate_label->priv->template,
328 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rotate_label->priv->rotate_check)));
333 /****************************************************************************/
334 /* query state of widget. */
335 /****************************************************************************/
337 gl_wdgt_rotate_label_get_state (glWdgtRotateLabel *rotate_label)
340 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON
341 (rotate_label->priv->rotate_check));
344 /****************************************************************************/
345 /* set state of widget. */
346 /****************************************************************************/
348 gl_wdgt_rotate_label_set_state (glWdgtRotateLabel *rotate_label,
351 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
352 (rotate_label->priv->rotate_check), state);
355 /****************************************************************************/
356 /* set template for widget. */
357 /****************************************************************************/
359 gl_wdgt_rotate_label_set_template_name (glWdgtRotateLabel *rotate_label,
362 lglTemplate *template;
363 const lglTemplateFrame *frame;
364 gdouble raw_w, raw_h;
368 rotate_label->priv->template = NULL;
370 gtk_widget_set_sensitive (rotate_label->priv->rotate_check,
373 drawingarea_update (GTK_DRAWING_AREA (rotate_label->priv->rotate_drawingarea),
379 template = lgl_db_lookup_template_from_name (name);
380 frame = (lglTemplateFrame *)template->frames->data;
382 rotate_label->priv->template = template;
383 lgl_template_frame_get_size (frame, &raw_w, &raw_h);
385 gtk_widget_set_sensitive (rotate_label->priv->rotate_check,
388 drawingarea_update (GTK_DRAWING_AREA (rotate_label->priv->rotate_drawingarea),
389 rotate_label->priv->template,
392 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON
393 (rotate_label->priv->rotate_check), FALSE);