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 /****************************************************************************/
G_DEFINE_TYPE(glMiniLabelPreview,gl_mini_label_preview,GTK_TYPE_DRAWING_AREA)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
gl_mini_label_preview_init(glMiniLabelPreview * this)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
gl_mini_label_preview_finalize(GObject * object)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 *
gl_mini_label_preview_new(gint w,gint h)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
gl_mini_label_preview_set_by_name(glMiniLabelPreview * this,gchar * name,gboolean rotate_flag)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
style_set_cb(GtkWidget * widget,GtkStyle * previous_style)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
redraw(glMiniLabelPreview * this)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
draw_cb(GtkWidget * widget,cairo_t * cr)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
draw_preview(glMiniLabelPreview * this,cairo_t * cr)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 */
307