summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2016-04-18 20:17:24 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2016-04-20 10:47:40 +0900
commita0f92d9befb25038e513f006f442393f41095f7c (patch)
treef7030b53a280c25f21f71e3b1befb0c8005db853
parente4889ca367b2cde28a8c4bafedd36ec3fc0b3879 (diff)
downloadefl-a0f92d9befb25038e513f006f442393f41095f7c.tar.gz
Efl.Ui.Grid: Implement custom layout functions
Untested yet. Will need to add the common 3 classes: - standard - homogenous - homogenous max_size And then implement a true custom layout function, that respects weights in a certain manner (need to define it clearly).
-rw-r--r--src/bin/elementary/test_ui_box.c4
-rw-r--r--src/bin/elementary/test_ui_grid.c89
-rw-r--r--src/lib/efl/interfaces/efl_pack_grid.eo2
-rw-r--r--src/lib/elementary/efl_ui_box.c16
-rw-r--r--src/lib/elementary/efl_ui_grid.c121
-rw-r--r--src/lib/elementary/efl_ui_grid.eo8
6 files changed, 194 insertions, 46 deletions
diff --git a/src/bin/elementary/test_ui_box.c b/src/bin/elementary/test_ui_box.c
index 3d5a2c23e3..ba83b55d42 100644
--- a/src/bin/elementary/test_ui_box.c
+++ b/src/bin/elementary/test_ui_box.c
@@ -200,13 +200,13 @@ static const Eo_Class_Description custom_engine_class_desc = {
EO_CLASS_DESCRIPTION_OPS(custom_engine_op_desc), NULL, 0, NULL, NULL
};
-EO_DEFINE_CLASS(custom_engine_class_get, &custom_engine_class_desc, EFL_PACK_ENGINE_INTERFACE, NULL)
+EO_DEFINE_CLASS(_test_ui_box_custom_engine_class_get, &custom_engine_class_desc, EFL_PACK_ENGINE_INTERFACE, NULL)
static Eina_Bool
custom_check_cb(void *data, const Eo_Event *event)
{
Eina_Bool chk = elm_check_selected_get(event->obj);
- efl_pack_layout_engine_set(data, chk ? custom_engine_class_get() : NULL, NULL);
+ efl_pack_layout_engine_set(data, chk ? _test_ui_box_custom_engine_class_get() : NULL, NULL);
return EO_CALLBACK_CONTINUE;
}
diff --git a/src/bin/elementary/test_ui_grid.c b/src/bin/elementary/test_ui_grid.c
index c2745269e3..2d261f706e 100644
--- a/src/bin/elementary/test_ui_grid.c
+++ b/src/bin/elementary/test_ui_grid.c
@@ -10,47 +10,68 @@ typedef enum {
NONE_BUT_FILL,
EQUAL,
ONE,
- TWO
+ TWO,
+ CUSTOM
} Weight_Mode;
-#define P(i) ((void*)(intptr_t)i)
-#define I(p) ((int)(intptr_t)p)
+static void _custom_engine_layout_do(Eo *obj, void *pd, Efl_Pack *pack, const void *data);
+
+/* Common Eo Class boilerplate. */
+static const Eo_Op_Description custom_engine_op_desc[] = {
+ EO_OP_CLASS_FUNC_OVERRIDE(efl_pack_engine_layout_do, _custom_engine_layout_do),
+};
+
+static const Eo_Class_Description custom_engine_class_desc = {
+ EO_VERSION, "Custom Layout Engine", EO_CLASS_TYPE_INTERFACE,
+ EO_CLASS_DESCRIPTION_OPS(custom_engine_op_desc), NULL, 0, NULL, NULL
+};
+
+EO_DEFINE_CLASS(_test_ui_grid_custom_engine_class_get, &custom_engine_class_desc, EFL_PACK_ENGINE_INTERFACE, NULL)
+
+#define CUSTOM_ENGINE_CLASS _test_ui_grid_custom_engine_class_get()
static Eina_Bool
weights_cb(void *data, const Eo_Event *event)
{
Weight_Mode mode = elm_radio_state_value_get(event->obj);
+ Eo *grid = data;
+
+ if (mode != CUSTOM)
+ efl_pack_layout_engine_set(grid, NULL, NULL);
switch (mode)
{
case NONE:
- evas_object_size_hint_align_set(data, 0.5, 0.5);
+ evas_object_size_hint_align_set(grid, 0.5, 0.5);
for (int i = 0; i < 7; i++)
evas_object_size_hint_weight_set(objects[i], 0, 0);
break;
case NONE_BUT_FILL:
- evas_object_size_hint_align_set(data, -1, -1);
+ evas_object_size_hint_align_set(grid, -1, -1);
for (int i = 0; i < 7; i++)
evas_object_size_hint_weight_set(objects[i], 0, 0);
break;
case EQUAL:
- evas_object_size_hint_align_set(data, 0.5, 0.5);
+ evas_object_size_hint_align_set(grid, 0.5, 0.5);
for (int i = 0; i < 7; i++)
evas_object_size_hint_weight_set(objects[i], 1, 1);
break;
case ONE:
- evas_object_size_hint_align_set(data, 0.5, 0.5);
+ evas_object_size_hint_align_set(grid, 0.5, 0.5);
for (int i = 0; i < 6; i++)
evas_object_size_hint_weight_set(objects[i], 0, 0);
evas_object_size_hint_weight_set(objects[6], 1, 1);
break;
case TWO:
- evas_object_size_hint_align_set(data, 0.5, 0.5);
+ evas_object_size_hint_align_set(grid, 0.5, 0.5);
for (int i = 0; i < 5; i++)
evas_object_size_hint_weight_set(objects[i], 0, 0);
evas_object_size_hint_weight_set(objects[5], 1, 1);
evas_object_size_hint_weight_set(objects[6], 1, 1);
break;
+ case CUSTOM:
+ efl_pack_layout_engine_set(grid, CUSTOM_ENGINE_CLASS, NULL);
+ break;
}
return EO_CALLBACK_CONTINUE;
@@ -123,6 +144,49 @@ child_evt_cb(void *data, const Eo_Event *event)
return EO_CALLBACK_CONTINUE;
}
+static void
+_custom_engine_layout_do(Eo *obj EINA_UNUSED, void *pd EINA_UNUSED,
+ Efl_Pack *pack, const void *data EINA_UNUSED)
+{
+ /* Example custom layout for grid:
+ * divide space into regions of same size, place objects in center of their
+ * cells using their min size
+ * Note: This is a TERRIBLE layout function (disregards align, weight, ...)
+ */
+
+ int rows, cols, gw, gh, gx, gy, c, r, cs, rs, gmw = 0, gmh = 0;
+ Eina_Iterator *it;
+ Eo *item;
+
+ efl_gfx_size_get(pack, &gw, &gh);
+ efl_gfx_position_get(pack, &gx, &gy);
+
+ efl_pack_grid_size_get(pack, &cols, &rows);
+ if (!cols || !rows) goto end;
+
+ it = efl_pack_contents_iterate(pack);
+ EINA_ITERATOR_FOREACH(it, item)
+ {
+ if (efl_pack_child_position_get(pack, item, &c, &r, &cs, &rs))
+ {
+ int x, y, mw, mh;
+
+ evas_object_size_hint_min_get(item, &mw, &mh);
+ x = gx + c * gw / cols + (cs * gw / cols - mw) / 2;
+ y = gy + r * gh / rows + (rs * gh / rows - mh) / 2;
+ efl_gfx_size_set(item, mw, mh);
+ efl_gfx_position_set(item, x, y);
+
+ gmw = MAX(gmw, mw);
+ gmh = MAX(gmh, mh);
+ }
+ }
+ eina_iterator_free(it);
+
+end:
+ evas_object_size_hint_min_set(pack, gmw * cols, gmh * rows);
+}
+
void
test_ui_grid(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
{
@@ -211,6 +275,15 @@ test_ui_grid(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_i
efl_pack(bx, o);
efl_gfx_visible_set(o, 1);
+ o = elm_radio_add(win);
+ elm_object_text_set(o, "Custom layout");
+ eo_event_callback_add(o, ELM_RADIO_EVENT_CHANGED, weights_cb, grid);
+ evas_object_size_hint_align_set(o, 0, 0.5);
+ elm_radio_state_value_set(o, CUSTOM);
+ elm_radio_group_add(o, chk);
+ efl_pack(bx, o);
+ efl_gfx_visible_set(o, 1);
+
elm_radio_value_set(chk, EQUAL);
diff --git a/src/lib/efl/interfaces/efl_pack_grid.eo b/src/lib/efl/interfaces/efl_pack_grid.eo
index a4ea673ede..2ca2c0d5d0 100644
--- a/src/lib/efl/interfaces/efl_pack_grid.eo
+++ b/src/lib/efl/interfaces/efl_pack_grid.eo
@@ -36,7 +36,7 @@ interface Efl.Pack_Grid (Efl.Pack_Linear)
@property pack_child_position {
[[position and span of the $subobj in this container, may be modified to move the $subobj]]
set { [[same as grid_pack]] }
- get {}
+ get { return: bool; [[returns false if item is not a child]] }
keys {
subobj: Efl.Pack_Item*;
}
diff --git a/src/lib/elementary/efl_ui_box.c b/src/lib/elementary/efl_ui_box.c
index cd9e3e48a8..79fb089972 100644
--- a/src/lib/elementary/efl_ui_box.c
+++ b/src/lib/elementary/efl_ui_box.c
@@ -148,16 +148,6 @@ _evas_box_custom_layout(Evas_Object *evas_box EINA_UNUSED,
efl_pack_layout_update(obj);
}
-static void
-_layout_do(Efl_Ui_Box *obj)
-{
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
- Evas_Object_Box_Data *bd;
-
- bd = eo_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS);
- _efl_ui_box_custom_layout(obj, bd);
-}
-
EOLIAN static void
_efl_ui_box_efl_pack_layout_update(Eo *obj, Efl_Ui_Box_Data *pd)
{
@@ -170,7 +160,11 @@ _efl_ui_box_efl_pack_engine_layout_do(Eo *klass EINA_UNUSED,
void *_pd EINA_UNUSED,
Eo *obj, const void *data EINA_UNUSED)
{
- _layout_do(obj);
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+ Evas_Object_Box_Data *bd;
+
+ bd = eo_data_scope_get(wd->resize_obj, EVAS_BOX_CLASS);
+ _efl_ui_box_custom_layout(obj, bd);
}
EOLIAN static Eina_Bool
diff --git a/src/lib/elementary/efl_ui_grid.c b/src/lib/elementary/efl_ui_grid.c
index 3b0e7ce810..b8a7ee06a2 100644
--- a/src/lib/elementary/efl_ui_grid.c
+++ b/src/lib/elementary/efl_ui_grid.c
@@ -8,6 +8,7 @@
#include "elm_priv.h"
#include "efl_ui_grid.eo.h"
+#include "../evas/canvas/evas_table.eo.h"
#define MY_CLASS EFL_UI_GRID_CLASS
#define MY_CLASS_NAME "Efl.Ui.Grid"
@@ -15,6 +16,7 @@
typedef struct _Efl_Ui_Grid_Data Efl_Ui_Grid_Data;
typedef struct _Grid_Item_Iterator Grid_Item_Iterator;
typedef struct _Grid_Item Grid_Item;
+typedef struct _Custom_Table_Data Custom_Table_Data;
static Eina_Bool _subobj_del_cb(void *data, const Eo_Event *event);
static void _item_remove(Efl_Ui_Grid *obj, Efl_Ui_Grid_Data *pd, Efl_Pack_Item *subobj);
@@ -34,6 +36,9 @@ struct _Grid_Item
struct _Efl_Ui_Grid_Data
{
+ const Eo_Class *layout_engine;
+ const void *layout_data;
+
Grid_Item *items;
int count;
@@ -49,12 +54,18 @@ struct _Efl_Ui_Grid_Data
struct _Grid_Item_Iterator
{
- Eina_List *list;
Eina_Iterator iterator;
Eina_Iterator *real_iterator;
+ Eina_List *list;
Efl_Ui_Grid *object;
};
+struct _Custom_Table_Data
+{
+ Efl_Ui_Grid *parent;
+ Efl_Ui_Grid_Data *gd;
+};
+
static const Eo_Callback_Array_Item subobj_callbacks [] = {
{ EO_BASE_EVENT_DEL, _subobj_del_cb },
{ NULL, NULL }
@@ -173,7 +184,6 @@ _efl_ui_grid_elm_widget_theme_apply(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
static void
_layout_updated_emit(Efl_Ui_Grid *obj)
{
- /* FIXME: can't be called properly since there is no smart calc event */
eo_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
}
@@ -197,7 +207,6 @@ _sizing_eval(Evas_Object *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
if ((maxw >= 0) && (w > maxw)) w = maxw;
if ((maxh >= 0) && (h > maxh)) h = maxh;
evas_object_resize(obj, w, h);
- _layout_updated_emit(obj);
}
static void
@@ -210,14 +219,93 @@ _table_size_hints_changed(void *data, Evas *e EINA_UNUSED,
_sizing_eval(data, pd);
}
+/* Custom table class: overrides smart_calculate. */
+static void _custom_table_calc(Eo *obj, Custom_Table_Data *pd);
+
+static const Eo_Op_Description custom_table_op_desc[] = {
+ EO_OP_CLASS_FUNC_OVERRIDE(evas_obj_smart_calculate, _custom_table_calc),
+};
+
+static const Eo_Class_Description custom_table_class_desc = {
+ EO_VERSION, "Efl.Ui.Grid.Internal", EO_CLASS_TYPE_REGULAR,
+ EO_CLASS_DESCRIPTION_OPS(custom_table_op_desc), NULL,
+ sizeof(Custom_Table_Data), NULL, NULL
+};
+
+EO_DEFINE_CLASS(_efl_ui_grid_custom_table_class_get, &custom_table_class_desc,
+ EVAS_TABLE_CLASS, NULL)
+
+#define CUSTOM_TABLE_CLASS _efl_ui_grid_custom_table_class_get()
+
+static void
+_custom_table_calc(Eo *obj, Custom_Table_Data *pd)
+{
+ int cols, rows;
+
+ evas_object_table_col_row_size_get(obj, &cols, &rows);
+ if ((cols < 1) || (rows < 1)) return;
+
+ efl_pack_layout_update(pd->parent);
+ _layout_updated_emit(pd->parent);
+}
+/* End of custom table class */
+
+EOLIAN Eina_Bool
+_efl_ui_grid_efl_pack_layout_engine_set(Eo *obj, Efl_Ui_Grid_Data *pd, const Eo_Class *engine, const void *data)
+{
+ pd->layout_engine = engine ? engine : eo_class_get(obj);
+ pd->layout_data = data;
+ efl_pack_layout_request(obj);
+ return EINA_TRUE;
+}
+
+EOLIAN void
+_efl_ui_grid_efl_pack_layout_engine_get(Eo *obj EINA_UNUSED, Efl_Ui_Grid_Data *pd, const Eo_Class **engine, const void **data)
+{
+ if (engine) *engine = pd->layout_engine;
+ if (data) *data = pd->layout_data;
+}
+
+EOLIAN static void
+_efl_ui_grid_efl_pack_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
+{
+ _sizing_eval(obj, pd);
+ efl_pack_engine_layout_do(pd->layout_engine, obj, pd->layout_data);
+}
+
EOLIAN static void
-_efl_ui_grid_evas_object_smart_add(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
+_efl_ui_grid_efl_pack_engine_layout_do(Eo *klass EINA_UNUSED,
+ void *_pd EINA_UNUSED,
+ Eo *obj, const void *data EINA_UNUSED)
{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ evas_obj_smart_calculate(eo_super(wd->resize_obj, CUSTOM_TABLE_CLASS));
+}
+
+EOLIAN void
+_efl_ui_grid_evas_object_smart_calculate(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
+{
+ ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
+
+ efl_pack_layout_update(obj);
+}
+
+EOLIAN static void
+_efl_ui_grid_evas_object_smart_add(Eo *obj, Efl_Ui_Grid_Data *pd)
+{
+ Custom_Table_Data *custom;
Evas_Object *table;
+ pd->layout_engine = MY_CLASS;
+
elm_widget_sub_object_parent_add(obj);
- table = evas_object_table_add(evas_object_evas_get(obj));
+ table = eo_add(CUSTOM_TABLE_CLASS, obj);
+ custom = eo_data_scope_get(table, CUSTOM_TABLE_CLASS);
+ custom->gd = pd;
+ custom->parent = obj;
+
evas_object_table_homogeneous_set(table, EVAS_OBJECT_TABLE_HOMOGENEOUS_TABLE);
elm_widget_resize_object_set(obj, table, EINA_TRUE);
@@ -276,6 +364,8 @@ _efl_ui_grid_eo_base_constructor(Eo *obj, Efl_Ui_Grid_Data *pd)
return obj;
}
+
+
EOLIAN static void
_efl_ui_grid_efl_pack_padding_set(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, double h, double v, Eina_Bool scalable)
{
@@ -408,11 +498,12 @@ _efl_ui_grid_efl_pack_grid_pack_child_position_set(Eo *obj, Efl_Ui_Grid_Data *pd
_pack_at(obj, pd, subobj, col, row, colspan, rowspan, EINA_FALSE);
}
-EOLIAN static void
+EOLIAN static Eina_Bool
_efl_ui_grid_efl_pack_grid_pack_child_position_get(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED, Evas_Object *subobj, int *col, int *row, int *colspan, int *rowspan)
{
int c = -1, r = -1, cs = 0, rs = 0;
Grid_Item *gi;
+ Eina_Bool ret = EINA_FALSE;
if (obj != elm_widget_parent_widget_get(subobj))
{
@@ -429,11 +520,14 @@ _efl_ui_grid_efl_pack_grid_pack_child_position_get(Eo *obj, Efl_Ui_Grid_Data *pd
rs = gi->row_span;
}
+ ret = EINA_TRUE;
+
end:
if (col) *col = c;
if (row) *row = r;
if (colspan) *colspan = cs;
if (rowspan) *rowspan = rs;
+ return ret;
}
EOLIAN static Efl_Pack_Item *
@@ -534,21 +628,6 @@ _efl_ui_grid_efl_pack_unpack_all(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
}
EOLIAN void
-_efl_ui_grid_evas_object_smart_calculate(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
-{
- ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
-
- evas_object_smart_calculate(wd->resize_obj);
-}
-
-EOLIAN void
-_efl_ui_grid_efl_pack_layout_update(Eo *obj, Efl_Ui_Grid_Data *pd)
-{
- _sizing_eval(obj, pd);
- _layout_updated_emit(obj);
-}
-
-EOLIAN void
_efl_ui_grid_efl_pack_layout_request(Eo *obj, Efl_Ui_Grid_Data *pd EINA_UNUSED)
{
evas_object_smart_need_recalculate_set(obj, EINA_TRUE);
diff --git a/src/lib/elementary/efl_ui_grid.eo b/src/lib/elementary/efl_ui_grid.eo
index 9a32f427b2..839d7a24a9 100644
--- a/src/lib/elementary/efl_ui_grid.eo
+++ b/src/lib/elementary/efl_ui_grid.eo
@@ -1,7 +1,5 @@
-class Efl.Ui.Grid (Elm.Widget, Efl.Pack_Grid)
+class Efl.Ui.Grid (Elm.Widget, Efl.Pack_Grid, Efl.Pack_Engine)
{
- methods {
- }
implements {
Eo.Base.constructor;
@@ -41,5 +39,9 @@ class Efl.Ui.Grid (Elm.Widget, Efl.Pack_Grid)
Efl.Pack_Linear.pack_end;
Efl.Pack_Linear.direction.set;
Efl.Pack_Linear.direction.get;
+
+ Efl.Pack.layout_engine.get;
+ Efl.Pack.layout_engine.set;
+ Efl.Pack_Engine.layout_do;
}
}