Initialize Tizen 2.3
[framework/uifw/elementary.git] / src / lib / els_box.c
1 #include <Elementary.h>
2 #include "elm_priv.h"
3 #include "els_box.h"
4
5 static void
6 _smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horizontal, int homogeneous)
7 {
8    Evas_Coord minw, minh, mnw, mnh, maxw, maxh;
9    const Eina_List *l;
10    Evas_Object_Box_Option *opt;
11    Eina_Bool max = EINA_TRUE;
12    int c;
13
14    minw = 0;
15    minh = 0;
16    maxw = -1;
17    maxh = -1;
18    if (homogeneous)
19      {
20         EINA_LIST_FOREACH(priv->children, l, opt)
21           {
22              evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
23              if (minh < mnh) minh = mnh;
24              if (minw < mnw) minw = mnw;
25
26              evas_object_size_hint_max_get(opt->obj, &mnw, &mnh);
27              if (mnh >= 0)
28                {
29                   if (maxh == -1) maxh = mnh;
30                   else if (maxh > mnh) maxh = mnh;
31                }
32              if (mnw >= 0)
33                {
34                   if (maxw == -1) maxw = mnw;
35                   else if (maxw > mnw) maxw = mnw;
36                }
37           }
38         if (horizontal)
39           {
40              minw *= eina_list_count(priv->children);
41              if (maxw != -1)
42                 maxw *= eina_list_count(priv->children);
43              else maxw = -1;
44           }
45         else
46           {
47              minh *= eina_list_count(priv->children);
48              if (maxh != -1)
49                 maxh *= eina_list_count(priv->children);
50              else maxh = -1;
51           }
52      }
53    else
54      {
55         EINA_LIST_FOREACH(priv->children, l, opt)
56           {
57              evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
58              if (horizontal)
59                {
60                   if (minh < mnh) minh = mnh;
61                   minw += mnw;
62                }
63              else
64                {
65                   if (minw < mnw) minw = mnw;
66                   minh += mnh;
67                }
68              evas_object_size_hint_max_get(opt->obj, &mnw, &mnh);
69              if (horizontal)
70                {
71                   if (mnw < 0)
72                     {
73                        maxw = -1;
74                        max = EINA_FALSE;
75                     }
76                   if (max) maxw += mnw;
77
78                   if (mnh >= 0)
79                     {
80                        if (maxh == -1) maxh = mnh;
81                        else if (maxh > mnh) maxh = mnh;
82                     }
83                }
84              else
85                {
86                   if (mnh < 0)
87                     {
88                        maxh = -1;
89                        max = EINA_FALSE;
90                     }
91                   if (max) maxh += mnh;
92
93                   if (mnw >= 0)
94                     {
95                        if (maxw == -1) maxw = mnw;
96                        else if (maxw > mnw) maxw = mnw;
97                     }
98                }
99           }
100      }
101    c = eina_list_count(priv->children) - 1;
102    if (c > 0)
103      {
104         if (horizontal)
105           {
106              minw += priv->pad.h * c;
107              if (maxw != -1) maxw += priv->pad.h * c;
108           }
109         else
110           {
111              minh += priv->pad.v * c;
112              if (maxh != -1) maxh += priv->pad.v * c;
113           }
114      }
115    evas_object_size_hint_min_set(box, minw, minh);
116    evas_object_size_hint_max_set(box, maxw, maxh);
117 }
118
119 void
120 _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous, int rtl)
121 {
122    Evas_Coord x, y, w, h, xx, yy;
123    const Eina_List *l;
124    Evas_Object *obj;
125    Evas_Coord minw, minh;
126    int count = 0;
127    double expand = 0.0;
128    double ax, ay;
129    Evas_Object_Box_Option *opt;
130
131    _smart_extents_calculate(o, priv, horizontal, homogeneous);
132
133    evas_object_geometry_get(o, &x, &y, &w, &h);
134
135    evas_object_size_hint_min_get(o, &minw, &minh);
136    evas_object_size_hint_align_get(o, &ax, &ay);
137    if ((w < minw) || (h < minh)) return;
138    count = eina_list_count(priv->children);
139    if (rtl) ax = 1.0 - ax;
140
141    if (w < minw)
142      {
143         x = x + ((w - minw) * (1.0 - ax));
144         w = minw;
145      }
146    if (h < minh)
147      {
148         y = y + ((h - minh) * (1.0 - ay));
149         h = minh;
150      }
151    EINA_LIST_FOREACH(priv->children, l, opt)
152      {
153         double wx, wy;
154
155         evas_object_size_hint_weight_get(opt->obj, &wx, &wy);
156         if (horizontal)
157           {
158              if (wx > 0.0) expand += wx;
159           }
160         else
161           {
162              if (wy > 0.0) expand += wy;
163           }
164      }
165    if (!expand)
166      {
167         evas_object_size_hint_align_get(o, &ax, &ay);
168         if (rtl) ax = 1.0 - ax;
169         if (horizontal)
170           {
171              x += (double)(w - minw) * ax;
172              w = minw;
173           }
174         else
175           {
176              y += (double)(h - minh) * ay;
177              h = minh;
178           }
179      }
180    xx = x;
181    yy = y;
182    EINA_LIST_FOREACH(priv->children, l, opt)
183      {
184         Evas_Coord mnw, mnh, mxw, mxh;
185         double wx, wy;
186         int fw, fh, xw, xh;
187
188         obj = opt->obj;
189         evas_object_size_hint_align_get(obj, &ax, &ay);
190         evas_object_size_hint_weight_get(obj, &wx, &wy);
191         evas_object_size_hint_min_get(obj, &mnw, &mnh);
192         evas_object_size_hint_max_get(obj, &mxw, &mxh);
193         fw = fh = 0;
194         xw = xh = 0;
195         if (ax == -1.0) {fw = 1; ax = 0.5;}
196         if (ay == -1.0) {fh = 1; ay = 0.5;}
197         if (rtl) ax = 1.0 - ax;
198         if (wx > 0.0) xw = 1;
199         if (wy > 0.0) xh = 1;
200         if (horizontal)
201           {
202              Evas_Coord ww, hh, ow, oh;
203
204              if (homogeneous)
205                {
206                   ww = (w / (Evas_Coord)count);
207                }
208              else
209                {
210                   ww = mnw;
211                   if ((expand > 0) && (xw))
212                     {
213                        ow = ((w - minw) * wx) / expand;
214                        ww += ow;
215                     }
216                }
217              hh = h;
218              ow = mnw;
219              if (fw) ow = ww;
220              if ((mxw >= 0) && (mxw < ow)) ow = mxw;
221              oh = mnh;
222              if (fh) oh = hh;
223              if ((mxh >= 0) && (mxh < oh)) oh = mxh;
224              evas_object_move(obj,
225                               ((!rtl) ? (xx) : (x + (w - (xx - x) - ww)))
226                               + (Evas_Coord)(((double)(ww - ow)) * ax),
227                               yy + (Evas_Coord)(((double)(hh - oh)) * ay));
228              evas_object_resize(obj, ow, oh);
229              xx += ww;
230              xx += priv->pad.h;
231           }
232         else
233           {
234              Evas_Coord ww, hh, ow, oh;
235
236              if (homogeneous)
237                {
238                   hh = (h / (Evas_Coord)count);
239                }
240              else
241                {
242                   hh = mnh;
243                   if ((expand > 0) && (xh))
244                     {
245                        oh = ((h - minh) * wy) / expand;
246                        hh += oh;
247                     }
248                }
249              ww = w;
250              ow = mnw;
251              if (fw) ow = ww;
252              if ((mxw >= 0) && (mxw < ow)) ow = mxw;
253              oh = mnh;
254              if (fh) oh = hh;
255              if ((mxh >= 0) && (mxh < oh)) oh = mxh;
256              evas_object_move(obj,
257                               xx + (Evas_Coord)(((double)(ww - ow)) * ax),
258                               yy + (Evas_Coord)(((double)(hh - oh)) * ay));
259              evas_object_resize(obj, ow, oh);
260              yy += hh;
261              yy += priv->pad.v;
262           }
263      }
264 }
265