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.
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.
32 * All fields are private and should not be used directly.
33 * Use its public methods instead.
37 #include "adg-arrow.h"
38 #include "adg-arrow-private.h"
49 static void get_property (GObject
*object
,
53 static void set_property (GObject
*object
,
57 static gboolean
render (AdgEntity
*entity
,
59 static AdgModel
* create_model (AdgMarker
*marker
);
60 static gboolean
set_angle (AdgArrow
*arrow
,
64 G_DEFINE_TYPE(AdgArrow
, adg_arrow
, ADG_TYPE_MARKER
);
68 adg_arrow_class_init(AdgArrowClass
*klass
)
70 GObjectClass
*gobject_class
;
71 AdgEntityClass
*entity_class
;
72 AdgMarkerClass
*marker_class
;
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",
90 P_("The opening angle of the arrow"),
93 g_object_class_install_property(gobject_class
, PROP_ANGLE
, param
);
97 adg_arrow_init(AdgArrow
*arrow
)
99 AdgArrowPrivate
*data
= G_TYPE_INSTANCE_GET_PRIVATE(arrow
,
103 data
->angle
= G_PI
/6;
109 get_property(GObject
*object
,
110 guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
112 AdgArrowPrivate
*data
= ((AdgArrow
*) object
)->data
;
116 g_value_set_double(value
, data
->angle
);
119 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
125 set_property(GObject
*object
,
126 guint prop_id
, const GValue
*value
, GParamSpec
*pspec
)
128 AdgArrow
*arrow
= (AdgArrow
*) object
;
132 set_angle(arrow
, g_value_get_double(value
));
135 G_OBJECT_WARN_INVALID_PROPERTY_ID(object
, prop_id
, pspec
);
142 * adg_arrow_get_angle:
143 * @arrow: an #AdgArrow
145 * Gets the current angle of @arrow.
147 * Returns: the arrow angle, in radians
150 adg_arrow_get_angle(AdgArrow
*arrow
)
152 AdgArrowPrivate
*data
;
154 g_return_val_if_fail(ADG_IS_ARROW(arrow
), 0);
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.
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");
180 render(AdgEntity
*entity
, cairo_t
*cr
)
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
);
196 cairo_set_matrix(cr
, &ctm
);
197 cairo_append_path(cr
, cairo_path
);
207 create_model(AdgMarker
*marker
)
209 AdgArrowPrivate
*data
;
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
;
226 set_angle(AdgArrow
*arrow
, gdouble angle
)
228 AdgArrowPrivate
*data
= arrow
->data
;
230 if (angle
== data
->angle
)
234 adg_entity_invalidate((AdgEntity
*) arrow
);