1316 lines
42 KiB
C
1316 lines
42 KiB
C
#ifdef HAVE_CONFIG_H
|
|
#include "elementary_config.h"
|
|
#endif
|
|
|
|
#define ELM_LAYOUT_PROTECTED
|
|
#define EFL_UI_SCROLL_MANAGER_PROTECTED
|
|
#define EFL_UI_SCROLLBAR_PROTECTED
|
|
|
|
#include <Elementary.h>
|
|
#include "elm_priv.h"
|
|
#include "efl_ui_grid_private.h"
|
|
#include "efl_ui_item_private.h"
|
|
#include "efl_ui_grid_item_private.h"
|
|
|
|
#define MY_CLASS EFL_UI_GRID_CLASS
|
|
#define MY_CLASS_PFX efl_ui_grid
|
|
|
|
#define MY_CLASS_NAME "Efl.Ui.Grid"
|
|
|
|
static void _grid_clear_internal(Eo *obj, Efl_Ui_Grid_Data *pd);
|
|
static void _grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *item);
|
|
|
|
static void
|
|
_need_update(Efl_Ui_Grid_Data *pd)
|
|
{
|
|
pd->need_update = EINA_TRUE;
|
|
//group_calculate call
|
|
efl_canvas_group_change(pd->obj);
|
|
}
|
|
|
|
static void
|
|
_relayout(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
|
|
{
|
|
Eina_List *l;
|
|
Efl_Ui_Grid_Item *item;
|
|
Efl_Ui_Grid_Item_Data *prev;
|
|
Eina_Position2D ipos;
|
|
Eina_Position2D cur = {0, 0};
|
|
int outer;
|
|
int count = 0;
|
|
Eina_Bool horiz = 0;
|
|
Eina_Size2D min, max;
|
|
|
|
if (pd->dir == EFL_UI_DIR_HORIZONTAL) horiz = 1;
|
|
|
|
if (!pd->linemax)
|
|
{
|
|
pd->linemax =(horiz ?
|
|
((pd->geo.h + pd->item.pad.h) / (pd->item.size.h + pd->item.pad.h)) :
|
|
((pd->geo.w + pd->item.pad.w) / (pd->item.size.w + pd->item.pad.w)));
|
|
if (!pd->linemax) pd->linemax = 1;
|
|
}
|
|
|
|
|
|
outer = (horiz ?
|
|
(pd->geo.h + pd->item.pad.h) - (pd->linemax * (pd->item.size.h + pd->item.pad.h)) :
|
|
(pd->geo.w + pd->item.pad.w) - (pd->linemax * (pd->item.size.w + pd->item.pad.w)));
|
|
// outer left top
|
|
outer = (horiz ? (outer * pd->item.align.h) : (outer * pd->item.align.w));
|
|
outer = (horiz ? (outer + pd->geo.y) : (outer + pd->geo.x));
|
|
|
|
// Block?
|
|
EINA_LIST_FOREACH(pd->items, l, item)
|
|
{
|
|
EFL_UI_GRID_ITEM_DATA_GET(item, id);
|
|
|
|
if (pd->need_update || (id && (id->update_me || id->update_begin)))
|
|
{
|
|
// Index begin with zero value :
|
|
id->index = count;
|
|
if (id->update_me) id->update_me = EINA_FALSE;
|
|
if (id->update_begin)
|
|
{
|
|
id->update_begin = EINA_FALSE;
|
|
pd->need_update = EINA_TRUE;
|
|
}
|
|
if (horiz)
|
|
{
|
|
id->pos.row = (count % pd->linemax);
|
|
id->pos.col = (count / pd->linemax);
|
|
//Next Line
|
|
if (count == 0)
|
|
{
|
|
cur.x = pd->geo.x;
|
|
cur.y = outer;
|
|
}
|
|
else if (id->pos.row == 0)// ((cur.y + pd->item.pad.h + pd->item.size.h) > pd->geo.h)
|
|
{
|
|
cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
|
|
cur.y = outer;
|
|
}
|
|
else
|
|
{
|
|
//cur.x = cur.x;
|
|
cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
id->pos.row = (count / pd->linemax);
|
|
id->pos.col = (count % pd->linemax);
|
|
//Next Line
|
|
if (count == 0)
|
|
{
|
|
cur.x = outer;
|
|
cur.y = pd->geo.y;
|
|
}
|
|
else if (id->pos.col == 0)//((cur.x + pd->item.pad.w + pd->item.size.w) > pd->geo.w)
|
|
{
|
|
cur.x = outer;
|
|
cur.y = prev->geo.y + pd->item.size.h + pd->item.pad.h;
|
|
}
|
|
else
|
|
{
|
|
cur.x = prev->geo.x + pd->item.size.w + pd->item.pad.w;
|
|
//cur.y = cur.y;
|
|
}
|
|
}
|
|
|
|
min = efl_gfx_hint_size_min_get(item);
|
|
max = efl_gfx_hint_size_max_get(item);
|
|
|
|
if (pd->item.size.w < min.w) pd->item.size.w = min.w;
|
|
if (pd->item.size.h < min.h) pd->item.size.h = min.h;
|
|
if ((max.w > 0) && pd->item.size.w > max.w) pd->item.size.w = max.w;
|
|
if ((max.h > 0) && pd->item.size.h > max.h) pd->item.size.h = max.h;
|
|
|
|
id->geo.x = cur.x;
|
|
id->geo.y = cur.y;
|
|
id->geo.w = pd->item.size.w;
|
|
id->geo.h = pd->item.size.h;
|
|
|
|
|
|
}
|
|
|
|
ipos.x = id->geo.x - pan.x;
|
|
ipos.y = id->geo.y - pan.y;
|
|
|
|
//
|
|
efl_gfx_entity_position_set(item, ipos);
|
|
efl_gfx_entity_size_set(item, id->geo.size);
|
|
//efl_gfx_hint_size_restricted_min_set(item, id->geo.size);
|
|
|
|
prev = id;
|
|
count++;
|
|
}
|
|
|
|
if (horiz)
|
|
pd->geo.w = cur.x + pd->item.size.w + pd->item.pad.w - pd->geo.x;
|
|
else
|
|
pd->geo.h = cur.y + pd->item.size.h + pd->item.pad.h - pd->geo.y;
|
|
|
|
//efl_gfx_hint_size_restricted_min_set(pd->content, pd->geo.size);
|
|
efl_gfx_entity_size_set(pd->content, pd->geo.size);
|
|
|
|
pd->need_update = EINA_FALSE;
|
|
}
|
|
|
|
static void
|
|
_reposition(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Position2D pan)
|
|
{
|
|
Efl_Ui_Grid_Item *item;
|
|
Eina_List *l;
|
|
Eina_Position2D ipos;
|
|
|
|
// Block?
|
|
EINA_LIST_FOREACH(pd->items, l, item)
|
|
{
|
|
EFL_UI_GRID_ITEM_DATA_GET(item, id);
|
|
|
|
ipos.x = id->geo.x - pan.x;
|
|
ipos.y = id->geo.y - pan.y;
|
|
efl_gfx_entity_position_set(item, ipos);
|
|
efl_gfx_entity_size_set(item, id->geo.size);
|
|
//efl_gfx_hint_size_min_set(item, id->geo.size);
|
|
}
|
|
|
|
}
|
|
|
|
//Need to reimplements for grid
|
|
static void
|
|
_item_scroll_internal(Eo *obj,
|
|
Efl_Ui_Grid_Item *item,
|
|
double align,
|
|
Eina_Bool anim)
|
|
{
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
Eina_Rect ipos, view;
|
|
Eina_Position2D vpos;
|
|
|
|
if (!pd->smanager) return;
|
|
|
|
ipos = efl_gfx_entity_geometry_get(item);
|
|
view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
|
|
vpos = efl_ui_scrollable_content_pos_get(pd->smanager);
|
|
|
|
if (pd->dir == EFL_UI_DIR_HORIZONTAL)
|
|
{
|
|
ipos.y = view.y;
|
|
//ipos.h = ipos.h;
|
|
|
|
// FIXME: align case will not correctly show in the position because of
|
|
// bar size calculation. there are no certain way to know the scroll calcuation finished.
|
|
if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
|
|
{
|
|
ipos.x = ipos.x + vpos.x - view.x;
|
|
//ipos.w = ipos.w;
|
|
}
|
|
else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
|
|
(align < 1.0 || EINA_DBL_EQ(align, 1.0)))
|
|
{
|
|
ipos.x = ipos.x + vpos.x - view.x - (int)((view.w - ipos.w) * align);
|
|
ipos.w = view.w;
|
|
}
|
|
else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
|
|
|
|
}
|
|
else //VERTICAL
|
|
{
|
|
ipos.x = view.x;
|
|
//ipos.w = ipos.w;
|
|
|
|
// FIXME: align case will not correctly show in the position because of
|
|
// bar size calculation. there are no certain way to know the scroll calcuation finished.
|
|
if (EINA_DBL_EQ(align, -1.0)) //Internal Prefix
|
|
{
|
|
ipos.y = ipos.y + vpos.y - view.y;
|
|
//ipos.h = ipos.h;
|
|
}
|
|
else if ((align > 0.0 || EINA_DBL_EQ(align, 0.0)) &&
|
|
(align < 1.0 || EINA_DBL_EQ(align, 1.0)))
|
|
{
|
|
ipos.y = ipos.y + vpos.y - view.y - (int)((view.h - ipos.h) * align);
|
|
ipos.h = view.h;
|
|
}
|
|
else ERR("align (%.2lf) is not proper value. it must be the value between [0.0 , 1.0]!", align);
|
|
}
|
|
|
|
efl_ui_scrollable_scroll(pd->smanager, ipos, anim);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_bar_read_and_update(Eo *obj)
|
|
{
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
|
double vx = 0.0, vy = 0.0;
|
|
|
|
edje_object_part_drag_value_get
|
|
(wd->resize_obj, "efl.dragable.vbar", NULL, &vy);
|
|
|
|
edje_object_part_drag_value_get
|
|
(wd->resize_obj, "efl.dragable.hbar", &vx, NULL);
|
|
|
|
efl_ui_scrollbar_bar_position_set(pd->smanager, vx, vy);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_reload_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
Eo *list = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(list, pd);
|
|
|
|
efl_ui_scrollbar_bar_visibility_update(pd->smanager);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_vbar_drag_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
_efl_ui_grid_bar_read_and_update(data);
|
|
|
|
Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
|
|
efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_vbar_press_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
|
|
efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_vbar_unpress_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_VERTICAL;
|
|
efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_edje_drag_start_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
Eo *list = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(list, pd);
|
|
|
|
_efl_ui_grid_bar_read_and_update(list);
|
|
|
|
pd->freeze_want = efl_ui_scrollable_scroll_freeze_get(pd->smanager);
|
|
efl_ui_scrollable_scroll_freeze_set(pd->smanager, EINA_TRUE);
|
|
efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_START, NULL);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_edje_drag_stop_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
Eo *list = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(list, pd);
|
|
|
|
_efl_ui_grid_bar_read_and_update(list);
|
|
|
|
efl_ui_scrollable_scroll_freeze_set(pd->smanager, pd->freeze_want);
|
|
efl_event_callback_call(list, EFL_UI_EVENT_SCROLL_DRAG_STOP, NULL);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_edje_drag_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
_efl_ui_grid_bar_read_and_update(data);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_hbar_drag_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
_efl_ui_grid_bar_read_and_update(data);
|
|
|
|
Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
|
|
efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_DRAG, &type);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_hbar_press_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
|
|
efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_PRESS, &type);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_hbar_unpress_cb(void *data,
|
|
Evas_Object *obj EINA_UNUSED,
|
|
const char *emission EINA_UNUSED,
|
|
const char *source EINA_UNUSED)
|
|
{
|
|
Efl_Ui_Scrollbar_Direction type = EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL;
|
|
efl_event_callback_call(data, EFL_UI_SCROLLBAR_EVENT_BAR_UNPRESS, &type);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_bar_size_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
|
{
|
|
Eo *obj = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
|
|
|
double width = 0.0, height = 0.0;
|
|
|
|
edje_object_calc_force(wd->resize_obj);
|
|
efl_ui_scrollbar_bar_size_get(pd->smanager, &width, &height);
|
|
edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.hbar", width, 1.0);
|
|
edje_object_part_drag_size_set(wd->resize_obj, "efl.dragable.vbar", 1.0, height);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_bar_pos_changed_cb(void *data, const Efl_Event *event EINA_UNUSED)
|
|
{
|
|
Eo *obj = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
|
|
|
double posx = 0.0, posy = 0.0;
|
|
|
|
efl_ui_scrollbar_bar_position_get(pd->smanager, &posx, &posy);
|
|
edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.hbar", posx, 0.0);
|
|
edje_object_part_drag_value_set(wd->resize_obj, "efl.dragable.vbar", 0.0, posy);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_bar_show_cb(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
|
Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
|
|
|
|
if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
|
|
edje_object_signal_emit(wd->resize_obj, "efl,action,show,hbar", "efl");
|
|
else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
|
|
edje_object_signal_emit(wd->resize_obj, "efl,action,show,vbar", "efl");
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_bar_hide_cb(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
|
Efl_Ui_Scrollbar_Direction type = *(Efl_Ui_Scrollbar_Direction *)(event->info);
|
|
|
|
if (type == EFL_UI_SCROLLBAR_DIRECTION_HORIZONTAL)
|
|
edje_object_signal_emit(wd->resize_obj, "efl,action,hide,hbar", "efl");
|
|
else if (type == EFL_UI_SCROLLBAR_DIRECTION_VERTICAL)
|
|
edje_object_signal_emit(wd->resize_obj, "efl,action,hide,vbar", "efl");
|
|
}
|
|
|
|
static void
|
|
_scroll_edje_object_attach(Eo *obj)
|
|
{
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
|
|
efl_layout_signal_callback_add(obj, "reload", "efl",
|
|
obj, _efl_ui_grid_reload_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_vbar_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,set", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,start", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_start_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,stop", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_stop_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,step", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,page", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "efl,vbar,press", "efl",
|
|
obj, _efl_ui_grid_vbar_press_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "efl,vbar,unpress", "efl",
|
|
obj, _efl_ui_grid_vbar_unpress_cb, NULL);
|
|
|
|
efl_layout_signal_callback_add(obj, "drag", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_hbar_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,set", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,start", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_start_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,stop", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_stop_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,step", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "drag,page", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "efl,hbar,press", "efl",
|
|
obj, _efl_ui_grid_hbar_press_cb, NULL);
|
|
efl_layout_signal_callback_add(obj, "efl,hbar,unpress", "efl",
|
|
obj, _efl_ui_grid_hbar_unpress_cb, NULL);
|
|
}
|
|
|
|
static void
|
|
_scroll_edje_object_detach(Eo *obj)
|
|
{
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
|
|
efl_layout_signal_callback_del(obj, "reload", "efl",
|
|
obj, _efl_ui_grid_reload_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_vbar_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,set", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,start", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_start_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,stop", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_stop_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,step", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,page", "efl.dragable.vbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "efl,vbar,press", "efl",
|
|
obj, _efl_ui_grid_vbar_press_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "efl,vbar,unpress", "efl",
|
|
obj, _efl_ui_grid_vbar_unpress_cb, NULL);
|
|
|
|
efl_layout_signal_callback_del(obj, "drag", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_hbar_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,set", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,start", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_start_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,stop", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_stop_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,step", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "drag,page", "efl.dragable.hbar",
|
|
obj, _efl_ui_grid_edje_drag_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "efl,hbar,press", "efl",
|
|
obj, _efl_ui_grid_hbar_press_cb, NULL);
|
|
efl_layout_signal_callback_del(obj, "efl,hbar,unpress", "efl",
|
|
obj, _efl_ui_grid_hbar_unpress_cb, NULL);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_content_moved_cb(void *data, const Efl_Event *ev EINA_UNUSED)
|
|
{
|
|
Eo *obj = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
if (!pd->smanager) return;
|
|
|
|
efl_canvas_group_change(pd->obj);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_pan_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
|
|
{
|
|
Eo *obj = data;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
if (!pd->smanager) return;
|
|
|
|
//reset linemax for recalculate layout.
|
|
pd->linemax = 0;
|
|
|
|
_need_update(pd);
|
|
elm_layout_sizing_eval(obj);
|
|
|
|
pd->pan_resized = EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_resized_cb(void *data, const Efl_Event *ev EINA_UNUSED)
|
|
{
|
|
elm_layout_sizing_eval(data);
|
|
}
|
|
|
|
static void
|
|
_efl_ui_grid_size_hint_changed_cb(void *data, const Efl_Event *ev EINA_UNUSED)
|
|
{
|
|
elm_layout_sizing_eval(data);
|
|
}
|
|
|
|
EOLIAN static Eo *
|
|
_efl_ui_grid_efl_object_constructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
|
{
|
|
obj = efl_constructor(efl_super(obj, MY_CLASS));
|
|
|
|
return obj;
|
|
}
|
|
|
|
EOLIAN static Eo *
|
|
_efl_ui_grid_efl_object_finalize(Eo *obj,
|
|
Efl_Ui_Grid_Data *pd)
|
|
{
|
|
pd->obj = obj = efl_finalize(efl_super(obj, MY_CLASS));
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd, NULL);
|
|
|
|
efl_ui_layout_theme_set(obj, "grid", "base", efl_ui_widget_style_get(obj));
|
|
|
|
pd->smanager = efl_add(EFL_UI_SCROLL_MANAGER_CLASS, obj);
|
|
efl_composite_attach(obj, pd->smanager);
|
|
efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
|
|
|
|
pd->pan = efl_add(EFL_UI_PAN_CLASS, obj);
|
|
|
|
efl_ui_scroll_manager_pan_set(pd->smanager, pd->pan);
|
|
edje_object_part_swallow(wd->resize_obj, "efl.content", pd->pan);
|
|
|
|
pd->select_mode = EFL_UI_SELECT_SINGLE;
|
|
|
|
if ((pd->item.size.w == 0) && (pd->item.size.h == 0))
|
|
{
|
|
pd->item.size.w = 1;
|
|
pd->item.size.h = 1;
|
|
}
|
|
|
|
_scroll_edje_object_attach(obj);
|
|
|
|
//FIXME: Workaround code! fake Content for pan resize.
|
|
// to remove this code, we need to customize pan class.
|
|
pd->content = efl_add(EFL_CANVAS_RECTANGLE_CLASS, evas_object_evas_get(obj));
|
|
efl_gfx_color_set(pd->content, 0, 0, 0, 0);
|
|
efl_content_set(pd->pan, pd->content);
|
|
|
|
efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
|
|
_efl_ui_grid_bar_size_changed_cb, obj);
|
|
efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
|
|
_efl_ui_grid_bar_pos_changed_cb, obj);
|
|
efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
|
|
_efl_ui_grid_bar_show_cb, obj);
|
|
efl_event_callback_add(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
|
|
_efl_ui_grid_bar_hide_cb, obj);
|
|
efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
|
|
_efl_ui_grid_resized_cb, obj);
|
|
efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
|
|
_efl_ui_grid_size_hint_changed_cb, obj);
|
|
efl_event_callback_add(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
|
|
_efl_ui_grid_pan_resized_cb, obj);
|
|
efl_event_callback_add(pd->content, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED,
|
|
_efl_ui_grid_content_moved_cb, obj);
|
|
|
|
elm_layout_sizing_eval(obj);
|
|
|
|
return obj;
|
|
}
|
|
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_object_invalidate(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
_scroll_edje_object_detach(obj);
|
|
|
|
efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SIZE_CHANGED,
|
|
_efl_ui_grid_bar_size_changed_cb, obj);
|
|
efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_POS_CHANGED,
|
|
_efl_ui_grid_bar_pos_changed_cb, obj);
|
|
efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_SHOW,
|
|
_efl_ui_grid_bar_show_cb, obj);
|
|
efl_event_callback_del(obj, EFL_UI_SCROLLBAR_EVENT_BAR_HIDE,
|
|
_efl_ui_grid_bar_hide_cb, obj);
|
|
efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
|
|
_efl_ui_grid_resized_cb, obj);
|
|
efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
|
|
_efl_ui_grid_size_hint_changed_cb, obj);
|
|
efl_event_callback_del(pd->pan, EFL_GFX_ENTITY_EVENT_SIZE_CHANGED,
|
|
_efl_ui_grid_pan_resized_cb, obj);
|
|
efl_event_callback_del(pd->content, EFL_GFX_ENTITY_EVENT_POSITION_CHANGED,
|
|
_efl_ui_grid_content_moved_cb, obj);
|
|
_grid_clear_internal(obj, pd);
|
|
|
|
if (pd->smanager) efl_del(pd->smanager);
|
|
pd->smanager = NULL;
|
|
if (pd->content) efl_del(pd->content);
|
|
pd->content = NULL;
|
|
if (pd->pan) efl_del(pd->pan);
|
|
pd->pan = NULL;
|
|
|
|
efl_invalidate(efl_super(obj, MY_CLASS));
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_object_destructor(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
|
|
{
|
|
efl_destructor(efl_super(obj, MY_CLASS));
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
|
|
Eina_Position2D pos = efl_ui_scrollable_content_pos_get(pd->smanager);
|
|
Eina_Rect geo = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
|
|
|
|
//ERR("pos[%d,%d], geo[%d,%d,%d,%d]", pos.x, pos.y, geo.x, geo.y, geo.w, geo.h);
|
|
|
|
if (geo.w <= 1 || geo.h <= 1) return;
|
|
// Need to be implemented
|
|
if (pd->need_update)
|
|
{
|
|
_relayout(obj, pd, pos);
|
|
}
|
|
else
|
|
{
|
|
if (pd->pre_pos.x != pos.x || pd->pre_pos.y != pos.y)
|
|
{
|
|
_reposition(obj, pd, pos);
|
|
}
|
|
}
|
|
|
|
pd->pre_pos = pos;
|
|
|
|
if (pd->pan_resized)
|
|
{
|
|
pd->pan_resized = EINA_FALSE;
|
|
// FIXME: Below code is workaround size check
|
|
if ((geo.h > 1) && (pd->scroll.item))
|
|
{
|
|
_item_scroll_internal(obj, pd->scroll.item, pd->scroll.align, pd->scroll.anim);
|
|
|
|
pd->scroll.item = NULL;
|
|
pd->scroll.align = 0.0;
|
|
pd->scroll.anim = EINA_FALSE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
efl_canvas_group_calculate(efl_super(obj, MY_CLASS));
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_elm_layout_sizing_eval(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
Eina_Size2D min = {0, 0}, max = {0, 0}, size = {-1, -1};
|
|
Eina_Rect view = {};
|
|
Evas_Coord vmw = 0, vmh = 0;
|
|
double xw = 0.0, yw = 0.0;
|
|
|
|
ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
|
|
|
|
|
|
min = efl_gfx_hint_size_combined_min_get(obj);
|
|
max = efl_gfx_hint_size_max_get(obj);
|
|
efl_gfx_hint_weight_get(obj, &xw, &yw);
|
|
|
|
if (pd->smanager)
|
|
view = efl_ui_scrollable_viewport_geometry_get(pd->smanager);
|
|
|
|
if (xw > 0.0)
|
|
{
|
|
if ((min.w > 0) && (view.w < min.w))
|
|
view.w = min.w;
|
|
else if ((max.w > 0) && (view.w > max.w))
|
|
view.w = max.w;
|
|
}
|
|
else if (min.w > 0)
|
|
view.w = min.w;
|
|
|
|
if (yw > 0.0)
|
|
{
|
|
if ((min.h > 0) && (view.h < min.h))
|
|
view.h = min.h;
|
|
else if ((max.h > 0) && (view.h > max.h))
|
|
view.h = max.h;
|
|
}
|
|
else if (min.h > 0)
|
|
view.h = min.h;
|
|
|
|
edje_object_size_min_calc(wd->resize_obj, &vmw, &vmh);
|
|
|
|
if (pd->match_content_w) size.w = vmw + min.w;
|
|
if (pd->match_content_h) size.h = vmh + min.h;
|
|
|
|
max = efl_gfx_hint_size_max_get(obj);
|
|
if ((max.w > 0) && (size.w > max.w)) size.w = max.w;
|
|
if ((max.h > 0) && (size.h > max.h)) size.h = max.h;
|
|
pd->geo = view;
|
|
efl_gfx_hint_size_min_set(obj, size);
|
|
|
|
_need_update(pd);
|
|
return;
|
|
}
|
|
|
|
EOLIAN static int
|
|
_efl_ui_grid_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
return eina_list_count(pd->items);
|
|
}
|
|
|
|
static Eina_Bool
|
|
_grid_item_iterator_next(Item_Iterator *it, void **data)
|
|
{
|
|
Efl_Ui_Grid_Item *item;
|
|
|
|
if (!eina_iterator_next(it->real_iterator, (void **)&item))
|
|
return EINA_FALSE;
|
|
|
|
if (data) *data = item;
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static Eo *
|
|
_grid_item_iterator_get_container(Item_Iterator *it)
|
|
{
|
|
return it->object;
|
|
}
|
|
|
|
static void
|
|
_grid_item_iterator_free(Item_Iterator *it)
|
|
{
|
|
eina_iterator_free(it->real_iterator);
|
|
eina_list_free(it->list);
|
|
free(it);
|
|
}
|
|
|
|
static Eina_Iterator *
|
|
_grid_item_iterator_new(Eo *obj, Eina_List *list)
|
|
{
|
|
// NEED-TO-IMPLEMENTS
|
|
Item_Iterator *item;
|
|
|
|
item = calloc(1, sizeof(*item));
|
|
if (!item) return NULL;
|
|
|
|
EINA_MAGIC_SET(&item->iterator, EINA_MAGIC_ITERATOR);
|
|
|
|
item->list = eina_list_clone(list);
|
|
item->real_iterator = eina_list_iterator_new(item->list);
|
|
item->iterator.version = EINA_ITERATOR_VERSION;
|
|
item->iterator.next = FUNC_ITERATOR_NEXT(_grid_item_iterator_next);
|
|
item->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(_grid_item_iterator_get_container);
|
|
item->iterator.free = FUNC_ITERATOR_FREE(_grid_item_iterator_free);
|
|
item->object = obj;
|
|
|
|
return &item->iterator;
|
|
}
|
|
|
|
EOLIAN static Eina_Iterator *
|
|
_efl_ui_grid_efl_container_content_iterate(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
return _grid_item_iterator_new(obj, pd->items);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_ui_direction_direction_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Efl_Ui_Dir dir)
|
|
{
|
|
//FIXME: Currently only support horizontal and vertical mode.
|
|
switch (dir)
|
|
{
|
|
case EFL_UI_DIR_RTL:
|
|
// FIXME: Should be inverted!
|
|
case EFL_UI_DIR_HORIZONTAL:
|
|
case EFL_UI_DIR_LTR:
|
|
pd->dir = EFL_UI_DIR_HORIZONTAL;
|
|
break;
|
|
|
|
case EFL_UI_DIR_UP:
|
|
// FIXME: Should be inverted!
|
|
case EFL_UI_DIR_DOWN:
|
|
case EFL_UI_DIR_VERTICAL:
|
|
case EFL_UI_DIR_DEFAULT:
|
|
default:
|
|
pd->dir = EFL_UI_DIR_VERTICAL;
|
|
break;
|
|
}
|
|
|
|
pd->linemax = 0;
|
|
efl_pack_layout_request(obj);
|
|
}
|
|
|
|
EOLIAN static Efl_Ui_Dir
|
|
_efl_ui_grid_efl_ui_direction_direction_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
return pd->dir;
|
|
}
|
|
|
|
|
|
EOLIAN static Efl_Ui_Theme_Apply_Result
|
|
_efl_ui_grid_efl_ui_widget_theme_apply(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
Efl_Ui_Theme_Apply_Result int_ret = EFL_UI_THEME_APPLY_RESULT_FAIL;
|
|
int_ret = efl_ui_widget_theme_apply(efl_super(obj, MY_CLASS));
|
|
if (!int_ret) return EFL_UI_THEME_APPLY_RESULT_FAIL;
|
|
|
|
efl_ui_mirrored_set(pd->smanager, efl_ui_mirrored_get(obj));
|
|
|
|
elm_layout_sizing_eval(obj);
|
|
|
|
return int_ret;
|
|
}
|
|
|
|
static void
|
|
_grid_item_pressed(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
Efl_Ui_Grid_Item *item = event->object;
|
|
efl_event_callback_call(obj, EFL_UI_EVENT_PRESSED, item);
|
|
}
|
|
|
|
static void
|
|
_grid_item_unpressed(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
Efl_Ui_Grid_Item *item = event->object;
|
|
efl_event_callback_call(obj, EFL_UI_EVENT_UNPRESSED, item);
|
|
}
|
|
|
|
static void
|
|
_grid_item_longpressed(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
Efl_Ui_Grid_Item *item = event->object;
|
|
efl_event_callback_call(obj, EFL_UI_EVENT_LONGPRESSED, item);
|
|
}
|
|
|
|
static void
|
|
_grid_item_selected(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
Efl_Ui_Grid_Item *item = event->object;
|
|
Efl_Ui_Grid_Item *selected;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
|
|
/* Single Select */
|
|
if (pd->select_mode != EFL_UI_SELECT_MULTI)
|
|
{
|
|
EINA_LIST_FREE(pd->selected, selected)
|
|
{
|
|
if (selected != item)
|
|
efl_ui_item_selected_set(selected, EINA_FALSE);
|
|
}
|
|
}
|
|
pd->selected = eina_list_append(pd->selected, item);
|
|
pd->last_selected = item;
|
|
|
|
efl_event_callback_call(obj, EFL_UI_EVENT_SELECTED, item);
|
|
}
|
|
|
|
static void
|
|
_grid_item_unselected(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
Efl_Ui_Grid_Item *item = event->object;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
|
|
pd->selected = eina_list_remove(pd->selected, item);
|
|
if (pd->last_selected == item) pd->last_selected = NULL;
|
|
|
|
efl_event_callback_call(obj, EFL_UI_EVENT_UNSELECTED, item);
|
|
}
|
|
|
|
static void
|
|
_grid_item_deleted(void *data, const Efl_Event *event)
|
|
{
|
|
Eo *obj = data;
|
|
Efl_Ui_Grid_Item *it = event->object;
|
|
EFL_UI_GRID_DATA_GET_OR_RETURN(obj, pd);
|
|
_grid_item_unpack_internal(obj, pd, it);
|
|
}
|
|
|
|
static Eina_Bool
|
|
_grid_item_process(Eo *obj, Efl_Ui_Grid_Data *pd, EINA_UNUSED Efl_Ui_Grid_Item *it)
|
|
{
|
|
EFL_UI_GRID_ITEM_CHECK_OR_RETURN(it, EINA_FALSE);
|
|
|
|
//FIXME: This is tricky workaround for set select mode and parent value.
|
|
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(it, gd, EINA_FALSE);
|
|
EFL_UI_ITEM_DATA_GET_OR_RETURN(it, id, EINA_FALSE);
|
|
id->select_mode = &(pd->select_mode);
|
|
id->parent = obj;
|
|
gd->parent = obj;
|
|
efl_canvas_group_member_add(pd->pan, it);
|
|
efl_ui_mirrored_set(it, efl_ui_mirrored_get(obj));
|
|
|
|
efl_event_callback_add(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
|
|
efl_event_callback_add(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
|
|
efl_event_callback_add(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
|
|
efl_event_callback_add(it, EFL_UI_EVENT_SELECTED, _grid_item_selected, obj);
|
|
efl_event_callback_add(it, EFL_UI_EVENT_UNSELECTED, _grid_item_unselected, obj);
|
|
efl_event_callback_add(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
|
|
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
static void
|
|
_grid_item_unpack_internal(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Ui_Grid_Item *it)
|
|
{
|
|
EFL_UI_GRID_ITEM_CHECK_OR_RETURN(it);
|
|
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(it, gd);
|
|
EFL_UI_ITEM_DATA_GET_OR_RETURN(it, id);
|
|
id->select_mode = NULL;
|
|
id->parent = NULL;
|
|
gd->parent = NULL;
|
|
|
|
pd->items = eina_list_remove(pd->items, it);
|
|
if (efl_ui_item_selected_get(it))
|
|
{
|
|
pd->selected = eina_list_remove(pd->selected, it);
|
|
}
|
|
|
|
efl_event_callback_del(it, EFL_UI_EVENT_PRESSED, _grid_item_pressed, obj);
|
|
efl_event_callback_del(it, EFL_UI_EVENT_UNPRESSED, _grid_item_unpressed, obj);
|
|
efl_event_callback_del(it, EFL_UI_EVENT_LONGPRESSED, _grid_item_longpressed, obj);
|
|
efl_event_callback_del(it, EFL_UI_EVENT_SELECTED, _grid_item_selected, obj);
|
|
efl_event_callback_del(it, EFL_UI_EVENT_UNSELECTED, _grid_item_unselected, obj);
|
|
efl_event_callback_del(it, EFL_EVENT_DEL, _grid_item_deleted, obj);
|
|
}
|
|
|
|
|
|
static void
|
|
_grid_clear_internal(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
Efl_Ui_Grid_Item *it = NULL;
|
|
Eina_List *l, *ll;
|
|
EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
|
|
{
|
|
efl_del(it);
|
|
}
|
|
eina_list_free(pd->selected);
|
|
pd->items = NULL;
|
|
pd->selected = NULL;
|
|
}
|
|
|
|
/* Pack APIs */
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_pack_clear(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
_grid_clear_internal(obj, pd);
|
|
|
|
elm_layout_sizing_eval(obj);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_unpack_all(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
|
|
Efl_Ui_Grid_Item *it = NULL;
|
|
Eina_List *l, *ll;
|
|
EINA_LIST_FOREACH_SAFE(pd->items, l, ll, it)
|
|
{
|
|
_grid_item_unpack_internal(obj, pd, it);
|
|
}
|
|
eina_list_free(pd->selected);
|
|
pd->items = NULL;
|
|
pd->selected = NULL;
|
|
|
|
elm_layout_sizing_eval(obj);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_unpack(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
|
|
{
|
|
Efl_Ui_Grid_Item *item = (Efl_Ui_Grid_Item *)subobj;
|
|
|
|
_grid_item_unpack_internal(obj, pd, item);
|
|
|
|
elm_layout_sizing_eval(obj);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_pack(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, Efl_Gfx_Entity *subobj)
|
|
{
|
|
return efl_pack_end(obj, subobj);
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_linear_pack_end(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
|
|
{
|
|
if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
|
|
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
|
|
pd->items = eina_list_append(pd->items, subobj);
|
|
|
|
pid->update_me = EINA_TRUE;
|
|
|
|
efl_canvas_group_change(obj);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_linear_pack_begin(Eo *obj, Efl_Ui_Grid_Data *pd, Efl_Gfx_Entity *subobj)
|
|
{
|
|
if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
|
|
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
|
|
pd->items = eina_list_prepend(pd->items, subobj);
|
|
// Defered item's placing in group calculation
|
|
pid->update_me = EINA_TRUE;
|
|
_need_update(pd);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_linear_pack_before(Eo *obj,
|
|
Efl_Ui_Grid_Data *pd,
|
|
Efl_Gfx_Entity *subobj,
|
|
const Efl_Gfx_Entity *existing)
|
|
{
|
|
if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
|
|
EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
|
|
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
|
|
|
|
pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
|
|
// Defered item's placing in group calculation
|
|
pid->update_begin = EINA_TRUE;
|
|
_need_update(pd);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_linear_pack_after(Eo *obj,
|
|
Efl_Ui_Grid_Data *pd,
|
|
Efl_Gfx_Entity *subobj,
|
|
const Efl_Gfx_Entity *existing)
|
|
{
|
|
if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
|
|
EFL_UI_GRID_ITEM_CHECK_OR_RETURN(existing, EINA_FALSE);
|
|
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
|
|
|
|
pd->items = eina_list_append_relative(pd->items, subobj, existing);
|
|
// Defered item's placing in group calculation
|
|
pid->update_begin = EINA_TRUE;
|
|
_need_update(pd);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Eina_Bool
|
|
_efl_ui_grid_efl_pack_linear_pack_at(Eo *obj,
|
|
Efl_Ui_Grid_Data *pd,
|
|
Efl_Gfx_Entity *subobj,
|
|
int index)
|
|
{
|
|
if (!_grid_item_process(obj, pd, subobj)) return EINA_FALSE;
|
|
Efl_Ui_Grid_Item *existing = eina_list_nth(pd->items, index);
|
|
EFL_UI_GRID_ITEM_DATA_GET_OR_RETURN(subobj, pid, EINA_FALSE);
|
|
|
|
pd->items = eina_list_prepend_relative(pd->items, subobj, existing);
|
|
// Defered item's placing in group calculation
|
|
pid->update_begin = EINA_TRUE;
|
|
_need_update(pd);
|
|
return EINA_TRUE;
|
|
}
|
|
|
|
EOLIAN static Efl_Gfx_Entity *
|
|
_efl_ui_grid_efl_pack_linear_pack_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
|
|
{
|
|
return eina_list_nth(pd->items, index);
|
|
}
|
|
|
|
EOLIAN static Efl_Gfx_Entity *
|
|
_efl_ui_grid_efl_pack_linear_pack_unpack_at(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, int index)
|
|
{
|
|
Efl_Gfx_Entity *target = eina_list_nth(pd->items, index);
|
|
pd->items = eina_list_remove(pd->items, target);
|
|
/*
|
|
if (after)
|
|
{
|
|
}
|
|
else
|
|
*/
|
|
_need_update(pd);
|
|
return target;
|
|
}
|
|
|
|
EOLIAN static int
|
|
_efl_ui_grid_efl_pack_linear_pack_index_get(Eo *obj EINA_UNUSED,
|
|
Efl_Ui_Grid_Data *pd,
|
|
const Efl_Gfx_Entity *subobj)
|
|
{
|
|
return eina_list_data_idx(pd->items, (void *)subobj);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
_need_update(pd);
|
|
elm_layout_sizing_eval(obj);
|
|
|
|
efl_event_callback_legacy_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
_need_update(pd);
|
|
elm_layout_sizing_eval(obj);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_pack_pack_padding_set(Eo *obj EINA_UNUSED,
|
|
Efl_Ui_Grid_Data *pd,
|
|
double h,
|
|
double v,
|
|
Eina_Bool scalable)
|
|
{
|
|
pd->item.pad.w = (int )h;
|
|
pd->item.pad.h = (int) v;
|
|
|
|
pd->pad_scalable = !!scalable;
|
|
|
|
//reset linemax for recalculate layout
|
|
pd->linemax = 0;
|
|
_need_update(pd);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_pack_pack_padding_get(const Eo *obj EINA_UNUSED,
|
|
Efl_Ui_Grid_Data *pd,
|
|
double *h,
|
|
double *v,
|
|
Eina_Bool *scalable)
|
|
{
|
|
//??
|
|
*h = (double) pd->item.pad.w;
|
|
*v = (double) pd->item.pad.h;
|
|
*scalable = !!pd->pad_scalable;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_pack_pack_align_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double h, double v)
|
|
{
|
|
pd->item.align.w = h;
|
|
pd->item.align.h = v;
|
|
_need_update(pd);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_pack_pack_align_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, double *h, double *v)
|
|
{
|
|
*h = pd->item.align.w;
|
|
*v = pd->item.align.h;
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_ui_scrollable_interactive_match_content_set(Eo *obj EINA_UNUSED,
|
|
Efl_Ui_Grid_Data *pd,
|
|
Eina_Bool match_content_w,
|
|
Eina_Bool match_content_h)
|
|
{
|
|
pd->match_content_w = !!match_content_w;
|
|
pd->match_content_h = !!match_content_h;
|
|
|
|
efl_ui_scrollable_match_content_set(pd->smanager, match_content_w, match_content_h);
|
|
|
|
elm_layout_sizing_eval(obj);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_efl_ui_multi_selectable_select_mode_set(Eo *obj EINA_UNUSED,
|
|
Efl_Ui_Grid_Data *pd,
|
|
Efl_Ui_Select_Mode mode)
|
|
{
|
|
Efl_Ui_Grid_Item *selected;
|
|
|
|
if ((pd->select_mode == EFL_UI_SELECT_MULTI &&
|
|
mode != EFL_UI_SELECT_MULTI) ||
|
|
mode == EFL_UI_SELECT_NONE)
|
|
{
|
|
Eina_List *clone = eina_list_clone(pd->selected);
|
|
EINA_LIST_FREE(clone, selected)
|
|
efl_ui_item_selected_set(selected, EINA_FALSE);
|
|
}
|
|
|
|
pd->select_mode = mode;
|
|
}
|
|
|
|
EOLIAN static Efl_Ui_Select_Mode
|
|
_efl_ui_grid_efl_ui_multi_selectable_select_mode_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
return pd->select_mode;
|
|
}
|
|
|
|
/* List APIs */
|
|
EOLIAN static void
|
|
_efl_ui_grid_item_scroll(Eo *obj,
|
|
Efl_Ui_Grid_Data *pd,
|
|
Efl_Ui_Grid_Item *item,
|
|
Eina_Bool animation)
|
|
{
|
|
// Need to be implemented here.
|
|
if (pd->pan_resized)
|
|
{
|
|
_item_scroll_internal(obj, item, -1.0, animation);
|
|
}
|
|
else
|
|
{
|
|
pd->scroll.item = item;
|
|
pd->scroll.align = -1.0;
|
|
pd->scroll.anim = animation;
|
|
}
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_item_scroll_align(Eo *obj,
|
|
Efl_Ui_Grid_Data *pd,
|
|
Efl_Ui_Grid_Item *item,
|
|
double align,
|
|
Eina_Bool animation)
|
|
{
|
|
// Need to be implemented here.
|
|
if (pd->pan_resized)
|
|
{
|
|
_item_scroll_internal(obj, item, align, animation);
|
|
}
|
|
else
|
|
{
|
|
pd->scroll.item = item;
|
|
pd->scroll.align = align;
|
|
pd->scroll.anim = animation;
|
|
}
|
|
}
|
|
|
|
EOLIAN static Efl_Ui_Grid_Item *
|
|
_efl_ui_grid_last_selected_item_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
return pd->last_selected;
|
|
}
|
|
|
|
EOLIAN static Eina_Iterator *
|
|
_efl_ui_grid_selected_items_get(Eo *obj, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
return _grid_item_iterator_new(obj, pd->selected);
|
|
}
|
|
|
|
EOLIAN static void
|
|
_efl_ui_grid_item_size_set(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, Eina_Size2D size)
|
|
{
|
|
pd->item.size = size;
|
|
//reset linemax for recalculate layout.
|
|
pd->linemax = 0;
|
|
|
|
_need_update(pd);
|
|
}
|
|
|
|
EOLIAN static Eina_Size2D
|
|
_efl_ui_grid_item_size_get(const Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd)
|
|
{
|
|
return pd->item.size;
|
|
}
|
|
|
|
/* Internal EO APIs and hidden overrides */
|
|
#define EFL_UI_GRID_EXTRA_OPS \
|
|
ELM_LAYOUT_SIZING_EVAL_OPS(efl_ui_grid)
|
|
|
|
#include "efl_ui_grid.eo.c"
|