Efl.Ui.Box: Add pack_align property
authorJean-Philippe Andre <jp.andre@samsung.com>
Fri, 15 Apr 2016 08:06:14 +0000 (17:06 +0900)
committerJean-Philippe Andre <jp.andre@samsung.com>
Wed, 20 Apr 2016 01:47:40 +0000 (10:47 +0900)
While at first I wanted to remove the box_align / table_align
properties, it ends up being a necessary value in some cases.

src/bin/elementary/test_ui_box.c
src/lib/efl/interfaces/efl_pack.eo
src/lib/elementary/efl_ui_box.c
src/lib/elementary/efl_ui_box.eo
src/lib/elementary/efl_ui_box_layout.c
src/lib/elementary/efl_ui_box_private.h

index f61ea20..2e8bed4 100644 (file)
@@ -91,6 +91,26 @@ margin_slider_cb(void *data, const Eo_Event *event)
    return EO_CALLBACK_CONTINUE;
 }
 
+static Eina_Bool
+alignh_slider_cb(void *data, const Eo_Event *event)
+{
+   double av, val;
+   val = elm_slider_value_get(event->obj);
+   efl_pack_align_get(data, NULL, &av);
+   efl_pack_align_set(data, val, av);
+   return EO_CALLBACK_CONTINUE;
+}
+
+static Eina_Bool
+alignv_slider_cb(void *data, const Eo_Event *event)
+{
+   double ah, val;
+   val = elm_slider_value_get(event->obj);
+   efl_pack_align_get(data, &ah, NULL);
+   efl_pack_align_set(data, ah, val);
+   return EO_CALLBACK_CONTINUE;
+}
+
 static Efl_Ui_Box_Flow_Params s_flow_params = { 0.5, 0.5, 0, 0 };
 static Eina_Bool flow = EINA_FALSE;
 
@@ -455,6 +475,46 @@ test_ui_box(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_in
    efl_gfx_visible_set(o, 1);
 
 
+   /* Box align */
+   bx = eo_add(EFL_UI_BOX_CLASS, win,
+               efl_pack_direction_set(eo_self, EFL_ORIENT_DOWN));
+   evas_object_size_hint_align_set(bx, 0, -1);
+   evas_object_size_hint_weight_set(bx, 1, 1);
+   efl_pack(hbox, bx);
+   efl_gfx_visible_set(bx, 1);
+
+   o = elm_label_add(win);
+   elm_object_text_set(o, "Box align");
+   efl_pack(bx, o);
+   efl_gfx_visible_set(o, 1);
+
+   o = elm_slider_add(win);
+   elm_slider_indicator_format_set(o, "%.1f");
+   elm_slider_indicator_show_set(o, 1);
+   elm_slider_horizontal_set(o, 0);
+   evas_object_size_hint_align_set(o, 0.5, -1);
+   evas_object_size_hint_weight_set(o, 1, 1);
+   eo_event_callback_add(o, ELM_SLIDER_EVENT_CHANGED, alignv_slider_cb, bottombox);
+   elm_slider_min_max_set(o, -0.1, 1.0);
+   elm_slider_step_set(o, 0.1);
+   elm_slider_value_set(o, 0.5);
+   efl_pack(bx, o);
+   efl_gfx_visible_set(o, 1);
+
+   o = elm_slider_add(win);
+   elm_slider_indicator_format_set(o, "%.1f");
+   elm_slider_indicator_show_set(o, 1);
+   elm_slider_horizontal_set(o, 1);
+   evas_object_size_hint_align_set(o, 0.5, -1);
+   evas_object_size_hint_weight_set(o, 1, 0);
+   eo_event_callback_add(o, ELM_SLIDER_EVENT_CHANGED, alignh_slider_cb, bottombox);
+   elm_slider_min_max_set(o, -0.1, 1.0);
+   elm_slider_step_set(o, 0.1);
+   elm_slider_value_set(o, 0.5);
+   efl_pack(bx, o);
+   efl_gfx_visible_set(o, 1);
+
+
    /* contents */
    f = elm_frame_add(win);
    elm_object_text_set(f, "Contents");
index 6e0333d..2c9780f 100644 (file)
@@ -46,6 +46,15 @@ interface Efl.Pack (Efl.Pack_Item)
             subobj: Efl.Pack_Item*;
          }
       }
+      @property pack_align {
+         [[Alignment of the container within its bounds]]
+         set {}
+         get {}
+         values {
+            align_horiz: double;
+            align_vert:  double;
+         }
+      }
       @property padding {
          [[Padding between items contained in this object.]]
          set {}
index d4bedf6..4e1b7bc 100644 (file)
@@ -273,6 +273,8 @@ _efl_ui_box_eo_base_constructor(Eo *obj, Efl_Ui_Box_Data *pd)
 
    pd->orient = EFL_ORIENT_RIGHT;
    pd->layout_engine = MY_CLASS;
+   pd->align.h = 0.5;
+   pd->align.v = 0.5;
 
    return obj;
 }
@@ -556,4 +558,24 @@ _efl_ui_box_efl_pack_padding_get(Eo *obj, Efl_Ui_Box_Data *pd, double *h, double
    if (v) *v = pd->pad.v;
 }
 
+EOLIAN static void
+_efl_ui_box_efl_pack_pack_align_set(Eo *obj, Efl_Ui_Box_Data *pd, double h, double v)
+{
+   if (h < 0) h = -1;
+   if (v < 0) v = -1;
+   if (h > 1) h = 1;
+   if (v > 1) v = 1;
+   pd->align.h = h;
+   pd->align.v = v;
+
+   efl_pack_layout_request(obj);
+}
+
+EOLIAN static void
+_efl_ui_box_efl_pack_pack_align_get(Eo *obj EINA_UNUSED, Efl_Ui_Box_Data *pd, double *h, double *v)
+{
+   if (h) *h = pd->align.h;
+   if (v) *v = pd->align.v;
+}
+
 #include "efl_ui_box.eo.c"
index 4a97db2..2ef5a76 100644 (file)
@@ -23,6 +23,8 @@ class Efl.Ui.Box (Elm.Widget, Efl.Pack_Engine, Efl.Pack_Linear)
       Efl.Pack.pack;
       Efl.Pack.padding.get;
       Efl.Pack.padding.set;
+      Efl.Pack.pack_align.get;
+      Efl.Pack.pack_align.set;
       Efl.Pack.layout_update;
       Efl.Pack.layout_request;
       Efl.Pack.layout_engine.get;
index 72cdb9f..2d81c17 100644 (file)
@@ -31,17 +31,28 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
    Eina_Bool horiz = _horiz(pd->orient), zeroweight = EINA_FALSE;
    int id = 0, count, boxl = 0, boxr = 0, boxt = 0, boxb = 0;
    int length, want, deficit = 0, pad, extra = 0, rounding = 0;
-   double cur_pos = 0, weight = 0, scale;
+   double cur_pos = 0, weight[2] = { 0, 0 }, scale;
    double box_align[2];
+   Eina_Bool box_fill[2] = { EINA_FALSE, EINA_FALSE };
 
    evas_object_geometry_get(ui_box, &boxx, &boxy, &boxw, &boxh);
    evas_object_size_hint_padding_get(ui_box, &boxl, &boxr, &boxt, &boxb);
    scale = evas_object_scale_get(ui_box);
 
    // Box align: used if "item has max size and fill" or "no item has a weight"
-   //box_align[0] = bd->align.h;
-   //box_align[1] = bd->align.v;
-   evas_object_size_hint_align_get(ui_box, &box_align[0], &box_align[1]);
+   // Note: cells always expand on the orthogonal direction
+   box_align[0] = pd->align.h;
+   box_align[1] = pd->align.v;
+   if (box_align[0] < 0)
+     {
+        box_fill[0] = EINA_TRUE;
+        box_align[0] = 0.5;
+     }
+   if (box_align[1] < 0)
+     {
+        box_fill[1] = EINA_TRUE;
+        box_align[1] = 0.5;
+     }
 
    count = eina_list_count(bd->children);
    if (!count)
@@ -89,16 +100,16 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
         item->want[0] = MAX(item->req[0], item->min[0]) + item->pad[0] + item->pad[1];
         item->want[1] = MAX(item->req[1], item->min[1]) + item->pad[2] + item->pad[3];
 
+        weight[0] += item->weight[0];
+        weight[1] += item->weight[1];
         if (horiz)
           {
-             weight += item->weight[0];
              wantw += item->want[0];
              if (item->want[1] > wanth)
                wanth = item->want[1];
           }
         else
           {
-             weight += item->weight[1];
              wanth += item->want[1];
              if (item->want[0] > wantw)
                wantw = item->want[0];
@@ -110,6 +121,8 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
    // box outer margin
    boxw -= boxl + boxr;
    boxh -= boxt + boxb;
+   boxx += boxl;
+   boxy += boxt;
 
    // total space & available space
    if (horiz)
@@ -151,10 +164,9 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
         extra = 0;
      }
 
-   if (!weight)
+   if (!weight[!horiz])
      {
-        double balign = box_align[!horiz];
-        if (balign < 0)
+        if (box_fill[!horiz])
           {
              // box is filled, set all weights to be equal
              zeroweight = EINA_TRUE;
@@ -162,15 +174,11 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
         else
           {
              // move bounding box according to box align
-             cur_pos = extra * balign;
+             cur_pos = extra * box_align[!horiz];
           }
-        weight = count;
+        weight[!horiz] = count;
      }
 
-   // reset box_align to 0.5 if filled (only used by items with max size)
-   if (box_align[0] < 0) box_align[0] = 0.5;
-   if (box_align[1] < 0) box_align[1] = 0.5;
-
    for (id = 0; id < count; id++)
      {
         double cx, cy, cw, ch, x, y, w, h;
@@ -182,18 +190,18 @@ _efl_ui_box_custom_layout(Efl_Ui_Box *ui_box, Evas_Object_Box_Data *bd)
 
         if (horiz)
           {
-             cx = boxx + boxl + cur_pos;
-             cy = boxy + boxt;
-             cw = item->want[0] + rounding + (zeroweight ? 1.0 : item->weight[0]) * extra / weight;
+             cx = boxx + cur_pos;
+             cy = boxy;
+             cw = item->want[0] + rounding + (zeroweight ? 1.0 : item->weight[0]) * extra / weight[0];
              ch = boxh;
              cur_pos += cw + pad;
           }
         else
           {
-             cx = boxx + boxl;
-             cy = boxy + boxt + cur_pos;
+             cx = boxx;
+             cy = boxy + cur_pos;
              cw = boxw;
-             ch = item->want[1] + rounding + (zeroweight ? 1.0 : item->weight[1]) * extra / weight;
+             ch = item->want[1] + rounding + (zeroweight ? 1.0 : item->weight[1]) * extra / weight[1];
              cur_pos += ch + pad;
           }
 
index 64b009e..234f7b1 100644 (file)
@@ -36,6 +36,10 @@ struct _Efl_Ui_Box_Data
       double h, v;
       Eina_Bool scalable: 1;
    } pad;
+
+   struct {
+      double h, v;
+   } align;
 };
 
 struct _Box_Item_Iterator