jpeg pushed a commit to branch master.

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

commit 24eccb6d62dc8de443bbd3db8f0d61248a170cf2
Author: Jean-Philippe Andre <jp.an...@samsung.com>
Date:   Tue Apr 12 16:20:54 2016 +0900

    Efl.Ui.Box: Implement way to override layout function
    
    So, since we don't have function pointers, all the solutions
    to reimplementing the layout function are quite convoluted:
    
    1. use events
    2. reimplement layout func
    3. use an extra object
    4. use a generic class (non instanciated)
    
    Promises don't apply here (layout will run multiple times).
    
    Problems:
    
    1. Multiple event callbacks will be called, resulting in
       potential performance impact, extra events, etc...
       Also, there is no way to define standard implementations
       that would be provided by the framework.
    
    2. Reimplementation of a function requires extra EO work
       (create an EO class, etc...), doesn't allow on-the-fly
       change of the layout method.
    
    3. Probably the best solution is to have an object implementing
       the layout. But this means creating an extra object along
       with the container.
    
    4. To avoid the extra object, use a class, and reimplement
       a @class function. This unfortunately requires extra
       EO work.
    
    Solution 4. has been selected, but it's not very nice...
---
 src/Makefile_Efl.am                          |  1 +
 src/lib/efl/Efl.h                            |  1 +
 src/lib/efl/interfaces/efl_interfaces_main.c |  1 +
 src/lib/efl/interfaces/efl_pack.eo           | 14 +++++-
 src/lib/efl/interfaces/efl_pack_engine.eo    | 12 +++++
 src/lib/elementary/efl_ui_box.c              | 65 +++++++++++++++++++++++++---
 src/lib/elementary/efl_ui_box.eo             |  6 ++-
 src/lib/elementary/efl_ui_box_layout.c       |  4 +-
 src/lib/elementary/efl_ui_box_private.h      |  6 ++-
 9 files changed, 97 insertions(+), 13 deletions(-)

diff --git a/src/Makefile_Efl.am b/src/Makefile_Efl.am
index d0ef34b..6c1d678 100644
--- a/src/Makefile_Efl.am
+++ b/src/Makefile_Efl.am
@@ -26,6 +26,7 @@ efl_eolian_files = \
       lib/efl/interfaces/efl_orientation.eo \
       lib/efl/interfaces/efl_flipable.eo \
       lib/efl/interfaces/efl_pack.eo \
+      lib/efl/interfaces/efl_pack_engine.eo \
       lib/efl/interfaces/efl_pack_linear.eo \
       lib/efl/interfaces/efl_pack_grid.eo \
       lib/efl/interfaces/efl_pack_named.eo \
diff --git a/src/lib/efl/Efl.h b/src/lib/efl/Efl.h
index dc9b094..f078e41 100644
--- a/src/lib/efl/Efl.h
+++ b/src/lib/efl/Efl.h
@@ -119,6 +119,7 @@ static inline void efl_gfx_color16_type_set(Efl_Gfx_Color 
*color,
 /* Packing & containers */
 #include "interfaces/efl_pack_item.eo.h"
 #include "interfaces/efl_pack.eo.h"
+#include "interfaces/efl_pack_engine.eo.h"
 #include "interfaces/efl_pack_linear.eo.h"
 #include "interfaces/efl_pack_grid.eo.h"
 #include "interfaces/efl_pack_named.eo.h"
diff --git a/src/lib/efl/interfaces/efl_interfaces_main.c 
b/src/lib/efl/interfaces/efl_interfaces_main.c
index 5f424f9..05be37f 100644
--- a/src/lib/efl/interfaces/efl_interfaces_main.c
+++ b/src/lib/efl/interfaces/efl_interfaces_main.c
@@ -34,6 +34,7 @@ EAPI const Eo_Event_Description _EFL_GFX_PATH_CHANGED =
   EO_EVENT_DESCRIPTION("Graphics path changed");
 
 #include "interfaces/efl_pack.eo.c"
+#include "interfaces/efl_pack_engine.eo.c"
 #include "interfaces/efl_pack_linear.eo.c"
 #include "interfaces/efl_pack_grid.eo.c"
 #include "interfaces/efl_pack_named.eo.c"
diff --git a/src/lib/efl/interfaces/efl_pack.eo 
b/src/lib/efl/interfaces/efl_pack.eo
index 7e9661b..44b8988 100644
--- a/src/lib/efl/interfaces/efl_pack.eo
+++ b/src/lib/efl/interfaces/efl_pack.eo
@@ -56,6 +56,18 @@ interface Efl.Pack (Efl.Pack_Item)
             scalable:  bool;
          }
       }
+      @property layout_engine {
+         [[Implementation of this container's layout algorithm.
+
+           The default value is the same as the widget class (eg. Efl.Ui.Box).
+         ]]
+         set { return: bool; }
+         get {}
+         values {
+            engine: const(Eo.Class)*; [[A class implementing a class function 
layout_do]]
+            data: void*; [[Any data to pass along to layout_do]]
+         }
+      }
       layout_update @protected {
          [[Implementation of this container's layout algorithm.
 
@@ -73,6 +85,6 @@ interface Efl.Pack (Efl.Pack_Item)
    events {
       child,added;
       child,removed;
-      layout,updated;
+      layout,updated; [[sent after the layout was updated]]
    }
 }
diff --git a/src/lib/efl/interfaces/efl_pack_engine.eo 
b/src/lib/efl/interfaces/efl_pack_engine.eo
new file mode 100644
index 0000000..1e2dc57
--- /dev/null
+++ b/src/lib/efl/interfaces/efl_pack_engine.eo
@@ -0,0 +1,12 @@
+interface Efl.Pack_Engine
+{
+   legacy_prefix: null;
+   methods {
+      layout_do @class {
+         params {
+            pack: Efl.Pack*;
+            data: void*;
+         }
+      }
+   }
+}
diff --git a/src/lib/elementary/efl_ui_box.c b/src/lib/elementary/efl_ui_box.c
index fa3792b..7f57d2f 100644
--- a/src/lib/elementary/efl_ui_box.c
+++ b/src/lib/elementary/efl_ui_box.c
@@ -1,5 +1,8 @@
 #include "efl_ui_box_private.h"
 
+// FIXME: stop using Evas.Box
+#include <../evas/canvas/evas_box.eo.h>
+
 /* COPIED FROM ELM_BOX
  * - removed transition stuff (TODO: add back - needs clean API first)
  */
@@ -136,6 +139,59 @@ _on_size_hints_changed(void *data, Evas *e EINA_UNUSED,
      _sizing_eval(data, pd);
 }
 
+static void
+_evas_box_custom_layout(Evas_Object *evas_box EINA_UNUSED,
+                        Evas_Object_Box_Data *bd EINA_UNUSED, void *data)
+{
+   Efl_Ui_Box *obj = data;
+
+   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)
+{
+   efl_pack_engine_layout_do(pd->layout_engine, obj, pd->layout_data);
+   eo_event_callback_call(obj, EFL_PACK_EVENT_LAYOUT_UPDATED, NULL);
+}
+
+EOLIAN static void
+_efl_ui_box_efl_pack_engine_layout_do(Eo *klass EINA_UNUSED,
+                                      void *_pd EINA_UNUSED,
+                                      Eo *obj, void *data EINA_UNUSED)
+{
+   _layout_do(obj);
+}
+
+EOLIAN static Eina_Bool
+_efl_ui_box_efl_pack_layout_engine_set(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data 
*pd,
+                                       const Eo_Class *klass, const void *data)
+{
+   EINA_SAFETY_ON_FALSE_RETURN_VAL(eo_isa(klass, EFL_PACK_INTERFACE), 
EINA_FALSE);
+   pd->layout_engine = klass;
+   pd->layout_data = data;
+
+   return EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_ui_box_efl_pack_layout_engine_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data 
*pd,
+                                       const Eo_Class **klass, const void 
**data)
+{
+   if (klass) *klass = pd->layout_engine;
+   if (data) *data = pd->layout_data;
+}
+
 EOLIAN static void
 _efl_ui_box_evas_object_smart_calculate(Eo *obj, Efl_Ui_Box_Data *pd)
 {
@@ -155,7 +211,7 @@ _efl_ui_box_evas_object_smart_add(Eo *obj, Efl_Ui_Box_Data 
*_pd EINA_UNUSED)
 
    ELM_WIDGET_DATA_GET_OR_RETURN(obj, wd);
    elm_widget_resize_object_set(obj, evas_object_box_add(e), EINA_TRUE);
-   evas_object_box_layout_set(wd->resize_obj, _efl_ui_box_custom_layout, obj, 
NULL);
+   evas_object_box_layout_set(wd->resize_obj, _evas_box_custom_layout, obj, 
NULL);
 
    evas_object_event_callback_add(wd->resize_obj, 
EVAS_CALLBACK_CHANGED_SIZE_HINTS, _on_size_hints_changed, obj);
    evas_object_event_callback_add(obj, EVAS_CALLBACK_CHANGED_SIZE_HINTS, 
_on_size_hints_changed, obj);
@@ -219,6 +275,7 @@ _efl_ui_box_eo_base_constructor(Eo *obj, Efl_Ui_Box_Data 
*pd)
    elm_interface_atspi_accessible_role_set(obj, ELM_ATSPI_ROLE_FILLER);
 
    pd->orient = EFL_ORIENT_RIGHT;
+   pd->layout_engine = MY_CLASS;
 
    return obj;
 }
@@ -392,12 +449,6 @@ _efl_ui_box_efl_pack_linear_child_at_set(Eo *obj, 
Efl_Ui_Box_Data *pd EINA_UNUSE
 }
 
 EOLIAN static void
-_efl_ui_box_efl_pack_layout_update(Eo *obj, Efl_Ui_Box_Data *pd)
-{
-   _sizing_eval(obj, pd);
-}
-
-EOLIAN static void
 _efl_ui_box_efl_pack_layout_request(Eo *obj, Efl_Ui_Box_Data *pd EINA_UNUSED)
 {
    evas_object_smart_need_recalculate_set(obj, EINA_TRUE);
diff --git a/src/lib/elementary/efl_ui_box.eo b/src/lib/elementary/efl_ui_box.eo
index 4cc7e8e..4a97db2 100644
--- a/src/lib/elementary/efl_ui_box.eo
+++ b/src/lib/elementary/efl_ui_box.eo
@@ -1,4 +1,4 @@
-class Efl.Ui.Box (Elm.Widget, Efl.Pack_Linear)
+class Efl.Ui.Box (Elm.Widget, Efl.Pack_Engine, Efl.Pack_Linear)
 {
    legacy_prefix: null;
    implements {
@@ -25,6 +25,8 @@ class Efl.Ui.Box (Elm.Widget, Efl.Pack_Linear)
       Efl.Pack.padding.set;
       Efl.Pack.layout_update;
       Efl.Pack.layout_request;
+      Efl.Pack.layout_engine.get;
+      Efl.Pack.layout_engine.set;
       Efl.Pack_Linear.pack_begin;
       Efl.Pack_Linear.pack_end;
       Efl.Pack_Linear.pack_before;
@@ -35,5 +37,7 @@ class Efl.Ui.Box (Elm.Widget, Efl.Pack_Linear)
       //Efl.Pack_Linear.child_index.set;
       Efl.Pack_Linear.direction.set;
       Efl.Pack_Linear.direction.get;
+
+      Efl.Pack_Engine.layout_do;
    }
 }
diff --git a/src/lib/elementary/efl_ui_box_layout.c 
b/src/lib/elementary/efl_ui_box_layout.c
index d51eca2..f5b457f 100644
--- a/src/lib/elementary/efl_ui_box_layout.c
+++ b/src/lib/elementary/efl_ui_box_layout.c
@@ -19,10 +19,8 @@ struct _Item_Calc
 };
 
 void
-_efl_ui_box_custom_layout(Evas_Object *evas_box EINA_UNUSED,
-                          Evas_Object_Box_Data *bd, void *data)
+_efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
 {
-   Efl_Ui_Box *ui_box = data;
    Efl_Ui_Box_Data *pd = eo_data_scope_get(ui_box, EFL_UI_BOX_CLASS);
    Evas_Object_Box_Option *opt;
    Evas_Object *o;
diff --git a/src/lib/elementary/efl_ui_box_private.h 
b/src/lib/elementary/efl_ui_box_private.h
index 38f9a8e..b9fc0dd 100644
--- a/src/lib/elementary/efl_ui_box_private.h
+++ b/src/lib/elementary/efl_ui_box_private.h
@@ -13,13 +13,17 @@
 #define MY_CLASS EFL_UI_BOX_CLASS
 #define MY_CLASS_NAME "Efl.Ui.Box"
 
-void _efl_ui_box_custom_layout(Evas_Object *evas_box, Evas_Object_Box_Data 
*priv, void *data);
+// FIXME: stop using evas box
+void _efl_ui_box_custom_layout(Efl_Ui_Box *box, Evas_Object_Box_Data *priv);
 
 typedef struct _Efl_Ui_Box_Data Efl_Ui_Box_Data;
 typedef struct _Box_Item_Iterator Box_Item_Iterator;
 
 struct _Efl_Ui_Box_Data
 {
+   const Eo_Class *layout_engine;
+   void *layout_data;
+
    Efl_Orient orient;
    Eina_Bool homogeneous : 1;
    Eina_Bool delete_me : 1;

-- 


Reply via email to