1 #include <Elementary.h>
4 typedef struct _Widget_Data Widget_Data;
5 typedef struct _Item Item;
11 Evas_Object *rect, *clip;
12 Eina_Bool disable_animation: 1;
17 Evas_Object *obj, *base, *content;
18 Evas_Coord minw, minh;
22 static const char *widtype = NULL;
23 static void _del_hook(Evas_Object *obj);
24 static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
25 static void _theme_hook(Evas_Object *obj);
26 static void _sizing_eval(Evas_Object *obj);
27 static void _changed_size_hints(void *data,
31 static void _content_del(void *data,
35 static Eina_List *_item_get(Evas_Object *obj, Evas_Object *content);
37 static const char SIG_HIDE_FINISHED[] = "hide,finished";
39 static const Evas_Smart_Cb_Description _signals[] = {
40 {SIG_HIDE_FINISHED, ""},
45 _del_hook(Evas_Object *obj)
47 Widget_Data *wd = elm_widget_data_get(obj);
53 _mirrored_set(Evas_Object *obj, Eina_Bool rtl)
55 Widget_Data *wd = elm_widget_data_get(obj);
59 EINA_LIST_FOREACH(wd->stack, l, it)
60 edje_object_mirrored_set(it->base, rtl);
64 _theme_hook(Evas_Object *obj)
66 Widget_Data *wd = elm_widget_data_get(obj);
70 _elm_widget_mirrored_reload(obj);
71 _mirrored_set(obj, elm_widget_mirrored_get(obj));
72 EINA_LIST_FOREACH(wd->stack, l, it)
74 _elm_theme_object_set(obj, it->base, "pager", "base",
75 elm_widget_style_get(obj));
76 edje_object_scale_set(it->base, elm_widget_scale_get(obj) *
83 _item_get(Evas_Object *obj, Evas_Object *content)
85 Widget_Data *wd = elm_widget_data_get(obj);
90 EINA_LIST_FOREACH(wd->stack, l, it)
92 if (it->content == content)
100 _elm_pager_focus_next_hook(const Evas_Object *obj, Elm_Focus_Direction dir, Evas_Object **next)
102 Widget_Data *wd = elm_widget_data_get(obj);
105 if ((!wd) || (!wd->top))
108 cur = wd->top->content;
110 /* Try Focus cycle in subitem */
111 return elm_widget_focus_next_get(cur, dir, next);
115 _sizing_eval(Evas_Object *obj)
117 Widget_Data *wd = elm_widget_data_get(obj);
118 Evas_Coord minw = -1, minh = -1;
122 EINA_LIST_FOREACH(wd->stack, l, it)
124 if (it->minw > minw) minw = it->minw;
125 if (it->minh > minh) minh = it->minh;
127 evas_object_size_hint_min_set(obj, minw, minh);
128 evas_object_size_hint_max_set(obj, -1, -1);
132 _changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
135 Evas_Coord minw = -1, minh = -1;
136 evas_object_size_hint_min_get(it->content, &minw, &minh);
137 // FIXME: why is this needed? how does edje get this unswallowed or
138 // lose its callbacks to edje
139 edje_object_part_swallow(it->base, "elm.swallow.content", it->content);
140 edje_object_size_min_calc(it->base, &it->minw, &it->minh);
141 _sizing_eval(it->obj);
145 _eval_top(Evas_Object *obj)
147 Widget_Data *wd = elm_widget_data_get(obj);
148 Eina_Bool show_noanimate = EINA_TRUE;
151 if (!wd->stack) return;
152 ittop = eina_list_last(wd->stack)->data;
153 if (ittop != wd->top)
156 const char *onshow, *onhide;
161 if(wd->disable_animation)
163 edje_object_signal_emit(o, "elm,action,hide,noanimate", "elm");
165 wd->stack = eina_list_remove(wd->stack, wd->top);
167 else if (wd->top->popme)
169 edje_object_signal_emit(o, "elm,action,pop", "elm");
170 wd->stack = eina_list_remove(wd->stack, wd->top);
173 edje_object_signal_emit(o, "elm,action,hide", "elm");
174 onhide = edje_object_data_get(o, "onhide");
177 if (!strcmp(onhide, "raise")) evas_object_raise(o);
178 else if (!strcmp(onhide, "lower")) evas_object_lower(o);
183 show_noanimate = EINA_FALSE;
185 wd->oldtop = wd->top;
189 if ((!show_noanimate)||(wd->disable_animation))
191 edje_object_signal_emit(o, "elm,action,show,noanimate", "elm");
195 if (elm_object_focus_get(wd->oldtop->content))
196 elm_widget_focused_object_clear(wd->oldtop->content);
197 if (wd->oldtop->popme)
198 edje_object_signal_emit(o, "elm,action,show", "elm");
200 edje_object_signal_emit(o, "elm,action,push", "elm");
203 edje_object_signal_emit(o, "elm,action,push", "elm");
204 onshow = edje_object_data_get(o, "onshow");
207 if (!strcmp(onshow, "raise")) evas_object_raise(o);
208 else if (!strcmp(onshow, "lower")) evas_object_lower(o);
214 _move(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
216 Widget_Data *wd = elm_widget_data_get(data);
221 evas_object_geometry_get(obj, &x, &y, NULL, NULL);
222 EINA_LIST_FOREACH(wd->stack, l, it)
223 evas_object_move(it->base, x, y);
227 _content_del(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
229 Widget_Data *wd = elm_widget_data_get(data);
233 l = _item_get(data, obj);
236 wd->stack = eina_list_remove_list(wd->stack, l);
237 evas_object_event_callback_del_full
238 (obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints, it);
239 evas_object_del(it->base);
245 _resize(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
247 Widget_Data *wd = elm_widget_data_get(data);
252 evas_object_geometry_get(obj, NULL, NULL, &w, &h);
253 EINA_LIST_FOREACH(wd->stack, l, it) evas_object_resize(it->base, w, h);
257 _signal_hide_finished(void *data, Evas_Object *obj __UNUSED__, const char *emission __UNUSED__, const char *source __UNUSED__)
260 Evas_Object *obj2 = it->obj;
261 Evas_Object *content = it->content;
265 evas_object_del(it->base);
266 evas_object_event_callback_del_full(content,
267 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
270 evas_object_event_callback_del(content,
273 evas_object_del(content);
278 evas_object_hide(it->base);
279 edje_object_signal_emit(it->base, "elm,action,reset", "elm");
280 edje_object_message_signal_process(it->base);
281 evas_object_hide(content);
283 evas_object_smart_callback_call(obj2, SIG_HIDE_FINISHED, content);
288 elm_pager_add(Evas_Object *parent)
294 ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
296 ELM_SET_WIDTYPE(widtype, "pager");
297 elm_widget_type_set(obj, "pager");
298 elm_widget_sub_object_add(parent, obj);
299 elm_widget_data_set(obj, wd);
300 elm_widget_del_hook_set(obj, _del_hook);
301 elm_widget_theme_hook_set(obj, _theme_hook);
302 elm_widget_focus_next_hook_set(obj, _elm_pager_focus_next_hook);
303 elm_widget_can_focus_set(obj, EINA_FALSE);
305 wd->clip = evas_object_rectangle_add(e);
306 elm_widget_resize_object_set(obj, wd->clip);
307 elm_widget_sub_object_add(obj, wd->clip);
309 wd->rect = evas_object_rectangle_add(e);
310 elm_widget_sub_object_add(obj, wd->rect);
311 evas_object_color_set(wd->rect, 255, 255, 255, 0);
312 evas_object_clip_set(wd->rect, wd->clip);
314 evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
315 evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
317 evas_object_smart_callbacks_descriptions_set(obj, _signals);
319 _mirrored_set(obj, elm_widget_mirrored_get(obj));
325 elm_pager_content_push(Evas_Object *obj, Evas_Object *content)
327 ELM_CHECK_WIDTYPE(obj, widtype);
328 Widget_Data *wd = elm_widget_data_get(obj);
329 Evas_Coord x, y, w, h;
332 if ((!wd) || (!content)) return;
333 if (_item_get(obj, content)) return;
338 it->content = content;
339 it->base = edje_object_add(evas_object_evas_get(obj));
340 evas_object_smart_member_add(it->base, obj);
341 evas_object_geometry_get(obj, &x, &y, &w, &h);
342 evas_object_move(it->base, x, y);
343 evas_object_resize(it->base, w, h);
344 evas_object_clip_set(it->base, wd->clip);
345 elm_widget_sub_object_add(obj, it->base);
346 elm_widget_sub_object_add(obj, it->content);
347 _elm_theme_object_set(obj,
351 elm_widget_style_get(obj));
352 edje_object_signal_callback_add(it->base,
353 "elm,action,hide,finished",
355 _signal_hide_finished,
357 evas_object_event_callback_add(it->content,
358 EVAS_CALLBACK_CHANGED_SIZE_HINTS,
361 evas_object_event_callback_add(it->content,
365 edje_object_part_swallow(it->base, "elm.swallow.content", it->content);
366 edje_object_size_min_calc(it->base, &it->minw, &it->minh);
367 evas_object_data_set(it->base, "_elm_leaveme", obj);
368 evas_object_show(it->content);
369 wd->stack = eina_list_append(wd->stack, it);
375 elm_pager_content_pop(Evas_Object *obj)
377 ELM_CHECK_WIDTYPE(obj, widtype);
378 Widget_Data *wd = elm_widget_data_get(obj);
382 if (!wd->stack) return;
383 it = eina_list_last(wd->stack)->data;
384 it->popme = EINA_TRUE;
385 ll = eina_list_last(wd->stack);
396 edje_object_signal_emit(o, "elm,action,pop", "elm");
397 wd->stack = eina_list_remove(wd->stack, it);
398 onhide = edje_object_data_get(o, "onhide");
401 if (!strcmp(onhide, "raise")) evas_object_raise(o);
402 else if (!strcmp(onhide, "lower")) evas_object_lower(o);
409 elm_pager_content_promote(obj, it->content);
417 Evas_Object *obj = data;
418 evas_object_del(obj);
422 elm_pager_to_content_pop(Evas_Object *obj, Evas_Object *content)
424 ELM_CHECK_WIDTYPE(obj, widtype);
425 Widget_Data *wd = elm_widget_data_get(obj);
429 if (!wd->stack) return;
430 it = eina_list_last(wd->stack)->data;
431 it->popme = EINA_TRUE;
432 ll = eina_list_last(wd->stack);
438 if(it->content != content)
440 wd->stack = eina_list_remove_list(wd->stack, ll);
441 ecore_job_add(_del_job, it->content);
454 elm_pager_content_promote(Evas_Object *obj, Evas_Object *content)
456 ELM_CHECK_WIDTYPE(obj, widtype);
457 Widget_Data *wd = elm_widget_data_get(obj);
461 l = _item_get(obj, content);
465 wd->stack = eina_list_remove_list(wd->stack, l);
466 wd->stack = eina_list_append(wd->stack, it);
471 elm_pager_content_bottom_get(const Evas_Object *obj)
473 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
474 Widget_Data *wd = elm_widget_data_get(obj);
476 if (!wd) return NULL;
477 if (!wd->stack) return NULL;
478 it = wd->stack->data;
483 elm_pager_content_top_get(const Evas_Object *obj)
485 ELM_CHECK_WIDTYPE(obj, widtype) NULL;
486 Widget_Data *wd = elm_widget_data_get(obj);
487 if (!wd) return NULL;
488 if (!wd->top) return NULL;
489 return wd->top->content;
493 elm_pager_animation_disabled_set(Evas_Object *obj, Eina_Bool disable)
495 ELM_CHECK_WIDTYPE(obj, widtype);
496 Widget_Data *wd = elm_widget_data_get(obj);
497 wd->disable_animation = disable;