1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010,2011,2012,2013 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: Arrow rendering related stuff
25 * Contains parameters on how to draw arrows, providing a way to register a
26 * custom rendering callback.
29 * By default, the #AdgEntity:local-mix property is set to #ADG_MIX_PARENT
30 * on #AdgArrow entities.
39 * All fields are private and should not be used directly.
40 * Use its public methods instead.
46 #include "adg-internal.h"
47 #include "adg-model.h"
48 #include "adg-trail.h"
50 #include "adg-marker.h"
51 #include "adg-entity-private.h"
53 #include "adg-arrow.h"
54 #include "adg-arrow-private.h"
57 G_DEFINE_TYPE(AdgArrow
, adg_arrow
, ADG_TYPE_MARKER
)
65 static void _adg_get_property (GObject
*object
,
69 static void _adg_set_property (GObject
*object
,
73 static void _adg_arrange (AdgEntity
*entity
);
74 static void _adg_render (AdgEntity
*entity
,
76 static AdgModel
* _adg_create_model (AdgMarker
*marker
);
80 adg_arrow_class_init(AdgArrowClass
*klass
)
82 GObjectClass
*gobject_class
;
83 AdgEntityClass
*entity_class
;
84 AdgMarkerClass
*marker_class
;
87 gobject_class
= (GObjectClass
*) klass
;
88 entity_class
= (AdgEntityClass
*) klass
;
89 marker_class
= (AdgMarkerClass
*) klass
;
91 g_type_class_add_private(klass
, sizeof(AdgArrowPrivate
));
93 gobject_class
->set_property
= _adg_set_property
;
94 gobject_class
->get_property
= _adg_get_property
;
96 entity_class
->arrange
= _adg_arrange
;
97 entity_class
->render
= _adg_render
;
99 marker_class
->create_model
= _adg_create_model
;
101 param
= g_param_spec_double("angle",
103 P_("The opening angle of the arrow"),
104 -G_PI
, G_PI
, G_PI
/ 6,
106 g_object_class_install_property(gobject_class
, PROP_ANGLE
, param
);
110 adg_arrow_init(AdgArrow
*arrow
)
112 AdgArrowPrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(arrow
,
115 AdgEntityPrivate
*entity_data
= ((AdgEntity
*) arrow
)->data
;
117 data
->angle
= G_PI
/6;
121 /* Initialize to custom default some AdgEntity field by directly
122 * accessing the private struct to avoid notify signal emissions
124 entity_data
->local_mix
= ADG_MIX_PARENT
;
128 _adg_get_property(GObject
*object
, guint prop_id
,
129 GValue
*value
, GParamSpec
*pspec
)
131 AdgArrowPrivate
*data
= ((AdgArrow
*) object
)->data
;
135 g_value_set_double(value
, data
->angle
);
138 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
144 _adg_set_property(GObject
*object
, guint prop_id
,
145 const GValue
*value
, GParamSpec
*pspec
)
147 AdgArrowPrivate
*data
= ((AdgArrow
*) object
)->data
;
151 data
->angle
= cpml_angle(g_value_get_double(value
));
154 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
163 * Creates a new undefined arrow entity. The position must be defined
164 * by setting the #AdgMarker:trail and #AdgMarker:pos properties.
166 * Returns: the newly created arrow entity
173 return g_object_new(ADG_TYPE_ARROW
, NULL
);
177 * adg_arrow_new_with_trail:
178 * @trail: the #AdgTrail where the arrow should be added
179 * @pos: the position ratio on @trail
181 * Creates a new arrow on the first segment on @trail at position
182 * @pos, where @pos is a ratio of the @trail length (being 0 the
183 * start point, 1 the end point, 0.5 the middle point and so on).
184 * By default, an arrow as #AdgEntity:local-mix set to #ADG_MIX_PARENT.
186 * Returns: the newly created arrow entity
191 adg_arrow_new_with_trail(AdgTrail
*trail
, gdouble pos
)
193 return g_object_new(ADG_TYPE_ARROW
,
194 "local-mix", ADG_MIX_PARENT
,
202 * adg_arrow_set_angle:
203 * @arrow: an #AdgArrow
204 * @angle: the new angle
206 * Sets a new angle: @angle will be the new opening angle of @arrow.
207 * Changing the arrow angle will invalidate @arrow.
212 adg_arrow_set_angle(AdgArrow
*arrow
, gdouble angle
)
214 g_return_if_fail(ADG_IS_ARROW(arrow
));
215 g_object_set(arrow
, "angle", angle
, NULL
);
219 * adg_arrow_get_angle:
220 * @arrow: an #AdgArrow
222 * Gets the current angle of @arrow.
224 * Returns: the arrow angle, in radians
229 adg_arrow_get_angle(AdgArrow
*arrow
)
231 AdgArrowPrivate
*data
;
233 g_return_val_if_fail(ADG_IS_ARROW(arrow
), 0);
242 _adg_arrange(AdgEntity
*entity
)
245 const CpmlExtents
*extents
;
246 CpmlExtents new_extents
;
248 model
= adg_marker_model((AdgMarker
*) entity
);
252 extents
= adg_trail_get_extents((AdgTrail
*) model
);
256 cpml_extents_copy(&new_extents
, extents
);
257 cpml_extents_transform(&new_extents
, adg_entity_get_local_matrix(entity
));
258 adg_entity_set_extents(entity
, &new_extents
);
262 _adg_render(AdgEntity
*entity
, cairo_t
*cr
)
265 const cairo_path_t
*cairo_path
;
267 model
= adg_marker_model((AdgMarker
*) entity
);
271 cairo_path
= adg_trail_get_cairo_path((AdgTrail
*) model
);
273 if (cairo_path
!= NULL
) {
275 cairo_transform(cr
, adg_entity_get_global_matrix(entity
));
276 cairo_transform(cr
, adg_entity_get_local_matrix(entity
));
277 cairo_append_path(cr
, cairo_path
);
285 _adg_create_model(AdgMarker
*marker
)
287 AdgArrowPrivate
*data
;
291 data
= ((AdgArrow
*) marker
)->data
;
292 path
= adg_path_new();
293 cpml_vector_from_angle(&p1
, data
->angle
/ 2);
297 adg_path_move_to_explicit(path
, 0, 0);
298 adg_path_line_to(path
, &p1
);
299 adg_path_line_to(path
, &p2
);
300 adg_path_close(path
);
302 return (AdgModel
*) path
;