jpeg pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=a0f92d9befb25038e513f006f442393f41095f7c

commit a0f92d9befb25038e513f006f442393f41095f7c
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Mon Apr 18 20:17:24 2016 +0900

    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).
---
 src/bin/elementary/test_ui_box.c        |   4 +-
 src/bin/elementary/test_ui_grid.c       |  89 ++++++++++++++++++++---
 src/lib/efl/interfaces/efl_pack_grid.eo |   2 +-
 src/lib/elementary/efl_ui_box.c         |  16 ++---
 src/lib/elementary/efl_ui_grid.c        | 121 ++++++++++++++++++++++++++------
 src/lib/elementary/efl_ui_grid.eo       |   8 ++-
 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 3d5a2c2..ba83b55 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 c274526..2d261f7 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 a4ea673..2ca2c0d 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 cd9e3e4..79fb089 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 3b0e7ce..b8a7ee0 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 9a32f42..839d7a2 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;
    }
 }

-- 


Reply via email to