[AdgArrow] Removed AdgPath cast
[adg.git] / adg / adg-arrow.c
blob4fa6631c99247a89848f2ed598787a5844bdb815
1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009 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-arrow
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.
27 **/
29 /**
30 * AdgArrow:
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
34 **/
37 #include "adg-arrow.h"
38 #include "adg-arrow-private.h"
39 #include "adg-path.h"
40 #include "adg-intl.h"
43 enum {
44 PROP_0,
45 PROP_ANGLE
49 static void get_property (GObject *object,
50 guint prop_id,
51 GValue *value,
52 GParamSpec *pspec);
53 static void set_property (GObject *object,
54 guint prop_id,
55 const GValue *value,
56 GParamSpec *pspec);
57 static gboolean render (AdgEntity *entity,
58 cairo_t *cr);
59 static AdgModel * create_model (AdgMarker *marker);
60 static gboolean set_angle (AdgArrow *arrow,
61 gdouble angle);
64 G_DEFINE_TYPE(AdgArrow, adg_arrow, ADG_TYPE_MARKER);
67 static void
68 adg_arrow_class_init(AdgArrowClass *klass)
70 GObjectClass *gobject_class;
71 AdgEntityClass *entity_class;
72 AdgMarkerClass *marker_class;
73 GParamSpec *param;
75 gobject_class = (GObjectClass *) klass;
76 entity_class = (AdgEntityClass *) klass;
77 marker_class = (AdgMarkerClass *) klass;
79 g_type_class_add_private(klass, sizeof(AdgArrowPrivate));
81 gobject_class->set_property = set_property;
82 gobject_class->get_property = get_property;
84 entity_class->render = render;
86 marker_class->create_model = create_model;
88 param = g_param_spec_double("angle",
89 P_("Arrow Angle"),
90 P_("The opening angle of the arrow"),
91 0, G_PI*2, G_PI/6,
92 G_PARAM_READWRITE);
93 g_object_class_install_property(gobject_class, PROP_ANGLE, param);
96 static void
97 adg_arrow_init(AdgArrow *arrow)
99 AdgArrowPrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(arrow,
100 ADG_TYPE_ARROW,
101 AdgArrowPrivate);
103 data->angle = G_PI/6;
105 arrow->data = data;
108 static void
109 get_property(GObject *object,
110 guint prop_id, GValue *value, GParamSpec *pspec)
112 AdgArrowPrivate *data = ((AdgArrow *) object)->data;
114 switch (prop_id) {
115 case PROP_ANGLE:
116 g_value_set_double(value, data->angle);
117 break;
118 default:
119 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
120 break;
124 static void
125 set_property(GObject *object,
126 guint prop_id, const GValue *value, GParamSpec *pspec)
128 AdgArrow *arrow = (AdgArrow *) object;
130 switch (prop_id) {
131 case PROP_ANGLE:
132 set_angle(arrow, g_value_get_double(value));
133 break;
134 default:
135 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
136 break;
142 * adg_arrow_get_angle:
143 * @arrow: an #AdgArrow
145 * Gets the current angle of @arrow.
147 * Returns: the arrow angle, in radians
149 gdouble
150 adg_arrow_get_angle(AdgArrow *arrow)
152 AdgArrowPrivate *data;
154 g_return_val_if_fail(ADG_IS_ARROW(arrow), 0);
156 data = arrow->data;
158 return data->angle;
162 * adg_arrow_set_angle:
163 * @arrow: an #AdgArrow
164 * @angle: the new angle
166 * Sets a new angle: @angle will be the new opening angle of @arrow.
167 * Changing the arrow angle will invalidate @arrow.
169 void
170 adg_arrow_set_angle(AdgArrow *arrow, gdouble angle)
172 g_return_if_fail(ADG_IS_ARROW(arrow));
174 if (set_angle(arrow, angle))
175 g_object_notify((GObject *) arrow, "angle");
179 static gboolean
180 render(AdgEntity *entity, cairo_t *cr)
182 AdgModel *model;
183 const cairo_path_t *cairo_path;
185 model = adg_marker_get_model((AdgMarker *) entity);
186 cairo_path = adg_trail_get_cairo_path((AdgTrail *) model);
188 if (cairo_path != NULL) {
189 AdgMatrix local, ctm;
191 adg_entity_get_local_matrix(entity, &local);
192 cairo_get_matrix(cr, &ctm);
193 cairo_matrix_multiply(&ctm, &ctm, &local);
195 cairo_save(cr);
196 cairo_set_matrix(cr, &ctm);
197 cairo_append_path(cr, cairo_path);
198 cairo_restore(cr);
200 cairo_fill(cr);
203 return TRUE;
206 static AdgModel *
207 create_model(AdgMarker *marker)
209 AdgArrowPrivate *data;
210 AdgPath *path;
211 CpmlVector vector;
213 data = ((AdgArrow *) marker)->data;
214 path = adg_path_new();
215 cpml_vector_from_angle(&vector, data->angle / 2, 1);
217 adg_path_move_to(path, 0, 0);
218 adg_path_line_to(path, vector.x, vector.y);
219 adg_path_line_to(path, vector.x, -vector.y);
220 adg_path_close(path);
222 return (AdgModel *) path;
225 static gboolean
226 set_angle(AdgArrow *arrow, gdouble angle)
228 AdgArrowPrivate *data = arrow->data;
230 if (angle == data->angle)
231 return FALSE;
233 data->angle = angle;
234 adg_entity_invalidate((AdgEntity *) arrow);
236 return TRUE;