[AdgStroke] Disposing the subject AdgTrail
[adg.git] / adg / adg-stroke.c
blobed43af260325c249e79f1a3c5b75e882ba6c52a3
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-stroke
23 * @short_description: A stroked entity
25 * The #AdgStroke object is a stroked representation of an #AdgTrail model.
26 **/
28 /**
29 * AdgStroke:
31 * All fields are private and should not be used directly.
32 * Use its public methods instead.
33 **/
36 #include "adg-stroke.h"
37 #include "adg-stroke-private.h"
38 #include "adg-line-style.h"
39 #include "adg-intl.h"
41 #define PARENT_OBJECT_CLASS ((GObjectClass *) adg_stroke_parent_class)
44 enum {
45 PROP_0,
46 PROP_TRAIL
49 static void dispose (GObject *object);
50 static void get_property (GObject *object,
51 guint param_id,
52 GValue *value,
53 GParamSpec *pspec);
54 static void set_property (GObject *object,
55 guint param_id,
56 const GValue *value,
57 GParamSpec *pspec);
58 static gboolean set_trail (AdgStroke *stroke,
59 AdgTrail *trail);
60 static void unset_trail (AdgStroke *stroke);
61 static gboolean render (AdgEntity *entity,
62 cairo_t *cr);
65 G_DEFINE_TYPE(AdgStroke, adg_stroke, ADG_TYPE_ENTITY);
68 static void
69 adg_stroke_class_init(AdgStrokeClass *klass)
71 GObjectClass *gobject_class;
72 AdgEntityClass *entity_class;
73 GParamSpec *param;
75 gobject_class = (GObjectClass *) klass;
76 entity_class = (AdgEntityClass *) klass;
78 g_type_class_add_private(klass, sizeof(AdgStrokePrivate));
80 gobject_class->dispose = dispose;
81 gobject_class->get_property = get_property;
82 gobject_class->set_property = set_property;
84 entity_class->render = render;
86 param = g_param_spec_object("trail",
87 P_("Trail"),
88 P_("The trail to be stroked"),
89 ADG_TYPE_TRAIL,
90 G_PARAM_CONSTRUCT|G_PARAM_READWRITE);
91 g_object_class_install_property(gobject_class, PROP_TRAIL, param);
94 static void
95 adg_stroke_init(AdgStroke *stroke)
97 AdgStrokePrivate *data = G_TYPE_INSTANCE_GET_PRIVATE(stroke,
98 ADG_TYPE_STROKE,
99 AdgStrokePrivate);
101 data->trail = NULL;
103 stroke->data = data;
106 static void
107 dispose(GObject *object)
109 adg_stroke_set_trail((AdgStroke *) object, NULL);
111 if (PARENT_OBJECT_CLASS->dispose != NULL)
112 PARENT_OBJECT_CLASS->dispose(object);
115 static void
116 get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
118 AdgStrokePrivate *data = ((AdgStroke *) object)->data;
120 switch (prop_id) {
121 case PROP_TRAIL:
122 g_value_set_object(value, &data->trail);
123 break;
124 default:
125 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
126 break;
130 static void
131 set_property(GObject *object, guint prop_id,
132 const GValue *value, GParamSpec *pspec)
134 AdgStroke *stroke = (AdgStroke *) object;
136 switch (prop_id) {
137 case PROP_TRAIL:
138 set_trail(stroke, (AdgTrail *) g_value_get_object(value));
139 break;
140 default:
141 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
142 break;
148 * adg_stroke_new:
149 * @trail: the #AdgTrail to stroke
151 * Creates a new stroke entity.
153 * Returns: the newly created entity
155 AdgEntity *
156 adg_stroke_new(AdgTrail *trail)
158 g_return_val_if_fail(ADG_IS_TRAIL(trail), NULL);
160 return (AdgEntity *) g_object_new(ADG_TYPE_STROKE, "trail", trail, NULL);
165 * adg_stroke_get_trail:
166 * @stroke: an #AdgStroke
168 * Gets the #AdgTrail binded to this @stroke entity.
170 * Returns: the requested #AdgTrail or %NULL on errors
172 AdgTrail *
173 adg_stroke_get_trail(AdgStroke *stroke)
175 AdgStrokePrivate *data;
177 g_return_val_if_fail(ADG_IS_STROKE(stroke), NULL);
179 data = stroke->data;
181 return data->trail;
185 * adg_stroke_set_trail:
186 * @stroke: an #AdgStroke
187 * @trail: the new #AdgTrail to bind
189 * Sets @trail as the new trail to be stroked by @stroke.
191 void
192 adg_stroke_set_trail(AdgStroke *stroke, AdgTrail *trail)
194 g_return_if_fail(ADG_IS_STROKE(stroke));
196 if (set_trail(stroke, trail))
197 g_object_notify((GObject *) stroke, "trail");
201 static gboolean
202 set_trail(AdgStroke *stroke, AdgTrail *trail)
204 AdgEntity *entity;
205 AdgStrokePrivate *data;
207 entity = (AdgEntity *) stroke;
208 data = stroke->data;
210 if (trail == data->trail)
211 return FALSE;
213 if (data->trail != NULL) {
214 g_object_weak_unref((GObject *) data->trail,
215 (GWeakNotify) unset_trail, stroke);
216 adg_model_remove_dependency((AdgModel *) data->trail, entity);
219 data->trail = trail;
221 if (data->trail != NULL) {
222 g_object_weak_ref((GObject *) data->trail,
223 (GWeakNotify) unset_trail, stroke);
224 adg_model_add_dependency((AdgModel *) data->trail, entity);
227 return TRUE;
230 static void
231 unset_trail(AdgStroke *stroke)
233 AdgStrokePrivate *data = stroke->data;
235 if (data->trail != NULL) {
236 data->trail = NULL;
237 adg_entity_invalidate((AdgEntity *) stroke);
241 static gboolean
242 render(AdgEntity *entity, cairo_t *cr)
244 AdgStroke *stroke;
245 AdgStrokePrivate *data;
246 const cairo_path_t *cairo_path;
248 stroke = (AdgStroke *) entity;
249 data = stroke->data;
250 cairo_path = adg_trail_get_cairo_path(data->trail);
252 if (cairo_path != NULL) {
253 cairo_save(cr);
254 adg_entity_apply_local_matrix(entity, cr);
255 cairo_append_path(cr, cairo_path);
256 cairo_restore(cr);
258 adg_entity_apply(entity, ADG_SLOT_LINE_STYLE, cr);
259 cairo_stroke(cr);
262 return TRUE;