1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2021 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 base class of all styling objects
25 * This is the fundamental abstract class for styles.
33 * All fields are private and should not be used directly.
34 * Use its public methods instead.
41 * @invalidate: virtual method to reset the style.
42 * @apply: abstract virtual to apply a style to a cairo context.
44 * The default @invalidate handler does not do anything.
46 * The virtual method @apply *must* be implemented by any derived class.
47 * The default implementation will trigger an error if called.
53 #include "adg-internal.h"
55 #include "adg-style.h"
58 #define _ADG_OLD_OBJECT_CLASS ((GObjectClass *) adg_style_parent_class)
61 G_DEFINE_ABSTRACT_TYPE(AdgStyle
, adg_style
, G_TYPE_OBJECT
)
69 static void _adg_dispose (GObject
*object
);
70 static void _adg_apply (AdgStyle
*style
,
73 static guint _adg_signals
[LAST_SIGNAL
] = { 0 };
77 adg_style_class_init(AdgStyleClass
*klass
)
79 GObjectClass
*gobject_class
;
81 gobject_class
= (GObjectClass
*) klass
;
83 gobject_class
->dispose
= _adg_dispose
;
85 klass
->clone
= (AdgStyle
*(*)(AdgStyle
*)) adg_object_clone
;
86 klass
->invalidate
= NULL
;
87 klass
->apply
= _adg_apply
;
90 * AdgStyle::invalidate:
91 * @style: an #AdgStyle
93 * Invalidates the @style, that is resets all the cache, if any,
94 * retained by the internal implementation.
96 * This signal is emitted while disposing @style, so be sure it
97 * can be called more than once without harms. Furthermore it
98 * will be emitted from property setter code of new implementations
99 * to force the recomputation of the cache.
103 _adg_signals
[INVALIDATE
] =
104 g_signal_new("invalidate",
105 G_OBJECT_CLASS_TYPE(klass
),
107 G_STRUCT_OFFSET(AdgStyleClass
, invalidate
),
109 g_cclosure_marshal_VOID__VOID
,
114 * @style: an #AdgStyle
115 * @entity: the caller #AdgEntity
116 * @cr: the #cairo_t context
118 * Applies @style to @cr so the next rendering operations will be
119 * done accordling to this style directives. The @entity parameter
120 * is used to resolve the internal dresses of @style, if any.
124 _adg_signals
[APPLY
] =
125 g_signal_new("apply",
126 G_OBJECT_CLASS_TYPE(klass
),
128 G_STRUCT_OFFSET(AdgStyleClass
, apply
),
130 adg_marshal_VOID__OBJECT_POINTER
,
131 G_TYPE_NONE
, 2, ADG_TYPE_ENTITY
, G_TYPE_POINTER
);
135 adg_style_init(AdgStyle
*style
)
140 _adg_dispose(GObject
*object
)
142 g_signal_emit(object
, _adg_signals
[INVALIDATE
], 0);
144 if (_ADG_OLD_OBJECT_CLASS
->dispose
!= NULL
)
145 _ADG_OLD_OBJECT_CLASS
->dispose(object
);
150 * adg_style_invalidate:
151 * @style: an #AdgStyle derived style
153 * Emits the #AdgStyle::invalidate signal on @style. This signal
154 * is always emitted while disposing @style, so be sure it
155 * can be called more than once without harms.
158 * This function is only useful in new style implementations.
164 adg_style_invalidate(AdgStyle
*style
)
166 g_return_if_fail(ADG_IS_STYLE(style
));
168 g_signal_emit(style
, _adg_signals
[INVALIDATE
], 0);
173 * @style: (transfer none): an #AdgStyle derived style
175 * Clones @style. Useful for customizing styles.
177 * Returns: (transfer full): a newly created style.
182 adg_style_clone(AdgStyle
*style
)
184 AdgStyleClass
*klass
;
186 g_return_val_if_fail(ADG_IS_STYLE(style
), NULL
);
188 klass
= ADG_STYLE_GET_CLASS(style
);
190 if (klass
->clone
== NULL
)
193 return klass
->clone(style
);
198 * @style: an #AdgStyle derived style
199 * @entity: the caller #AdgEntity
200 * @cr: the subject cairo context
202 * Emits the #AdgStyle::apply signal on @style, passing @entity and
203 * @cr as parameters to the signal.
208 adg_style_apply(AdgStyle
*style
, AdgEntity
*entity
, cairo_t
*cr
)
210 g_return_if_fail(ADG_IS_STYLE(style
));
211 g_return_if_fail(ADG_IS_ENTITY(entity
));
212 g_return_if_fail(cr
!= NULL
);
214 g_signal_emit(style
, _adg_signals
[APPLY
], 0, entity
, cr
);
219 _adg_apply(AdgStyle
*style
, AdgEntity
*entity
, cairo_t
*cr
)
221 /* The apply method must be defined */
222 g_warning(_("%s: 'apply' method not implemented for type '%s'"),
223 G_STRLOC
, g_type_name(G_OBJECT_TYPE(style
)));