2009-02-27 23:32:50 -08:00
|
|
|
#include <Elementary.h>
|
|
|
|
#include "elm_priv.h"
|
|
|
|
|
2009-05-19 02:29:20 -07:00
|
|
|
/**
|
|
|
|
* @defgroup Pager Pager
|
|
|
|
*
|
|
|
|
* The pager is an object that allows flipping (with animation) between 1 or more “pages” of objects, much like a stack of windows within the window.
|
|
|
|
*
|
|
|
|
* Objects can be pushed or popped from he stack or deleted as normal. Pushes an pops will animate (and a pop will delete the object once the animation is finished). Any object in the pager can be promoted to the top (from its current stacking position) as well. Objects are pushed to the top with elm_pager_content_push() and when the top item is no longer wanted, simply pop it with elm_pager_content_pop() and it will also be deleted. Any object you wish to promote to the top that is already in the pager, simply use elm_pager_content_promote(). If an object is no longer needed and is not the top item, just delete it as normal. You can query which objects are the top and bottom with elm_pager_content_bottom_get() and elm_pager_content_top_get()
|
|
|
|
*/
|
|
|
|
|
2009-02-27 23:32:50 -08:00
|
|
|
typedef struct _Widget_Data Widget_Data;
|
2009-03-02 00:59:00 -08:00
|
|
|
typedef struct _Item Item;
|
2009-02-27 23:32:50 -08:00
|
|
|
|
|
|
|
struct _Widget_Data
|
|
|
|
{
|
|
|
|
Eina_List *stack;
|
2009-03-02 00:59:00 -08:00
|
|
|
Item *top, *oldtop;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct _Item
|
|
|
|
{
|
|
|
|
Evas_Object *obj, *base, *content;
|
|
|
|
Evas_Coord minw, minh;
|
2009-03-02 01:42:58 -08:00
|
|
|
Evas_Bool popme : 1;
|
2009-02-27 23:32:50 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
static void _del_hook(Evas_Object *obj);
|
|
|
|
static void _theme_hook(Evas_Object *obj);
|
|
|
|
static void _sizing_eval(Evas_Object *obj);
|
|
|
|
static void _changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info);
|
|
|
|
static void _sub_del(void *data, Evas_Object *obj, void *event_info);
|
|
|
|
|
|
|
|
static void
|
|
|
|
_del_hook(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
free(wd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_theme_hook(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-03-02 00:59:00 -08:00
|
|
|
Eina_List *l;
|
|
|
|
Item *it;
|
|
|
|
EINA_LIST_FOREACH(wd->stack, l, it)
|
|
|
|
edje_object_scale_set(it->base, elm_widget_scale_get(obj) * _elm_config->scale);
|
2009-02-27 23:32:50 -08:00
|
|
|
_sizing_eval(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_sizing_eval(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
|
|
|
Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
|
2009-03-02 00:59:00 -08:00
|
|
|
Eina_List *l;
|
|
|
|
Item *it;
|
|
|
|
EINA_LIST_FOREACH(wd->stack, l, it)
|
|
|
|
{
|
|
|
|
if (it->minw > minw) minw = it->minw;
|
|
|
|
if (it->minh > minh) minh = it->minh;
|
|
|
|
}
|
2009-02-27 23:32:50 -08:00
|
|
|
evas_object_size_hint_min_set(obj, minw, minh);
|
|
|
|
evas_object_size_hint_max_set(obj, maxw, maxh);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_changed_size_hints(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
2009-03-02 01:42:58 -08:00
|
|
|
Item *it = data;
|
|
|
|
edje_object_part_swallow(it->base, "elm.swallow.content", it->content);
|
2009-03-12 22:50:38 -07:00
|
|
|
edje_object_size_min_calc(it->base, &it->minw, &it->minh);
|
2009-03-02 01:42:58 -08:00
|
|
|
_sizing_eval(it->obj);
|
2009-02-27 23:32:50 -08:00
|
|
|
}
|
|
|
|
|
2009-03-01 15:52:13 -08:00
|
|
|
static void
|
|
|
|
_eval_top(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-03-02 00:59:00 -08:00
|
|
|
Item *it, *ittop;
|
|
|
|
if (!wd->stack) return;
|
|
|
|
ittop = eina_list_last(wd->stack)->data;
|
|
|
|
if (ittop != wd->top)
|
2009-03-01 15:52:13 -08:00
|
|
|
{
|
2009-03-02 00:59:00 -08:00
|
|
|
Evas_Object *o;
|
|
|
|
const char *onshow, *onhide;
|
|
|
|
|
|
|
|
if (wd->top)
|
|
|
|
{
|
|
|
|
o = wd->top->base;
|
|
|
|
edje_object_signal_emit(o, "elm,action,hide", "elm");
|
|
|
|
onhide = edje_object_data_get(o, "onhide");
|
|
|
|
if (onhide)
|
|
|
|
{
|
|
|
|
if (!strcmp(onhide, "raise")) evas_object_raise(o);
|
|
|
|
else if (!strcmp(onhide, "lower")) evas_object_lower(o);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wd->top = ittop;
|
|
|
|
o = wd->top->base;
|
|
|
|
evas_object_show(o);
|
|
|
|
edje_object_signal_emit(o, "elm,action,show", "elm");
|
|
|
|
onshow = edje_object_data_get(o, "onshow");
|
|
|
|
if (onshow)
|
|
|
|
{
|
|
|
|
if (!strcmp(onshow, "raise")) evas_object_raise(o);
|
|
|
|
else if (!strcmp(onshow, "lower")) evas_object_lower(o);
|
|
|
|
}
|
2009-03-01 15:52:13 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-02 00:59:00 -08:00
|
|
|
static void
|
|
|
|
_move(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
|
|
|
Evas_Coord x, y;
|
|
|
|
Eina_List *l;
|
|
|
|
Item *it;
|
|
|
|
evas_object_geometry_get(obj, &x, &y, NULL, NULL);
|
|
|
|
EINA_LIST_FOREACH(wd->stack, l, it)
|
|
|
|
evas_object_move(it->base, x, y);
|
|
|
|
}
|
|
|
|
|
2009-03-01 21:48:14 -08:00
|
|
|
static void
|
2009-03-02 01:42:58 -08:00
|
|
|
_sub_del(void *data, Evas_Object *obj, void *event_info)
|
2009-03-01 21:48:14 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
2009-03-02 01:42:58 -08:00
|
|
|
Evas_Object *sub = event_info;
|
2009-03-02 00:59:00 -08:00
|
|
|
Eina_List *l;
|
|
|
|
Item *it;
|
|
|
|
EINA_LIST_FOREACH(wd->stack, l, it)
|
2009-03-02 01:42:58 -08:00
|
|
|
{
|
|
|
|
if (it->content == sub)
|
|
|
|
{
|
|
|
|
wd->stack = eina_list_remove_list(wd->stack, l);
|
|
|
|
evas_object_event_callback_del
|
|
|
|
(sub, EVAS_CALLBACK_CHANGED_SIZE_HINTS, _changed_size_hints);
|
|
|
|
evas_object_del(it->base);
|
|
|
|
_eval_top(it->obj);
|
|
|
|
free(it);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-03-02 00:59:00 -08:00
|
|
|
|
|
|
|
static void
|
2009-03-02 01:42:58 -08:00
|
|
|
_resize(void *data, Evas *e, Evas_Object *obj, void *event_info)
|
2009-03-02 00:59:00 -08:00
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(data);
|
2009-03-02 01:42:58 -08:00
|
|
|
Evas_Coord w, h;
|
|
|
|
Eina_List *l;
|
|
|
|
Item *it;
|
|
|
|
evas_object_geometry_get(obj, NULL, NULL, &w, &h);
|
|
|
|
EINA_LIST_FOREACH(wd->stack, l, it)
|
|
|
|
evas_object_resize(it->base, w, h);
|
2009-03-02 00:59:00 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_signal_hide_finished(void *data, Evas_Object *obj, const char *emission, const char *source)
|
|
|
|
{
|
|
|
|
Item *it = data;
|
2009-03-02 01:42:58 -08:00
|
|
|
Evas_Object *obj2 = it->obj;
|
2009-03-02 00:59:00 -08:00
|
|
|
evas_object_hide(it->base);
|
2009-03-02 01:42:58 -08:00
|
|
|
edje_object_signal_emit(it->base, "elm,action,reset", "elm");
|
|
|
|
edje_object_message_signal_process(it->base);
|
|
|
|
if (it->popme)
|
|
|
|
{
|
|
|
|
evas_object_del(it->content);
|
|
|
|
}
|
|
|
|
_sizing_eval(obj2);
|
2009-03-01 21:48:14 -08:00
|
|
|
}
|
|
|
|
|
2009-05-19 02:29:20 -07:00
|
|
|
/**
|
|
|
|
* XXX
|
|
|
|
*
|
|
|
|
* @param xxx XXX
|
|
|
|
* @return XXX
|
|
|
|
*
|
|
|
|
* @ingroup Pager
|
|
|
|
*/
|
2009-02-27 23:32:50 -08:00
|
|
|
EAPI Evas_Object *
|
|
|
|
elm_pager_add(Evas_Object *parent)
|
|
|
|
{
|
|
|
|
Evas_Object *obj;
|
|
|
|
Evas *e;
|
|
|
|
Widget_Data *wd;
|
|
|
|
|
|
|
|
wd = ELM_NEW(Widget_Data);
|
|
|
|
e = evas_object_evas_get(parent);
|
|
|
|
obj = elm_widget_add(e);
|
2009-05-13 05:21:52 -07:00
|
|
|
elm_widget_type_set(obj, "pager");
|
|
|
|
elm_widget_sub_object_add(parent, obj);
|
2009-02-27 23:32:50 -08:00
|
|
|
elm_widget_data_set(obj, wd);
|
|
|
|
elm_widget_del_hook_set(obj, _del_hook);
|
|
|
|
elm_widget_theme_hook_set(obj, _theme_hook);
|
|
|
|
|
2009-03-02 00:59:00 -08:00
|
|
|
evas_object_event_callback_add(obj, EVAS_CALLBACK_MOVE, _move, obj);
|
|
|
|
evas_object_event_callback_add(obj, EVAS_CALLBACK_RESIZE, _resize, obj);
|
2009-02-27 23:32:50 -08:00
|
|
|
|
|
|
|
evas_object_smart_callback_add(obj, "sub-object-del", _sub_del, obj);
|
|
|
|
|
|
|
|
_sizing_eval(obj);
|
|
|
|
return obj;
|
|
|
|
}
|
|
|
|
|
2009-05-19 02:29:20 -07:00
|
|
|
/**
|
|
|
|
* XXX
|
|
|
|
*
|
|
|
|
* @param xxx XXX
|
|
|
|
* @return XXX
|
|
|
|
*
|
|
|
|
* @ingroup Pager
|
|
|
|
*/
|
2009-02-27 23:32:50 -08:00
|
|
|
EAPI void
|
|
|
|
elm_pager_content_push(Evas_Object *obj, Evas_Object *content)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-03-02 00:59:00 -08:00
|
|
|
Item *it = calloc(1, sizeof(Item));
|
|
|
|
Evas_Coord x, y, w, h;
|
|
|
|
if (!it) return;
|
|
|
|
it->obj = obj;
|
|
|
|
it->content = content;
|
|
|
|
it->base = edje_object_add(evas_object_evas_get(obj));
|
|
|
|
evas_object_smart_member_add(it->base, obj);
|
|
|
|
evas_object_geometry_get(obj, &x, &y, &w, &h);
|
|
|
|
evas_object_move(it->base, x, y);
|
|
|
|
evas_object_resize(it->base, w, h);
|
|
|
|
elm_widget_sub_object_add(obj, it->base);
|
2009-03-02 01:42:58 -08:00
|
|
|
elm_widget_sub_object_add(obj, it->content);
|
2009-04-22 21:03:27 -07:00
|
|
|
_elm_theme_set(it->base, "pager", "base", elm_widget_style_get(obj));
|
2009-03-02 00:59:00 -08:00
|
|
|
edje_object_signal_callback_add(it->base, "elm,action,hide,finished", "", _signal_hide_finished, it);
|
2009-03-02 01:42:58 -08:00
|
|
|
edje_object_part_swallow(it->base, "elm.swallow.content", it->content);
|
2009-03-02 00:59:00 -08:00
|
|
|
edje_object_size_min_calc(it->base, &it->minw, &it->minh);
|
2009-03-02 01:42:58 -08:00
|
|
|
evas_object_show(it->content);
|
|
|
|
evas_object_event_callback_add(content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
|
|
|
|
_changed_size_hints, it);
|
2009-03-02 00:59:00 -08:00
|
|
|
wd->stack = eina_list_append(wd->stack, it);
|
|
|
|
_eval_top(obj);
|
|
|
|
_sizing_eval(obj);
|
2009-02-27 23:32:50 -08:00
|
|
|
}
|
|
|
|
|
2009-05-19 02:29:20 -07:00
|
|
|
/**
|
|
|
|
* XXX
|
|
|
|
*
|
|
|
|
* @param xxx XXX
|
|
|
|
* @return XXX
|
|
|
|
*
|
|
|
|
* @ingroup Pager
|
|
|
|
*/
|
2009-02-27 23:32:50 -08:00
|
|
|
EAPI void
|
|
|
|
elm_pager_content_pop(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-03-02 01:42:58 -08:00
|
|
|
Eina_List *ll;
|
|
|
|
Item *it;
|
|
|
|
if (!wd->stack) return;
|
|
|
|
it = eina_list_last(wd->stack)->data;
|
|
|
|
it->popme = 1;
|
|
|
|
ll = eina_list_last(wd->stack);
|
|
|
|
if (ll)
|
|
|
|
{
|
|
|
|
ll = ll->prev;
|
|
|
|
if (!ll)
|
|
|
|
{
|
|
|
|
Evas_Object *o;
|
|
|
|
const char *onhide;
|
|
|
|
|
|
|
|
wd->top = it;
|
|
|
|
o = wd->top->base;
|
|
|
|
edje_object_signal_emit(o, "elm,action,hide", "elm");
|
|
|
|
onhide = edje_object_data_get(o, "onhide");
|
|
|
|
if (onhide)
|
|
|
|
{
|
|
|
|
if (!strcmp(onhide, "raise")) evas_object_raise(o);
|
|
|
|
else if (!strcmp(onhide, "lower")) evas_object_lower(o);
|
|
|
|
}
|
|
|
|
wd->top = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
it = ll->data;
|
|
|
|
elm_pager_content_promote(obj, it->content);
|
|
|
|
}
|
|
|
|
}
|
2009-02-27 23:32:50 -08:00
|
|
|
}
|
|
|
|
|
2009-05-19 02:29:20 -07:00
|
|
|
/**
|
|
|
|
* XXX
|
|
|
|
*
|
|
|
|
* @param xxx XXX
|
|
|
|
* @return XXX
|
|
|
|
*
|
|
|
|
* @ingroup Pager
|
|
|
|
*/
|
2009-02-27 23:32:50 -08:00
|
|
|
EAPI void
|
|
|
|
elm_pager_content_promote(Evas_Object *obj, Evas_Object *content)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-03-02 00:59:00 -08:00
|
|
|
Eina_List *l;
|
|
|
|
Item *it;
|
|
|
|
EINA_LIST_FOREACH(wd->stack, l, it)
|
|
|
|
{
|
|
|
|
if (it->content == content)
|
|
|
|
{
|
|
|
|
wd->stack = eina_list_remove_list(wd->stack, l);
|
|
|
|
wd->stack = eina_list_append(wd->stack, it);
|
|
|
|
_eval_top(obj);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2009-02-27 23:32:50 -08:00
|
|
|
}
|
|
|
|
|
2009-05-19 02:29:20 -07:00
|
|
|
/**
|
|
|
|
* XXX
|
|
|
|
*
|
|
|
|
* @param xxx XXX
|
|
|
|
* @return XXX
|
|
|
|
*
|
|
|
|
* @ingroup Pager
|
|
|
|
*/
|
2009-02-27 23:32:50 -08:00
|
|
|
EAPI Evas_Object *
|
|
|
|
elm_pager_content_bottom_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-03-02 01:42:58 -08:00
|
|
|
Item *it;
|
|
|
|
if (!wd->stack) return NULL;
|
|
|
|
it = wd->stack->data;
|
|
|
|
return it->content;
|
2009-02-27 23:32:50 -08:00
|
|
|
}
|
|
|
|
|
2009-05-19 02:29:20 -07:00
|
|
|
/**
|
|
|
|
* XXX
|
|
|
|
*
|
|
|
|
* @param xxx XXX
|
|
|
|
* @return XXX
|
|
|
|
*
|
|
|
|
* @ingroup Pager
|
|
|
|
*/
|
2009-02-27 23:32:50 -08:00
|
|
|
EAPI Evas_Object *
|
|
|
|
elm_pager_content_top_get(Evas_Object *obj)
|
|
|
|
{
|
|
|
|
Widget_Data *wd = elm_widget_data_get(obj);
|
2009-03-02 01:42:58 -08:00
|
|
|
Item *it;
|
|
|
|
if (!wd->stack) return NULL;
|
|
|
|
it = eina_list_last(wd->stack)->data;
|
|
|
|
return it->content;
|
2009-02-27 23:32:50 -08:00
|
|
|
}
|
|
|
|
|