From 138fa4eeaa37eb45ec52be9a194ae4d98aa76c1e Mon Sep 17 00:00:00 2001 From: Yeongjong Lee Date: Wed, 27 Feb 2019 14:45:32 -0500 Subject: [PATCH] ui.table: implement homogeneous mode Summary: Homogeneous mode means children are of the same weight and of the same min size which is determined by maximum min size of cells. Depends on D7841 Reviewers: Jaehyun_Cho, jpeg, zmike Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7892 --- src/lib/elementary/efl_ui_table.c | 14 ++++ src/lib/elementary/efl_ui_table.eo | 15 ++++ src/lib/elementary/efl_ui_table_layout.c | 95 +++++++++++++++++++++-- src/lib/elementary/efl_ui_table_private.h | 2 + 4 files changed, 118 insertions(+), 8 deletions(-) diff --git a/src/lib/elementary/efl_ui_table.c b/src/lib/elementary/efl_ui_table.c index 5f42043b16..ff7de54166 100644 --- a/src/lib/elementary/efl_ui_table.c +++ b/src/lib/elementary/efl_ui_table.c @@ -122,6 +122,20 @@ _custom_table_calc(Eo *obj, Custom_Table_Data *pd) } /* End of custom table class */ +EOLIAN static void +_efl_ui_table_homogeneous_set(Eo *obj EINA_UNUSED, Efl_Ui_Table_Data *pd, Eina_Bool homogeneoush, Eina_Bool homogeneousv) +{ + pd->homogeneoush = !!homogeneoush; + pd->homogeneousv = !!homogeneousv; +} + +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) { diff --git a/src/lib/elementary/efl_ui_table.eo b/src/lib/elementary/efl_ui_table.eo index f3c067f98b..7ccc7d1bc8 100644 --- a/src/lib/elementary/efl_ui_table.eo +++ b/src/lib/elementary/efl_ui_table.eo @@ -2,6 +2,21 @@ class @beta Efl.Ui.Table extends Efl.Ui.Widget implements Efl.Pack_Table, Efl.Pa Efl.Ui.Direction { [[Efl UI table class]] + methods { + @property homogeneous { + [[Control homogeneous mode. + + This will enable the homogeneous mode where cells are of the same + weight and of the same min size which is determined by maximum min + size of cells.]] + values { + homogeneoush : bool; [[$true if the box is homogeneous horizontally, + $false otherwise]] + homogeneousv : bool; [[$true if the box is homogeneous vertically, + $false otherwise]] + } + } + } implements { Efl.Object.constructor; Efl.Canvas.Group.group_calculate; diff --git a/src/lib/elementary/efl_ui_table_layout.c b/src/lib/elementary/efl_ui_table_layout.c index 0a21384a8f..b3009e9f7c 100644 --- a/src/lib/elementary/efl_ui_table_layout.c +++ b/src/lib/elementary/efl_ui_table_layout.c @@ -33,6 +33,7 @@ struct _Table_Calc int rows; int cols; int want[2]; + int hgsize[2]; double weight_sum[2]; Cell_Calc *cell_calc[2]; Efl_Ui_Container_Layout_Calc layout_calc[2]; @@ -97,6 +98,45 @@ _cell_weight_calc(Table_Calc *table_calc, Eina_Bool axis) } } +static void +_efl_ui_table_homogeneous_cell_init(Table_Calc *table_calc, Eina_Bool axis) +{ + int i, index = 0, mmin = 0, count; + Cell_Calc *prev_cell = NULL, *cell_calc; + + cell_calc = table_calc->cell_calc[axis]; + count = axis ? table_calc->rows : table_calc->cols; + + for (i = 0; i < count; i++) + { + if (!cell_calc[i].occupied) continue; + + cell_calc[i].index = index++; + if (cell_calc[i].space > mmin) + mmin = cell_calc[i].space; + + if (prev_cell) + prev_cell->next = i; + + prev_cell = &cell_calc[i]; + } + if (prev_cell) + prev_cell->next = count; + + table_calc->layout_calc[axis].size -= (table_calc->layout_calc[axis].pad + * (index - 1)); + + table_calc->want[axis] = mmin * index; + table_calc->weight_sum[axis] = index; + + if (table_calc->want[axis] > table_calc->layout_calc[axis].size) + table_calc->hgsize[axis] = table_calc->want[axis] / index; + else + table_calc->hgsize[axis] = table_calc->layout_calc[axis].size / index; + + table_calc->hgsize[axis] += table_calc->layout_calc[axis].pad; +} + static void _efl_ui_table_regular_cell_init(Table_Calc *table_calc, Eina_Bool axis) { @@ -139,6 +179,20 @@ _efl_ui_table_regular_cell_init(Table_Calc *table_calc, Eina_Bool axis) cell_calc[i].acc = acc; } +static inline int +_efl_ui_table_homogeneous_item_pos_get(Table_Calc *table_calc, Item_Calc *item, Eina_Bool axis) +{ + return 0.5 + table_calc->layout_calc[axis].pos + (table_calc->hgsize[axis] + * table_calc->cell_calc[axis][item->cell_index[axis]].index); +} + +static inline int +_efl_ui_table_homogeneous_item_size_get(Table_Calc *table_calc, Item_Calc *item, Eina_Bool axis) +{ + return (table_calc->hgsize[axis] * item->cell_span[axis]) + - table_calc->layout_calc[axis].pad; +} + static inline int _efl_ui_table_regular_item_pos_get(Table_Calc *table_calc, Item_Calc *item, Eina_Bool axis) { @@ -170,6 +224,8 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd) Item_Calc *items, *item; Efl_Ui_Container_Item_Hints *hints; int i = 0, rows, cols; + int (*_efl_ui_table_item_pos_get[2])(Table_Calc *, Item_Calc *, Eina_Bool); + int (*_efl_ui_table_item_size_get[2])(Table_Calc *, Item_Calc *, Eina_Bool); Table_Calc table_calc; @@ -215,12 +271,12 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd) _efl_ui_container_layout_item_init(item->obj, hints); - if (table_calc.layout_calc[0].fill) + if (table_calc.layout_calc[0].fill || pd->homogeneoush) hints[0].weight = 1; else if (hints[0].weight < 0) hints[0].weight = 0; - if (table_calc.layout_calc[1].fill) + if (table_calc.layout_calc[1].fill || pd->homogeneousv) hints[1].weight = 1; else if (hints[1].weight < 0) hints[1].weight = 0; @@ -251,8 +307,31 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd) } } - _efl_ui_table_regular_cell_init(&table_calc, 0); - _efl_ui_table_regular_cell_init(&table_calc, 1); + if (pd->homogeneoush) + { + _efl_ui_table_homogeneous_cell_init(&table_calc, 0); + _efl_ui_table_item_pos_get[0] = _efl_ui_table_homogeneous_item_pos_get; + _efl_ui_table_item_size_get[0] = _efl_ui_table_homogeneous_item_size_get; + } + else + { + _efl_ui_table_regular_cell_init(&table_calc, 0); + _efl_ui_table_item_pos_get[0] = _efl_ui_table_regular_item_pos_get; + _efl_ui_table_item_size_get[0] = _efl_ui_table_regular_item_size_get; + } + + if (pd->homogeneousv) + { + _efl_ui_table_homogeneous_cell_init(&table_calc, 1); + _efl_ui_table_item_pos_get[1] = _efl_ui_table_homogeneous_item_pos_get; + _efl_ui_table_item_size_get[1] = _efl_ui_table_homogeneous_item_size_get; + } + else + { + _efl_ui_table_regular_cell_init(&table_calc, 1); + _efl_ui_table_item_pos_get[1] = _efl_ui_table_regular_item_pos_get; + _efl_ui_table_item_size_get[1] = _efl_ui_table_regular_item_size_get; + } for (i = 0; i < pd->count; i++) { @@ -260,10 +339,10 @@ _efl_ui_table_custom_layout(Efl_Ui_Table *ui_table, Efl_Ui_Table_Data *pd) item = &items[i]; hints = items[i].hints; - space.x = _efl_ui_table_regular_item_pos_get(&table_calc, item, 0); - space.y = _efl_ui_table_regular_item_pos_get(&table_calc, item, 1); - space.w = _efl_ui_table_regular_item_size_get(&table_calc, item, 0); - space.h = _efl_ui_table_regular_item_size_get(&table_calc, item, 1); + space.x = _efl_ui_table_item_pos_get[0](&table_calc, item, 0); + space.y = _efl_ui_table_item_pos_get[1](&table_calc, item, 1); + space.w = _efl_ui_table_item_size_get[0](&table_calc, item, 0); + space.h = _efl_ui_table_item_size_get[1](&table_calc, item, 1); item_geom.w = hints[0].fill ? space.w : hints[0].min; item_geom.h = hints[1].fill ? space.h : hints[1].min; diff --git a/src/lib/elementary/efl_ui_table_private.h b/src/lib/elementary/efl_ui_table_private.h index 0ab08e5109..4aea410376 100644 --- a/src/lib/elementary/efl_ui_table_private.h +++ b/src/lib/elementary/efl_ui_table_private.h @@ -45,6 +45,8 @@ struct _Efl_Ui_Table_Data double h, v; } align; Eina_Bool linear_recalc : 1; + Eina_Bool homogeneoush : 1; + Eina_Bool homogeneousv : 1; }; struct _Table_Item_Iterator