]> git.sur5r.net Git - glabels/blob - src/mini-label-preview.c
Imported Upstream version 3.0.0
[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   draw_cb                        (GtkWidget            *widget,
67                                                   cairo_t              *cr);
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->style_set    = style_set_cb;
93         widget_class->draw         = draw_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         GtkAllocation  allocation;
186
187         window = gtk_widget_get_window (GTK_WIDGET (this));
188
189         if (window)
190         {
191                 gtk_widget_get_allocation (GTK_WIDGET (this), &allocation);
192                 gdk_window_invalidate_rect (window, &allocation, FALSE);
193         }
194 }
195
196
197 /*****************************************************************************/
198 /* "Expose event" callback.                                                  */
199 /*****************************************************************************/
200 static gboolean
201 draw_cb (GtkWidget      *widget,
202          cairo_t        *cr)
203 {
204
205         draw_preview (GL_MINI_LABEL_PREVIEW (widget), cr);
206
207         return FALSE;
208 }
209
210
211 /*****************************************************************************/
212 /* Draw sample.                                                              */
213 /*****************************************************************************/
214 static void
215 draw_preview (glMiniLabelPreview *this,
216               cairo_t            *cr)
217 {
218         GtkAllocation           allocation;
219         GtkStyle               *style;
220         gdouble                 w, h;
221         guint                   fill_color, line_color, shadow_color;
222         const lglTemplateFrame *frame;
223         gdouble                 w_label, h_label;
224         gdouble                 scale;
225
226
227         gtk_widget_get_allocation (GTK_WIDGET (this), &allocation);
228         w = allocation.width;
229         h = allocation.height;
230
231
232         style = gtk_widget_get_style (GTK_WIDGET (this));
233         if ( gtk_widget_is_sensitive (GTK_WIDGET (this)) )
234         {
235                 fill_color   = gl_color_from_gdk_color (&style->light[GTK_STATE_NORMAL]);
236                 line_color   = gl_color_from_gdk_color (&style->fg[GTK_STATE_NORMAL]);
237                 shadow_color = gl_color_from_gdk_color (&style->dark[GTK_STATE_NORMAL]);
238         }
239         else
240         {
241                 fill_color   = GL_COLOR_NONE;
242                 line_color   = gl_color_from_gdk_color (&style->fg[GTK_STATE_INSENSITIVE]);
243                 shadow_color = GL_COLOR_NONE;
244         }
245
246
247         if (this->priv->template == NULL)
248         {
249                 return;
250         }
251
252         frame = (lglTemplateFrame *)this->priv->template->frames->data;
253
254         if (this->priv->rotate_flag)
255         {
256                 lgl_template_frame_get_size (frame, &h_label, &w_label);
257         }
258         else
259         {
260                 lgl_template_frame_get_size (frame, &w_label, &h_label);
261         }
262
263         scale = MIN( (w - 2*MARGIN - 2*SHADOW_OFFSET)/w_label,
264                      (h - 2*MARGIN - 2*SHADOW_OFFSET)/h_label );
265
266
267         cairo_translate (cr, w/2.0, h/2.0);
268         cairo_scale (cr, scale, scale);
269         cairo_translate (cr, -w_label/2.0, -h_label/2.0);
270
271
272         /*
273          * Shadow
274          */
275         cairo_save (cr);
276         cairo_translate (cr, SHADOW_OFFSET/scale, SHADOW_OFFSET/scale);
277         gl_cairo_label_path (cr, this->priv->template, this->priv->rotate_flag, FALSE);
278
279         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (shadow_color));
280         cairo_fill (cr);
281         cairo_restore (cr);
282
283         /*
284          * Label + outline
285          */
286         gl_cairo_label_path (cr, this->priv->template, this->priv->rotate_flag, FALSE);
287
288         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (fill_color));
289         cairo_fill_preserve (cr);
290
291         cairo_set_line_width (cr, 1.0/scale);
292         cairo_set_source_rgba (cr, GL_COLOR_RGBA_ARGS (line_color));
293         cairo_stroke (cr);
294
295 }
296
297
298
299 /*
300  * Local Variables:       -- emacs
301  * mode: C                -- emacs
302  * c-basic-offset: 8      -- emacs
303  * tab-width: 8           -- emacs
304  * indent-tabs-mode: nil  -- emacs
305  * End:                   -- emacs
306  */