build: depends on cairo-gobject if introspection is enabled
[adg.git] / src / adg / adg-textual.c
blob08ad26b975fb2e3d40ed3d6ecd920ccfa626f607
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.
21 /**
22 * SECTION:adg-textual
23 * @Section_Id:AdgTextual
24 * @title: AdgTextual
25 * @short_description: An interface for entities that embeds text
27 * The #AdgTextual interface should be implemented by entities that
28 * can be expressed by text. #AdgToyText is a typical case but also
29 * more complex entities could implement it.
31 * Since: 1.0
32 **/
34 /**
35 * AdgTextual:
37 * Dummy type of the #AdgTextualIface interface.
39 * Since: 1.0
40 **/
42 /**
43 * AdgTextualIface:
44 * @set_font_dress: abstract virtual method to change the font dress.
45 * @get_font_dress: abstract virtual method to get the active font dress.
46 * @set_text: abstract virtual method to set a new text.
47 * @dup_text: abstract virtual method that returns a duplicate of
48 * the actual text.
49 * @text_changed: default signal handler for #AdgTextual::text-changed.
51 * The virtual methods @set_text and @dup_text must be implemented
52 * by all the types which implement this interface.
54 * Since: 1.0
55 **/
58 #include "adg-internal.h"
59 #include "adg-dress.h"
60 #include "adg-param-dress.h"
62 #include "adg-textual.h"
65 enum {
66 TEXT_CHANGED,
67 LAST_SIGNAL
71 static void _adg_iface_base (AdgTextualIface *iface);
72 static gchar * _adg_dup_text (AdgTextual *textual,
73 AdgTextualIface *iface);
74 static guint _adg_signals[LAST_SIGNAL] = { 0 };
77 GType
78 adg_textual_get_type(void)
80 static GType textual_type = 0;
82 if (G_UNLIKELY(textual_type == 0)) {
83 const GTypeInfo textual_info = {
84 sizeof(AdgTextualIface),
85 (GBaseInitFunc) _adg_iface_base,
86 (GBaseFinalizeFunc) NULL,
87 (GClassInitFunc) NULL,
88 (GClassFinalizeFunc) NULL,
90 textual_type = g_type_register_static(G_TYPE_INTERFACE, "AdgTextual",
91 &textual_info, 0);
92 g_type_interface_add_prerequisite(ADG_TYPE_TEXTUAL, G_TYPE_OBJECT);
95 return textual_type;
98 static void
99 _adg_iface_base(AdgTextualIface *iface)
101 static gboolean initialized = FALSE;
102 GParamSpec *param;
104 if (G_LIKELY(initialized))
105 return;
107 initialized = TRUE;
109 param = g_param_spec_string("text",
110 P_("Text"),
111 P_("The text associated to this entity"),
112 NULL,
113 G_PARAM_READWRITE);
114 g_object_interface_install_property(iface, param);
116 param = adg_param_spec_dress("font-dress",
117 P_("Font Dress"),
118 P_("The font dress to use for rendering this text"),
119 ADG_DRESS_FONT_TEXT,
120 G_PARAM_READWRITE);
121 g_object_interface_install_property(iface, param);
124 * AdgTextual::text-changed:
125 * @textual: an entity that implements #AdgTextual
126 * @old_text: the old text
128 * Emitted whenever the text of @textual has been changed.
130 * Since: 1.0
132 _adg_signals[TEXT_CHANGED] =
133 g_signal_new("text-changed",
134 G_OBJECT_CLASS_TYPE(iface),
135 G_SIGNAL_RUN_LAST,
136 G_STRUCT_OFFSET(AdgTextualIface, text_changed),
137 NULL, NULL,
138 adg_marshal_VOID__POINTER,
139 G_TYPE_NONE, 1, G_TYPE_POINTER);
144 * adg_textual_set_font_dress:
145 * @textual: an object that implements #AdgTextual
146 * @dress: the new dress
148 * Sets the font dress of @textual to @dress.
150 * Since: 1.0
152 void
153 adg_textual_set_font_dress(AdgTextual *textual, AdgDress dress)
155 AdgTextualIface *iface;
157 g_return_if_fail(ADG_IS_TEXTUAL(textual));
159 /* The set_font_dress() method must be defined */
160 iface = ADG_TEXTUAL_GET_IFACE(textual);
161 if (iface->set_font_dress == NULL) {
162 g_warning(_("%s: `set_font_dress' method not implemented for type `%s'"),
163 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
164 return;
167 iface->set_font_dress(textual, dress);
171 * adg_textual_get_font_dress:
172 * @textual: an object that implements #AdgTextual
174 * Gets the current font dress of @textual, eventually resolved to
175 * an #AdgFontStyle before the rendering.
177 * Returns: (transfer none): the current font dress of @textual.
179 * Since: 1.0
181 AdgDress
182 adg_textual_get_font_dress(AdgTextual *textual)
184 AdgTextualIface *iface;
186 g_return_val_if_fail(ADG_IS_TEXTUAL(textual), ADG_DRESS_UNDEFINED);
188 /* The get_font_dress() method must be defined */
189 iface = ADG_TEXTUAL_GET_IFACE(textual);
190 if (iface->get_font_dress == NULL) {
191 g_warning(_("%s: `get_font_dress' method not implemented for type `%s'"),
192 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
193 return ADG_DRESS_UNDEFINED;
196 return iface->get_font_dress(textual);
200 * adg_textual_set_text:
201 * @textual: an object that implements #AdgTextual
202 * @text: the new text to be set
204 * Sets a new text on @textual. If @text is the same as the old text
205 * no actions are performed, otherwise the set_text() virtual method
206 * is called and the #AdgTextual::text-changed signal is emitted.
208 * Since: 1.0
210 void
211 adg_textual_set_text(AdgTextual *textual, const gchar *text)
213 AdgTextualIface *iface;
214 gchar *old_text;
216 g_return_if_fail(ADG_IS_TEXTUAL(textual));
218 /* The set_text() method must be defined */
219 iface = ADG_TEXTUAL_GET_IFACE(textual);
220 if (iface->set_text == NULL) {
221 g_warning(_("%s: `set_text' method not implemented for type `%s'"),
222 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
223 return;
226 old_text = _adg_dup_text(textual, iface);
227 if (g_strcmp0(text, old_text) != 0) {
228 iface->set_text(textual, text);
229 g_signal_emit(textual, _adg_signals[TEXT_CHANGED], 0, old_text);
232 g_free(old_text);
236 * adg_textual_dup_text:
237 * @textual: an object that implements #AdgTextual
239 * Gets a duplicate of the current text bound to @textual.
241 * Returns: the current text of @textual: free with g_free() when finished
243 * Since: 1.0
245 gchar *
246 adg_textual_dup_text(AdgTextual *textual)
248 g_return_val_if_fail(ADG_IS_TEXTUAL(textual), NULL);
250 return _adg_dup_text(textual, ADG_TEXTUAL_GET_IFACE(textual));
254 * adg_textual_text_changed:
255 * @textual: an object that implements #AdgTextual
256 * @old_text: the old text bound to @textual
258 * Emits the #AdgTextual::text-changed signal on @textual.
260 * <note><para>
261 * This function is only useful when creating a new class that implements
262 * the #AdgTextual interface.
263 * </para></note>
265 * Since: 1.0
267 void
268 adg_textual_text_changed(AdgTextual *textual, const gchar *old_text)
270 g_return_if_fail(ADG_IS_TEXTUAL(textual));
272 g_signal_emit(textual, _adg_signals[TEXT_CHANGED], 0, old_text);
276 static gchar *
277 _adg_dup_text(AdgTextual *textual, AdgTextualIface *iface)
279 if (iface->dup_text == NULL) {
280 g_warning(_("%s: `dup_text' method not implemented for type `%s'"),
281 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
282 return NULL;
285 return iface->dup_text(textual);