[ADG] Moved include dependencies from .h to .c
[adg.git] / src / adg / adg-logo.c
bloba90d9684ca59f6ead76b4b3692974af4d27e64e1
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010,2011 Nicola Fontana <ntd at entidi.it>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
21 /**
22 * SECTION:adg-logo
23 * @short_description: The ADG default logo
25 * The #AdgLogo is an entity representing the default ADG logo.
26 **/
28 /**
29 * AdgLogo:
31 * All fields are private and should not be used directly.
32 * Use its public methods instead.
33 **/
36 #include "adg-internal.h"
37 #include "adg-dress.h"
38 #include "adg-dress-builtins.h"
39 #include "adg-model.h"
40 #include "adg-trail.h"
41 #include "adg-path.h"
43 #include "adg-logo.h"
44 #include "adg-logo-private.h"
47 G_DEFINE_TYPE(AdgLogo, adg_logo, ADG_TYPE_ENTITY);
49 enum {
50 PROP_0,
51 PROP_SYMBOL_DRESS,
52 PROP_SCREEN_DRESS,
53 PROP_FRAME_DRESS
57 static void _adg_get_property (GObject *object,
58 guint param_id,
59 GValue *value,
60 GParamSpec *pspec);
61 static void _adg_set_property (GObject *object,
62 guint param_id,
63 const GValue *value,
64 GParamSpec *pspec);
65 static void _adg_arrange (AdgEntity *entity);
66 static void _adg_render (AdgEntity *entity,
67 cairo_t *cr);
68 static void _adg_arrange_class (AdgLogoClass *logo_class);
71 static void
72 adg_logo_class_init(AdgLogoClass *klass)
74 GObjectClass *gobject_class;
75 AdgEntityClass *entity_class;
76 GParamSpec *param;
77 AdgLogoClassPrivate *data_class;
79 gobject_class = (GObjectClass *) klass;
80 entity_class = (AdgEntityClass *) klass;
82 g_type_class_add_private(klass, sizeof(AdgLogoPrivate));
84 gobject_class->get_property = _adg_get_property;
85 gobject_class->set_property = _adg_set_property;
87 entity_class->arrange = _adg_arrange;
88 entity_class->render = _adg_render;
90 param = adg_param_spec_dress("symbol-dress",
91 P_("Symbol Dress"),
92 P_("The line dress to use for rendering the symbol of the logo"),
93 ADG_DRESS_LINE,
94 G_PARAM_READWRITE);
95 g_object_class_install_property(gobject_class, PROP_SYMBOL_DRESS, param);
97 param = adg_param_spec_dress("screen-dress",
98 P_("Screen Dress"),
99 P_("The line dress to use for rendering the screen shape around the logo"),
100 ADG_DRESS_LINE,
101 G_PARAM_READWRITE);
102 g_object_class_install_property(gobject_class, PROP_SCREEN_DRESS, param);
104 param = adg_param_spec_dress("frame-dress",
105 P_("Frame Dress"),
106 P_("The line dress to use for rendering the frame"),
107 ADG_DRESS_LINE,
108 G_PARAM_READWRITE);
109 g_object_class_install_property(gobject_class, PROP_FRAME_DRESS, param);
111 /* Initialize the private class data: the allocated struct is
112 * never freed as this type is registered statically, hence
113 * never destroyed. A better approach would be to use the old
114 * type initialization (no G_TYPE_DEFINE and friends) that
115 * allows to specify a custom class finalization method */
116 data_class = g_new(AdgLogoClassPrivate, 1);
118 data_class->symbol = NULL;
119 data_class->screen = NULL;
120 data_class->frame = NULL;
121 data_class->extents.is_defined = FALSE;
123 klass->data_class = data_class;
126 static void
127 adg_logo_init(AdgLogo *logo)
129 AdgLogoPrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(logo, ADG_TYPE_LOGO,
130 AdgLogoPrivate);
132 data->symbol_dress = ADG_DRESS_LINE;
133 data->screen_dress = ADG_DRESS_LINE;
134 data->frame_dress = ADG_DRESS_LINE;
136 logo->data = data;
139 static void
140 _adg_get_property(GObject *object, guint prop_id,
141 GValue *value, GParamSpec *pspec)
143 AdgLogoPrivate *data = ((AdgLogo *) object)->data;
145 switch (prop_id) {
146 case PROP_SYMBOL_DRESS:
147 g_value_set_int(value, data->symbol_dress);
148 break;
149 case PROP_SCREEN_DRESS:
150 g_value_set_int(value, data->screen_dress);
151 break;
152 case PROP_FRAME_DRESS:
153 g_value_set_int(value, data->frame_dress);
154 break;
155 default:
156 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
157 break;
161 static void
162 _adg_set_property(GObject *object, guint prop_id,
163 const GValue *value, GParamSpec *pspec)
165 AdgLogo *logo;
166 AdgLogoPrivate *data;
168 logo = (AdgLogo *) object;
169 data = logo->data;
171 switch (prop_id) {
172 case PROP_SYMBOL_DRESS:
173 data->symbol_dress = g_value_get_int(value);
174 break;
175 case PROP_SCREEN_DRESS:
176 data->screen_dress = g_value_get_int(value);
177 break;
178 case PROP_FRAME_DRESS:
179 data->frame_dress = g_value_get_int(value);
180 break;
181 default:
182 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
183 break;
189 * adg_logo_new:
191 * Creates a new logo entity.
193 * Returns: the newly created logo entity
195 AdgLogo *
196 adg_logo_new(void)
198 return g_object_new(ADG_TYPE_LOGO, NULL);
202 * adg_logo_set_symbol_dress:
203 * @logo: an #AdgLogo
204 * @dress: the new #AdgDress to use
206 * Sets a new line dress for rendering the symbol of @logo. The
207 * new dress must be a line dress: the check is done by calling
208 * adg_dress_are_related() with @dress and the old dress as
209 * arguments. Check out its documentation for further details.
211 * The default dress is a transparent line dress: the rendering
212 * callback will stroke the symbol using the default color with
213 * a predefined thickness.
215 void
216 adg_logo_set_symbol_dress(AdgLogo *logo, AdgDress dress)
218 g_return_if_fail(ADG_IS_LOGO(logo));
219 g_object_set(logo, "symbol-dress", dress, NULL);
223 * adg_logo_get_symbol_dress:
224 * @logo: an #AdgLogo
226 * Gets the line dress to be used in stroking the symbol of @logo.
228 * Returns: the requested line dress
230 AdgDress
231 adg_logo_get_symbol_dress(AdgLogo *logo)
233 AdgLogoPrivate *data;
235 g_return_val_if_fail(ADG_IS_LOGO(logo), ADG_DRESS_UNDEFINED);
237 data = logo->data;
239 return data->symbol_dress;
243 * adg_logo_set_screen_dress:
244 * @logo: an #AdgLogo
245 * @dress: the new #AdgDress to use
247 * Sets a new line dress for rendering the screen of @logo.
248 * The new dress must be a line dress: the check is done by
249 * calling adg_dress_are_related() with @dress and the old
250 * dress as arguments. Check out its documentation for
251 * further details.
253 * The default dress is a transparent line dress: the rendering
254 * callback will stroke the screen using the default color with
255 * a predefined thickness.
257 void
258 adg_logo_set_screen_dress(AdgLogo *logo, AdgDress dress)
260 g_return_if_fail(ADG_IS_LOGO(logo));
261 g_object_set(logo, "screen-dress", dress, NULL);
265 * adg_logo_get_screen_dress:
266 * @logo: an #AdgLogo
268 * Gets the line dress to be used in stroking the screen shape of @logo.
270 * Returns: the requested line dress
272 AdgDress
273 adg_logo_get_screen_dress(AdgLogo *logo)
275 AdgLogoPrivate *data;
277 g_return_val_if_fail(ADG_IS_LOGO(logo), ADG_DRESS_UNDEFINED);
279 data = logo->data;
281 return data->screen_dress;
285 * adg_logo_set_frame_dress:
286 * @logo: an #AdgLogo
287 * @dress: the new #AdgDress to use
289 * Sets a new line dress for rendering the frame of @logo.
290 * The new dress must be a line dress: the check is done by
291 * calling adg_dress_are_related() with @dress and the old
292 * dress as arguments. Check out its documentation for
293 * further details.
295 * The default dress is a transparent line dress: the rendering
296 * callback will stroke the frame using the default color with
297 * a predefined thickness.
299 void
300 adg_logo_set_frame_dress(AdgLogo *logo, AdgDress dress)
302 g_return_if_fail(ADG_IS_LOGO(logo));
303 g_object_set(logo, "frame-dress", dress, NULL);
307 * adg_logo_get_frame_dress:
308 * @logo: an #AdgLogo
310 * Gets the line dress to be used in stroking the frame of @logo.
312 * Returns: the requested line dress
314 AdgDress
315 adg_logo_get_frame_dress(AdgLogo *logo)
317 AdgLogoPrivate *data;
319 g_return_val_if_fail(ADG_IS_LOGO(logo), ADG_DRESS_UNDEFINED);
321 data = logo->data;
323 return data->frame_dress;
327 static void
328 _adg_arrange(AdgEntity *entity)
330 AdgLogoClass *logo_class;
331 AdgLogoClassPrivate *data_class;
332 CpmlExtents extents;
334 logo_class = ADG_LOGO_GET_CLASS(entity);
335 data_class = logo_class->data_class;
337 _adg_arrange_class(logo_class);
338 cpml_extents_copy(&extents, &data_class->extents);
340 cpml_extents_transform(&extents, adg_entity_get_local_matrix(entity));
341 cpml_extents_transform(&extents, adg_entity_get_global_matrix(entity));
342 adg_entity_set_extents(entity, &extents);
345 static void
346 _adg_arrange_class(AdgLogoClass *logo_class)
348 AdgLogoClassPrivate *data_class;
349 CpmlExtents *extents;
351 data_class = logo_class->data_class;
352 extents = &data_class->extents;
354 if (data_class->symbol == NULL) {
355 AdgPath *path = adg_path_new();
357 adg_path_move_to_explicit(path, 8, 26);
358 adg_path_line_to_explicit(path, 24, 10);
359 adg_path_arc_to_explicit(path, 32, 18, 24, 26);
360 adg_path_line_to_explicit(path, 24, 11);
362 adg_path_move_to_explicit(path, 40, 10);
363 adg_path_arc_to_explicit(path, 32, 18, 40, 26);
364 adg_path_line_to_explicit(path, 40, 22);
365 adg_path_line_to_explicit(path, 38, 22);
367 adg_path_move_to_explicit(path, 23, 22);
368 adg_path_line_to_explicit(path, 16, 22);
370 data_class->symbol = path;
371 extents->is_defined = FALSE;
374 if (data_class->screen == NULL) {
375 AdgPath *path = adg_path_new();
377 adg_path_move_to_explicit(path, 3, 3);
378 adg_path_line_to_explicit(path, 47, 3);
379 adg_path_fillet(path, 10);
380 adg_path_line_to_explicit(path, 47, 33);
381 adg_path_fillet(path, 10);
382 adg_path_line_to_explicit(path, 3, 33);
383 adg_path_fillet(path, 10);
384 adg_path_close(path);
385 adg_path_fillet(path, 10);
387 data_class->screen = path;
388 extents->is_defined = FALSE;
391 if (data_class->frame == NULL) {
392 AdgPath *path = adg_path_new();
394 adg_path_move_to_explicit(path, 0, 0);
395 adg_path_line_to_explicit(path, 50, 0);
396 adg_path_line_to_explicit(path, 50, 36);
397 adg_path_line_to_explicit(path, 0, 36);
398 adg_path_close(path);
400 data_class->frame = path;
401 extents->is_defined = FALSE;
404 if (!data_class->extents.is_defined) {
405 cpml_extents_add(extents,
406 adg_trail_get_extents((AdgTrail *) data_class->symbol));
407 cpml_extents_add(extents,
408 adg_trail_get_extents((AdgTrail *) data_class->screen));
409 cpml_extents_add(extents,
410 adg_trail_get_extents((AdgTrail *) data_class->frame));
414 static void
415 _adg_render(AdgEntity *entity, cairo_t *cr)
417 AdgLogoClassPrivate *data_class;
418 AdgLogoPrivate *data;
419 const cairo_path_t *cairo_path;
421 data_class = ADG_LOGO_GET_CLASS(entity)->data_class;
422 data = ((AdgLogo *) entity)->data;
424 cairo_transform(cr, adg_entity_get_global_matrix(entity));
425 cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
427 cairo_path = adg_trail_get_cairo_path((AdgTrail *) data_class->symbol);
428 if (cairo_path != NULL) {
429 cairo_save(cr);
430 cairo_transform(cr, adg_entity_get_local_matrix(entity));
431 cairo_append_path(cr, cairo_path);
432 cairo_restore(cr);
434 cairo_set_line_width(cr, 3);
435 adg_entity_apply_dress(entity, data->symbol_dress, cr);
437 cairo_stroke(cr);
440 cairo_path = adg_trail_get_cairo_path((AdgTrail *) data_class->screen);
441 if (cairo_path != NULL) {
442 cairo_save(cr);
443 cairo_transform(cr, adg_entity_get_local_matrix(entity));
444 cairo_append_path(cr, cairo_path);
445 cairo_restore(cr);
447 cairo_set_line_width(cr, 2);
448 adg_entity_apply_dress(entity, data->screen_dress, cr);
450 cairo_stroke(cr);
453 cairo_path = adg_trail_get_cairo_path((AdgTrail *) data_class->frame);
454 if (cairo_path != NULL) {
455 cairo_save(cr);
456 cairo_transform(cr, adg_entity_get_local_matrix(entity));
457 cairo_append_path(cr, cairo_path);
458 cairo_restore(cr);
460 cairo_set_line_width(cr, 2);
461 cairo_set_antialias(cr, CAIRO_ANTIALIAS_NONE);
462 adg_entity_apply_dress(entity, data->frame_dress, cr);
464 cairo_stroke(cr);