adg: inherit AdgDress from GEnum
[adg.git] / src / adg / adg-textual.c
blob71d809dc894f2473cd5c66514b3c312a287332c3
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"
61 #include "adg-textual.h"
64 enum {
65 TEXT_CHANGED,
66 LAST_SIGNAL
70 static void _adg_iface_base (AdgTextualIface *iface);
71 static gchar * _adg_dup_text (AdgTextual *textual,
72 AdgTextualIface *iface);
73 static guint _adg_signals[LAST_SIGNAL] = { 0 };
76 GType
77 adg_textual_get_type(void)
79 static GType textual_type = 0;
81 if (G_UNLIKELY(textual_type == 0)) {
82 const GTypeInfo textual_info = {
83 sizeof(AdgTextualIface),
84 (GBaseInitFunc) _adg_iface_base,
85 (GBaseFinalizeFunc) NULL,
86 (GClassInitFunc) NULL,
87 (GClassFinalizeFunc) NULL,
89 textual_type = g_type_register_static(G_TYPE_INTERFACE, "AdgTextual",
90 &textual_info, 0);
91 g_type_interface_add_prerequisite(ADG_TYPE_TEXTUAL, G_TYPE_OBJECT);
94 return textual_type;
97 static void
98 _adg_iface_base(AdgTextualIface *iface)
100 static gboolean initialized = FALSE;
101 GParamSpec *param;
103 if (G_LIKELY(initialized))
104 return;
106 initialized = TRUE;
108 param = g_param_spec_string("text",
109 P_("Text"),
110 P_("The text associated to this entity"),
111 NULL,
112 G_PARAM_READWRITE);
113 g_object_interface_install_property(iface, param);
115 param = adg_param_spec_dress("font-dress",
116 P_("Font Dress"),
117 P_("The font dress to use for rendering this text"),
118 ADG_DRESS_FONT_TEXT,
119 G_PARAM_READWRITE);
120 g_object_interface_install_property(iface, param);
123 * AdgTextual::text-changed:
124 * @textual: an entity that implements #AdgTextual
125 * @old_text: the old text
127 * Emitted whenever the text of @textual has been changed.
129 * Since: 1.0
131 _adg_signals[TEXT_CHANGED] =
132 g_signal_new("text-changed",
133 G_OBJECT_CLASS_TYPE(iface),
134 G_SIGNAL_RUN_LAST,
135 G_STRUCT_OFFSET(AdgTextualIface, text_changed),
136 NULL, NULL,
137 adg_marshal_VOID__POINTER,
138 G_TYPE_NONE, 1, G_TYPE_POINTER);
143 * adg_textual_set_font_dress:
144 * @textual: an object that implements #AdgTextual
145 * @dress: the new dress
147 * Sets the font dress of @textual to @dress.
149 * Since: 1.0
151 void
152 adg_textual_set_font_dress(AdgTextual *textual, AdgDress dress)
154 AdgTextualIface *iface;
156 g_return_if_fail(ADG_IS_TEXTUAL(textual));
158 /* The set_font_dress() method must be defined */
159 iface = ADG_TEXTUAL_GET_IFACE(textual);
160 if (iface->set_font_dress == NULL) {
161 g_warning(_("%s: `set_font_dress' method not implemented for type `%s'"),
162 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
163 return;
166 iface->set_font_dress(textual, dress);
170 * adg_textual_get_font_dress:
171 * @textual: an object that implements #AdgTextual
173 * Gets the current font dress of @textual, eventually resolved to
174 * an #AdgFontStyle before the rendering.
176 * Returns: (transfer none): the current font dress of @textual.
178 * Since: 1.0
180 AdgDress
181 adg_textual_get_font_dress(AdgTextual *textual)
183 AdgTextualIface *iface;
185 g_return_val_if_fail(ADG_IS_TEXTUAL(textual), ADG_DRESS_UNDEFINED);
187 /* The get_font_dress() method must be defined */
188 iface = ADG_TEXTUAL_GET_IFACE(textual);
189 if (iface->get_font_dress == NULL) {
190 g_warning(_("%s: `get_font_dress' method not implemented for type `%s'"),
191 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
192 return ADG_DRESS_UNDEFINED;
195 return iface->get_font_dress(textual);
199 * adg_textual_set_text:
200 * @textual: an object that implements #AdgTextual
201 * @text: the new text to be set
203 * Sets a new text on @textual. If @text is the same as the old text
204 * no actions are performed, otherwise the set_text() virtual method
205 * is called and the #AdgTextual::text-changed signal is emitted.
207 * Since: 1.0
209 void
210 adg_textual_set_text(AdgTextual *textual, const gchar *text)
212 AdgTextualIface *iface;
213 gchar *old_text;
215 g_return_if_fail(ADG_IS_TEXTUAL(textual));
217 /* The set_text() method must be defined */
218 iface = ADG_TEXTUAL_GET_IFACE(textual);
219 if (iface->set_text == NULL) {
220 g_warning(_("%s: `set_text' method not implemented for type `%s'"),
221 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
222 return;
225 old_text = _adg_dup_text(textual, iface);
226 if (g_strcmp0(text, old_text) != 0) {
227 iface->set_text(textual, text);
228 g_signal_emit(textual, _adg_signals[TEXT_CHANGED], 0, old_text);
231 g_free(old_text);
235 * adg_textual_dup_text:
236 * @textual: an object that implements #AdgTextual
238 * Gets a duplicate of the current text bound to @textual.
240 * Returns: the current text of @textual: free with g_free() when finished
242 * Since: 1.0
244 gchar *
245 adg_textual_dup_text(AdgTextual *textual)
247 g_return_val_if_fail(ADG_IS_TEXTUAL(textual), NULL);
249 return _adg_dup_text(textual, ADG_TEXTUAL_GET_IFACE(textual));
253 * adg_textual_text_changed:
254 * @textual: an object that implements #AdgTextual
255 * @old_text: the old text bound to @textual
257 * Emits the #AdgTextual::text-changed signal on @textual.
259 * <note><para>
260 * This function is only useful when creating a new class that implements
261 * the #AdgTextual interface.
262 * </para></note>
264 * Since: 1.0
266 void
267 adg_textual_text_changed(AdgTextual *textual, const gchar *old_text)
269 g_return_if_fail(ADG_IS_TEXTUAL(textual));
271 g_signal_emit(textual, _adg_signals[TEXT_CHANGED], 0, old_text);
275 static gchar *
276 _adg_dup_text(AdgTextual *textual, AdgTextualIface *iface)
278 if (iface->dup_text == NULL) {
279 g_warning(_("%s: `dup_text' method not implemented for type `%s'"),
280 G_STRLOC, g_type_name(G_OBJECT_TYPE(textual)));
281 return NULL;
284 return iface->dup_text(textual);