diff options
author | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-04-22 09:20:32 +1000 |
commit | 3ad3455551be0d7859ecb02290376206d5e66498 (patch) | |
tree | 497917e12b4d7f458dff9765d9b53f64c4e03fc3 /libraries/elementary/src/lib/elc_popup.c | |
parent | Update EFL to latest beta. (diff) | |
download | SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.zip SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.gz SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.bz2 SledjHamr-3ad3455551be0d7859ecb02290376206d5e66498.tar.xz |
And actually include new files, plus elementary libraries.
Diffstat (limited to '')
-rw-r--r-- | libraries/elementary/src/lib/elc_popup.c | 1454 |
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 | ||
5 | typedef struct _Widget_Data Widget_Data; | ||
6 | typedef struct _Elm_Popup_Content_Item Elm_Popup_Content_Item; | ||
7 | typedef struct _Action_Area_Data Action_Area_Data; | ||
8 | |||
9 | struct _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 | |||
30 | struct _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 | |||
39 | struct _Action_Area_Data | ||
40 | { | ||
41 | Evas_Object *obj; | ||
42 | Evas_Object *btn; | ||
43 | Eina_Bool delete_me; | ||
44 | }; | ||
45 | |||
46 | static const char *widtype = NULL; | ||
47 | static void _del_hook(Evas_Object *obj); | ||
48 | static void _theme_hook(Evas_Object *obj); | ||
49 | static void _text_set_hook(Evas_Object *obj, const char *part, | ||
50 | const char *label); | ||
51 | static const char *_text_get_hook(const Evas_Object *obj, | ||
52 | const char *part); | ||
53 | static void _content_set_hook(Evas_Object *obj, const char *part, | ||
54 | Evas_Object *content); | ||
55 | static Evas_Object *_content_get_hook(Evas_Object *obj, | ||
56 | const char *part); | ||
57 | static Evas_Object *_content_unset_hook(Evas_Object *obj, | ||
58 | const char *part); | ||
59 | static void _item_text_set_hook(Elm_Object_Item *it, const char *part, | ||
60 | const char *label); | ||
61 | static const char *_item_text_get_hook(const Elm_Object_Item *it, | ||
62 | const char *part); | ||
63 | static void _item_content_set_hook(Elm_Object_Item *it, const char *part, | ||
64 | Evas_Object *content); | ||
65 | static Evas_Object *_item_content_unset_hook(const Elm_Object_Item *it, | ||
66 | const char *part); | ||
67 | static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it, | ||
68 | const char *part); | ||
69 | static void _item_disable_hook(Elm_Object_Item *it); | ||
70 | static void _item_del_pre_hook(Elm_Object_Item *it); | ||
71 | static void _item_signal_emit_hook(Elm_Object_Item *it, const char *emission, | ||
72 | const char *source); | ||
73 | static void _sizing_eval(Evas_Object *obj); | ||
74 | static void _block_clicked_cb(void *data, Evas_Object *obj, void *event_info); | ||
75 | static void _notify_resize(void *data, Evas *e, Evas_Object *obj, | ||
76 | void *event_info); | ||
77 | static void _scroller_resize(void *data, Evas *e, Evas_Object *obj, | ||
78 | void *event_info); | ||
79 | static void _timeout(void *data, Evas_Object *obj , void *event_info); | ||
80 | static void _sub_del(void *data, Evas_Object *obj, void *event_info); | ||
81 | static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl); | ||
82 | static void _restack(void *data, Evas *e, Evas_Object *obj, void *event_info); | ||
83 | static void _layout_change_cb(void *data, Evas_Object *obj __UNUSED__, | ||
84 | const char *emission __UNUSED__, | ||
85 | const char *source __UNUSED__); | ||
86 | static void _item_new(Elm_Popup_Content_Item *item); | ||
87 | static void _remove_items(Widget_Data *wd); | ||
88 | static void _list_new(Evas_Object *obj); | ||
89 | static void _list_del(Widget_Data *wd); | ||
90 | static void _item_sizing_eval(Elm_Popup_Content_Item *item); | ||
91 | static void _item_select_cb(void *data, Evas_Object *obj __UNUSED__, | ||
92 | const char *emission __UNUSED__, | ||
93 | const char *source __UNUSED__); | ||
94 | static void _scroller_size_calc(Evas_Object *obj); | ||
95 | static void _action_button_set(Evas_Object *obj, Evas_Object *btn, | ||
96 | unsigned int idx); | ||
97 | static Evas_Object *_action_button_get(Evas_Object *obj, unsigned int idx); | ||
98 | static Evas_Object *_action_button_unset(Evas_Object *obj, unsigned int idx); | ||
99 | static void _button_remove(Evas_Object *obj, Evas_Object *content, | ||
100 | Eina_Bool delete); | ||
101 | static void _popup_show(void *data, Evas *e, Evas_Object *obj, | ||
102 | void *event_info); | ||
103 | static void _popup_hide(void *data, Evas *e, Evas_Object *obj, | ||
104 | void *event_info); | ||
105 | static const char SIG_BLOCK_CLICKED[] = "block,clicked"; | ||
106 | static const char SIG_TIMEOUT[] = "timeout"; | ||
107 | static 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 | |||
117 | static 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 | |||
133 | static 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 | |||
142 | static 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 | |||
170 | static 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 | |||
237 | static 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 | |||
248 | static 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 | |||
284 | static 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 | |||
291 | static 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 | |||
359 | static 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 | |||
369 | static 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 | |||
376 | static 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 | |||
390 | static 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 | |||
402 | static 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 | |||
412 | static 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 | |||
437 | static 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 | |||
466 | static 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 | |||
480 | static 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 | |||
509 | static 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 | |||
520 | static 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 | |||
545 | static 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 | |||
568 | static 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 | |||
579 | static 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 | |||
602 | static 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 | |||
641 | static 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 | |||
657 | static 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 | |||
667 | static 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 | |||
680 | static 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 | |||
697 | static 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 | |||
720 | static 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 | |||
750 | static 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 | |||
803 | static 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 | |||
860 | static 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 | |||
891 | static 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 | |||
901 | static 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 | |||
911 | static 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 | |||
924 | static 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 | |||
956 | static 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 | |||
971 | static 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 | |||
984 | static 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 | |||
1003 | static 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 | |||
1035 | static 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 | |||
1047 | static 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 | |||
1061 | static 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 | |||
1075 | static 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 | |||
1087 | static 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 | |||
1112 | static 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 | |||
1125 | static 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 | |||
1138 | static 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 | |||
1153 | static 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 | |||
1168 | static 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 | |||
1182 | static 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 | |||
1201 | static 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 | |||
1211 | static 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 | |||
1223 | static 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 | |||
1235 | EAPI Evas_Object * | ||
1236 | elm_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 | |||
1326 | EAPI void | ||
1327 | elm_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 | |||
1345 | EAPI Elm_Wrap_Type | ||
1346 | elm_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 | |||
1355 | EAPI void | ||
1356 | elm_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 | |||
1366 | EAPI Elm_Popup_Orient | ||
1367 | elm_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 | |||
1376 | EAPI void | ||
1377 | elm_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 | |||
1386 | EAPI double | ||
1387 | elm_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 | |||
1396 | EAPI void | ||
1397 | elm_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 | |||
1407 | EAPI Eina_Bool | ||
1408 | elm_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 | |||
1417 | EAPI Elm_Object_Item * | ||
1418 | elm_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 | } | ||