Merge "[Password]: New design based changes, a new style removed password mode contro...
[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, int extended)
6 {
7    Evas_Coord minw, minh, maxw, maxh, mnw, mnh, ww;
8    Evas_Coord w, cw = 0, cmaxh = 0;
9    const Eina_List *l;
10    Evas_Object_Box_Option *opt;
11    double wx;
12
13    /* FIXME: need to calc max */
14    minw = 0;
15    minh = 0;
16    maxw = -1;
17    maxh = -1;
18
19    if (homogeneous)
20      {
21         EINA_LIST_FOREACH(priv->children, l, opt)
22           {
23              evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
24              if (minh < mnh) minh = mnh;
25              if (minw < mnw) minw = mnw;
26           }
27         if (horizontal)
28           minw *= eina_list_count(priv->children);
29         else
30           minh *= eina_list_count(priv->children);
31      }
32    else
33      {
34         if (horizontal && extended)
35           {
36              evas_object_geometry_get(box, NULL, NULL, &w, NULL);
37              evas_object_size_hint_min_get(box, &minw, NULL);
38           }
39
40         EINA_LIST_FOREACH(priv->children, l, opt)
41           {
42              evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
43              if (horizontal)
44                {
45                   if (extended)
46                     {
47                        evas_object_size_hint_weight_get(opt->obj, &wx, NULL);
48
49                        if(wx)
50                          {
51                             if (mnw != -1 && (w - cw) >= mnw)
52                                ww = w - cw;
53                             else
54                                ww = w;
55                          }
56                        else
57                           ww = mnw;
58
59                        if ((cw + mnw) > w)
60                          {
61                             minh += cmaxh;
62
63                             cw = 0;
64                             cmaxh = 0;
65                          }
66                        cw += ww;
67                        if (cmaxh < mnh) cmaxh = mnh;
68                     }
69                   else
70                     {
71                        if (minh < mnh) minh = mnh;
72                        minw += mnw;
73                     }
74                }
75              else
76                {
77                   if (minw < mnw) minw = mnw;
78                   minh += mnh;
79                }
80           }
81
82         if(horizontal && extended)
83           {
84              minh += cmaxh;
85           }
86
87      }
88    evas_object_size_hint_min_set(box, minw, minh);
89 }
90
91 static Evas_Coord
92 _smart_extents_calculate_max_height(Evas_Object *box, Evas_Object_Box_Data *priv, int obj_index)
93 {
94    Evas_Coord mnw, mnh, cw = 0, cmaxh = 0, w, ww;
95    const Eina_List *l;
96    Evas_Object_Box_Option *opt;
97    int index = 0;
98    double wx;
99
100    evas_object_geometry_get(box, NULL, NULL, &w, NULL);
101
102    EINA_LIST_FOREACH(priv->children, l, opt)
103      {
104         evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
105         evas_object_size_hint_weight_get(opt->obj, &wx, NULL);
106
107         if(wx)
108           {
109              if (mnw != -1 && (w - cw) >= mnw)
110                 ww = w - cw;
111              else
112                 ww = w;
113           }
114         else
115            ww = mnw;
116
117         if ((cw + ww) > w)
118           {
119              if (index > obj_index )
120                {
121                   return cmaxh;
122                }
123              cw = 0;
124              cmaxh = 0;
125           }
126
127         cw += ww;
128         if (cmaxh < mnh) cmaxh = mnh;
129
130         index++;
131      }
132
133    return cmaxh;
134 }
135
136 void
137 _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous, int rtl)
138 {
139    _els_box_layout_ex(o, priv, horizontal, homogeneous, 0, rtl);
140 }
141
142 void
143 _els_box_layout_ex(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int homogeneous, int extended, int rtl)
144 {
145    Evas_Coord x, y, w, h, xx, yy;
146    const Eina_List *l;
147    Evas_Object *obj;
148    Evas_Coord minw, minh, wdif, hdif;
149    int count = 0, expand = 0;
150    double ax, ay;
151    Evas_Object_Box_Option *opt;
152
153    _smart_extents_calculate(o, priv, horizontal, homogeneous, extended);
154
155    evas_object_geometry_get(o, &x, &y, &w, &h);
156
157    evas_object_size_hint_min_get(o, &minw, &minh);
158    evas_object_size_hint_align_get(o, &ax, &ay);
159    count = eina_list_count(priv->children);
160    if (w < minw)
161      {
162         x = x + ((w - minw) * (1.0 - ax));
163         w = minw;
164      }
165    if (h < minh)
166      {
167         y = y + ((h - minh) * (1.0 - ay));
168         h = minh;
169      }
170    EINA_LIST_FOREACH(priv->children, l, opt)
171      {
172         double wx, wy;
173
174         evas_object_size_hint_weight_get(opt->obj, &wx, &wy);
175         if (horizontal)
176           {
177              if (wx > 0.0) expand++;
178           }
179         else
180           {
181              if (wy > 0.0) expand++;
182           }
183      }
184    if ((!expand) && (!extended))
185      {
186         evas_object_size_hint_align_get(o, &ax, &ay);
187         if (horizontal)
188           {
189              x += (double)(w - minw) * ax;
190              w = minw;
191           }
192         else
193           {
194              y += (double)(h - minh) * ay;
195              h = minh;
196           }
197      }
198    wdif = w - minw;
199    hdif = h - minh;
200    xx = x;
201    yy = y;
202
203    Evas_Coord cw = 0, ch = 0, cmaxh = 0, obj_index = 0;
204
205    EINA_LIST_FOREACH(priv->children, l, opt)
206      {
207         Evas_Coord mnw, mnh, mxw, mxh;
208         double wx, wy;
209         int fw, fh, xw, xh;
210
211         obj = opt->obj;
212         evas_object_size_hint_align_get(obj, &ax, &ay);
213         evas_object_size_hint_weight_get(obj, &wx, &wy);
214         evas_object_size_hint_min_get(obj, &mnw, &mnh);
215         evas_object_size_hint_max_get(obj, &mxw, &mxh);
216         fw = fh = 0;
217         xw = xh = 0;
218         if (ax == -1.0) {fw = 1; ax = 0.5;}
219         if (ay == -1.0) {fh = 1; ay = 0.5;}
220         if (wx > 0.0) xw = 1;
221         if (wy > 0.0) xh = 1;
222         if (horizontal)
223           {
224              Evas_Coord ww, hh, ow, oh;
225
226              if (extended)
227                {
228                  if(wx)
229                    {
230                       if (mnw != -1 && (w - cw) >= mnw)
231                          ww = w - cw;
232                       else
233                          ww = w;
234                    }
235                  else
236                     ww = mnw;
237                  hh = _smart_extents_calculate_max_height(o, priv, obj_index);
238
239                  ow = mnw;
240                  if (fw) ow = ww;
241                  if ((mxw >= 0) && (mxw < ow)) ow = mxw;
242                  oh = mnh;
243                  if (fh) oh = hh;
244                  if ((mxh >= 0) && (mxh < oh)) oh = mxh;
245
246                  if ((cw + ww) > w)
247                    {
248                       ch += cmaxh;
249
250                       cw = 0;
251                       cmaxh = 0;
252                    }
253
254                  evas_object_move(obj,
255                                   xx + cw + (Evas_Coord)(((double)(ww - ow)) * ax),
256                                   yy + ch + (Evas_Coord)(((double)(hh - oh)) * ay));
257                  evas_object_resize(obj, ow, oh);
258
259                  cw += ww;
260                  if (cmaxh < hh) cmaxh = hh;
261                }
262              else
263                {
264                 if (homogeneous)
265                   {
266                      ww = (w / (Evas_Coord)count);
267                   }
268                 else
269                   {
270                      ww = mnw;
271                      if ((expand > 0) && (xw))
272                        {
273                           if (expand == 1) ow = wdif;
274                           else ow = (w - minw) / expand;
275                           wdif -= ow;
276                           ww += ow;
277                        }
278                   }
279                 hh = h;
280                 ow = mnw;
281                 if (fw) ow = ww;
282                 if ((mxw >= 0) && (mxw < ow)) ow = mxw;
283                 oh = mnh;
284                 if (fh) oh = hh;
285                 if ((mxh >= 0) && (mxh < oh)) oh = mxh;
286                 evas_object_move(obj,
287                                  ((!rtl) ? (xx) : (x + (w - (xx - x) - ww)))
288                                  + (Evas_Coord)(((double)(ww - ow)) * ax),
289                                  yy + (Evas_Coord)(((double)(hh - oh)) * ay));
290                 evas_object_resize(obj, ow, oh);
291                 xx += ww;
292                }
293           }
294         else
295           {
296              Evas_Coord ww, hh, ow, oh;
297
298              if (homogeneous)
299                {
300                   hh = (h / (Evas_Coord)count);
301                }
302              else
303                {
304                   hh = mnh;
305                   if ((expand > 0) && (xh))
306                     {
307                        if (expand == 1) oh = hdif;
308                        else oh = (h - minh) / expand;
309                        hdif -= oh;
310                        hh += oh;
311                     }
312                }
313              ww = w;
314              ow = mnw;
315              if (fw) ow = ww;
316              if ((mxw >= 0) && (mxw < ow)) ow = mxw;
317              oh = mnh;
318              if (fh) oh = hh;
319              if ((mxh >= 0) && (mxh < oh)) oh = mxh;
320              evas_object_move(obj,
321                               xx + (Evas_Coord)(((double)(ww - ow)) * ax),
322                               yy + (Evas_Coord)(((double)(hh - oh)) * ay));
323              evas_object_resize(obj, ow, oh);
324              yy += hh;
325           }
326
327         obj_index++;
328      }
329 }
330