1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2019 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.
23 * @short_description: The ADG default logo
25 * The #AdgLogo is an entity representing the default ADG logo.
33 * All fields are private and should not be used directly.
34 * Use its public methods instead.
40 #include "adg-internal.h"
41 #include "adg-model.h"
42 #include "adg-trail.h"
44 #include "adg-dress.h"
45 #include "adg-param-dress.h"
48 #include "adg-logo-private.h"
51 G_DEFINE_TYPE_WITH_PRIVATE(AdgLogo
, adg_logo
, ADG_TYPE_ENTITY
)
61 static void _adg_get_property (GObject
*object
,
65 static void _adg_set_property (GObject
*object
,
69 static void _adg_arrange (AdgEntity
*entity
);
70 static void _adg_render (AdgEntity
*entity
,
72 static void _adg_arrange_class (AdgLogoClass
*logo_class
);
76 adg_logo_class_init(AdgLogoClass
*klass
)
78 GObjectClass
*gobject_class
;
79 AdgEntityClass
*entity_class
;
81 AdgLogoClassPrivate
*data_class
;
83 gobject_class
= (GObjectClass
*) klass
;
84 entity_class
= (AdgEntityClass
*) klass
;
86 gobject_class
->get_property
= _adg_get_property
;
87 gobject_class
->set_property
= _adg_set_property
;
89 entity_class
->arrange
= _adg_arrange
;
90 entity_class
->render
= _adg_render
;
92 param
= adg_param_spec_dress("symbol-dress",
94 P_("The line dress to use for rendering the symbol of the logo"),
97 g_object_class_install_property(gobject_class
, PROP_SYMBOL_DRESS
, param
);
99 param
= adg_param_spec_dress("screen-dress",
101 P_("The line dress to use for rendering the screen shape around the logo"),
104 g_object_class_install_property(gobject_class
, PROP_SCREEN_DRESS
, param
);
106 param
= adg_param_spec_dress("frame-dress",
108 P_("The line dress to use for rendering the frame"),
111 g_object_class_install_property(gobject_class
, PROP_FRAME_DRESS
, param
);
113 /* Initialize the private class data: the allocated struct is
114 * never freed as this type is registered statically, hence
115 * never destroyed. A better approach would be to use the old
116 * type initialization (no G_TYPE_DEFINE and friends) that
117 * allows to specify a custom class finalization method */
118 data_class
= g_new(AdgLogoClassPrivate
, 1);
120 data_class
->symbol
= NULL
;
121 data_class
->screen
= NULL
;
122 data_class
->frame
= NULL
;
123 data_class
->extents
.is_defined
= FALSE
;
125 klass
->data_class
= data_class
;
129 adg_logo_init(AdgLogo
*logo
)
131 AdgLogoPrivate
*data
= adg_logo_get_instance_private(logo
);
132 data
->symbol_dress
= ADG_DRESS_LINE
;
133 data
->screen_dress
= ADG_DRESS_LINE
;
134 data
->frame_dress
= ADG_DRESS_LINE
;
138 _adg_get_property(GObject
*object
, guint prop_id
,
139 GValue
*value
, GParamSpec
*pspec
)
141 AdgLogoPrivate
*data
= adg_logo_get_instance_private((AdgLogo
*) object
);
144 case PROP_SYMBOL_DRESS
:
145 g_value_set_enum(value
, data
->symbol_dress
);
147 case PROP_SCREEN_DRESS
:
148 g_value_set_enum(value
, data
->screen_dress
);
150 case PROP_FRAME_DRESS
:
151 g_value_set_enum(value
, data
->frame_dress
);
154 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
160 _adg_set_property(GObject
*object
, guint prop_id
,
161 const GValue
*value
, GParamSpec
*pspec
)
163 AdgLogoPrivate
*data
= adg_logo_get_instance_private((AdgLogo
*) object
);
166 case PROP_SYMBOL_DRESS
:
167 data
->symbol_dress
= g_value_get_enum(value
);
169 case PROP_SCREEN_DRESS
:
170 data
->screen_dress
= g_value_get_enum(value
);
172 case PROP_FRAME_DRESS
:
173 data
->frame_dress
= g_value_get_enum(value
);
176 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
185 * Creates a new logo entity.
187 * Returns: (transfer full): the newly created logo entity.
194 return g_object_new(ADG_TYPE_LOGO
, NULL
);
198 * adg_logo_set_symbol_dress:
200 * @dress: the new #AdgDress to use
202 * Sets a new line dress for rendering the symbol of @logo. The
203 * new dress must be a line dress: the check is done by calling
204 * adg_dress_are_related() with @dress and the old dress as
205 * arguments. Check out its documentation for further details.
207 * The default dress is a transparent line dress: the rendering
208 * callback will stroke the symbol using the default color with
209 * a predefined thickness.
214 adg_logo_set_symbol_dress(AdgLogo
*logo
, AdgDress dress
)
216 g_return_if_fail(ADG_IS_LOGO(logo
));
217 g_object_set(logo
, "symbol-dress", dress
, NULL
);
221 * adg_logo_get_symbol_dress:
224 * Gets the line dress to be used in stroking the symbol of @logo.
226 * Returns: (transfer none): the requested line dress.
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
= adg_logo_get_instance_private(logo
);
238 return data
->symbol_dress
;
242 * adg_logo_set_screen_dress:
244 * @dress: the new #AdgDress to use
246 * Sets a new line dress for rendering the screen of @logo.
247 * The new dress must be a line dress: the check is done by
248 * calling adg_dress_are_related() with @dress and the old
249 * dress as arguments. Check out its documentation for
252 * The default dress is a transparent line dress: the rendering
253 * callback will stroke the screen using the default color with
254 * a predefined thickness.
259 adg_logo_set_screen_dress(AdgLogo
*logo
, AdgDress dress
)
261 g_return_if_fail(ADG_IS_LOGO(logo
));
262 g_object_set(logo
, "screen-dress", dress
, NULL
);
266 * adg_logo_get_screen_dress:
269 * Gets the line dress to be used in stroking the screen shape of @logo.
271 * Returns: (transfer none): the requested line dress.
276 adg_logo_get_screen_dress(AdgLogo
*logo
)
278 AdgLogoPrivate
*data
;
280 g_return_val_if_fail(ADG_IS_LOGO(logo
), ADG_DRESS_UNDEFINED
);
282 data
= adg_logo_get_instance_private(logo
);
283 return data
->screen_dress
;
287 * adg_logo_set_frame_dress:
289 * @dress: the new #AdgDress to use
291 * Sets a new line dress for rendering the frame of @logo.
292 * The new dress must be a line dress: the check is done by
293 * calling adg_dress_are_related() with @dress and the old
294 * dress as arguments. Check out its documentation for
297 * The default dress is a transparent line dress: the rendering
298 * callback will stroke the frame using the default color with
299 * a predefined thickness.
304 adg_logo_set_frame_dress(AdgLogo
*logo
, AdgDress dress
)
306 g_return_if_fail(ADG_IS_LOGO(logo
));
307 g_object_set(logo
, "frame-dress", dress
, NULL
);
311 * adg_logo_get_frame_dress:
314 * Gets the line dress to be used in stroking the frame of @logo.
316 * Returns: (transfer none): the requested line dress.
321 adg_logo_get_frame_dress(AdgLogo
*logo
)
323 AdgLogoPrivate
*data
;
325 g_return_val_if_fail(ADG_IS_LOGO(logo
), ADG_DRESS_UNDEFINED
);
327 data
= adg_logo_get_instance_private(logo
);
328 return data
->frame_dress
;
333 _adg_arrange(AdgEntity
*entity
)
335 AdgLogoClass
*logo_class
;
336 AdgLogoClassPrivate
*data_class
;
339 logo_class
= ADG_LOGO_GET_CLASS(entity
);
340 data_class
= logo_class
->data_class
;
342 _adg_arrange_class(logo_class
);
343 cpml_extents_copy(&extents
, &data_class
->extents
);
345 cpml_extents_transform(&extents
, adg_entity_get_local_matrix(entity
));
346 cpml_extents_transform(&extents
, adg_entity_get_global_matrix(entity
));
347 adg_entity_set_extents(entity
, &extents
);
351 _adg_arrange_class(AdgLogoClass
*logo_class
)
353 AdgLogoClassPrivate
*data_class
;
354 CpmlExtents
*extents
;
356 data_class
= logo_class
->data_class
;
357 extents
= &data_class
->extents
;
359 if (data_class
->symbol
== NULL
) {
360 AdgPath
*path
= adg_path_new();
362 adg_path_move_to_explicit(path
, 8, 26);
363 adg_path_line_to_explicit(path
, 24, 10);
364 adg_path_arc_to_explicit(path
, 32, 18, 24, 26);
365 adg_path_line_to_explicit(path
, 24, 11);
367 adg_path_move_to_explicit(path
, 40, 10);
368 adg_path_arc_to_explicit(path
, 32, 18, 40, 26);
369 adg_path_line_to_explicit(path
, 40, 22);
370 adg_path_line_to_explicit(path
, 38, 22);
372 adg_path_move_to_explicit(path
, 23, 22);
373 adg_path_line_to_explicit(path
, 16, 22);
375 data_class
->symbol
= path
;
376 extents
->is_defined
= FALSE
;
379 if (data_class
->screen
== NULL
) {
380 AdgPath
*path
= adg_path_new();
382 adg_path_move_to_explicit(path
, 3, 3);
383 adg_path_line_to_explicit(path
, 47, 3);
384 adg_path_fillet(path
, 10);
385 adg_path_line_to_explicit(path
, 47, 33);
386 adg_path_fillet(path
, 10);
387 adg_path_line_to_explicit(path
, 3, 33);
388 adg_path_fillet(path
, 10);
389 adg_path_close(path
);
390 adg_path_fillet(path
, 10);
392 data_class
->screen
= path
;
393 extents
->is_defined
= FALSE
;
396 if (data_class
->frame
== NULL
) {
397 AdgPath
*path
= adg_path_new();
399 adg_path_move_to_explicit(path
, 0, 0);
400 adg_path_line_to_explicit(path
, 50, 0);
401 adg_path_line_to_explicit(path
, 50, 36);
402 adg_path_line_to_explicit(path
, 0, 36);
403 adg_path_close(path
);
405 data_class
->frame
= path
;
406 extents
->is_defined
= FALSE
;
409 if (!data_class
->extents
.is_defined
) {
410 cpml_extents_add(extents
,
411 adg_trail_get_extents((AdgTrail
*) data_class
->symbol
));
412 cpml_extents_add(extents
,
413 adg_trail_get_extents((AdgTrail
*) data_class
->screen
));
414 cpml_extents_add(extents
,
415 adg_trail_get_extents((AdgTrail
*) data_class
->frame
));
420 _adg_render(AdgEntity
*entity
, cairo_t
*cr
)
422 AdgLogoClassPrivate
*data_class
= ADG_LOGO_GET_CLASS(entity
)->data_class
;
423 AdgLogoPrivate
*data
= adg_logo_get_instance_private((AdgLogo
*) entity
);
424 const cairo_path_t
*cairo_path
;
426 cairo_transform(cr
, adg_entity_get_global_matrix(entity
));
427 cairo_set_line_cap(cr
, CAIRO_LINE_CAP_ROUND
);
429 cairo_path
= adg_trail_get_cairo_path((AdgTrail
*) data_class
->symbol
);
430 if (cairo_path
!= NULL
) {
432 cairo_transform(cr
, adg_entity_get_local_matrix(entity
));
433 cairo_append_path(cr
, cairo_path
);
436 cairo_set_line_width(cr
, 3);
437 adg_entity_apply_dress(entity
, data
->symbol_dress
, cr
);
442 cairo_path
= adg_trail_get_cairo_path((AdgTrail
*) data_class
->screen
);
443 if (cairo_path
!= NULL
) {
445 cairo_transform(cr
, adg_entity_get_local_matrix(entity
));
446 cairo_append_path(cr
, cairo_path
);
449 cairo_set_line_width(cr
, 2);
450 adg_entity_apply_dress(entity
, data
->screen_dress
, cr
);
455 cairo_path
= adg_trail_get_cairo_path((AdgTrail
*) data_class
->frame
);
456 if (cairo_path
!= NULL
) {
458 cairo_transform(cr
, adg_entity_get_local_matrix(entity
));
459 cairo_append_path(cr
, cairo_path
);
462 cairo_set_line_width(cr
, 2);
463 cairo_set_antialias(cr
, CAIRO_ANTIALIAS_NONE
);
464 adg_entity_apply_dress(entity
, data
->frame_dress
, cr
);