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