forked from enlightenment/efl
211 lines
6.3 KiB
C
211 lines
6.3 KiB
C
#ifdef HAVE_CONFIG_H
|
|
# include "elementary_config.h"
|
|
#endif
|
|
|
|
#include <Elementary.h>
|
|
#include "elm_priv.h"
|
|
#include "efl_ui_widget_pan.h"
|
|
|
|
#define MY_CLASS EFL_UI_PAN_CLASS
|
|
#define MY_CLASS_NAME "Efl_Ui_Pan"
|
|
|
|
#define EFL_UI_PAN_DATA_GET(o, sd) \
|
|
Efl_Ui_Pan_Data *sd = efl_data_scope_safe_get(o, MY_CLASS)
|
|
|
|
#define EFL_UI_PAN_DATA_GET_OR_RETURN(o, ptr, ...) \
|
|
EFL_UI_PAN_DATA_GET(o, ptr); \
|
|
if (EINA_UNLIKELY(!ptr)) \
|
|
{ \
|
|
ERR("No widget data for object %p (%s)", \
|
|
o, evas_object_type_get(o)); \
|
|
return __VA_ARGS__; \
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_pan_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Pan_Data *psd, Eina_Position2D pos)
|
|
{
|
|
if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_MOVE, 0, pos.x, pos.y))
|
|
return;
|
|
|
|
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
|
|
|
|
psd->x = pos.x;
|
|
psd->y = pos.y;
|
|
|
|
evas_object_smart_changed(obj);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_pan_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Pan_Data *psd, Eina_Size2D sz)
|
|
{
|
|
if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_RESIZE, 0, sz.w, sz.h))
|
|
return;
|
|
|
|
efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
|
|
|
|
psd->w = sz.w;
|
|
psd->h = sz.h;
|
|
|
|
evas_object_smart_changed(obj);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_pan_efl_gfx_entity_visible_set(Eo *obj, Efl_Ui_Pan_Data *psd, Eina_Bool vis)
|
|
{
|
|
if (_evas_object_intercept_call(obj, EVAS_OBJECT_INTERCEPT_CB_VISIBLE, 0, vis))
|
|
return;
|
|
|
|
efl_gfx_entity_visible_set(efl_super(obj, MY_CLASS), vis);
|
|
if (psd->content) efl_gfx_entity_visible_set(psd->content, vis);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_pan_pan_position_set(Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *psd, Eina_Position2D pos)
|
|
{
|
|
if ((pos.x == psd->px) && (pos.y == psd->py)) return;
|
|
psd->px = pos.x;
|
|
psd->py = pos.y;
|
|
|
|
evas_object_smart_changed(obj);
|
|
efl_event_callback_call(obj, EFL_UI_PAN_EVENT_PAN_CONTENT_POSITION_CHANGED, &pos);
|
|
}
|
|
|
|
EOLIAN static Eina_Position2D
|
|
_efl_ui_pan_pan_position_get(const Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *psd)
|
|
{
|
|
return EINA_POSITION2D(psd->px, psd->py);
|
|
}
|
|
|
|
EOLIAN static Eina_Position2D
|
|
_efl_ui_pan_pan_position_max_get(const Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *psd)
|
|
{
|
|
Eina_Position2D pos = { 0, 0};
|
|
if (psd->w < psd->content_w) pos.x = psd->content_w - psd->w;
|
|
if (psd->h < psd->content_h) pos.y = psd->content_h - psd->h;
|
|
|
|
return pos;
|
|
}
|
|
|
|
EOLIAN static Eina_Position2D
|
|
_efl_ui_pan_pan_position_min_get(const Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *_pd EINA_UNUSED)
|
|
{
|
|
return EINA_POSITION2D(0 ,0);
|
|
}
|
|
|
|
EOLIAN static Eina_Size2D
|
|
_efl_ui_pan_content_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *psd)
|
|
{
|
|
return EINA_SIZE2D(psd->content_w, psd->content_h);
|
|
}
|
|
|
|
EOLIAN static Eo *
|
|
_efl_ui_pan_efl_object_constructor(Eo *obj, Efl_Ui_Pan_Data *_pd EINA_UNUSED)
|
|
{
|
|
efl_canvas_group_clipped_set(obj, EINA_TRUE);
|
|
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
|
|
|
return obj;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_pan_efl_object_destructor(Eo *obj, Efl_Ui_Pan_Data *sd EINA_UNUSED)
|
|
{
|
|
/* our implementation is a little bit incomplete, efl_content_set(obj, NULL) does not delete the content, However, if we do that, list grid and scroller would fail, because the assume ownership of the content */
|
|
Eo *content = efl_content_unset(obj);
|
|
efl_del(content);
|
|
efl_destructor(efl_super(obj, MY_CLASS));
|
|
}
|
|
|
|
static void
|
|
_efl_ui_pan_content_del_cb(void *data,
|
|
Evas *e EINA_UNUSED,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
void *event_info EINA_UNUSED)
|
|
{
|
|
efl_content_unset(data);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_pan_content_resize_cb(void *data,
|
|
Evas *e EINA_UNUSED,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
void *event_info EINA_UNUSED)
|
|
{
|
|
Evas_Object *pobj = data;
|
|
EFL_UI_PAN_DATA_GET_OR_RETURN(pobj, psd);
|
|
|
|
Eina_Size2D sz = efl_gfx_entity_size_get(psd->content);
|
|
if ((sz.w != psd->content_w) || (sz.h != psd->content_h))
|
|
{
|
|
psd->content_w = sz.w;
|
|
psd->content_h = sz.h;
|
|
evas_object_smart_changed(pobj);
|
|
}
|
|
efl_event_callback_call(pobj, EFL_UI_PAN_EVENT_PAN_CONTENT_SIZE_CHANGED, &sz);
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_pan_efl_content_content_set(Evas_Object *obj, Efl_Ui_Pan_Data *psd, Evas_Object *content)
|
|
{
|
|
Eina_Size2D sz;
|
|
|
|
if (content == psd->content) return EINA_TRUE;
|
|
if (psd->content)
|
|
{
|
|
efl_content_unset(obj);
|
|
}
|
|
if (!content) return EINA_TRUE;
|
|
|
|
psd->content = content;
|
|
efl_canvas_group_member_add(obj, content);
|
|
sz = efl_gfx_entity_size_get(psd->content);
|
|
psd->content_w = sz.w;
|
|
psd->content_h = sz.h;
|
|
evas_object_event_callback_add
|
|
(content, EVAS_CALLBACK_DEL, _efl_ui_pan_content_del_cb, obj);
|
|
evas_object_event_callback_add
|
|
(content, EVAS_CALLBACK_RESIZE, _efl_ui_pan_content_resize_cb, obj);
|
|
|
|
if (evas_object_visible_get(obj))
|
|
evas_object_show(psd->content);
|
|
else
|
|
evas_object_hide(psd->content);
|
|
|
|
evas_object_smart_changed(obj);
|
|
|
|
efl_event_callback_call(obj, EFL_CONTENT_EVENT_CONTENT_CHANGED, content);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Efl_Gfx_Entity*
|
|
_efl_ui_pan_efl_content_content_get(const Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *pd)
|
|
{
|
|
return pd->content;
|
|
}
|
|
|
|
EOLIAN static Efl_Gfx_Entity*
|
|
_efl_ui_pan_efl_content_content_unset(Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *pd)
|
|
{
|
|
Efl_Gfx_Stack *old_content = pd->content;
|
|
|
|
efl_canvas_group_member_remove(obj, pd->content);
|
|
evas_object_event_callback_del_full
|
|
(pd->content, EVAS_CALLBACK_DEL, _efl_ui_pan_content_del_cb, obj);
|
|
evas_object_event_callback_del_full
|
|
(pd->content, EVAS_CALLBACK_RESIZE, _efl_ui_pan_content_resize_cb,
|
|
obj);
|
|
pd->content = NULL;
|
|
pd->content_w = pd->content_h = pd->px = pd->py = 0;
|
|
efl_event_callback_call(obj, EFL_CONTENT_EVENT_CONTENT_CHANGED, NULL);
|
|
|
|
return old_content;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_pan_efl_canvas_group_group_calculate(Eo *obj EINA_UNUSED, Efl_Ui_Pan_Data *psd)
|
|
{
|
|
efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
|
|
efl_gfx_entity_position_set(psd->content, EINA_POSITION2D(psd->x - psd->px, psd->y - psd->py));
|
|
}
|
|
#include "efl_ui_pan.eo.c"
|