[box] added extended mode to horizontal box
authorMyungjae Lee <mjae.lee@samsung.com>
Sun, 22 Aug 2010 06:22:35 +0000 (15:22 +0900)
committerMyungjae Lee <mjae.lee@samsung.com>
Sun, 22 Aug 2010 06:22:35 +0000 (15:22 +0900)
src/lib/elm_box.c
src/lib/els_box.c
src/lib/els_box.h

index 6eb9078..b003784 100644 (file)
@@ -26,6 +26,7 @@ struct _Widget_Data
    Evas_Object *box;
    Eina_Bool horizontal:1;
    Eina_Bool homogeneous:1;
+   Eina_Bool extended:1;
 };
 
 static const char *widtype = NULL;
@@ -88,7 +89,7 @@ _layout(Evas_Object *o, Evas_Object_Box_Data *priv, void *data)
 {
    Widget_Data *wd = data;
    if (!wd) return;
-   _els_box_layout(o, priv, wd->horizontal, wd->homogeneous);
+   _els_box_layout_ex(o, priv, wd->horizontal, wd->homogeneous, wd->extended);
 }
 
 
@@ -132,6 +133,32 @@ elm_box_add(Evas_Object *parent)
 }
 
 /**
+ * Set the extended mode
+ *
+ * By default box object arrange their contents vertically from top to bottom.
+ * By calling this and providing @p orizontal as true, the box will become
+ * extended arranging contents left to right.
+ *
+ * @param obj The box object
+ * @param extended The extended flag (1 = extended, 0 = normal)
+ *
+ * @ingroup Box
+ */
+EAPI void
+elm_box_extended_set(Evas_Object *obj, Eina_Bool extended)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->extended = !!extended;
+   if (extended)
+          wd->horizontal = 1;  /* Do NOT support vertical extended mode */
+   evas_object_smart_calculate(wd->box);
+
+}
+
+
+/**
  * Set the horizontal orientation
  *
  * By default box object arrange their contents vertically from top to bottom.
index 3d6d2c8..419341b 100644 (file)
 #include "elm_priv.h"
 
 static void
-_smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horizontal, int homogeneous)
+_smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horizontal, int homogeneous, int extended)
 {
-   Evas_Coord minw, minh, maxw, maxh, mnw, mnh;
-   const Eina_List *l;
-   Evas_Object_Box_Option *opt;
+       Evas_Coord minw, minh, maxw, maxh, mnw, mnh;
+       Evas_Coord w, h, cal_w = 0, cal_h = 0, cur_line_max_h = 0;
+       const Eina_List *l;
+       Evas_Object_Box_Option *opt;
 
-   /* FIXME: need to calc max */
-   minw = 0;
-   minh = 0;
-   maxw = -1;
-   maxh = -1;
-   if (homogeneous)
-     {
-       EINA_LIST_FOREACH(priv->children, l, opt)
-         {
-            evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
-            if (minh < mnh) minh = mnh;
-            if (minw < mnw) minw = mnw;
-         }
-       if (horizontal)
-          minw *= eina_list_count(priv->children);
+       /* FIXME: need to calc max */
+       minw = 0;
+       minh = 0;
+       maxw = -1;
+       maxh = -1;
+
+       if (homogeneous)
+       {
+               EINA_LIST_FOREACH(priv->children, l, opt)
+               {
+                       evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
+                       if (minh < mnh) minh = mnh;
+                       if (minw < mnw) minw = mnw;
+               }
+               if (horizontal)
+                       minw *= eina_list_count(priv->children);
+               else
+                       minh *= eina_list_count(priv->children);
+       }
        else
-          minh *= eina_list_count(priv->children);
-     }
-   else
-     {
+       {
+               if (horizontal && extended)
+               {
+                       evas_object_geometry_get(box, NULL, NULL, &w, &h);
+                       minw = w;
+               }
+
+               EINA_LIST_FOREACH(priv->children, l, opt)
+               {
+                       evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
+                       if (horizontal)
+                       {
+                               if (extended)
+                               {
+                                       if ((cal_w + mnw) > w)
+                                       {
+                                               minh += cur_line_max_h;
+                                               cal_w = 0;
+                                               cur_line_max_h = 0;
+                                       }
+                                       cal_w += mnw;
+                                       if (cur_line_max_h < mnh) cur_line_max_h = mnh;
+                               }
+                               else
+                               {
+                                       if (minh < mnh) minh = mnh;
+                                       minw += mnw;
+                               }
+                       }
+                       else
+                       {
+                               if (minw < mnw) minw = mnw;
+                               minh += mnh;
+                       }
+               }
+
+               if(horizontal && extended)
+               {
+                       minh += cur_line_max_h;
+               }
+
+       }
+       evas_object_size_hint_min_set(box, minw, minh);
+}
+
+
+static Evas_Coord
+_smart_extents_calculate_max_height(Evas_Object *box, Evas_Object_Box_Data *priv, int obj_index)
+{
+       Evas_Coord mnw, mnh, box_w, cal_w = 0, cur_line_max_h = 0;
+       const Eina_List *l;
+       Evas_Object_Box_Option *opt;
+       int index = 0;
+
+       evas_object_geometry_get(box, NULL, NULL, &box_w, NULL);
+
        EINA_LIST_FOREACH(priv->children, l, opt)
-         {
-            evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
-            if (horizontal)
-              {
-                 if (minh < mnh) minh = mnh;
-                 minw += mnw;
-              }
-            else
-              {
-                 if (minw < mnw) minw = mnw;
-                 minh += mnh;
-              }
-         }
-     }
-   evas_object_size_hint_min_set(box, minw, minh);
+       {
+               evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
+
+               if ((cal_w + mnw) > box_w)
+               {
+                       if (index > obj_index )
+                       {
+                               return cur_line_max_h;
+                       }
+                       cal_w = 0;
+                       cur_line_max_h = 0;
+               }
+
+               cal_w += mnw;
+               if (cur_line_max_h < mnh) cur_line_max_h = mnh;
+
+               index++;
+       }
+       
+       return cur_line_max_h;
 }
 
+
 void
 _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous)
 {
+       _els_box_layout_ex(o, priv, horizontal, homogeneous, 0);
+}
+
+void
+_els_box_layout_ex(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous, int extended)
+{
    Evas_Coord x, y, w, h, xx, yy;
    const Eina_List *l;
    Evas_Object *obj;
@@ -57,7 +126,7 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int
    double ax, ay;
    Evas_Object_Box_Option *opt;
 
-   _smart_extents_calculate(o, priv, horizontal, homogeneous);
+   _smart_extents_calculate(o, priv, horizontal, homogeneous, extended);
 
    evas_object_geometry_get(o, &x, &y, &w, &h);
 
@@ -106,6 +175,9 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int
    hdif = h - minh;
    xx = x;
    yy = y;
+
+   Evas_Coord cal_w = 0, cal_h = 0, cur_line_max_h = 0, obj_index = 0;
+
    EINA_LIST_FOREACH(priv->children, l, opt)
      {
         Evas_Coord mnw, mnh, mxw, mxh;
@@ -147,28 +219,60 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int
               }
             else
               {
-                 Evas_Coord ww, hh, ow, oh;
+                          if (extended)
+                          {
+                                  Evas_Coord ww, hh, ow, oh;
+                                  ww = mnw;
+                                  hh = _smart_extents_calculate_max_height(o, priv, obj_index);
 
-                 ww = mnw;
-                 if ((expand > 0) && (xw))
-                   {
-                      if (expand == 1) ow = wdif;
-                      else ow = (w - minw) / expand;
-                      wdif -= ow;
-                      ww += ow;
-                   }
-                 hh = h;
-                 ow = mnw;
-                 if (fw) ow = ww;
-                 if ((mxw >= 0) && (mxw < ow)) ow = mxw;
-                 oh = mnh;
-                 if (fh) oh = hh;
-                 if ((mxh >= 0) && (mxh < oh)) oh = mxh;
-                 evas_object_move(obj,
-                                  xx + (Evas_Coord)(((double)(ww - ow)) * ax),
-                                  yy + (Evas_Coord)(((double)(hh - oh)) * ay));
-                 evas_object_resize(obj, ow, oh);
-                 xx += ww;
+                                  ow = mnw;
+                                  if (fw) ow = ww;
+                                  if ((mxw >= 0) && (mxw < ow)) ow = mxw;
+                                  oh = mnh;
+                                  if (fh) oh = hh;
+                                  if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+
+                                  if ((cal_w + ww) > w)
+                                  {
+                                          cal_h += cur_line_max_h;
+
+                                          cal_w = 0;
+                                          cur_line_max_h = 0;
+                                  }
+
+                                  evas_object_move(obj,
+                                                  xx + cal_w + (Evas_Coord)(((double)(ww - ow)) * ax),
+                                                  yy + cal_h + (Evas_Coord)(((double)(hh - oh)) * ay));
+                                  evas_object_resize(obj, ow, oh);
+
+                                  cal_w += ww;
+                                  if (cur_line_max_h < hh) cur_line_max_h = hh;
+                          }
+                          else
+                          {
+                                 Evas_Coord ww, hh, ow, oh;
+
+                                 ww = mnw;
+                                 if ((expand > 0) && (xw))
+                                       {
+                                          if (expand == 1) ow = wdif;
+                                          else ow = (w - minw) / expand;
+                                          wdif -= ow;
+                                          ww += ow;
+                                       }
+                                 hh = h;
+                                 ow = mnw;
+                                 if (fw) ow = ww;
+                                 if ((mxw >= 0) && (mxw < ow)) ow = mxw;
+                                 oh = mnh;
+                                 if (fh) oh = hh;
+                                 if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+                                 evas_object_move(obj,
+                                                  xx + (Evas_Coord)(((double)(ww - ow)) * ax),
+                                                  yy + (Evas_Coord)(((double)(hh - oh)) * ay));
+                                 evas_object_resize(obj, ow, oh);
+                                 xx += ww;
+                          }
               }
          }
        else
@@ -217,6 +321,8 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int
                  yy += hh;
               }
          }
+
+               obj_index++;
      }
 }
 
index e394884..9cf025b 100644 (file)
@@ -1 +1,2 @@
 void _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous);
+void _els_box_layout_ex(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous, int extended);