Merge branch 'master' into svn_merge
[framework/uifw/elementary.git] / src / lib / els_box.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3
4 static void
5 _smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horizontal, int homogeneous)
6 {
7    Evas_Coord minw, minh, mnw, mnh;
8    const Eina_List *l;
9    Evas_Object_Box_Option *opt;
10    int c;
11
12    /* FIXME: need to calc max */
13    minw = 0;
14    minh = 0;
15    if (homogeneous)
16      {
17         EINA_LIST_FOREACH(priv->children, l, opt)
18           {
19              evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
20              if (minh < mnh) minh = mnh;
21              if (minw < mnw) minw = mnw;
22           }
23         if (horizontal)
24           minw *= eina_list_count(priv->children);
25         else
26           minh *= eina_list_count(priv->children);
27      }
28    else
29      {
30         EINA_LIST_FOREACH(priv->children, l, opt)
31           {
32              evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
33              if (horizontal)
34                {
35                   if (minh < mnh) minh = mnh;
36                   minw += mnw;
37                }
38              else
39                {
40                   if (minw < mnw) minw = mnw;
41                   minh += mnh;
42                }
43           }
44      }
45    c = eina_list_count(priv->children) - 1;
46    if (c > 0)
47      {
48         if (horizontal) minw += priv->pad.h * c;
49         else            minh += priv->pad.v * c;
50      }
51    evas_object_size_hint_min_set(box, minw, minh);
52 }
53
54 void
55 _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous, int rtl)
56 {
57    Evas_Coord x, y, w, h, xx, yy;
58    const Eina_List *l;
59    Evas_Object *obj;
60    Evas_Coord minw, minh, wdif, hdif;
61    int count = 0, expand = 0;
62    double ax, ay;
63    Evas_Object_Box_Option *opt;
64
65    _smart_extents_calculate(o, priv, horizontal, homogeneous);
66
67    evas_object_geometry_get(o, &x, &y, &w, &h);
68
69    evas_object_size_hint_min_get(o, &minw, &minh);
70    evas_object_size_hint_align_get(o, &ax, &ay);
71    count = eina_list_count(priv->children);
72
73    if (w < minw)
74      {
75         x = x + ((w - minw) * (1.0 - ax));
76         w = minw;
77      }
78    if (h < minh)
79      {
80         y = y + ((h - minh) * (1.0 - ay));
81         h = minh;
82      }
83    EINA_LIST_FOREACH(priv->children, l, opt)
84      {
85         double wx, wy;
86
87         evas_object_size_hint_weight_get(opt->obj, &wx, &wy);
88         if (horizontal)
89           {
90              if (wx > 0.0) expand++;
91           }
92         else
93           {
94              if (wy > 0.0) expand++;
95           }
96      }
97    if (!expand)
98      {
99         evas_object_size_hint_align_get(o, &ax, &ay);
100         if (horizontal)
101           {
102              x += (double)(w - minw) * ax;
103              w = minw;
104           }
105         else
106           {
107              y += (double)(h - minh) * ay;
108              h = minh;
109           }
110      }
111    wdif = w - minw;
112    hdif = h - minh;
113    xx = x;
114    yy = y;
115    EINA_LIST_FOREACH(priv->children, l, opt)
116      {
117         Evas_Coord mnw, mnh, mxw, mxh;
118         double wx, wy;
119         int fw, fh, xw, xh;
120
121         obj = opt->obj;
122         evas_object_size_hint_align_get(obj, &ax, &ay);
123         evas_object_size_hint_weight_get(obj, &wx, &wy);
124         evas_object_size_hint_min_get(obj, &mnw, &mnh);
125         evas_object_size_hint_max_get(obj, &mxw, &mxh);
126         fw = fh = 0;
127         xw = xh = 0;
128         if (ax == -1.0) {fw = 1; ax = 0.5;}
129         if (ay == -1.0) {fh = 1; ay = 0.5;}
130         if (wx > 0.0) xw = 1;
131         if (wy > 0.0) xh = 1;
132         if (horizontal)
133           {
134              Evas_Coord ww, hh, ow, oh;
135
136              if (homogeneous)
137                {
138                   ww = (w / (Evas_Coord)count);
139                }
140              else
141                {
142                   ww = mnw;
143                   if ((expand > 0) && (xw))
144                     {
145                        if (expand == 1) ow = wdif;
146                        else ow = (w - minw) / expand;
147                        wdif -= ow;
148                        ww += ow;
149                     }
150                }
151              hh = h;
152              ow = mnw;
153              if (fw) ow = ww;
154              if ((mxw >= 0) && (mxw < ow)) ow = mxw;
155              oh = mnh;
156              if (fh) oh = hh;
157              if ((mxh >= 0) && (mxh < oh)) oh = mxh;
158              evas_object_move(obj,
159                               ((!rtl) ? (xx) : (x + (w - (xx - x) - ww)))
160                               + (Evas_Coord)(((double)(ww - ow)) * ax),
161                               yy + (Evas_Coord)(((double)(hh - oh)) * ay));
162              evas_object_resize(obj, ow, oh);
163              xx += ww;
164              xx += priv->pad.h;
165           }
166         else
167           {
168              Evas_Coord ww, hh, ow, oh;
169
170              if (homogeneous)
171                {
172                   hh = (h / (Evas_Coord)count);
173                }
174              else
175                {
176                   hh = mnh;
177                   if ((expand > 0) && (xh))
178                     {
179                        if (expand == 1) oh = hdif;
180                        else oh = (h - minh) / expand;
181                        hdif -= oh;
182                        hh += oh;
183                     }
184                }
185              ww = w;
186              ow = mnw;
187              if (fw) ow = ww;
188              if ((mxw >= 0) && (mxw < ow)) ow = mxw;
189              oh = mnh;
190              if (fh) oh = hh;
191              if ((mxh >= 0) && (mxh < oh)) oh = mxh;
192              evas_object_move(obj,
193                               xx + (Evas_Coord)(((double)(ww - ow)) * ax),
194                               yy + (Evas_Coord)(((double)(hh - oh)) * ay));
195              evas_object_resize(obj, ow, oh);
196              yy += hh;
197              yy += priv->pad.v;
198           }
199      }
200 }
201