[Elementary.h.in] fix vim modeline. fix indent
[framework/uifw/elementary.git] / src / lib / elm_bubble.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 /**
5  * @defgroup Bubble Bubble
6  * @ingroup Elementary
7  *
8  * The Bubble is an widget used to show a text in a frame as speech is
9  * represented in comics.
10  */
11
12 typedef struct _Widget_Data Widget_Data;
13
14 struct _Widget_Data
15 {
16    Evas_Object *bbl;
17    Evas_Object *content, *icon;
18    const char *label, *info;
19 };
20
21 static const char *widtype = NULL;
22 static void _del_hook(Evas_Object *obj);
23 static void _theme_hook(Evas_Object *obj);
24 static void _sizing_eval(Evas_Object *obj);
25 static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
26 static void _sub_del(void *data, Evas_Object *obj, void *event_info);
27
28 static void
29 _del_hook(Evas_Object *obj)
30 {
31    Widget_Data *wd = elm_widget_data_get(obj);
32    if (!wd) return;
33    if (wd->label) eina_stringshare_del(wd->label);
34    if (wd->info) eina_stringshare_del(wd->info);
35    free(wd);
36 }
37
38 static void
39 _theme_hook(Evas_Object *obj)
40 {
41    Widget_Data *wd = elm_widget_data_get(obj);
42    if (!wd) return;
43    _elm_theme_object_set(obj, wd->bbl, "bubble", "base", elm_widget_style_get(obj));
44    edje_object_part_text_set(wd->bbl, "elm.text", wd->label);
45    edje_object_part_text_set(wd->bbl, "elm.info", wd->info);
46    edje_object_scale_set(wd->bbl, elm_widget_scale_get(obj) * _elm_config->scale);
47    _sizing_eval(obj);
48 }
49
50 static void
51 _sizing_eval(Evas_Object *obj)
52 {
53    Widget_Data *wd = elm_widget_data_get(obj);
54    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
55    if (!wd) return;
56    edje_object_size_min_calc(wd->bbl, &minw, &minh);
57    evas_object_size_hint_min_set(obj, minw, minh);
58    evas_object_size_hint_max_set(obj, maxw, maxh);
59 }
60
61 static void
62 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
63 {
64    Widget_Data *wd = elm_widget_data_get(data);
65    if (!wd) return;
66    _sizing_eval(data);
67 }
68
69 static void
70 _sub_del(void *data __UNUSED__, Evas_Object *obj, void *event_info)
71 {
72    Widget_Data *wd = elm_widget_data_get(obj);
73    Evas_Object *sub = event_info;
74    if (!wd) return;
75    evas_object_event_callback_del_full(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
76                                   _changed_size_hints, obj);
77    if (sub == wd->content) wd->content = NULL;
78    else if (sub == wd->icon)
79      {
80         edje_object_signal_emit(wd->bbl, "elm,state,icon,hidden", "elm");
81         wd->icon = NULL;
82         edje_object_message_signal_process(wd->bbl);
83      }
84    _sizing_eval(obj);
85 }
86
87 /**
88  * Add a new bubble to the parent
89  *
90  * @param parent The parent object
91  * @return The new object or NULL if it cannot be created
92  *
93  * This function adds a text bubble to the given parent evas object.
94  *
95  * @ingroup Bubble
96  */
97 EAPI Evas_Object *
98 elm_bubble_add(Evas_Object *parent)
99 {
100    Evas_Object *obj;
101    Evas *e;
102    Widget_Data *wd;
103
104    wd = ELM_NEW(Widget_Data);
105    e = evas_object_evas_get(parent);
106    obj = elm_widget_add(e);
107    ELM_SET_WIDTYPE(widtype, "bubble");
108    elm_widget_type_set(obj, "bubble");
109    elm_widget_sub_object_add(parent, obj);
110    elm_widget_data_set(obj, wd);
111    elm_widget_del_hook_set(obj, _del_hook);
112    elm_widget_theme_hook_set(obj, _theme_hook);
113
114    wd->bbl = edje_object_add(e);
115    _elm_theme_object_set(obj, wd->bbl, "bubble", "base", "default");
116    elm_widget_resize_object_set(obj, wd->bbl);
117
118    evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
119
120    _sizing_eval(obj);
121    return obj;
122 }
123
124 /**
125  * Set the label of the bubble
126  *
127  * @param obj The bubble object
128  * @param label The string to set in the label
129  *
130  * This function sets the title of the bubble that is shown on top of
131  * the bubble.
132  *
133  * @ingroup Bubble
134  */
135 EAPI void
136 elm_bubble_label_set(Evas_Object *obj, const char *label)
137 {
138    ELM_CHECK_WIDTYPE(obj, widtype);
139    Widget_Data *wd = elm_widget_data_get(obj);
140    if (!wd) return;
141    if (label) edje_object_signal_emit(wd->bbl, "elm,state,label,visible", "elm");
142    else edje_object_signal_emit(wd->bbl, "elm,state,label,hidden", "elm");
143    eina_stringshare_replace(&wd->label, label);
144    edje_object_part_text_set(wd->bbl, "elm.text", label);
145    _sizing_eval(obj);
146 }
147
148 /**
149  * Get the label of the bubble
150  *
151  * @param obj The bubble object
152  * @return The string of set in the label
153  *
154  * This function gets the title of the bubble that is shown on top of
155  * the bubble.
156  *
157  * @ingroup Bubble
158  */
159 EAPI const char*
160 elm_bubble_label_get(const Evas_Object *obj)
161 {
162    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
163    Widget_Data *wd = elm_widget_data_get(obj);
164    if (!wd) return NULL;
165    return wd->label;
166 }
167
168 /**
169  * Set the info of the bubble
170  *
171  * @param obj The bubble object
172  * @param info The given info about the bubble
173  *
174  * This function sets the text shown on the top right of bubble.
175  * In the Anchorblock example of the Elementary tests application it
176  * shows time.
177  *
178  * @ingroup Bubble
179  *
180  */
181 EAPI void
182 elm_bubble_info_set(Evas_Object *obj, const char *info)
183 {
184    ELM_CHECK_WIDTYPE(obj, widtype);
185    Widget_Data *wd = elm_widget_data_get(obj);
186    if (!wd) return;
187    eina_stringshare_replace(&wd->info, info);
188    edje_object_part_text_set(wd->bbl, "elm.info", info);
189    _sizing_eval(obj);
190 }
191
192 /**
193  * Get the info of the bubble
194  *
195  * @param obj The bubble object
196  *
197  * @return The "info" string of the bubble
198  *
199  * This function gets the text set to be displayed at the top right of
200  * the bubble.
201  *
202  * @ingroup Bubble
203  *
204  */
205 EAPI const char *
206 elm_bubble_info_get(const Evas_Object *obj)
207 {
208    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
209    Widget_Data *wd = elm_widget_data_get(obj);
210    if (!wd) return NULL;
211    return wd->info;
212 }
213
214 /**
215  * Set the content to be shown in the bubble
216  *
217  * Once the content object is set, a previously set one will be deleted.
218  * If you want to keep the old content object, use the
219  * elm_bubble_content_unset() function.
220  *
221  * @param obj The bubble object
222  * @param content The given content of the bubble
223  *
224  * This function sets the content shown on the middle of the bubble.
225  * In the Anchorblock example of the Elementary tests application it
226  * shows time.
227  *
228  * @ingroup Bubble
229  */
230 EAPI void
231 elm_bubble_content_set(Evas_Object *obj, Evas_Object *content)
232 {
233    ELM_CHECK_WIDTYPE(obj, widtype);
234    Widget_Data *wd = elm_widget_data_get(obj);
235    if (!wd) return;
236    if (wd->content == content) return;
237    if (wd->content) evas_object_del(wd->content);
238    wd->content = content;
239    if (content)
240      {
241         elm_widget_sub_object_add(obj, content);
242         evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
243                                        _changed_size_hints, obj);
244         edje_object_part_swallow(wd->bbl, "elm.swallow.content", content);
245      }
246    _sizing_eval(obj);
247 }
248
249 /**
250  * Unset the content shown in the bubble
251  *
252  * Unparent and return the content object which was set for this widget.
253  *
254  * @param obj The bubble object
255  * @return The content that was being used
256  *
257  * @ingroup Bubble
258  */
259 EAPI Evas_Object *
260 elm_bubble_content_unset(Evas_Object *obj)
261 {
262    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
263    Widget_Data *wd = elm_widget_data_get(obj);
264    Evas_Object *content;
265    if (!wd) return NULL;
266    if (!wd->content) return NULL;
267    content = wd->content;
268    elm_widget_sub_object_del(obj, wd->content);
269    edje_object_part_unswallow(wd->bbl, wd->content);
270    wd->content = NULL;
271    return content;
272 }
273
274 /**
275  * Set the icon of the bubble
276  *
277  * Once the icon object is set, a previously set one will be deleted.
278  *
279  * @param obj The bubble object
280  * @param icon The given icon for the bubble
281  *
282  * @ingroup Bubble
283  */
284 EAPI void
285 elm_bubble_icon_set(Evas_Object *obj, Evas_Object *icon)
286 {
287    ELM_CHECK_WIDTYPE(obj, widtype);
288    Widget_Data *wd = elm_widget_data_get(obj);
289    if (!wd) return;
290    if (wd->icon == icon) return;
291    if (wd->icon) evas_object_del(wd->icon);
292    wd->icon = icon;
293    if (icon)
294      {
295         elm_widget_sub_object_add(obj, icon);
296         edje_object_part_swallow(wd->bbl, "elm.swallow.icon", icon);
297         evas_object_event_callback_add(icon, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
298                                        _changed_size_hints, obj);
299         edje_object_signal_emit(wd->bbl, "elm,state,icon,visible", "elm");
300         edje_object_message_signal_process(wd->bbl);
301      }
302    
303    _sizing_eval(obj);
304 }
305
306 /**
307  * Get the icon of the bubble
308  *
309  * @param obj The bubble object
310  * @return The icon for the bubble
311  *
312  * This function gets the icon shown on the top left of bubble.
313  *
314  * @ingroup Bubble
315  */
316 EAPI Evas_Object *
317 elm_bubble_icon_get(const Evas_Object *obj)
318 {
319    ELM_CHECK_WIDTYPE(obj, widtype) NULL;
320    Widget_Data *wd = elm_widget_data_get(obj);
321    if (!wd) return NULL;
322    return wd->icon;
323 }
324
325 /**
326  * Set the corner of the bubble
327  *
328  * @param obj The bubble object.
329  * @param corner The given corner for the bubble.
330  *
331  * This function sets the corner of the bubble.
332  *
333  * @ingroup Bubble
334  */
335 EAPI void
336 elm_bubble_corner_set(Evas_Object *obj, const char *corner)
337 {
338    ELM_CHECK_WIDTYPE(obj, widtype);
339    Widget_Data *wd = elm_widget_data_get(obj);
340    if (!wd) return;
341    _elm_theme_object_set(obj, wd->bbl, "bubble", corner, elm_widget_style_get(obj));
342    if (wd->icon)
343      edje_object_part_swallow(wd->bbl, "elm.swallow.icon", wd->icon);
344    if (wd->content)
345      edje_object_part_swallow(wd->bbl, "elm.swallow.content", wd->content);
346    // FIXME: fix label etc.
347    _sizing_eval(obj);
348 }