efl/src/lib/elementary/efl_ui_table.c

861 lines
22 KiB
C

#include "efl_ui_table_private.h"
#define MY_CLASS EFL_UI_TABLE_CLASS
#define MY_CLASS_NAME "Efl.Ui.Table"
#define EFL_UI_TABLE_DATA_GET(o, pd) \
Efl_Ui_Table_Data *pd = efl_data_scope_get(o, EFL_UI_TABLE_CLASS)
inline static Table_Item *
_efl_ui_table_item_date_get(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj)
{
Table_Item *gi;
if (!efl_invalidated_get(subobj) &&
(obj != efl_canvas_object_render_parent_get(subobj)))
{
ERR("%p is not a child of %p", subobj, obj);
return NULL;
}
gi = efl_key_data_get(subobj, TABLE_ITEM_KEY);
if (!gi)
{
WRN("item %p has no table internal data", subobj);
EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), gi)
{
if (gi->object == subobj)
break;
}
if (!gi)
{
ERR("item %p was not found in this table", subobj);
return NULL;
}
}
return gi;
}
static void
_on_child_size_changed(void *data, const Efl_Event *event EINA_UNUSED)
{
Eo *table = data;
efl_pack_layout_request(table);
}
static void
_on_child_hints_changed(void *data, const Efl_Event *event EINA_UNUSED)
{
Eo *table = data;
efl_pack_layout_request(table);
}
static void
_on_child_del(void *data, const Efl_Event *event)
{
Eo *table = data;
Table_Item *gi;
EFL_UI_TABLE_DATA_GET(table, pd);
gi = _efl_ui_table_item_date_get(table, pd, event->object);
if (!gi) return;
if ((gi->col == pd->last_col) && (gi->row == pd->last_row))
pd->linear_recalc = EINA_TRUE;
if (gi->col + gi->col_span >= pd->cols)
pd->cols_recalc = EINA_TRUE;
if (gi->row + gi->row_span >= pd->rows)
pd->rows_recalc = EINA_TRUE;
pd->items = (Table_Item *)
eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
free(gi);
pd->count--;
efl_key_data_set(event->object, TABLE_ITEM_KEY, NULL);
efl_pack_layout_request(table);
}
EFL_CALLBACKS_ARRAY_DEFINE(efl_ui_table_callbacks,
{ EFL_GFX_ENTITY_EVENT_SIZE_CHANGED, _on_child_size_changed },
{ EFL_GFX_ENTITY_EVENT_HINTS_CHANGED, _on_child_hints_changed },
{ EFL_EVENT_DEL, _on_child_del }
);
static void
_efl_ui_table_last_position_get(Eo * obj, Efl_Ui_Table_Data *pd, int *last_col, int *last_row)
{
Table_Item *gi;
int col = -1, row = -1;
int req_cols, req_rows;
int item_row, item_col;
if (!pd->linear_recalc)
{
*last_col = pd->last_col;
*last_row = pd->last_row;
return;
}
efl_pack_table_size_get(obj, &req_cols, &req_rows);
if (efl_ui_layout_orientation_is_horizontal(pd->fill_dir, EINA_TRUE))
{
EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
{
item_row = gi->row + gi->row_span - 1;
item_col = gi->col + gi->col_span - 1;
if ((item_row < row) || (req_cols < item_col) ||
(req_rows < item_row))
continue;
if (item_row > row)
{
row = item_row;
col = item_col;
}
else if (item_col > col)
{
col = item_col;
}
}
}
else
{
EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
{
item_row = gi->row + gi->row_span - 1;
item_col = gi->col + gi->col_span - 1;
if ((item_col < col) || (req_cols < item_col) ||
(req_rows < item_row))
continue;
if (item_col > col)
{
col = item_col;
row = item_row;
}
else if (item_row > row)
{
row = item_row;
}
}
}
*last_col = col;
*last_row = row;
pd->linear_recalc = EINA_FALSE;
}
static void
_efl_ui_table_size_hints_changed_cb(void *data EINA_UNUSED, const Efl_Event *ev)
{
efl_pack_layout_request(ev->object);
}
EOLIAN static void
_efl_ui_table_homogeneous_set(Eo *obj, Efl_Ui_Table_Data *pd, Eina_Bool homogeneoush, Eina_Bool homogeneousv)
{
homogeneoush = !!homogeneoush;
homogeneousv = !!homogeneousv;
if ((pd->homogeneoush == homogeneoush) && (pd->homogeneousv == homogeneousv))
return;
pd->homogeneoush = homogeneoush;
pd->homogeneousv = homogeneousv;
efl_pack_layout_request(obj);
}
EOLIAN static void
_efl_ui_table_homogeneous_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, Eina_Bool *homogeneoush, Eina_Bool *homogeneousv)
{
if (homogeneoush) *homogeneoush = pd->homogeneoush;
if (homogeneousv) *homogeneousv = pd->homogeneousv;
}
EOLIAN static void
_efl_ui_table_efl_pack_layout_layout_update(Eo *obj, Efl_Ui_Table_Data *pd)
{
_efl_ui_table_custom_layout(obj, pd);
}
EOLIAN void
_efl_ui_table_efl_canvas_group_group_calculate(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED)
{
efl_canvas_group_need_recalculate_set(obj, EINA_FALSE);
efl_pack_layout_update(obj);
}
EOLIAN static void
_efl_ui_table_efl_gfx_entity_size_set(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED, Eina_Size2D sz)
{
efl_gfx_entity_size_set(efl_super(obj, MY_CLASS), sz);
efl_pack_layout_request(obj);
}
EOLIAN static void
_efl_ui_table_efl_gfx_entity_position_set(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED, Eina_Position2D pos)
{
efl_gfx_entity_position_set(efl_super(obj, MY_CLASS), pos);
efl_canvas_group_change(obj);
}
EOLIAN static void
_efl_ui_table_efl_canvas_group_group_add(Eo *obj, Efl_Ui_Table_Data *pd)
{
pd->clipper = efl_add(EFL_CANVAS_RECTANGLE_CLASS, obj);
evas_object_static_clip_set(pd->clipper, EINA_TRUE);
efl_gfx_entity_geometry_set(pd->clipper, EINA_RECT(-49999, -49999, 99999, 99999));
efl_canvas_group_member_add(obj, pd->clipper);
efl_ui_widget_sub_object_add(obj, pd->clipper);
efl_canvas_group_add(efl_super(obj, MY_CLASS));
elm_widget_sub_object_parent_add(obj);
efl_ui_widget_focus_allow_set(obj, EINA_FALSE);
elm_widget_highlight_ignore_set(obj, EINA_FALSE);
efl_event_callback_add(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
_efl_ui_table_size_hints_changed_cb, NULL);
}
EOLIAN static void
_efl_ui_table_efl_canvas_group_group_del(Eo *obj, Efl_Ui_Table_Data *_pd EINA_UNUSED)
{
efl_event_callback_del(obj, EFL_GFX_ENTITY_EVENT_HINTS_CHANGED,
_efl_ui_table_size_hints_changed_cb, NULL);
efl_canvas_group_del(efl_super(obj, MY_CLASS));
}
EOLIAN static Eo *
_efl_ui_table_efl_object_constructor(Eo *obj, Efl_Ui_Table_Data *pd)
{
obj = efl_constructor(efl_super(obj, MY_CLASS));
efl_canvas_object_type_set(obj, MY_CLASS_NAME);
efl_access_object_access_type_set(obj, EFL_ACCESS_TYPE_SKIPPED);
efl_access_object_role_set(obj, EFL_ACCESS_ROLE_FILLER);
pd->fill_dir = EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
pd->last_col = -1;
pd->last_row = -1;
pd->req_cols = 0;
pd->req_rows = 0;
pd->cols = 0;
pd->rows = 0;
pd->align.h = 0.5;
pd->align.v = 0.5;
return obj;
}
EOLIAN static void
_efl_ui_table_efl_object_invalidate(Eo *obj, Efl_Ui_Table_Data *pd)
{
Table_Item *gi;
efl_invalidate(efl_super(obj, MY_CLASS));
EINA_INLIST_FREE(EINA_INLIST_GET(pd->items), gi)
{
efl_event_callback_array_del(gi->object, efl_ui_table_callbacks(), obj);
pd->items = (Table_Item *)
eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
free(gi);
}
}
EOLIAN static void
_efl_ui_table_efl_gfx_arrangement_content_padding_set(Eo *obj, Efl_Ui_Table_Data *pd, unsigned int h, unsigned int v)
{
if (pd->pad.h == h && pd->pad.v == v)
return;
pd->pad.h = h;
pd->pad.v = v;
efl_pack_layout_request(obj);
}
EOLIAN static void
_efl_ui_table_efl_gfx_arrangement_content_padding_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, unsigned int *h, unsigned int *v)
{
if (h) *h = pd->pad.h;
if (v) *v = pd->pad.v;
}
EOLIAN static void
_efl_ui_table_efl_gfx_arrangement_content_align_set(Eo *obj, Efl_Ui_Table_Data *pd, double h, double v)
{
if (h < 0) h = -1;
else if (h > 1) h = 1;
if (v < 0) v = -1;
else if (v > 1) v = 1;
if (EINA_DBL_EQ(pd->align.h, h) && EINA_DBL_EQ(pd->align.v, v))
return;
pd->align.h = h;
pd->align.v = v;
efl_pack_layout_request(obj);
}
EOLIAN static void
_efl_ui_table_efl_gfx_arrangement_content_align_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, double *h, double *v)
{
if (h) *h = pd->align.h;
if (v) *v = pd->align.v;
}
static Eina_Bool
_pack_at(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj, int col, int row, int colspan, int rowspan)
{
Table_Item *gi;
if (efl_key_data_get(subobj, TABLE_ITEM_KEY))
{
if (efl_canvas_object_render_parent_get(subobj) == obj)
ERR("subobj %p %s is already added to this", subobj, efl_class_name_get(subobj));
else
ERR("subobj %p %s currently belongs to different table", subobj, efl_class_name_get(subobj));
return EINA_FALSE;
}
if (col < 0) col = 0;
if (row < 0) row = 0;
// note: we could have colspan = -1 mean "full width" if req_cols is set?
if (colspan < 1) colspan = 1;
if (rowspan < 1) rowspan = 1;
if (((int64_t) col + (int64_t) colspan) > (int64_t) INT_MAX)
colspan = INT_MAX - col;
if (((int64_t) row + (int64_t) rowspan) > (int64_t) INT_MAX)
rowspan = INT_MAX - row;
if ((pd->req_cols && ((col + colspan) > pd->req_cols)) ||
(pd->req_rows && ((row + rowspan) > pd->req_rows)))
{
ERR("table requested size exceeded! packing in extra cell at "
"%d,%d %dx%d (table: %dx%d)",
col, row, colspan, rowspan, pd->req_cols, pd->req_rows);
}
if (!efl_ui_widget_sub_object_add(obj, subobj))
return EINA_FALSE;
gi = calloc(1, sizeof(*gi));
if (!gi) return EINA_FALSE;
gi->col = col;
gi->row = row;
gi->col_span = colspan;
gi->row_span = rowspan;
gi->object = subobj;
pd->count++;
pd->items = (Table_Item *)
eina_inlist_append(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
efl_key_data_set(subobj, TABLE_ITEM_KEY, gi);
efl_key_data_set(subobj, "_elm_leaveme", obj);
efl_canvas_object_clipper_set(subobj, pd->clipper);
efl_event_callback_array_add(subobj, efl_ui_table_callbacks(), obj);
efl_canvas_group_member_add(obj, subobj);
efl_event_callback_call(obj, EFL_CONTAINER_EVENT_CONTENT_ADDED, subobj);
if ((gi->col > pd->last_col) || (gi->row > pd->last_row))
pd->linear_recalc = EINA_TRUE;
if (pd->cols < gi->col + gi->col_span)
pd->cols = gi->col + gi->col_span;
if (pd->rows < gi->row + gi->row_span)
pd->rows = gi->row + gi->row_span;
efl_pack_layout_request(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_efl_ui_table_efl_pack_table_pack_table(Eo *obj, Efl_Ui_Table_Data *pd,
Efl_Gfx_Entity *subobj,
int col, int row, int colspan, int rowspan)
{
EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE);
return _pack_at(obj, pd, subobj, col, row, colspan, rowspan);
}
EOLIAN static Eina_Bool
_efl_ui_table_efl_pack_table_table_cell_column_get(const Eo *obj, Efl_Ui_Table_Data *pd, Evas_Object *subobj, int *col, int *colspan)
{
int c = -1, cs = 0;
Table_Item *gi;
Eina_Bool ret = EINA_FALSE;
gi = _efl_ui_table_item_date_get((Eo *)obj, pd, subobj);
if (gi)
{
c = gi->col;
cs = gi->col_span;
ret = EINA_TRUE;
}
if (col) *col = c;
if (colspan) *colspan = cs;
return ret;
}
EOLIAN static void
_efl_ui_table_efl_pack_table_table_cell_column_set(Eo *obj, Efl_Ui_Table_Data *pd, Evas_Object *subobj, int col, int colspan)
{
Table_Item *gi;
gi = _efl_ui_table_item_date_get((Eo *)obj, pd, subobj);
if (!gi)
return;
if (col < 0) col = 0;
if (colspan < 1) colspan = 1;
if (((int64_t) col + (int64_t) colspan) > (int64_t) INT_MAX)
colspan = INT_MAX - col;
if (pd->req_cols && ((col + colspan) > pd->req_cols))
{
ERR("table requested size exceeded! packing in extra cell at "
"%d+%d (table cols: %d)", col, colspan, pd->req_cols);
}
gi->col = col;
gi->col_span = colspan;
if (gi->col > pd->last_col)
pd->linear_recalc = EINA_TRUE;
if (pd->cols < gi->col + gi->col_span)
pd->cols = gi->col + gi->col_span;
efl_pack_layout_request(obj);
}
EOLIAN static Eina_Bool
_efl_ui_table_efl_pack_table_table_cell_row_get(const Eo *obj, Efl_Ui_Table_Data *pd, Evas_Object *subobj, int *row, int *rowspan)
{
int r = -1, rs = 0;
Table_Item *gi;
Eina_Bool ret = EINA_FALSE;
gi = _efl_ui_table_item_date_get((Eo *)obj, pd, subobj);
if (gi)
{
r = gi->row;
rs = gi->row_span;
ret = EINA_TRUE;
}
if (row) *row = r;
if (rowspan) *rowspan = rs;
return ret;
}
EOLIAN static void
_efl_ui_table_efl_pack_table_table_cell_row_set(Eo *obj, Efl_Ui_Table_Data *pd, Evas_Object *subobj, int row, int rowspan)
{
Table_Item *gi;
gi = _efl_ui_table_item_date_get((Eo *)obj, pd, subobj);
if (!gi)
return;
if (row < 0) row = 0;
if (rowspan < 1) rowspan = 1;
if (((int64_t) row + (int64_t) rowspan) > (int64_t) INT_MAX)
rowspan = INT_MAX - row;
if (pd->req_rows && ((row + rowspan) > pd->req_rows))
{
ERR("table requested size exceeded! packing in extra cell at "
"%d+%d (table rows: %d)", row, rowspan, pd->req_rows);
}
gi->row = row;
gi->row_span = rowspan;
if (gi->row > pd->last_row)
pd->linear_recalc = EINA_TRUE;
if (pd->rows < gi->row + gi->row_span)
pd->rows = gi->row + gi->row_span;
efl_pack_layout_request(obj);
}
EOLIAN static Efl_Gfx_Entity *
_efl_ui_table_efl_pack_table_table_content_get(Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, int col, int row)
{
Table_Item *gi;
EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), gi)
{
if (gi->col == col && gi->row == row)
return gi->object;
}
return NULL;
}
static Eina_Bool
_item_remove(Efl_Ui_Table *obj, Efl_Ui_Table_Data *pd, Table_Item *gi)
{
Efl_Gfx_Entity *subobj = gi->object;
if (!subobj || !_elm_widget_sub_object_redirect_to_top(obj, subobj))
return EINA_FALSE;
efl_canvas_object_clipper_set(subobj, NULL);
efl_key_data_set(subobj, "_elm_leaveme", NULL);
efl_key_data_set(subobj, TABLE_ITEM_KEY, NULL);
efl_event_callback_array_del(subobj, efl_ui_table_callbacks(), obj);
efl_canvas_group_member_remove(obj, subobj);
efl_event_callback_call(obj, EFL_CONTAINER_EVENT_CONTENT_REMOVED, subobj);
if ((gi->col == pd->last_col) && (gi->row == pd->last_row))
pd->linear_recalc = EINA_TRUE;
if (gi->col + gi->col_span >= pd->cols)
pd->cols_recalc = EINA_TRUE;
if (gi->row + gi->row_span >= pd->rows)
pd->rows_recalc = EINA_TRUE;
pd->items = (Table_Item *)
eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
free(gi);
pd->count--;
efl_pack_layout_request(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_efl_ui_table_efl_pack_unpack(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj)
{
Table_Item *gi = _efl_ui_table_item_date_get(obj, pd, subobj);
if (!gi) return EINA_FALSE;
return _item_remove(obj, pd, gi);
}
EOLIAN static Eina_Bool
_efl_ui_table_efl_pack_pack_clear(Eo *obj, Efl_Ui_Table_Data *pd)
{
Table_Item *gi;
EINA_INLIST_FREE(EINA_INLIST_GET(pd->items), gi)
{
efl_event_callback_array_del(gi->object, efl_ui_table_callbacks(), obj);
efl_del(gi->object);
pd->items = (Table_Item *)
eina_inlist_remove(EINA_INLIST_GET(pd->items), EINA_INLIST_GET(gi));
free(gi);
}
pd->linear_recalc = EINA_TRUE;
pd->cols_recalc = EINA_TRUE;
pd->rows_recalc = EINA_TRUE;
pd->last_col = -1;
pd->last_row = -1;
pd->cols = 0;
pd->rows = 0;
pd->count = 0;
efl_pack_layout_request(obj);
return EINA_TRUE;
}
EOLIAN static Eina_Bool
_efl_ui_table_efl_pack_unpack_all(Eo *obj, Efl_Ui_Table_Data *pd)
{
Table_Item *gi;
Eina_Bool ret = EINA_TRUE;
EINA_INLIST_FREE(EINA_INLIST_GET(pd->items), gi)
ret &= _item_remove(obj, pd, gi);
pd->linear_recalc = EINA_TRUE;
pd->cols_recalc = EINA_TRUE;
pd->rows_recalc = EINA_TRUE;
pd->last_col = -1;
pd->last_row = -1;
pd->cols = 0;
pd->rows = 0;
return ret;
}
EOLIAN static void
_efl_ui_table_efl_pack_layout_layout_request(Eo *obj, Efl_Ui_Table_Data *pd)
{
pd->full_recalc = EINA_TRUE;
efl_canvas_group_need_recalculate_set(obj, EINA_TRUE);
}
static Eina_Bool
_efl_ui_table_item_iterator_next(Table_Item_Iterator *it, void **data)
{
Table_Item *gi;
if (!it->cur)
return EINA_FALSE;
if (data)
{
gi = EINA_INLIST_CONTAINER_GET(it->cur, Table_Item);
*data = gi->object;
}
it->cur = it->cur->next;
return EINA_TRUE;
}
static Eo *
_efl_ui_table_item_iterator_get_container(Table_Item_Iterator *it)
{
return it->object;
}
static void
_efl_ui_table_item_iterator_free(Table_Item_Iterator *it)
{
free(it);
}
static inline Eina_Iterator *
_efl_ui_table_item_iterator_create(Eo *obj, Eina_Inlist *list)
{
Table_Item_Iterator *it;
it = calloc(1, sizeof(*it));
if (!it) return NULL;
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->object = obj;
it->cur = list;
it->iterator.version = EINA_ITERATOR_VERSION;
it->iterator.next = FUNC_ITERATOR_NEXT(_efl_ui_table_item_iterator_next);
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
_efl_ui_table_item_iterator_get_container);
it->iterator.free = FUNC_ITERATOR_FREE(_efl_ui_table_item_iterator_free);
return &it->iterator;
}
EOLIAN static Eina_Iterator *
_efl_ui_table_efl_container_content_iterate(Eo *obj, Efl_Ui_Table_Data *pd)
{
Table_Item_Iterator *it;
if (!pd->count)
return NULL;
it = calloc(1, sizeof(*it));
if (!it) return NULL;
EINA_MAGIC_SET(&it->iterator, EINA_MAGIC_ITERATOR);
it->object = obj;
it->cur = EINA_INLIST_GET(pd->items);
it->iterator.version = EINA_ITERATOR_VERSION;
it->iterator.next = FUNC_ITERATOR_NEXT(_efl_ui_table_item_iterator_next);
it->iterator.get_container = FUNC_ITERATOR_GET_CONTAINER(
_efl_ui_table_item_iterator_get_container);
it->iterator.free = FUNC_ITERATOR_FREE(_efl_ui_table_item_iterator_free);
return &it->iterator;
}
EOLIAN static int
_efl_ui_table_efl_container_content_count(Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd)
{
return pd->count;
}
EOLIAN static Eina_Iterator *
_efl_ui_table_efl_pack_table_table_contents_get(Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, int col, int row, Eina_Bool below)
{
Table_Item *gi;
Eina_List *atlist = NULL;
EINA_INLIST_FOREACH(EINA_INLIST_GET(pd->items), gi)
{
if ((gi->col == col) && (gi->row == row))
atlist = eina_list_append(atlist, gi->object);
else if (below)
{
if ((gi->col <= col) && (gi->col + gi->col_span >= col) &&
(gi->row <= row) && (gi->row + gi->row_span >= row))
atlist = eina_list_append(atlist, gi->object);
}
}
return eina_list_iterator_new(atlist);
}
EOLIAN static void
_efl_ui_table_efl_ui_layout_orientable_orientation_set(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Ui_Layout_Orientation dir)
{
if (pd->fill_dir == dir)
return;
if (dir == EFL_UI_LAYOUT_ORIENTATION_DEFAULT)
dir = EFL_UI_LAYOUT_ORIENTATION_HORIZONTAL;
pd->fill_dir = dir;
efl_pack_layout_request(obj);
}
EOLIAN static Efl_Ui_Layout_Orientation
_efl_ui_table_efl_ui_layout_orientable_orientation_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd)
{
return pd->fill_dir;
}
EOLIAN static void
_efl_ui_table_efl_pack_table_table_size_set(Eo *obj, Efl_Ui_Table_Data *pd, int cols, int rows)
{
if (cols < 0) cols = 0;
if (rows < 0) rows = 0;
if ((pd->req_cols == cols) && (pd->req_rows == rows))
return;
pd->req_cols = cols;
pd->req_rows = rows;
pd->linear_recalc = EINA_TRUE;
efl_pack_layout_request(obj);
}
EOLIAN static void
_efl_ui_table_efl_pack_table_table_size_get(const Eo *obj, Efl_Ui_Table_Data *pd EINA_UNUSED, int *cols, int *rows)
{
if (cols) *cols = efl_pack_table_columns_get(obj);
if (rows) *rows = efl_pack_table_rows_get(obj);
}
EOLIAN static void
_efl_ui_table_efl_pack_table_table_columns_set(Eo *obj, Efl_Ui_Table_Data *pd, int columns)
{
if (pd->req_cols == columns)
return;
pd->req_cols = columns;
pd->linear_recalc = EINA_TRUE;
efl_pack_layout_request(obj);
}
EOLIAN static int
_efl_ui_table_efl_pack_table_table_columns_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd)
{
Table_Item *gi;
if (pd->cols_recalc)
{
pd->cols = 0;
EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
{
if (pd->cols < gi->col + gi->col_span)
pd->cols = gi->col+ gi->col_span;
}
pd->cols_recalc = EINA_FALSE;
}
return pd->req_cols ? : pd->cols;
}
EOLIAN static void
_efl_ui_table_efl_pack_table_table_rows_set(Eo *obj, Efl_Ui_Table_Data *pd, int rows)
{
if (pd->req_rows == rows)
return;
pd->req_rows = rows;
pd->linear_recalc = EINA_TRUE;
efl_pack_layout_request(obj);
}
EOLIAN static int
_efl_ui_table_efl_pack_table_table_rows_get(const Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd)
{
Table_Item *gi;
if (pd->rows_recalc)
{
pd->rows = 0;
EINA_INLIST_REVERSE_FOREACH(EINA_INLIST_GET(pd->items), gi)
{
if (pd->rows < gi->row + gi->row_span)
pd->rows = gi->row + gi->row_span;
}
pd->rows_recalc = EINA_FALSE;
}
return pd->req_rows ? : pd->rows;
}
EOLIAN static Eina_Bool
_efl_ui_table_efl_pack_pack(Eo *obj, Efl_Ui_Table_Data *pd, Efl_Gfx_Entity *subobj)
{
int last_col, last_row;
EINA_SAFETY_ON_NULL_RETURN_VAL(subobj, EINA_FALSE);
_efl_ui_table_last_position_get(obj, pd, &last_col, &last_row);
if (efl_ui_layout_orientation_is_horizontal(pd->fill_dir, EINA_TRUE))
{
last_col++;
if (pd->req_cols && (last_col >= pd->req_cols))
{
last_col = 0;
last_row++;
}
if (last_row < 0) last_row = 0;
}
else
{
last_row++;
if (pd->req_rows && (last_row >= pd->req_rows))
{
last_row = 0;
last_col++;
}
if (last_col < 0) last_col = 0;
}
pd->last_col = last_col;
pd->last_row = last_row;
DBG("packing new obj at %d,%d", last_col, last_row);
return _pack_at(obj, pd, subobj, last_col, last_row, 1, 1);
}
/* Internal EO APIs and hidden overrides */
#define EFL_UI_TABLE_EXTRA_OPS \
EFL_CANVAS_GROUP_ADD_DEL_OPS(efl_ui_table)
#include "efl_ui_table.eo.c"