Add a task to copy configuration files to user's HOME dir from data dir for multi...
[platform/core/uifw/e17.git] / src / bin / e_table.c
1 #include "e.h"
2
3 typedef struct _E_Smart_Data E_Smart_Data;
4 typedef struct _E_Table_Item E_Table_Item;
5
6 struct _E_Smart_Data
7 {
8    Evas_Coord    x, y, w, h;
9    Evas_Object  *obj;
10    Evas_Object  *clip;
11    int           frozen;
12    unsigned char changed : 1;
13    unsigned char homogenous : 1;
14    Eina_List    *items;
15    struct
16    {
17       Evas_Coord w, h;
18    } min, max;
19    struct
20    {
21       double x, y;
22    } align;
23    struct
24    {
25       int cols, rows;
26    } size;
27 };
28
29 struct _E_Table_Item
30 {
31    E_Smart_Data *sd;
32    int           col, row, colspan, rowspan;
33    unsigned char fill_w : 1;
34    unsigned char fill_h : 1;
35    unsigned char expand_w : 1;
36    unsigned char expand_h : 1;
37    struct
38    {
39       Evas_Coord w, h;
40    } min, max;
41    struct
42    {
43       double x, y;
44    } align;
45    Evas_Object  *obj;
46 };
47
48 /* local subsystem functions */
49 static E_Table_Item *_e_table_smart_adopt(E_Smart_Data *sd, Evas_Object *obj);
50 static void          _e_table_smart_disown(Evas_Object *obj);
51 static void          _e_table_smart_item_del_hook(void *data, Evas *e, Evas_Object *obj, void *event_info);
52 static void          _e_table_smart_reconfigure(E_Smart_Data *sd);
53 static void          _e_table_smart_extents_calcuate(E_Smart_Data *sd);
54
55 static void          _e_table_smart_init(void);
56 static void          _e_table_smart_add(Evas_Object *obj);
57 static void          _e_table_smart_del(Evas_Object *obj);
58 static void          _e_table_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
59 static void          _e_table_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h);
60 static void          _e_table_smart_show(Evas_Object *obj);
61 static void          _e_table_smart_hide(Evas_Object *obj);
62 static void          _e_table_smart_color_set(Evas_Object *obj, int r, int g, int b, int a);
63 static void          _e_table_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
64 static void          _e_table_smart_clip_unset(Evas_Object *obj);
65
66 /* local subsystem globals */
67 static Evas_Smart *_e_smart = NULL;
68
69 /* externally accessible functions */
70 EAPI Evas_Object *
71 e_table_add(Evas *evas)
72 {
73    _e_table_smart_init();
74    return evas_object_smart_add(evas, _e_smart);
75 }
76
77 EAPI int
78 e_table_freeze(Evas_Object *obj)
79 {
80    E_Smart_Data *sd;
81
82    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
83    sd = evas_object_smart_data_get(obj);
84    sd->frozen++;
85    return sd->frozen;
86 }
87
88 EAPI int
89 e_table_thaw(Evas_Object *obj)
90 {
91    E_Smart_Data *sd;
92
93    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERR(0);
94    sd = evas_object_smart_data_get(obj);
95    sd->frozen--;
96    if (sd->frozen <= 0) _e_table_smart_reconfigure(sd);
97    return sd->frozen;
98 }
99
100 EAPI void
101 e_table_homogenous_set(Evas_Object *obj, int homogenous)
102 {
103    E_Smart_Data *sd;
104
105    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
106    sd = evas_object_smart_data_get(obj);
107    if (sd->homogenous == homogenous) return;
108    sd->homogenous = homogenous;
109    sd->changed = 1;
110    if (sd->frozen <= 0) _e_table_smart_reconfigure(sd);
111 }
112
113 EAPI void
114 e_table_pack(Evas_Object *obj, Evas_Object *child, int col, int row, int colspan, int rowspan)
115 {
116    E_Smart_Data *sd;
117    E_Table_Item *ti;
118
119    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
120    sd = evas_object_smart_data_get(obj);
121    _e_table_smart_adopt(sd, child);
122    sd->items = eina_list_append(sd->items, child);
123    ti = evas_object_data_get(child, "e_table_data");
124    if (ti)
125      {
126         ti->col = col;
127         ti->row = row;
128         ti->colspan = colspan;
129         ti->rowspan = rowspan;
130         if (sd->size.cols < (col + colspan)) sd->size.cols = col + colspan;
131         if (sd->size.rows < (row + rowspan)) sd->size.rows = row + rowspan;
132      }
133    sd->changed = 1;
134    if (sd->frozen <= 0) _e_table_smart_reconfigure(sd);
135 }
136
137 EAPI void
138 e_table_pack_options_set(Evas_Object *obj, int fill_w, int fill_h, int expand_w, int expand_h, double align_x, double align_y, Evas_Coord min_w, Evas_Coord min_h, Evas_Coord max_w, Evas_Coord max_h)
139 {
140    E_Table_Item *ti;
141
142    ti = evas_object_data_get(obj, "e_table_data");
143    if (!ti) return;
144    ti->fill_w = fill_w;
145    ti->fill_h = fill_h;
146    ti->expand_w = expand_w;
147    ti->expand_h = expand_h;
148    ti->align.x = align_x;
149    ti->align.y = align_y;
150    ti->min.w = min_w;
151    ti->min.h = min_h;
152    ti->max.w = max_w;
153    ti->max.h = max_h;
154    ti->sd->changed = 1;
155    if (ti->sd->frozen <= 0) _e_table_smart_reconfigure(ti->sd);
156 }
157
158 EAPI void
159 e_table_unpack(Evas_Object *obj)
160 {
161    E_Table_Item *ti;
162    E_Smart_Data *sd;
163
164    ti = evas_object_data_get(obj, "e_table_data");
165    if (!ti) return;
166    sd = ti->sd;
167    sd->items = eina_list_remove(sd->items, obj);
168    _e_table_smart_disown(obj);
169    sd->changed = 1;
170    if (sd->frozen <= 0) _e_table_smart_reconfigure(sd);
171 }
172
173 EAPI void
174 e_table_col_row_size_get(Evas_Object *obj, int *cols, int *rows)
175 {
176    E_Smart_Data *sd;
177
178    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
179    sd = evas_object_smart_data_get(obj);
180    if (sd->changed) _e_table_smart_extents_calcuate(sd);
181    if (cols) *cols = sd->size.cols;
182    if (rows) *rows = sd->size.rows;
183 }
184
185 EAPI void
186 e_table_size_min_get(Evas_Object *obj, Evas_Coord *minw, Evas_Coord *minh)
187 {
188    E_Smart_Data *sd;
189
190    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
191    sd = evas_object_smart_data_get(obj);
192    if (sd->changed) _e_table_smart_extents_calcuate(sd);
193    if (minw) *minw = sd->min.w;
194    if (minh) *minh = sd->min.h;
195 }
196
197 EAPI void
198 e_table_size_max_get(Evas_Object *obj, Evas_Coord *maxw, Evas_Coord *maxh)
199 {
200    E_Smart_Data *sd;
201
202    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
203    sd = evas_object_smart_data_get(obj);
204    if (sd->changed) _e_table_smart_extents_calcuate(sd);
205    if (maxw) *maxw = sd->max.w;
206    if (maxh) *maxh = sd->max.h;
207 }
208
209 EAPI void
210 e_table_align_get(Evas_Object *obj, double *ax, double *ay)
211 {
212    E_Smart_Data *sd;
213
214    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
215    sd = evas_object_smart_data_get(obj);
216    if (ax) *ax = sd->align.x;
217    if (ay) *ay = sd->align.y;
218 }
219
220 EAPI void
221 e_table_align_set(Evas_Object *obj, double ax, double ay)
222 {
223    E_Smart_Data *sd;
224
225    if (evas_object_smart_smart_get(obj) != _e_smart) SMARTERRNR();
226    sd = evas_object_smart_data_get(obj);
227    if ((sd->align.x == ax) && (sd->align.y == ay)) return;
228    sd->align.x = ax;
229    sd->align.y = ay;
230    sd->changed = 1;
231    if (sd->frozen <= 0) _e_table_smart_reconfigure(sd);
232 }
233
234 /* local subsystem functions */
235 static E_Table_Item *
236 _e_table_smart_adopt(E_Smart_Data *sd, Evas_Object *obj)
237 {
238    E_Table_Item *ti;
239
240    ti = calloc(1, sizeof(E_Table_Item));
241    if (!ti) return NULL;
242    ti->sd = sd;
243    ti->obj = obj;
244    /* defaults */
245    ti->col = 0;
246    ti->row = 0;
247    ti->colspan = 1;
248    ti->rowspan = 1;
249    ti->fill_w = 0;
250    ti->fill_h = 0;
251    ti->expand_w = 0;
252    ti->expand_h = 0;
253    ti->align.x = 0.5;
254    ti->align.y = 0.5;
255    ti->min.w = 0;
256    ti->min.h = 0;
257    ti->max.w = 0;
258    ti->max.h = 0;
259    evas_object_clip_set(obj, sd->clip);
260 //   evas_object_stack_above(obj, sd->obj);
261    evas_object_smart_member_add(obj, ti->sd->obj);
262    evas_object_data_set(obj, "e_table_data", ti);
263    evas_object_event_callback_add(obj, EVAS_CALLBACK_FREE,
264                                   _e_table_smart_item_del_hook, NULL);
265 //   evas_object_stack_below(obj, sd->obj);
266    if ((!evas_object_visible_get(sd->clip)) &&
267        (evas_object_visible_get(sd->obj)))
268      evas_object_show(sd->clip);
269    return ti;
270 }
271
272 static void
273 _e_table_smart_disown(Evas_Object *obj)
274 {
275    E_Table_Item *ti;
276
277    ti = evas_object_data_get(obj, "e_table_data");
278    if (!ti) return;
279    if (!ti->sd->items)
280      {
281         if (evas_object_visible_get(ti->sd->clip))
282           evas_object_hide(ti->sd->clip);
283      }
284    evas_object_event_callback_del(obj,
285                                   EVAS_CALLBACK_FREE,
286                                   _e_table_smart_item_del_hook);
287    evas_object_smart_member_del(obj);
288    evas_object_data_del(obj, "e_table_data");
289    free(ti);
290 }
291
292 static void
293 _e_table_smart_item_del_hook(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
294 {
295    e_table_unpack(obj);
296 }
297
298 static void
299 _e_table_smart_reconfigure(E_Smart_Data *sd)
300 {
301    Evas_Coord x, y, w, h, xx, yy;
302    Eina_List *l;
303    Evas_Object *obj;
304    int minw, minh, expandw, expandh;
305
306    if (!sd->changed) return;
307
308    w = sd->w;
309    h = sd->h;
310
311    _e_table_smart_extents_calcuate(sd);
312
313    minw = sd->min.w;
314    minh = sd->min.h;
315    expandw = 0;
316    expandh = 0;
317    if (w < minw) w = minw;
318    if (h < minh) h = minh;
319    EINA_LIST_FOREACH(sd->items, l, obj)
320      {
321         E_Table_Item *ti;
322
323         ti = evas_object_data_get(obj, "e_table_data");
324         if (ti->expand_w) expandw++;
325         if (ti->expand_h) expandh++;
326      }
327    if (expandw == 0)
328      {
329         w = minw;
330      }
331    if (expandh == 0)
332      {
333         h = minh;
334      }
335    x = sd->x;
336    y = sd->y;
337    if (sd->homogenous)
338      {
339         EINA_LIST_FOREACH(sd->items, l, obj)
340           {
341              E_Table_Item *ti;
342              Evas_Coord ww, hh, ow, oh;
343
344              ti = evas_object_data_get(obj, "e_table_data");
345
346              xx = x + ((ti->col) * (w / (Evas_Coord)sd->size.cols));
347              yy = y + ((ti->row) * (h / (Evas_Coord)sd->size.rows));
348              ww = ((w / (Evas_Coord)sd->size.cols) * (ti->colspan));
349              hh = ((h / (Evas_Coord)sd->size.rows) * (ti->rowspan));
350              ow = ti->min.w;
351              if (ti->expand_w) ow = ww;
352              if ((ti->max.w >= 0) && (ti->max.w < ow)) ow = ti->max.w;
353              oh = ti->min.h;
354              if (ti->expand_h) oh = hh;
355              if ((ti->max.h >= 0) && (ti->max.h < oh)) oh = ti->max.h;
356              evas_object_move(obj,
357                               xx + (Evas_Coord)(((double)(ww - ow)) * ti->align.x),
358                               yy + (Evas_Coord)(((double)(hh - oh)) * ti->align.y));
359              evas_object_resize(obj, ow, oh);
360           }
361      }
362    else
363      {
364         int i, ex, tot, need, num, dif, left, nx;
365         EINA_LIST_FOREACH(sd->items, l, obj)
366           {
367              E_Table_Item *ti;
368
369              ti = evas_object_data_get(obj, "e_table_data");
370              if (sd->size.cols < (ti->col + ti->colspan))
371                sd->size.cols = ti->col + ti->colspan;
372              if (sd->size.rows < (ti->row + ti->rowspan))
373                sd->size.rows = ti->row + ti->rowspan;
374           }
375         if ((sd->size.cols > 0) && (sd->size.rows > 0))
376           {
377              int *cols, *rows, *colsx, *rowsx;
378
379              cols = calloc(sd->size.cols, sizeof(int));
380              rows = calloc(sd->size.rows, sizeof(int));
381              colsx = calloc(sd->size.cols, sizeof(int));
382              rowsx = calloc(sd->size.rows, sizeof(int));
383
384              EINA_LIST_FOREACH(sd->items, l, obj)
385                {
386                   E_Table_Item *ti;
387
388                   ti = evas_object_data_get(obj, "e_table_data");
389                   for (i = ti->col; i < (ti->col + ti->colspan); i++)
390                     colsx[i] |= ti->expand_w;
391                   for (i = ti->row; i < (ti->row + ti->rowspan); i++)
392                     rowsx[i] |= ti->expand_h;
393                }
394
395              EINA_LIST_FOREACH(sd->items, l, obj)
396                {
397                   E_Table_Item *ti;
398
399                   ti = evas_object_data_get(obj, "e_table_data");
400
401                   /* handle horizontal */
402                   ex = 0;
403                   tot = 0;
404                   num = ti->colspan;
405                   for (i = ti->col; i < (ti->col + num); i++)
406                     {
407                        if (colsx[i]) ex++;
408                        tot += cols[i];
409                     }
410                   need = ti->min.w;
411                   if (tot < need)
412                     {
413                        dif = need - tot;
414                        left = dif;
415                        if (ex == 0)
416                          {
417                             nx = num;
418                             for (i = ti->col; i < (ti->col + num); i++)
419                               {
420                                  if (nx > 1)
421                                    {
422                                       cols[i] += dif / num;
423                                       left -= dif / num;
424                                    }
425                                  else
426                                    {
427                                       cols[i] += left;
428                                       left = 0;
429                                    }
430                                  nx--;
431                               }
432                          }
433                        else
434                          {
435                             nx = ex;
436                             for (i = ti->col; i < (ti->col + num); i++)
437                               {
438                                  if (colsx[i])
439                                    {
440                                       if (nx > 1)
441                                         {
442                                            cols[i] += dif / ex;
443                                            left -= dif / ex;
444                                         }
445                                       else
446                                         {
447                                            cols[i] += left;
448                                            left = 0;
449                                         }
450                                       nx--;
451                                    }
452                               }
453                          }
454                     }
455
456                   /* handle vertical */
457                   ex = 0;
458                   tot = 0;
459                   num = ti->rowspan;
460                   for (i = ti->row; i < (ti->row + num); i++)
461                     {
462                        if (rowsx[i]) ex++;
463                        tot += rows[i];
464                     }
465                   need = ti->min.h;
466                   if (tot < need)
467                     {
468                        dif = need - tot;
469                        left = dif;
470                        if (ex == 0)
471                          {
472                             nx = num;
473                             for (i = ti->row; i < (ti->row + num); i++)
474                               {
475                                  if (nx > 1)
476                                    {
477                                       rows[i] += dif / num;
478                                       left -= dif / num;
479                                    }
480                                  else
481                                    {
482                                       rows[i] += left;
483                                       left = 0;
484                                    }
485                                  nx--;
486                               }
487                          }
488                        else
489                          {
490                             nx = ex;
491                             for (i = ti->row; i < (ti->row + num); i++)
492                               {
493                                  if (rowsx[i])
494                                    {
495                                       if (nx > 1)
496                                         {
497                                            rows[i] += dif / ex;
498                                            left -= dif / ex;
499                                         }
500                                       else
501                                         {
502                                            rows[i] += left;
503                                            left = 0;
504                                         }
505                                       nx--;
506                                    }
507                               }
508                          }
509                     }
510                }
511
512              ex = 0;
513              for (i = 0; i < sd->size.cols; i++) {
514                   if (colsx[i])
515                     ex++;
516                }
517              tot = 0;
518              for (i = 0; i < sd->size.cols; i++)
519                tot += cols[i];
520              dif = w - tot;
521              if ((ex > 0) && (dif > 0))
522                {
523                   int exl;
524
525                   left = dif;
526                   exl = ex;
527                   for (i = 0; i < sd->size.cols; i++)
528                     {
529                        if (colsx[i])
530                          {
531                             if (exl == 1)
532                               {
533                                  cols[i] += left;
534                                  exl--;
535                                  left = 0;
536                               }
537                             else
538                               {
539                                  cols[i] += dif / ex;
540                                  exl--;
541                                  left -= dif / ex;
542                               }
543                          }
544                     }
545                }
546
547              ex = 0;
548              for (i = 0; i < sd->size.rows; i++) {
549                   if (rowsx[i])
550                     ex++;
551                }
552              tot = 0;
553              for (i = 0; i < sd->size.rows; i++)
554                tot += rows[i];
555              dif = h - tot;
556              if ((ex > 0) && (dif > 0))
557                {
558                   int exl;
559
560                   left = dif;
561                   exl = ex;
562                   for (i = 0; i < sd->size.rows; i++)
563                     {
564                        if (rowsx[i])
565                          {
566                             if (exl == 1)
567                               {
568                                  rows[i] += left;
569                                  exl--;
570                                  left = 0;
571                               }
572                             else
573                               {
574                                  rows[i] += dif / ex;
575                                  exl--;
576                                  left -= dif / ex;
577                               }
578                          }
579                     }
580                }
581
582              EINA_LIST_FOREACH(sd->items, l, obj)
583                {
584                   E_Table_Item *ti;
585                   Evas_Coord ww, hh, ow, oh, idx;
586
587                   ti = evas_object_data_get(obj, "e_table_data");
588
589                   xx = x;
590                   for (idx = 0; idx < ti->col; idx++)
591                     xx += cols[idx];
592                   ww = 0;
593                   for (idx = ti->col; idx < (ti->col + ti->colspan); idx++)
594                     ww += cols[idx];
595                   yy = y;
596                   for (idx = 0; idx < ti->row; idx++)
597                     yy += rows[idx];
598                   hh = 0;
599                   for (idx = ti->row; idx < (ti->row + ti->rowspan); idx++)
600                     hh += rows[idx];
601
602                   ow = ti->min.w;
603                   if (ti->fill_w) ow = ww;
604                   if ((ti->max.w >= 0) && (ti->max.w < ow)) ow = ti->max.w;
605                   oh = ti->min.h;
606                   if (ti->fill_h) oh = hh;
607                   if ((ti->max.h >= 0) && (ti->max.h < oh)) oh = ti->max.h;
608                   evas_object_move(obj,
609                                    xx + (Evas_Coord)(((double)(ww - ow)) * ti->align.x),
610                                    yy + (Evas_Coord)(((double)(hh - oh)) * ti->align.y));
611                   evas_object_resize(obj, ow, oh);
612                }
613              free(rows);
614              free(cols);
615              free(rowsx);
616              free(colsx);
617           }
618      }
619    sd->changed = 0;
620 }
621
622 static void
623 _e_table_smart_extents_calcuate(E_Smart_Data *sd)
624 {
625    Eina_List *l;
626    Evas_Object *obj;
627    int minw, minh;
628
629    sd->max.w = -1; /* max < 0 == unlimited */
630    sd->max.h = -1;
631    sd->size.cols = 0;
632    sd->size.rows = 0;
633
634    minw = 0;
635    minh = 0;
636    if (sd->homogenous)
637      {
638         EINA_LIST_FOREACH(sd->items, l, obj)
639           {
640              E_Table_Item *ti;
641              int mw, mh;
642
643              ti = evas_object_data_get(obj, "e_table_data");
644              if (sd->size.cols < (ti->col + ti->colspan))
645                sd->size.cols = ti->col + ti->colspan;
646              if (sd->size.rows < (ti->row + ti->rowspan))
647                sd->size.rows = ti->row + ti->rowspan;
648              mw = (ti->min.w + (ti->colspan - 1)) / ti->colspan;
649              mh = (ti->min.h + (ti->rowspan - 1)) / ti->rowspan;
650              if (minw < mw) minw = mw;
651              if (minh < mh) minh = mh;
652           }
653         minw *= sd->size.cols;
654         minh *= sd->size.rows;
655      }
656    else
657      {
658         int i, ex, tot, need, num, dif, left, nx;
659         EINA_LIST_FOREACH(sd->items, l, obj)
660           {
661              E_Table_Item *ti;
662
663              ti = evas_object_data_get(obj, "e_table_data");
664              if (sd->size.cols < (ti->col + ti->colspan))
665                sd->size.cols = ti->col + ti->colspan;
666              if (sd->size.rows < (ti->row + ti->rowspan))
667                sd->size.rows = ti->row + ti->rowspan;
668           }
669         if ((sd->size.cols > 0) && (sd->size.rows > 0))
670           {
671              int *cols, *rows, *colsx, *rowsx;
672
673              cols = calloc(sd->size.cols, sizeof(int));
674              rows = calloc(sd->size.rows, sizeof(int));
675              colsx = calloc(sd->size.cols, sizeof(int));
676              rowsx = calloc(sd->size.rows, sizeof(int));
677
678              EINA_LIST_FOREACH(sd->items, l, obj)
679                {
680                   E_Table_Item *ti;
681
682                   ti = evas_object_data_get(obj, "e_table_data");
683                   for (i = ti->col; i < (ti->col + ti->colspan); i++)
684                     colsx[i] |= ti->expand_w;
685                   for (i = ti->row; i < (ti->row + ti->rowspan); i++)
686                     rowsx[i] |= ti->expand_h;
687                }
688
689              EINA_LIST_FOREACH(sd->items, l, obj)
690                {
691                   E_Table_Item *ti;
692
693                   ti = evas_object_data_get(obj, "e_table_data");
694
695                   /* handle horizontal */
696                   ex = 0;
697                   tot = 0;
698                   num = ti->colspan;
699                   for (i = ti->col; i < (ti->col + num); i++)
700                     {
701                        if (colsx[i]) ex++;
702                        tot += cols[i];
703                     }
704                   need = ti->min.w;
705                   if (tot < need)
706                     {
707                        dif = need - tot;
708                        left = dif;
709                        if (ex == 0)
710                          {
711                             nx = num;
712                             for (i = ti->col; i < (ti->col + num); i++)
713                               {
714                                  if (nx > 1)
715                                    {
716                                       cols[i] += dif / num;
717                                       left -= dif / num;
718                                    }
719                                  else
720                                    {
721                                       cols[i] += left;
722                                       left = 0;
723                                    }
724                                  nx--;
725                               }
726                          }
727                        else
728                          {
729                             nx = ex;
730                             for (i = ti->col; i < (ti->col + num); i++)
731                               {
732                                  if (colsx[i])
733                                    {
734                                       if (nx > 1)
735                                         {
736                                            cols[i] += dif / ex;
737                                            left -= dif / ex;
738                                         }
739                                       else
740                                         {
741                                            cols[i] += left;
742                                            left = 0;
743                                         }
744                                       nx--;
745                                    }
746                               }
747                          }
748                     }
749
750                   /* handle vertical */
751                   ex = 0;
752                   tot = 0;
753                   num = ti->rowspan;
754                   for (i = ti->row; i < (ti->row + num); i++)
755                     {
756                        if (rowsx[i]) ex++;
757                        tot += rows[i];
758                     }
759                   need = ti->min.h;
760                   if (tot < need)
761                     {
762                        dif = need - tot;
763                        left = dif;
764                        if (ex == 0)
765                          {
766                             nx = num;
767                             for (i = ti->row; i < (ti->row + num); i++)
768                               {
769                                  if (nx > 1)
770                                    {
771                                       rows[i] += dif / num;
772                                       left -= dif / num;
773                                    }
774                                  else
775                                    {
776                                       rows[i] += left;
777                                       left = 0;
778                                    }
779                                  nx--;
780                               }
781                          }
782                        else
783                          {
784                             nx = ex;
785                             for (i = ti->row; i < (ti->row + num); i++)
786                               {
787                                  if (rowsx[i])
788                                    {
789                                       if (nx > 1)
790                                         {
791                                            rows[i] += dif / ex;
792                                            left -= dif / ex;
793                                         }
794                                       else
795                                         {
796                                            rows[i] += left;
797                                            left = 0;
798                                         }
799                                       nx--;
800                                    }
801                               }
802                          }
803                     }
804                }
805              for (i = 0; i < sd->size.cols; i++)
806                minw += cols[i];
807              for (i = 0; i < sd->size.rows; i++)
808                minh += rows[i];
809              free(rows);
810              free(cols);
811              free(rowsx);
812              free(colsx);
813           }
814      }
815    sd->min.w = minw;
816    sd->min.h = minh;
817 }
818
819 static void
820 _e_table_smart_init(void)
821 {
822    if (_e_smart) return;
823    {
824       static const Evas_Smart_Class sc =
825       {
826          "e_table",
827          EVAS_SMART_CLASS_VERSION,
828          _e_table_smart_add,
829          _e_table_smart_del,
830          _e_table_smart_move,
831          _e_table_smart_resize,
832          _e_table_smart_show,
833          _e_table_smart_hide,
834          _e_table_smart_color_set,
835          _e_table_smart_clip_set,
836          _e_table_smart_clip_unset,
837          NULL,
838          NULL,
839          NULL,
840          NULL,
841          NULL,
842          NULL,
843          NULL
844       };
845       _e_smart = evas_smart_class_new(&sc);
846    }
847 }
848
849 static void
850 _e_table_smart_add(Evas_Object *obj)
851 {
852    E_Smart_Data *sd;
853
854    sd = calloc(1, sizeof(E_Smart_Data));
855    if (!sd) return;
856    sd->obj = obj;
857    sd->x = 0;
858    sd->y = 0;
859    sd->w = 0;
860    sd->h = 0;
861    sd->clip = evas_object_rectangle_add(evas_object_evas_get(obj));
862    evas_object_smart_member_add(sd->clip, obj);
863    evas_object_move(sd->clip, -100002, -100002);
864    evas_object_resize(sd->clip, 200004, 200004);
865    evas_object_color_set(sd->clip, 255, 255, 255, 255);
866    evas_object_smart_data_set(obj, sd);
867 }
868
869 static void
870 _e_table_smart_del(Evas_Object *obj)
871 {
872    E_Smart_Data *sd;
873
874    sd = evas_object_smart_data_get(obj);
875    if (!sd) return;
876    e_table_freeze(obj);
877    while (sd->items)
878      {
879         Evas_Object *child;
880
881         child = eina_list_data_get(sd->items);
882         e_table_unpack(child);
883      }
884    e_table_thaw(obj);
885    evas_object_del(sd->clip);
886    free(sd);
887 }
888
889 static void
890 _e_table_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
891 {
892    E_Smart_Data *sd;
893
894    sd = evas_object_smart_data_get(obj);
895    if (!sd) return;
896    if ((x == sd->x) && (y == sd->y)) return;
897    if ((x == sd->x) && (y == sd->y)) return;
898    {
899       Eina_List *l;
900       Evas_Object *item;
901       Evas_Coord dx, dy;
902
903       dx = x - sd->x;
904       dy = y - sd->y;
905       EINA_LIST_FOREACH(sd->items, l, item)
906         {
907            Evas_Coord ox, oy;
908
909            evas_object_geometry_get(item, &ox, &oy, NULL, NULL);
910            evas_object_move(item, ox + dx, oy + dy);
911         }
912    }
913    sd->x = x;
914    sd->y = y;
915 }
916
917 static void
918 _e_table_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
919 {
920    E_Smart_Data *sd;
921
922    sd = evas_object_smart_data_get(obj);
923    if (!sd) return;
924    if ((w == sd->w) && (h == sd->h)) return;
925    sd->w = w;
926    sd->h = h;
927    sd->changed = 1;
928    _e_table_smart_reconfigure(sd);
929 }
930
931 static void
932 _e_table_smart_show(Evas_Object *obj)
933 {
934    E_Smart_Data *sd;
935
936    sd = evas_object_smart_data_get(obj);
937    if (!sd) return;
938    if (sd->items) evas_object_show(sd->clip);
939 }
940
941 static void
942 _e_table_smart_hide(Evas_Object *obj)
943 {
944    E_Smart_Data *sd;
945
946    sd = evas_object_smart_data_get(obj);
947    if (!sd) return;
948    evas_object_hide(sd->clip);
949 }
950
951 static void
952 _e_table_smart_color_set(Evas_Object *obj, int r, int g, int b, int a)
953 {
954    E_Smart_Data *sd;
955
956    sd = evas_object_smart_data_get(obj);
957    if (!sd) return;
958    evas_object_color_set(sd->clip, r, g, b, a);
959 }
960
961 static void
962 _e_table_smart_clip_set(Evas_Object *obj, Evas_Object *clip)
963 {
964    E_Smart_Data *sd;
965
966    sd = evas_object_smart_data_get(obj);
967    if (!sd) return;
968    evas_object_clip_set(sd->clip, clip);
969 }
970
971 static void
972 _e_table_smart_clip_unset(Evas_Object *obj)
973 {
974    E_Smart_Data *sd;
975
976    sd = evas_object_smart_data_get(obj);
977    if (!sd) return;
978    evas_object_clip_unset(sd->clip);
979 }
980