]> git.sur5r.net Git - glabels/blob - src/mini-label-preview.c
Fixed a few -Wall warnings
[glabels] / src / mini-label-preview.c
1 /*
2  *  mini-label-preview.c
3  *  Copyright (C) 2009  Jim Evins <evins@snaught.com>.
4  *
5  *  This file is part of gLabels.
6  *
7  *  gLabels is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  gLabels is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with gLabels.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22
23 #include "mini-label-preview.h"
24
25 #include <libglabels.h>
26 #include "cairo-label-path.h"
27 #include "color.h"
28 #include "marshal.h"
29
30
31 /*===========================================*/
32 /* Private macros and constants.             */
33 /*===========================================*/
34
35 #define MARGIN 2
36 #define SHADOW_OFFSET 3
37
38
39 /*===========================================*/
40 /* Private types                             */
41 /*===========================================*/
42
43 struct _glMiniLabelPreviewPrivate {
44
45         lglTemplate *template;
46         gboolean     rotate_flag;
47 };
48
49
50 /*===========================================*/
51 /* Private globals                           */
52 /*===========================================*/
53
54
55 /*===========================================*/
56 /* Local function prototypes                 */
57 /*===========================================*/
58
59 static void       gl_mini_label_preview_finalize (GObject              *object);
60
61 static void       style_set_cb                   (GtkWidget            *widget,
62                                                   GtkStyle             *previous_style);
63
64 static void       redraw                         (glMiniLabelPreview   *this);
65
66 static gboolean   expose_event_cb                (GtkWidget            *widget,
67                                                   GdkEventExpose       *event);
68
69 static void       draw_preview                   (glMiniLabelPreview   *this,
70                                                   cairo_t              *cr);
71
72
73 /****************************************************************************/
74 /* Boilerplate Object stuff.                                                */
75 /****************************************************************************/
76 G_DEFINE_TYPE (glMiniLabelPreview, gl_mini_label_preview, GTK_TYPE_DRAWING_AREA);
77
78
79 /*****************************************************************************/
80 /* Class Init Function.                                                      */
81 /*****************************************************************************/
82 static void
83 gl_mini_label_preview_class_init (glMiniLabelPreviewClass *class)
84 {
85         GObjectClass   *gobject_class = G_OBJECT_CLASS (class);
86         GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
87
88         gl_mini_label_preview_parent_class = g_type_class_peek_parent (class);
89
90         gobject_class->finalize    = gl_mini_label_preview_finalize;
91
92         widget_class->expose_event = expose_event_cb;
93         widget_class->style_set    = style_set_cb;
94 }
95
96
97 /*****************************************************************************/
98 /* Object Instance Init Function.                                            */
99 /*****************************************************************************/
100 static void
101 gl_mini_label_preview_init (glMiniLabelPreview *this)
102 {
103         gtk_widget_set_has_window (GTK_WIDGET (this), FALSE);
104
105         this->priv = g_new0 (glMiniLabelPreviewPrivate, 1);
106 }
107
108
109 /*****************************************************************************/
110 /* Finalize Method.                                                          */
111 /*****************************************************************************/
112 static void
113 gl_mini_label_preview_finalize (GObject *object)
114 {
115         glMiniLabelPreview *this = GL_MINI_LABEL_PREVIEW (object);
116
117         g_return_if_fail (object != NULL);
118         g_return_if_fail (GL_IS_MINI_LABEL_PREVIEW (object));
119
120         lgl_template_free (this->priv->template);
121         g_free (this->priv);
122
123         G_OBJECT_CLASS (gl_mini_label_preview_parent_class)->finalize (object);
124 }
125
126
127 /*****************************************************************************/
128 /** New Object Generator.                                                    */
129 /*****************************************************************************/
130 GtkWidget *
131 gl_mini_label_preview_new (gint         w,
132                            gint         h)
133 {
134         glMiniLabelPreview *this;
135
136         this = g_object_new (GL_TYPE_MINI_LABEL_PREVIEW, NULL);
137
138         gtk_widget_set_size_request (GTK_WIDGET (this), w, h);
139
140         return GTK_WIDGET (this);
141 }
142
143
144 /*****************************************************************************/
145 /* Set label by name.                                                        */
146 /*****************************************************************************/
147 void
148 gl_mini_label_preview_set_by_name (glMiniLabelPreview *this,
149                                    gchar              *name,
150                                    gboolean            rotate_flag)
151 {
152         if (!name)
153         {
154                 lgl_template_free (this->priv->template);
155                 this->priv->template = NULL;
156         }
157         else
158         {
159                 this->priv->template = lgl_db_lookup_template_from_name (name);
160                 this->priv->rotate_flag = rotate_flag;
161         }
162
163         redraw (this);
164 }
165
166
167 /*--------------------------------------------------------------------------*/
168 /* Style set handler (updates colors when style/theme changes).             */
169 /*--------------------------------------------------------------------------*/
170 static void
171 style_set_cb (GtkWidget        *widget,
172               GtkStyle         *previous_style)
173 {
174         redraw (GL_MINI_LABEL_PREVIEW (widget));
175 }
176
177
178 /*****************************************************************************/
179 /* Request redraw.                                                           */
180 /*****************************************************************************/
181 static void
182 redraw (glMiniLabelPreview  *this)
183 {
184         GdkWindow *window;
185         GdkRegion *region;
186
187         window = gtk_widget_get_window (GTK_WIDGET (this));
188
189         if (window)
190         {
191                 /* redraw the cairo canvas forcing an expose event */
192                 region = gdk_drawable_get_clip_region (window);
193                 gdk_window_invalidate_region (window, region, TRUE);
194                 gdk_region_destroy (region);
195         }
196 }
197
198
199 /*****************************************************************************/
200 /* "Expose event" callback.                                                  */
201 /*****************************************************************************/
202 static gboolean
203 expose_event_cb (GtkWidget      *widget,
204                  GdkEventExpose *event)
205 {
206         GdkWindow     *window;
207         cairo_t       *cr;
208         GtkAllocation  allocation;
209
210         window = gtk_widget_get_window (widget);
211
212         cr = gdk_cairo_create (window);
213
214         cairo_rectangle (cr,
215                         event->area.x, event->area.y,
216                         event->area.width, event->area.height);
217         cairo_clip (cr);
218
219         gtk_widget_get_allocation (widget, &allocation);
220         cairo_translate (cr, allocation.x, allocation.y);
221
222         draw_preview (GL_MINI_LABEL_PREVIEW (widget), cr);
223
224         cairo_destroy (cr);
225
226         return FALSE;
227 }
228
229
230 /*****************************************************************************/
231 /* Draw sample.                                                              */
232 /*****************************************************************************/
233 static void
234 draw_preview (glMiniLabelPreview *this,
235               cairo_t            *cr)
236 {
237         GtkAllocation           allocation;
238         GtkStyle               *style;
239         gdouble                 w, h;
240         guint                   fill_color, line_color, shadow_color;
241         const lglTemplateFrame *frame;
242         gdouble                 w_label, h_label;
243         gdouble                 scale;
244
245
246         gtk_widget_get_allocation (GTK_WIDGET (this), &allocation);
247         w = allocation.width;
248         h = allocation.height;
249
250
251         style = gtk_widget_get_style (GTK_WIDGET (this));
252         if ( gtk_widget_is_sensitive (GTK_WIDGET (this)) )
253         {
254                 fill_color   = gl_color_from_gdk_color (&style->light[GTK_STATE_NORMAL]);
255                 line_color   = gl_color_from_gdk_color (&style->fg[GTK_STATE_NORMAL]);
256                 shadow_color = gl_color_from_gdk_color (&style->dark[GTK_STATE_NORMAL]);
257         }
258         else
259         {
260                 fill_color   = GL_COLOR_NONE;
261                 line_color   = gl_color_from_gdk_color (&style->fg[GTK_STATE_INSENSITIVE]);
262                 shadow_color = GL_COLOR_NONE;
263         }
264
265
266         if (this->priv->template == NULL)
267         {
268                 return;
269         }
270
271         frame = (lglTemplateFrame *)this->priv->template->frames->data;
272
273         if (this->priv->rotate_flag)
274         {
275                 lgl_template_frame_get_size (frame, &h_label, &w_label);
276         }
277         else
278         {
279                 lgl_template_frame_get_size (frame, &w_label, &h_label);
280         }
281
282         scale = MIN( (w - 2*MARGIN - 2*SHADOW_OFFSET)/w_label,
283                      (h - 2*MARGIN - 2*SHADOW_OFFSET)/h_label );
284
285
286         cairo_translate (cr, w/2.0, h/2.0);
287         cairo_scale (cr, scale, scale);
288         cairo_translate (cr, -w_label/2.0, -h_label/2.0);
289
290
291         /*
292          * Shadow
293          */
294         cairo_save (cr);
295         cairo_translate (cr, SHADOW_OFFSET/scale, SHADOW_OFFSET/scale);
296         gl_cairo_label_path (cr, this->priv->template, this->priv->rotate_flag, FALSE);
297
298         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_color));
299         cairo_fill (cr);
300         cairo_restore (cr);
301
302         /*
303          * Label + outline
304          */
305         gl_cairo_label_path (cr, this->priv->template, this->priv->rotate_flag, FALSE);
306
307         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color));
308         cairo_fill_preserve (cr);
309
310         cairo_set_line_width (cr, 1.0/scale);
311         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color));
312         cairo_stroke (cr);
313
314 }
315
316
317
318 /*
319  * Local Variables:       -- emacs
320  * mode: C                -- emacs
321  * c-basic-offset: 8      -- emacs
322  * tab-width: 8           -- emacs
323  * indent-tabs-mode: nil  -- emacs
324  * End:                   -- emacs
325  */