aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/elementary/src/lib/elc_popup.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libraries/elementary/src/lib/elc_popup.c1454
1 files changed, 1454 insertions, 0 deletions
diff --git a/libraries/elementary/src/lib/elc_popup.c b/libraries/elementary/src/lib/elc_popup.c
new file mode 100644
index 0000000..1013f49
--- /dev/null
+++ b/libraries/elementary/src/lib/elc_popup.c
@@ -0,0 +1,1454 @@
1#include <Elementary.h>
2#include "elm_priv.h"
3
4#define ELM_POPUP_ACTION_BUTTON_MAX 3
5typedef struct _Widget_Data Widget_Data;
6typedef struct _Elm_Popup_Content_Item Elm_Popup_Content_Item;
7typedef struct _Action_Area_Data Action_Area_Data;
8
9struct _Widget_Data
10{
11 Evas_Object *base;
12 Evas_Object *notify;
13 Evas_Object *title_icon;
14 Evas_Object *content_area;
15 Evas_Object *content_text_obj;
16 Evas_Object *action_area;
17 Evas_Object *box;
18 Evas_Object *scr;
19 Evas_Object *content;
20 Eina_List *items;
21 const char *title_text;
22 Action_Area_Data *buttons[ELM_POPUP_ACTION_BUTTON_MAX];
23 Elm_Wrap_Type content_text_wrap_type;
24 unsigned int button_count;
25 Evas_Coord max_sc_w;
26 Evas_Coord max_sc_h;
27 Eina_Bool scr_size_recalc:1;
28};
29
30struct _Elm_Popup_Content_Item
31{
32 Elm_Widget_Item base;
33 const char *label;
34 Evas_Object *icon;
35 Evas_Smart_Cb func;
36 Eina_Bool disabled:1;
37};
38
39struct _Action_Area_Data
40{
41 Evas_Object *obj;
42 Evas_Object *btn;
43 Eina_Bool delete_me;
44};
45
46static const char *widtype = NULL;
47static void _del_hook(Evas_Object *obj);
48static void _theme_hook(Evas_Object *obj);
49static void _text_set_hook(Evas_Object *obj, const char *part,
50 const char *label);
51static const char *_text_get_hook(const Evas_Object *obj,
52 const char *part);
53static void _content_set_hook(Evas_Object *obj, const char *part,
54 Evas_Object *content);
55static Evas_Object *_content_get_hook(Evas_Object *obj,
56 const char *part);
57static Evas_Object *_content_unset_hook(Evas_Object *obj,
58 const char *part);
59static void _item_text_set_hook(Elm_Object_Item *it, const char *part,
60 const char *label);
61static const char *_item_text_get_hook(const Elm_Object_Item *it,
62 const char *part);
63static void _item_content_set_hook(Elm_Object_Item *it, const char *part,
64 Evas_Object *content);
65static Evas_Object *_item_content_unset_hook(const Elm_Object_Item *it,
66 const char *part);
67static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
68 const char *part);
69static void _item_disable_hook(Elm_Object_Item *it);
70static void _item_del_pre_hook(Elm_Object_Item *it);
71static void _item_signal_emit_hook(Elm_Object_Item *it, const char *emission,
72 const char *source);
73static void _sizing_eval(Evas_Object *obj);
74static void _block_clicked_cb(void *data, Evas_Object *obj, void *event_info);
75static void _notify_resize(void *data, Evas *e, Evas_Object *obj,
76 void *event_info);
77static void _scroller_resize(void *data, Evas *e, Evas_Object *obj,
78 void *event_info);
79static void _timeout(void *data, Evas_Object *obj , void *event_info);
80static void _sub_del(void *data, Evas_Object *obj, void *event_info);
81static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
82static void _restack(void *data, Evas *e, Evas_Object *obj, void *event_info);
83static void _layout_change_cb(void *data, Evas_Object *obj __UNUSED__,
84 const char *emission __UNUSED__,
85 const char *source __UNUSED__);
86static void _item_new(Elm_Popup_Content_Item *item);
87static void _remove_items(Widget_Data *wd);
88static void _list_new(Evas_Object *obj);
89static void _list_del(Widget_Data *wd);
90static void _item_sizing_eval(Elm_Popup_Content_Item *item);
91static void _item_select_cb(void *data, Evas_Object *obj __UNUSED__,
92 const char *emission __UNUSED__,
93 const char *source __UNUSED__);
94static void _scroller_size_calc(Evas_Object *obj);
95static void _action_button_set(Evas_Object *obj, Evas_Object *btn,
96 unsigned int idx);
97static Evas_Object *_action_button_get(Evas_Object *obj, unsigned int idx);
98static Evas_Object *_action_button_unset(Evas_Object *obj, unsigned int idx);
99static void _button_remove(Evas_Object *obj, Evas_Object *content,
100 Eina_Bool delete);
101static void _popup_show(void *data, Evas *e, Evas_Object *obj,
102 void *event_info);
103static void _popup_hide(void *data, Evas *e, Evas_Object *obj,
104 void *event_info);
105static const char SIG_BLOCK_CLICKED[] = "block,clicked";
106static const char SIG_TIMEOUT[] = "timeout";
107static const Evas_Smart_Cb_Description _signals[] = {
108 {SIG_BLOCK_CLICKED, ""},
109 {SIG_TIMEOUT, ""},
110 {NULL, NULL}
111};
112
113#define ELM_POPUP_CONTENT_ITEM_CHECK_RETURN(it, ...) \
114 ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
115 ELM_CHECK_WIDTYPE(WIDGET(item), widtype) __VA_ARGS__;
116
117static void
118_layout_set(Evas_Object *obj)
119{
120 Widget_Data *wd = elm_widget_data_get(obj);
121
122 if (!wd) return;
123 if ((!(wd->title_text)) && (!(wd->title_icon)))
124 elm_object_signal_emit(wd->base, "elm,state,title_area,hidden", "elm");
125 else
126 elm_object_signal_emit(wd->base, "elm,state,title_area,visible", "elm");
127 if (wd->button_count)
128 elm_object_signal_emit(wd->base, "elm,state,action_area,visible", "elm");
129 else
130 elm_object_signal_emit(wd->base, "elm,state,action_area,hidden", "elm");
131}
132
133static void
134_del_hook(Evas_Object *obj)
135{
136 Widget_Data *wd = elm_widget_data_get(obj);
137
138 if (!wd) return;
139 free(wd);
140}
141
142static void
143_del_pre_hook(Evas_Object *obj)
144{
145 unsigned int i;
146 Widget_Data *wd = elm_widget_data_get(obj);
147
148 if (!wd) return;
149 evas_object_smart_callback_del(wd->notify, "block,clicked",
150 _block_clicked_cb);
151 evas_object_smart_callback_del(wd->notify, "timeout", _timeout);
152 evas_object_event_callback_del(wd->notify, EVAS_CALLBACK_RESIZE,
153 _notify_resize);
154 evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _popup_show);
155 wd->button_count = 0;
156 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
157 if (wd->buttons[i])
158 {
159 evas_object_del(wd->buttons[i]->btn);
160 free(wd->buttons[i]);
161 wd->buttons[i] = NULL;
162 }
163 if (wd->items)
164 {
165 _remove_items(wd);
166 _list_del(wd);
167 }
168}
169
170static void
171_theme_hook(Evas_Object *obj)
172{
173 Eina_List *elist;
174 Elm_Popup_Content_Item *item;
175 char buf[128];
176 unsigned int i = 0;
177 Widget_Data *wd = elm_widget_data_get(obj);
178
179 if (!wd) return;
180 elm_layout_theme_set(wd->base, "popup", "base", elm_widget_style_get(obj));
181 _elm_widget_mirrored_reload(obj);
182 _mirrored_set(obj, elm_widget_mirrored_get(obj));
183 if (wd->button_count)
184 {
185 snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
186 elm_layout_theme_set(wd->action_area, "popup", buf,
187 elm_widget_style_get(obj));
188 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
189 {
190 if (!wd->buttons[i]) continue;
191 elm_object_style_set(wd->buttons[i]->btn, buf);
192 }
193 }
194 elm_layout_theme_set(wd->content_area, "popup", "content",
195 elm_widget_style_get(obj));
196 if (wd->content_text_obj)
197 {
198 snprintf(buf, sizeof(buf), "popup/%s", elm_widget_style_get(obj));
199 elm_object_style_set(wd->content_text_obj, buf);
200 }
201 else if (wd->items)
202 {
203 EINA_LIST_FOREACH(wd->items, elist, item)
204 {
205 _elm_theme_object_set(obj, VIEW(item), "popup",
206 "item", elm_widget_style_get(obj));
207 if (item->label)
208 {
209 edje_object_part_text_escaped_set(VIEW(item), "elm.text",
210 item->label);
211 edje_object_signal_emit(VIEW(item),
212 "elm,state,item,text,visible", "elm");
213 }
214 if (item->icon)
215 edje_object_signal_emit(VIEW(item),
216 "elm,state,item,icon,visible", "elm");
217 if (item->disabled)
218 edje_object_signal_emit(VIEW(item),
219 "elm,state,item,disabled", "elm");
220 evas_object_show(VIEW(item));
221 edje_object_message_signal_process(VIEW(item));
222 }
223 _scroller_size_calc(obj);
224 }
225 if (wd->title_text)
226 {
227 elm_object_part_text_set(wd->base, "elm.text.title", wd->title_text);
228 elm_object_signal_emit(wd->base, "elm,state,title,text,visible", "elm");
229 }
230 if (wd->title_icon)
231 elm_object_signal_emit(wd->base, "elm,state,title,icon,visible", "elm");
232 _layout_set(obj);
233 edje_object_message_signal_process(elm_layout_edje_get(wd->base));
234 _sizing_eval(obj);
235}
236
237static void
238_item_sizing_eval(Elm_Popup_Content_Item *item)
239{
240 Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
241
242 edje_object_size_min_restricted_calc(VIEW(item), &min_w, &min_h, min_w,
243 min_h);
244 evas_object_size_hint_min_set(VIEW(item), min_w, min_h);
245 evas_object_size_hint_max_set(VIEW(item), max_w, max_h);
246}
247
248static void
249_sizing_eval(Evas_Object *obj)
250{
251 Eina_List *elist;
252 Elm_Popup_Content_Item *item;
253 Evas_Coord w_box = 0, h_box = 0;
254 Evas_Coord minw_box = 0, minh_box = 0;
255 Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
256 Widget_Data *wd = elm_widget_data_get(obj);
257
258 if (!wd) return;
259 if (wd->items)
260 {
261 EINA_LIST_FOREACH(wd->items, elist, item)
262 {
263 _item_sizing_eval(item);
264 evas_object_size_hint_min_get(VIEW(item), &minw_box,
265 &minh_box);
266 if (minw_box > w_box)
267 w_box = minw_box;
268 if (minh_box != -1)
269 h_box += minh_box;
270 }
271 evas_object_size_hint_min_set(wd->box, w_box, h_box);
272 evas_object_size_hint_min_set(wd->scr, w_box, MIN(h_box, wd->max_sc_h));
273 evas_object_size_hint_max_set(wd->scr, w_box, wd->max_sc_h);
274 evas_object_smart_calculate(wd->scr);
275 }
276 edje_object_size_min_calc(elm_layout_edje_get(wd->base), &minw, &minh);
277 evas_object_size_hint_min_set(wd->base, minw, minh);
278 evas_object_size_hint_max_set(wd->base, maxw, maxh);
279 evas_object_size_hint_min_set(obj, minw, minh);
280 evas_object_size_hint_max_set(obj, maxw, maxh);
281 elm_layout_sizing_eval(wd->base);
282}
283
284static void
285_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
286 void *event_info __UNUSED__)
287{
288 _sizing_eval(data);
289}
290
291static void
292_sub_del(void *data, Evas_Object *obj, void *event_info)
293{
294 Elm_Popup_Content_Item *item;
295 unsigned int i;
296 Evas_Object *sub = event_info;
297 Widget_Data *wd = elm_widget_data_get(data);
298
299 if (!wd) return;
300 if (obj == data)
301 {
302 if ((item = evas_object_data_get(sub, "_popup_content_item")) != NULL)
303 {
304 if (sub == item->icon)
305 {
306 edje_object_part_unswallow(VIEW(item), sub);
307 edje_object_signal_emit(VIEW(item),
308 "elm,state,item,icon,hidden", "elm");
309 item->icon = NULL;
310 }
311 }
312 }
313 else if (obj == wd->content_area)
314 {
315 if (sub == wd->content)
316 {
317 wd->content = NULL;
318 elm_object_part_content_unset(wd->base, "elm.swallow.content");
319 _sizing_eval(data);
320 }
321 else if (sub == wd->content_text_obj)
322 {
323 wd->content_text_obj = NULL;
324 elm_object_part_content_unset(wd->base, "elm.swallow.content");
325 _sizing_eval(data);
326 }
327 else if (sub == wd->scr)
328 {
329 wd->scr = NULL;
330 wd->box = NULL;
331 elm_object_part_content_unset(wd->base, "elm.swallow.content");
332 _sizing_eval(data);
333 }
334 }
335 else if (obj == wd->action_area)
336 {
337 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
338 {
339 if (wd->buttons[i] && sub == wd->buttons[i]->btn &&
340 wd->buttons[i]->delete_me == EINA_TRUE)
341 {
342 _button_remove(data, sub, EINA_FALSE);
343 break;
344 }
345 }
346 }
347 else if (obj == wd->base)
348 {
349 if (sub == wd->title_icon)
350 {
351 elm_object_signal_emit(wd->base, "elm,state,title,icon,hidden",
352 "elm");
353 edje_object_message_signal_process(wd->base);
354 wd->title_icon = NULL;
355 }
356 }
357}
358
359static void
360_block_clicked_cb(void *data, Evas_Object *obj __UNUSED__,
361 void *event_info __UNUSED__)
362{
363 Widget_Data *wd = elm_widget_data_get(data);
364
365 if (!wd) return;
366 evas_object_smart_callback_call(data, SIG_BLOCK_CLICKED, NULL);
367}
368
369static void
370_timeout(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
371{
372 evas_object_hide(data);
373 evas_object_smart_callback_call(data, SIG_TIMEOUT, NULL);
374}
375
376static void
377_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
378{
379 Eina_List *elist;
380 Elm_Popup_Content_Item *item;
381 Widget_Data *wd = elm_widget_data_get(obj);
382
383 if (!wd) return;
384 elm_object_mirrored_set(wd->notify, rtl);
385 if (wd->items)
386 EINA_LIST_FOREACH(wd->items, elist, item)
387 edje_object_mirrored_set(VIEW(item), rtl);
388}
389
390static void
391_layout_change_cb(void *data, Evas_Object *obj __UNUSED__,
392 const char *emission __UNUSED__,
393 const char *source __UNUSED__)
394{
395 Widget_Data *wd = elm_widget_data_get((Evas_Object*)data);
396
397 if (!wd) return;
398 if (wd->base)
399 elm_layout_sizing_eval(wd->base);
400}
401
402static void
403_restack(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
404 void *event_info __UNUSED__)
405{
406 Widget_Data *wd = elm_widget_data_get(obj);
407
408 if (!wd) return;
409 evas_object_layer_set(wd->notify, evas_object_layer_get(obj));
410}
411
412static void
413_scroller_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
414 void *event_info __UNUSED__)
415{
416 Evas_Coord w, h;
417 Widget_Data *wd = elm_widget_data_get(data);
418
419 if (!wd || wd->scr_size_recalc) return;
420 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
421 if (w && h)
422 {
423 if ((w <= wd->max_sc_w) && (h <= wd->max_sc_h))
424 {
425 _sizing_eval(data);
426 wd->scr_size_recalc = EINA_TRUE;
427 return;
428 }
429 }
430 if (wd->max_sc_w < w)
431 wd->max_sc_w = w;
432 if (wd->max_sc_h < h)
433 wd->max_sc_h = h;
434 _sizing_eval(data);
435}
436
437static void
438_list_new(Evas_Object *obj)
439{
440 Widget_Data *wd = elm_widget_data_get(obj);
441
442 if (!wd) return;
443 //Scroller
444 wd->scr = elm_scroller_add(obj);
445 elm_scroller_bounce_set(wd->scr, EINA_FALSE, EINA_TRUE);
446 elm_object_content_set(wd->scr, wd->box);
447 evas_object_size_hint_weight_set(wd->scr, EVAS_HINT_EXPAND,
448 EVAS_HINT_EXPAND);
449 evas_object_size_hint_align_set(wd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
450 evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE,
451 _scroller_resize, obj);
452 evas_object_event_callback_add(wd->scr,
453 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
454 _changed_size_hints, obj);
455 elm_object_part_content_set(wd->base, "elm.swallow.content", wd->scr);
456
457 //Box
458 wd->box = elm_box_add(obj);
459 evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND,
460 EVAS_HINT_EXPAND);
461 evas_object_size_hint_align_set(wd->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
462
463 elm_object_content_set(wd->scr, wd->box);
464}
465
466static void
467_list_del(Widget_Data *wd)
468{
469 if (!wd->scr) return;
470 elm_object_part_content_unset(wd->base, "elm.swallow.content");
471 evas_object_event_callback_del(wd->scr, EVAS_CALLBACK_RESIZE,
472 _scroller_resize);
473 evas_object_event_callback_del(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
474 _changed_size_hints);
475 evas_object_del(wd->scr);
476 wd->scr = NULL;
477 wd->box = NULL;
478}
479
480static void
481_scroller_size_calc(Evas_Object *obj)
482{
483 Evas_Coord h;
484 Evas_Coord h_title = 0;
485 Evas_Coord h_action_area = 0;
486 Evas_Coord h_content = 0;
487 const char *action_area_height;
488 Widget_Data *wd = elm_widget_data_get(obj);
489
490 if (!wd || !wd->items) return;
491 wd->scr_size_recalc = EINA_FALSE;
492 wd->max_sc_h = -1;
493 wd->max_sc_w = -1;
494 evas_object_geometry_get(wd->notify, NULL, NULL, NULL, &h);
495 if (wd->title_text || wd->title_icon)
496 edje_object_part_geometry_get(elm_layout_edje_get(wd->base),
497 "elm.bg.title", NULL, NULL, NULL, &h_title);
498 if (wd->button_count)
499 {
500 action_area_height = edje_object_data_get(
501 elm_layout_edje_get(wd->action_area), "action_area_height");
502 if (action_area_height) h_action_area = (int)(atoi(action_area_height)
503 * _elm_config->scale * elm_object_scale_get(obj));
504 }
505 h_content = h - (h_title + h_action_area);
506 wd->max_sc_h = h_content;
507}
508
509static void
510_item_select_cb(void *data, Evas_Object *obj __UNUSED__,
511 const char *emission __UNUSED__, const char *source __UNUSED__)
512{
513 Elm_Popup_Content_Item *item = data;
514
515 if (!item || item->disabled) return;
516 if (item->func)
517 item->func((void*)item->base.data, WIDGET(item), data);
518}
519
520static void
521_item_new(Elm_Popup_Content_Item *item)
522{
523 Widget_Data *wd = elm_widget_data_get(WIDGET(item));
524
525 if (!wd) return;
526 elm_widget_item_text_set_hook_set(item, _item_text_set_hook);
527 elm_widget_item_text_get_hook_set(item, _item_text_get_hook);
528 elm_widget_item_content_set_hook_set(item, _item_content_set_hook);
529 elm_widget_item_content_get_hook_set(item, _item_content_get_hook);
530 elm_widget_item_content_unset_hook_set(item, _item_content_unset_hook);
531 elm_widget_item_disable_hook_set(item, _item_disable_hook);
532 elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
533 elm_widget_item_signal_emit_hook_set(item, _item_signal_emit_hook);
534 VIEW(item) = edje_object_add(evas_object_evas_get(wd->base));
535 _elm_theme_object_set(WIDGET(item), VIEW(item), "popup", "item",
536 elm_widget_style_get(WIDGET(item)));
537 edje_object_mirrored_set(VIEW(item), elm_widget_mirrored_get(WIDGET(item)));
538 edje_object_signal_callback_add(VIEW(item), "elm,action,click", "",
539 _item_select_cb, item);
540 evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL,
541 EVAS_HINT_FILL);
542 evas_object_show(VIEW(item));
543}
544
545static void
546_remove_items(Widget_Data *wd)
547{
548 Eina_List *elist;
549 Elm_Popup_Content_Item *item;
550
551 if (!wd->items) return;
552 EINA_LIST_FOREACH(wd->items, elist, item)
553 {
554 if (item->label)
555 eina_stringshare_del(item->label);
556 if (item->icon)
557 {
558 evas_object_del(item->icon);
559 item->icon = NULL;
560 }
561 evas_object_del(VIEW(item));
562 wd->items = eina_list_remove(wd->items, item);
563 free(item);
564 }
565 wd->items = NULL;
566}
567
568static void
569_notify_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
570 void *event_info __UNUSED__)
571{
572 Widget_Data *wd = elm_widget_data_get(data);
573
574 if (wd->items)
575 _scroller_size_calc(data);
576 _sizing_eval(data);
577}
578
579static void
580_title_text_set(Evas_Object *obj, const char *text)
581{
582 ELM_CHECK_WIDTYPE(obj, widtype);
583 Eina_Bool title_visibility_old, title_visibility_current;
584 Widget_Data *wd = elm_widget_data_get(obj);
585
586 if (!wd) return;
587 if (wd->title_text == text) return;
588 title_visibility_old = (wd->title_text) || (wd->title_icon);
589 eina_stringshare_replace(&wd->title_text, text);
590 elm_object_part_text_set(wd->base, "elm.text.title", text);
591 if (wd->title_text)
592 elm_object_signal_emit(wd->base, "elm,state,title,text,visible", "elm");
593 else
594 elm_object_signal_emit(wd->base, "elm,state,title,text,hidden", "elm");
595 title_visibility_current = (wd->title_text) || (wd->title_icon);
596 if (title_visibility_old != title_visibility_current)
597 _layout_set(obj);
598 edje_object_message_signal_process(wd->base);
599 _sizing_eval(obj);
600}
601
602static void
603_content_text_set(Evas_Object *obj, const char *text)
604{
605 ELM_CHECK_WIDTYPE(obj, widtype);
606 Evas_Object *prev_content;
607 char buf[128];
608 Widget_Data *wd = elm_widget_data_get(obj);
609
610 if (!wd) return;
611 if (wd->items)
612 {
613 _remove_items(wd);
614 _list_del(wd);
615 }
616 prev_content = elm_object_part_content_get(wd->content_area,
617 "elm.swallow.content");
618 if (prev_content)
619 evas_object_del(prev_content);
620 if (text)
621 {
622 elm_object_part_content_set(wd->base, "elm.swallow.content",
623 wd->content_area);
624 wd->content_text_obj = elm_label_add(obj);
625 snprintf(buf, sizeof(buf), "popup/%s",
626 elm_widget_style_get(obj));
627 elm_object_style_set(wd->content_text_obj, buf);
628 elm_label_line_wrap_set(wd->content_text_obj,
629 wd->content_text_wrap_type);
630 elm_object_text_set(wd->content_text_obj, text);
631 evas_object_size_hint_weight_set(wd->content_text_obj, EVAS_HINT_EXPAND,
632 0.0);
633 evas_object_size_hint_align_set(wd->content_text_obj, EVAS_HINT_FILL,
634 EVAS_HINT_FILL);
635 elm_object_part_content_set(wd->content_area, "elm.swallow.content",
636 wd->content_text_obj);
637 }
638 _sizing_eval(obj);
639}
640
641static void
642_text_set_hook(Evas_Object *obj, const char *part,
643 const char *label)
644{
645 ELM_CHECK_WIDTYPE(obj, widtype);
646 Widget_Data *wd = elm_widget_data_get(obj);
647
648 if (!wd) return;
649 if (!part || !strcmp(part, "default"))
650 _content_text_set(obj, label);
651 else if (!strcmp(part, "title,text"))
652 _title_text_set(obj, label);
653 else
654 WRN("The part name is invalid! : popup=%p", obj);
655}
656
657static const char*
658_title_text_get(const Evas_Object *obj)
659{
660 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
661 Widget_Data *wd = elm_widget_data_get(obj);
662
663 if (!wd) return NULL;
664 return wd->title_text;
665}
666
667static const char*
668_content_text_get(const Evas_Object *obj)
669{
670 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
671 const char *str = NULL;
672 Widget_Data *wd = elm_widget_data_get(obj);
673
674 if (!wd) return NULL;
675 if (wd->content_text_obj)
676 str = elm_object_text_get(wd->content_text_obj);
677 return str;
678}
679
680static const char *
681_text_get_hook(const Evas_Object *obj, const char *part)
682{
683 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
684 const char *str = NULL;
685 Widget_Data *wd = elm_widget_data_get(obj);
686
687 if (!wd) return NULL;
688 if (!part || !strcmp(part, "default"))
689 str = _content_text_get(obj);
690 else if (!strcmp(part, "title,text"))
691 str = _title_text_get(obj);
692 else
693 WRN("The part name is invalid! : popup=%p", obj);
694 return str;
695}
696
697static void
698_title_icon_set(Evas_Object *obj, Evas_Object *icon)
699{
700 ELM_CHECK_WIDTYPE(obj, widtype);
701 Eina_Bool title_visibility_old, title_visibility_current;
702 Widget_Data *wd = elm_widget_data_get(obj);
703
704 if (!wd) return;
705 if (wd->title_icon == icon) return;
706 title_visibility_old = (wd->title_text) || (wd->title_icon);
707 if (wd->title_icon) evas_object_del(wd->title_icon);
708
709 wd->title_icon = icon;
710 title_visibility_current = (wd->title_text) || (wd->title_icon);
711 elm_object_part_content_set(wd->base, "elm.swallow.title.icon",
712 wd->title_icon);
713 if (wd->title_icon)
714 elm_object_signal_emit(wd->base, "elm,state,title,icon,visible", "elm");
715 if (title_visibility_old != title_visibility_current) _layout_set(obj);
716 edje_object_message_signal_process(wd->base);
717 _sizing_eval(obj);
718}
719
720static void
721_content_set(Evas_Object *obj, Evas_Object *content)
722{
723 ELM_CHECK_WIDTYPE(obj, widtype);
724 Evas_Object *prev_content;
725 Widget_Data *wd = elm_widget_data_get(obj);
726
727 if (!wd) return;
728 if (wd->content && wd->content == content) return;
729 if (wd->items)
730 {
731 _remove_items(wd);
732 _list_del(wd);
733 }
734 prev_content = elm_object_part_content_get(wd->content_area,
735 "elm.swallow.content");
736 if (prev_content)
737 evas_object_del(prev_content);
738 wd->content = content;
739 if (content)
740 {
741 elm_object_part_content_set(wd->base, "elm.swallow.content",
742 wd->content_area);
743 elm_object_part_content_set(wd->content_area, "elm.swallow.content",
744 content);
745 evas_object_show(content);
746 }
747 _sizing_eval(obj);
748}
749
750static void
751_button_remove(Evas_Object *obj, Evas_Object *content, Eina_Bool delete)
752{
753 unsigned int i = 0, position = 0;
754 char buf[128];
755 Widget_Data *wd = elm_widget_data_get(obj);
756
757 if (!wd->button_count) return;
758 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
759 {
760 if (wd->buttons[i])
761 {
762 position++;
763 wd->buttons[i]->delete_me = EINA_FALSE;
764 if (wd->buttons[i]->btn == content)
765 {
766 snprintf(buf, sizeof(buf), "actionbtn%u", position);
767 elm_object_part_content_unset(wd->action_area, buf);
768 evas_object_hide(content);
769 if (delete) evas_object_del(content);
770 free(wd->buttons[i]);
771 wd->buttons[i] = NULL;
772 wd->button_count -= 1;
773 }
774 }
775 }
776 position = 0;
777 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
778 {
779 if (!wd->buttons[i]) continue;
780 position++;
781 snprintf(buf, sizeof(buf), "actionbtn%u", position);
782 elm_object_part_content_unset(wd->action_area, buf);
783 elm_object_part_content_set(wd->action_area, buf,
784 wd->buttons[i]->btn);
785 evas_object_show(wd->buttons[i]->btn);
786 wd->buttons[i]->delete_me = EINA_TRUE;
787 }
788 if (!wd->button_count)
789 {
790 _layout_set(obj);
791 elm_object_part_content_unset(wd->base, "elm.swallow.action_area");
792 evas_object_hide(wd->action_area);
793 edje_object_message_signal_process(elm_layout_edje_get(wd->base));
794 }
795 else
796 {
797 snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
798 elm_layout_theme_set(wd->action_area, "popup", buf,
799 elm_widget_style_get(obj));
800 }
801}
802
803static void
804_action_button_set(Evas_Object *obj, Evas_Object *btn, unsigned int idx)
805{
806 Action_Area_Data *adata;
807 char buf[128];
808 unsigned int num = idx - 1, i = 0, position = 0;
809 Widget_Data *wd = elm_widget_data_get(obj);
810
811 if (!wd) return;
812 if (num >= ELM_POPUP_ACTION_BUTTON_MAX) return;
813 if (wd->buttons[num])
814 _button_remove(obj, wd->buttons[num]->btn, EINA_TRUE);
815 if (btn)
816 {
817 wd->button_count++;
818 snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
819 elm_layout_theme_set(wd->action_area, "popup", buf,
820 elm_widget_style_get(obj));
821 adata = ELM_NEW(Action_Area_Data);
822 adata->obj = obj;
823 adata->btn = btn;
824 wd->buttons[num] = adata;
825 /* Adding delete_me state inside action data as unset calls _sub_del
826 too and before setting a new content, the previous one needs to
827 be unset in order to avoid unwanted deletion. This way rearrangement
828 of buttons can be achieved in action area.
829 */
830 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
831 if (wd->buttons[i])
832 wd->buttons[i]->delete_me = EINA_FALSE;
833 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
834 {
835 if (!wd->buttons[i]) continue;
836 position++;
837 snprintf(buf, sizeof(buf), "actionbtn%u", position);
838 elm_object_part_content_unset(wd->action_area, buf);
839 elm_object_part_content_set(wd->action_area, buf,
840 wd->buttons[i]->btn);
841 evas_object_show(wd->buttons[i]->btn);
842 /* Setting delete_me to TRUE in order to let _sub_del handle it
843 if deleted externally and update the buttons array after freeing
844 action data allocated earlier.
845 */
846 wd->buttons[i]->delete_me = EINA_TRUE;
847 }
848 elm_object_part_content_set(wd->base, "elm.swallow.action_area",
849 wd->action_area);
850 evas_object_show(wd->action_area);
851 if (wd->button_count == 1)
852 _layout_set(obj);
853 edje_object_message_signal_process(wd->base);
854 if (wd->items)
855 _scroller_size_calc(obj);
856 _sizing_eval(obj);
857 }
858}
859
860static void
861_content_set_hook(Evas_Object *obj, const char *part,
862 Evas_Object *content)
863{
864 ELM_CHECK_WIDTYPE(obj, widtype);
865 char buff[3];
866 unsigned int i;
867 Widget_Data *wd = elm_widget_data_get(obj);
868
869 if (!wd) return;
870 if (!part || !strcmp(part, "default"))
871 _content_set(obj, content);
872 else if (!strcmp(part, "title,icon"))
873 _title_icon_set(obj, content);
874 else if (!strncmp(part, "button", 6))
875 {
876 part += 6;
877 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
878 {
879 snprintf(buff, sizeof(buff), "%u", i+1);
880 if (!strncmp(part, buff, sizeof(buff)))
881 {
882 _action_button_set(obj, content, i+1);
883 break;
884 }
885 }
886 }
887 else
888 WRN("The part name is invalid! : popup=%p", obj);
889}
890
891static Evas_Object *
892_title_icon_get(Evas_Object *obj)
893{
894 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
895 Widget_Data *wd = elm_widget_data_get(obj);
896
897 if (!wd) return NULL;
898 return wd->title_icon;
899}
900
901static Evas_Object *
902_content_get(Evas_Object *obj)
903{
904 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
905 Widget_Data *wd = elm_widget_data_get(obj);
906
907 if (!wd) return NULL;
908 return wd->content;
909}
910
911static Evas_Object *
912_action_button_get(Evas_Object *obj, unsigned int idx)
913{
914 unsigned int num = idx - 1;
915 Evas_Object *button = NULL;
916 Widget_Data *wd = elm_widget_data_get(obj);
917
918 if (!wd || !wd->button_count) return NULL;
919 if (wd->buttons[num])
920 button = wd->buttons[num]->btn;
921 return button;
922}
923
924static Evas_Object *
925_content_get_hook(Evas_Object *obj, const char *part)
926{
927 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
928 Evas_Object *content = NULL;
929 char buff[3];
930 unsigned int i;
931 Widget_Data *wd = elm_widget_data_get(obj);
932
933 if (!wd) return NULL;
934 if (!part || !strcmp(part, "default"))
935 content = _content_get(obj);
936 else if (!strcmp(part, "title,text"))
937 content = _title_icon_get(obj);
938 else if (!strncmp(part, "button", 6))
939 {
940 part += 6;
941 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
942 {
943 snprintf(buff, sizeof(buff), "%u", i+1);
944 if (!strncmp(part, buff, sizeof(buff)))
945 {
946 content = _action_button_get(obj, i+1);
947 break;
948 }
949 }
950 }
951 else
952 WRN("The part name is invalid! : popup=%p", obj);
953 return content;
954}
955
956static Evas_Object *
957_content_unset(Evas_Object *obj)
958{
959 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
960 Evas_Object *content;
961 Widget_Data *wd = elm_widget_data_get(obj);
962
963 if (!wd || !wd->content) return NULL;
964 content = elm_object_part_content_unset(wd->content_area,
965 "elm.swallow.content");
966 wd->content = NULL;
967 _sizing_eval(obj);
968 return content;
969}
970
971static Evas_Object *
972_title_icon_unset(Evas_Object *obj)
973{
974 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
975 Evas_Object *icon;
976 Widget_Data *wd = elm_widget_data_get(obj);
977
978 if (!wd || !wd->title_icon) return NULL;
979 icon = elm_object_part_content_unset(wd->base, "elm.swallow.title.icon");
980 wd->title_icon = NULL;
981 return icon;
982}
983
984static Evas_Object *
985_action_button_unset(Evas_Object *obj, unsigned int idx)
986{
987 unsigned int num = idx -1;
988 Evas_Object *button = NULL;
989 Widget_Data *wd = elm_widget_data_get(obj);
990
991 if (!wd) return NULL;
992 if ((!wd->button_count) || (num >= ELM_POPUP_ACTION_BUTTON_MAX))
993 return NULL;
994
995 if (wd->buttons[num])
996 {
997 button = wd->buttons[num]->btn;
998 _button_remove(obj, button, EINA_FALSE);
999 }
1000 return button;
1001}
1002
1003static Evas_Object *
1004_content_unset_hook(Evas_Object *obj, const char *part)
1005{
1006 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1007 Evas_Object *content = NULL;
1008 char buff[3];
1009 unsigned int i;
1010 Widget_Data *wd = elm_widget_data_get(obj);
1011
1012 if (!wd) return NULL;
1013 if (!part || !strcmp(part, "default"))
1014 content = _content_unset(obj);
1015 else if (!strcmp(part, "title,icon"))
1016 content = _title_icon_unset(obj);
1017 else if (!strncmp(part, "button", 6))
1018 {
1019 part += 6;
1020 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
1021 {
1022 snprintf(buff, sizeof(buff), "%u", i+1);
1023 if (!strncmp(part, buff, sizeof(buff)))
1024 {
1025 content = _action_button_unset(obj, i+1);
1026 break;
1027 }
1028 }
1029 }
1030 else
1031 WRN("The part name is invalid! : popup=%p", obj);
1032 return content;
1033}
1034
1035static Eina_Bool
1036_focus_next_hook(const Evas_Object *obj,
1037 Elm_Focus_Direction dir,
1038 Evas_Object **next)
1039{
1040 Widget_Data *wd = elm_widget_data_get(obj);
1041
1042 if (!wd)
1043 return EINA_FALSE;
1044 return elm_widget_focus_next_get(wd->notify, dir, next);
1045}
1046
1047static void
1048_item_text_set(Elm_Popup_Content_Item *item, const char *label)
1049{
1050 if (!eina_stringshare_replace(&item->label, label)) return;
1051 edje_object_part_text_escaped_set(VIEW(item), "elm.text", label);
1052 if (item->label)
1053 edje_object_signal_emit(VIEW(item),
1054 "elm,state,item,text,visible", "elm");
1055 else
1056 edje_object_signal_emit(VIEW(item),
1057 "elm,state,item,text,hidden", "elm");
1058 edje_object_message_signal_process(VIEW(item));
1059}
1060
1061static void
1062_item_text_set_hook(Elm_Object_Item *it, const char *part, const char *label)
1063{
1064 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1065 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1066
1067 if ((!part) || (!strcmp(part, "default")))
1068 {
1069 _item_text_set(item, label);
1070 return;
1071 }
1072 WRN("The part name is invalid! : popup=%p", WIDGET(item));
1073}
1074
1075static const char *
1076_item_text_get_hook(const Elm_Object_Item *it, const char *part)
1077{
1078 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1079 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1080
1081 if ((!part) || (!strcmp(part, "default")))
1082 return item->label;
1083 WRN("The part name is invalid! : popup=%p", WIDGET(item));
1084 return NULL;
1085}
1086
1087static void
1088_item_icon_set(Elm_Popup_Content_Item *item, Evas_Object *icon)
1089{
1090 if (item->icon == icon) return;
1091 if (item->icon)
1092 {
1093 evas_object_data_del(item->icon, "_popup_content_item");
1094 evas_object_del(item->icon);
1095 }
1096 item->icon = icon;
1097 if (item->icon)
1098 {
1099 elm_widget_sub_object_add(WIDGET(item), item->icon);
1100 evas_object_data_set(item->icon, "_popup_content_item", item);
1101 edje_object_part_swallow(VIEW(item), "elm.swallow.content",
1102 item->icon);
1103 edje_object_signal_emit(VIEW(item),
1104 "elm,state,item,icon,visible", "elm");
1105 }
1106 else
1107 edje_object_signal_emit(VIEW(item),
1108 "elm,state,item,icon,hidden", "elm");
1109 edje_object_message_signal_process(item->base.view);
1110}
1111
1112static void
1113_item_content_set_hook(Elm_Object_Item *it, const char *part,
1114 Evas_Object *content)
1115{
1116 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1117 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1118
1119 if ((!(part)) || (!strcmp(part, "default")))
1120 _item_icon_set(item, content);
1121 else
1122 WRN("The part name is invalid! : popup=%p", WIDGET(item));
1123}
1124
1125static Evas_Object *
1126_item_content_get_hook(const Elm_Object_Item *it,
1127 const char *part)
1128{
1129 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1130 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1131
1132 if ((!(part)) || (!strcmp(part, "default")))
1133 return item->icon;
1134 WRN("The part name is invalid! : popup=%p", WIDGET(item));
1135 return NULL;
1136}
1137
1138static Evas_Object *
1139_item_icon_unset(Elm_Popup_Content_Item *item)
1140{
1141 Evas_Object *icon = item->icon;
1142
1143 if (!item->icon) return NULL;
1144 elm_widget_sub_object_del(WIDGET(item), icon);
1145 evas_object_data_del(icon, "_popup_content_item");
1146 edje_object_part_unswallow(item->base.view, icon);
1147 edje_object_signal_emit(VIEW(item),
1148 "elm,state,item,icon,hidden", "elm");
1149 item->icon = NULL;
1150 return icon;
1151}
1152
1153static Evas_Object *
1154_item_content_unset_hook(const Elm_Object_Item *it,
1155 const char *part)
1156{
1157 ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
1158 Evas_Object *content = NULL;
1159 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1160
1161 if ((!(part)) || (!strcmp(part, "default")))
1162 content = _item_icon_unset(item);
1163 else
1164 WRN("The part name is invalid! : popup=%p", WIDGET(item));
1165 return content;
1166}
1167
1168static void
1169_item_disable_hook(Elm_Object_Item *it)
1170{
1171 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1172 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1173 Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1174
1175 if (!wd) return;
1176 if (elm_widget_item_disabled_get(it))
1177 edje_object_signal_emit(VIEW(item), "elm,state,item,disabled", "elm");
1178 else
1179 edje_object_signal_emit(VIEW(item), "elm,state,item,enabled", "elm");
1180}
1181
1182static void
1183_item_del_pre_hook(Elm_Object_Item *it)
1184{
1185 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1186 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1187 Widget_Data *wd = elm_widget_data_get(WIDGET(item));
1188
1189 if (!wd) return;
1190 if (item->icon)
1191 evas_object_del(item->icon);
1192 eina_stringshare_del(item->label);
1193 wd->items = eina_list_remove(wd->items, item);
1194 if (!eina_list_count(wd->items))
1195 {
1196 wd->items = NULL;
1197 _list_del(wd);
1198 }
1199}
1200
1201static void
1202_item_signal_emit_hook(Elm_Object_Item *it, const char *emission,
1203 const char *source)
1204{
1205 ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
1206 Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
1207
1208 edje_object_signal_emit(VIEW(item), emission, source);
1209}
1210
1211static void
1212_popup_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
1213 void *event_info __UNUSED__)
1214{
1215 Widget_Data *wd;
1216
1217 wd = elm_widget_data_get(obj);
1218 if (!wd) return;
1219
1220 evas_object_show(wd->notify);
1221}
1222
1223static void
1224_popup_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
1225 void *event_info __UNUSED__)
1226{
1227 Widget_Data *wd;
1228
1229 wd = elm_widget_data_get(obj);
1230 if (!wd) return;
1231
1232 evas_object_hide(wd->notify);
1233}
1234
1235EAPI Evas_Object *
1236elm_popup_add(Evas_Object *parent)
1237{
1238 Evas_Object *obj;
1239 Evas *e;
1240 int i = 0;
1241 Widget_Data *wd;
1242
1243 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
1244 ELM_SET_WIDTYPE(widtype, "popup");
1245 elm_widget_type_set(obj, widtype);
1246 elm_widget_sub_object_add(parent, obj);
1247 elm_widget_data_set(obj, wd);
1248 elm_widget_del_pre_hook_set(obj, _del_pre_hook);
1249 elm_widget_del_hook_set(obj, _del_hook);
1250 elm_widget_theme_hook_set(obj, _theme_hook);
1251 elm_widget_text_set_hook_set(obj, _text_set_hook);
1252 elm_widget_text_get_hook_set(obj, _text_get_hook);
1253 elm_widget_content_set_hook_set(obj, _content_set_hook);
1254 elm_widget_content_get_hook_set(obj, _content_get_hook);
1255 elm_widget_content_unset_hook_set(obj,_content_unset_hook);
1256 elm_widget_can_focus_set(obj, EINA_FALSE);
1257 elm_widget_focus_next_hook_set(obj, _focus_next_hook);
1258 evas_object_smart_callbacks_descriptions_set(obj, _signals);
1259
1260 wd->notify = elm_notify_add(obj);
1261 elm_notify_parent_set(wd->notify, parent);
1262 elm_notify_orient_set(wd->notify, ELM_NOTIFY_ORIENT_CENTER);
1263 elm_notify_allow_events_set(wd->notify, EINA_FALSE);
1264 evas_object_size_hint_weight_set(wd->notify,
1265 EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
1266 evas_object_size_hint_align_set(wd->notify, EVAS_HINT_FILL, EVAS_HINT_FILL);
1267 elm_object_style_set(wd->notify, "popup");
1268
1269 evas_object_event_callback_add(wd->notify, EVAS_CALLBACK_RESIZE,
1270 _notify_resize, obj);
1271 evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _popup_show,
1272 NULL);
1273 evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _popup_hide,
1274 NULL);
1275 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESTACK, _restack, NULL);
1276 wd->base = elm_layout_add(obj);
1277 evas_object_size_hint_weight_set(wd->base, EVAS_HINT_EXPAND,
1278 EVAS_HINT_EXPAND);
1279 evas_object_size_hint_align_set(wd->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
1280
1281 elm_layout_theme_set(wd->base, "popup", "base", elm_widget_style_get(obj));
1282 elm_object_content_set(wd->notify, wd->base);
1283
1284 elm_object_signal_callback_add(wd->base, "elm,state,title_area,visible",
1285 "elm", _layout_change_cb, obj);
1286 elm_object_signal_callback_add(wd->base, "elm,state,title_area,hidden",
1287 "elm", _layout_change_cb, obj);
1288 elm_object_signal_callback_add(wd->base, "elm,state,action_area,visible",
1289 "elm", _layout_change_cb, obj);
1290 elm_object_signal_callback_add(wd->base, "elm,state,action_area,hidden",
1291 "elm", _layout_change_cb, obj);
1292 wd->content_area = elm_layout_add(obj);
1293 elm_layout_theme_set(wd->content_area, "popup", "content",
1294 elm_widget_style_get(obj));
1295 wd->action_area = elm_layout_add(obj);
1296 evas_object_size_hint_weight_set(wd->action_area, EVAS_HINT_EXPAND,
1297 EVAS_HINT_EXPAND);
1298 evas_object_size_hint_align_set(wd->action_area, EVAS_HINT_FILL,
1299 EVAS_HINT_FILL);
1300 evas_object_event_callback_add(wd->action_area,
1301 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1302 _changed_size_hints, obj);
1303 evas_object_event_callback_add(wd->content_area,
1304 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
1305 _changed_size_hints, obj);
1306 evas_object_smart_callback_add(wd->base, "sub-object-del",
1307 _sub_del, obj);
1308 evas_object_smart_callback_add(wd->content_area, "sub-object-del",
1309 _sub_del, obj);
1310 evas_object_smart_callback_add(wd->action_area, "sub-object-del",
1311 _sub_del, obj);
1312 evas_object_smart_callback_add(obj, "sub-object-del",
1313 _sub_del, obj);
1314
1315 wd->content_text_wrap_type = ELM_WRAP_MIXED;
1316 evas_object_smart_callback_add(wd->notify, "block,clicked",
1317 _block_clicked_cb, obj);
1318 evas_object_smart_callback_add(wd->notify, "timeout", _timeout, obj);
1319 for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
1320 wd->buttons[i] = NULL;
1321 _layout_set(obj);
1322 //TODO: To use scroller for description also
1323 return obj;
1324}
1325
1326EAPI void
1327elm_popup_content_text_wrap_type_set(Evas_Object *obj, Elm_Wrap_Type wrap)
1328{
1329 ELM_CHECK_WIDTYPE(obj, widtype);
1330 Evas_Object *content_text_obj;
1331 Widget_Data *wd = elm_widget_data_get(obj);
1332
1333 if (!wd) return;
1334 if (wd->content_text_wrap_type == ELM_WRAP_NONE) return;
1335 //Need to wrap the content text, so not allowing ELM_WRAP_NONE
1336 wd->content_text_wrap_type = wrap;
1337 if (wd->content_text_obj)
1338 {
1339 content_text_obj = elm_object_part_content_get(wd->content_area,
1340 "elm.swallow.content");
1341 elm_label_line_wrap_set(content_text_obj, wrap);
1342 }
1343}
1344
1345EAPI Elm_Wrap_Type
1346elm_popup_content_text_wrap_type_get(const Evas_Object *obj)
1347{
1348 ELM_CHECK_WIDTYPE(obj, widtype) ELM_WRAP_LAST;
1349 Widget_Data *wd = elm_widget_data_get(obj);
1350
1351 if (!wd) return ELM_WRAP_LAST;
1352 return wd->content_text_wrap_type;
1353}
1354
1355EAPI void
1356elm_popup_orient_set(Evas_Object *obj, Elm_Popup_Orient orient)
1357{
1358 ELM_CHECK_WIDTYPE(obj, widtype);
1359 Widget_Data *wd = elm_widget_data_get(obj);
1360
1361 if (!wd) return;
1362 if (orient >= ELM_POPUP_ORIENT_LAST) return;
1363 elm_notify_orient_set(wd->notify, (Elm_Notify_Orient)orient);
1364}
1365
1366EAPI Elm_Popup_Orient
1367elm_popup_orient_get(const Evas_Object *obj)
1368{
1369 ELM_CHECK_WIDTYPE(obj, widtype) -1;
1370 Widget_Data *wd = elm_widget_data_get(obj);
1371
1372 if (!wd) return ELM_POPUP_ORIENT_LAST;
1373 return (Elm_Popup_Orient)elm_notify_orient_get(wd->notify);
1374}
1375
1376EAPI void
1377elm_popup_timeout_set(Evas_Object *obj, double timeout)
1378{
1379 ELM_CHECK_WIDTYPE(obj, widtype);
1380 Widget_Data *wd = elm_widget_data_get(obj);
1381
1382 if (!wd) return;
1383 elm_notify_timeout_set(wd->notify, timeout);
1384}
1385
1386EAPI double
1387elm_popup_timeout_get(const Evas_Object *obj)
1388{
1389 ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
1390 Widget_Data *wd = elm_widget_data_get(obj);
1391
1392 if (!wd) return 0.0;
1393 return elm_notify_timeout_get(wd->notify);
1394}
1395
1396EAPI void
1397elm_popup_allow_events_set(Evas_Object *obj, Eina_Bool allow)
1398{
1399 ELM_CHECK_WIDTYPE(obj, widtype);
1400 Eina_Bool allow_events = !!allow;
1401 Widget_Data *wd = elm_widget_data_get(obj);
1402
1403 if (!wd) return;
1404 elm_notify_allow_events_set(wd->notify, allow_events);
1405}
1406
1407EAPI Eina_Bool
1408elm_popup_allow_events_get(const Evas_Object *obj)
1409{
1410 ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
1411 Widget_Data *wd = elm_widget_data_get(obj);
1412
1413 if (!wd) return EINA_FALSE;
1414 return elm_notify_allow_events_get(wd->notify);
1415}
1416
1417EAPI Elm_Object_Item *
1418elm_popup_item_append(Evas_Object *obj, const char *label,
1419 Evas_Object *icon, Evas_Smart_Cb func,
1420 const void *data)
1421{
1422 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
1423 Evas_Object *prev_content;
1424 Elm_Popup_Content_Item *item;
1425 Widget_Data *wd = elm_widget_data_get(obj);
1426
1427 if (!wd) return NULL;
1428 item = elm_widget_item_new(obj, Elm_Popup_Content_Item);
1429 if (!item) return NULL;
1430 if (wd->content || wd->content_text_obj)
1431 {
1432 prev_content = elm_object_part_content_get(wd->content_area,
1433 "elm.swallow.content");
1434 if (prev_content)
1435 evas_object_del(prev_content);
1436 }
1437
1438 //The first item is appended.
1439 if (!wd->items)
1440 _list_new(obj);
1441
1442 item->func = func;
1443 item->base.data = data;
1444
1445 _item_new(item);
1446 _item_icon_set(item, icon);
1447 _item_text_set(item, label);
1448 elm_box_pack_end(wd->box, VIEW(item));
1449 wd->items = eina_list_append(wd->items, item);
1450
1451 _scroller_size_calc(obj);
1452 _sizing_eval(obj);
1453 return (Elm_Object_Item *)item;
1454}