working on factory - fix fixme in box while i'm at it.
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 29 Aug 2011 12:52:41 +0000 (12:52 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 29 Aug 2011 12:52:41 +0000 (12:52 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/elementary@62946 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/bin/test_factory.c
src/lib/Elementary.h.in
src/lib/elm_box.c
src/lib/elm_factory.c
src/lib/elm_scroller.c
src/lib/els_box.c

index 7765701..d513579 100644 (file)
@@ -4,15 +4,13 @@
 #endif
 #ifndef ELM_LIB_QUICKLAUNCH
 
-// 64 ^ 5 = 1 billion (or so)
-//#define BLOK 64
-// homogenous layout
-//#define HOMOG 1
-
-// 32 ^ 5 = 33mil
-#define BLOK 32
+// 16 ^ 4 = 65k
+#define BLOK 16
 // homogenous layout
 //#define HOMOG 1
+// aligned to top of box
+#define ZEROALIGN 1
+#define DEFSZ 64
 
 static void
 fac_unrealize(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
@@ -30,10 +28,13 @@ fac_realize_end(void *data, Evas_Object *obj, void *event_info __UNUSED__)
    int i;
 
    bx = elm_box_add(win);
-   printf("    ADD lv 4 = %p [%i]\n", bx, (BLOK * (int)evas_object_data_get(obj, "num")));
+   printf("   ADD lv 3 = %p [%i]\n", bx, (BLOK * (int)evas_object_data_get(obj, "num")));
 #ifdef HOMOG   
    elm_box_homogeneous_set(bx, EINA_TRUE);
 #endif
+#ifdef ZEROALIGN   
+   elm_box_align_set(bx, 0.0, 0.0);
+#endif
    
    for (i = 0; i < BLOK; i++)
      {
@@ -55,40 +56,6 @@ fac_realize_end(void *data, Evas_Object *obj, void *event_info __UNUSED__)
 }
 
 static void
-fac_realize3(void *data, Evas_Object *obj, void *event_info __UNUSED__)
-{
-   Evas_Object *win = data;
-   Evas_Object *bx, *fc;
-   int i;
-
-   bx = elm_box_add(win);
-   printf("   ADD lv 3 = %p [%i]\n", bx, (BLOK * (int)evas_object_data_get(obj, "num")));
-#ifdef HOMOG   
-   elm_box_homogeneous_set(bx, EINA_TRUE);
-#endif
-   
-   for (i = 0; i < BLOK; i++)
-     {
-        fc = elm_factory_add(win);
-        // initial height per factory of 1000
-        // scrollbar will be wrong until enough
-        // children have been realized and the
-        // real size is known
-        evas_object_data_set(fc, "num", (void *)(i + (BLOK * (int)evas_object_data_get(obj, "num"))));
-        evas_object_size_hint_min_set(fc, 0, 1000);
-        evas_object_size_hint_weight_set(fc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
-        evas_object_size_hint_align_set(fc, EVAS_HINT_FILL, EVAS_HINT_FILL);
-        evas_object_smart_callback_add(fc, "realize", fac_realize_end, win);
-        evas_object_smart_callback_add(fc, "unrealize", fac_unrealize, win);
-        elm_box_pack_end(bx, fc);
-        evas_object_show(fc);
-     }
-
-   elm_factory_content_set(obj, bx);
-   evas_object_show(bx);
-}
-
-static void
 fac_realize2(void *data, Evas_Object *obj, void *event_info __UNUSED__)
 {
    Evas_Object *win = data;
@@ -100,19 +67,23 @@ fac_realize2(void *data, Evas_Object *obj, void *event_info __UNUSED__)
 #ifdef HOMOG   
    elm_box_homogeneous_set(bx, EINA_TRUE);
 #endif
+#ifdef ZEROALIGN   
+   elm_box_align_set(bx, 0.0, 0.0);
+#endif
    
    for (i = 0; i < BLOK; i++)
      {
         fc = elm_factory_add(win);
-        // initial height per factory of 1000
+        elm_factory_maxmin_mode_set(fc, EINA_TRUE);
+        // initial height per factory of DEFSZ
         // scrollbar will be wrong until enough
         // children have been realized and the
         // real size is known
         evas_object_data_set(fc, "num", (void *)(i + (BLOK * (int)evas_object_data_get(obj, "num"))));
-        evas_object_size_hint_min_set(fc, 0, 1000);
+        evas_object_size_hint_min_set(fc, 0, DEFSZ);
         evas_object_size_hint_weight_set(fc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(fc, EVAS_HINT_FILL, EVAS_HINT_FILL);
-        evas_object_smart_callback_add(fc, "realize", fac_realize3, win);
+        evas_object_smart_callback_add(fc, "realize", fac_realize_end, win);
         evas_object_smart_callback_add(fc, "unrealize", fac_unrealize, win);
         elm_box_pack_end(bx, fc);
         evas_object_show(fc);
@@ -134,20 +105,24 @@ fac_realize1(void *data, Evas_Object *obj, void *event_info __UNUSED__)
 #ifdef HOMOG   
    elm_box_homogeneous_set(bx, EINA_TRUE);
 #endif
+#ifdef ZEROALIGN   
+   elm_box_align_set(bx, 0.0, 0.0);
+#endif
    
    for (i = 0; i < BLOK; i++)
      {
         fc = elm_factory_add(win);
-        // initial height per factory of 1000
+        elm_factory_maxmin_mode_set(fc, EINA_TRUE);
+        // initial height per factory of DEFSZ
         // scrollbar will be wrong until enough
         // children have been realized and the
         // real size is known
         evas_object_data_set(fc, "num", (void *)(i + (BLOK * (int)evas_object_data_get(obj, "num"))));
-        evas_object_size_hint_min_set(fc, 0, 1000);
+        evas_object_size_hint_min_set(fc, 0, DEFSZ);
         evas_object_size_hint_weight_set(fc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(fc, EVAS_HINT_FILL, EVAS_HINT_FILL);
         evas_object_smart_callback_add(fc, "realize", fac_realize2, win);
-        evas_object_smart_callback_add(fc, "unrealize", fac_unrealize, win);
+//        evas_object_smart_callback_add(fc, "unrealize", fac_unrealize, win);
         elm_box_pack_end(bx, fc);
         evas_object_show(fc);
      }
@@ -175,21 +150,25 @@ test_factory(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event_inf
 #ifdef HOMOG   
    elm_box_homogeneous_set(bx, EINA_TRUE);
 #endif   
-   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+#ifdef ZEROALIGN   
+   elm_box_align_set(bx, 0.0, 0.0);
+#endif   
+   evas_object_size_hint_weight_set(bx, EVAS_HINT_EXPAND, 0.0);
 
    for (i = 0; i < BLOK; i++)
      {
         fc = elm_factory_add(win);
-        // initial height per factory of 1000
+        elm_factory_maxmin_mode_set(fc, EINA_TRUE);
+        // initial height per factory of DEFSZ
         // scrollbar will be wrong until enough
         // children have been realized and the
         // real size is known
         evas_object_data_set(fc, "num", (void *)i);
-        evas_object_size_hint_min_set(fc, 0, 1000);
+        evas_object_size_hint_min_set(fc, 0, DEFSZ);
         evas_object_size_hint_weight_set(fc, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
         evas_object_size_hint_align_set(fc, EVAS_HINT_FILL, EVAS_HINT_FILL);
         evas_object_smart_callback_add(fc, "realize", fac_realize1, win);
-        evas_object_smart_callback_add(fc, "unrealize", fac_unrealize, win);
+//        evas_object_smart_callback_add(fc, "unrealize", fac_unrealize, win);
         elm_box_pack_end(bx, fc);
         evas_object_show(fc);
      }
index 9da2dee..c7fed62 100644 (file)
@@ -26422,6 +26422,9 @@ extern "C" {
    EAPI Evas_Object *elm_factory_add(Evas_Object *parent);
    EAPI void         elm_factory_content_set(Evas_Object *obj, Evas_Object *content);
    EAPI Evas_Object *elm_factory_content_get(const Evas_Object *obj);
+   EAPI void         elm_factory_maxmin_mode_set(Evas_Object *obj, Eina_Bool enabled);
+   EAPI Eina_Bool    elm_factory_maxmin_mode_get(const Evas_Object *obj);
+   EAPI void         elm_factory_maxmin_reset_set(Evas_Object *obj);
 
    /**
     * @defgroup Video Video
index 831a977..54c67e0 100644 (file)
@@ -639,7 +639,7 @@ elm_box_align_set(Evas_Object *obj, double horizontal, double vertical)
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   evas_object_box_align_set(wd->box, horizontal, vertical);
+   evas_object_size_hint_align_set(wd->box, horizontal, vertical);
 }
 
 EAPI void
@@ -648,5 +648,5 @@ elm_box_align_get(const Evas_Object *obj, double *horizontal, double *vertical)
    ELM_CHECK_WIDTYPE(obj, widtype);
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
-   evas_object_box_align_get(wd->box, horizontal, vertical);
+   evas_object_size_hint_align_get(wd->box, horizontal, vertical);
 }
index 1c36a5f..a999e7e 100644 (file)
@@ -1,6 +1,8 @@
 #include <Elementary.h>
 #include "elm_priv.h"
 
+// FIXME: handle if canvas resizes
+
 typedef struct _Widget_Data Widget_Data;
 
 struct _Widget_Data
@@ -8,7 +10,10 @@ struct _Widget_Data
    Evas_Object *obj;
    Evas_Object *content;
    int last_calc_count; 
+   Evas_Coord maxminw, maxminh;
    Eina_Bool eval : 1;
+   Eina_Bool szeval : 1;
+   Eina_Bool maxmin : 1;
 };
 
 static const char *widtype = NULL;
@@ -31,11 +36,28 @@ static const Evas_Smart_Cb_Description _signals[] = {
    {NULL, NULL}
 };
 
+static int fac = 0;
+
 static void
 _del_hook(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
+   if (wd->content)
+     {
+        Evas_Object *o = wd->content;
+        
+        evas_object_event_callback_del_full(o,
+                                            EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                            _child_change, obj);
+        evas_object_event_callback_del_full(o,
+                                            EVAS_CALLBACK_DEL,
+                                            _child_del, obj);
+        wd->content = NULL;
+        evas_object_del(o);
+        fac--;
+//        printf("FAC-- = %i\n", fac);
+     }
    free(wd);
 }
 
@@ -60,8 +82,18 @@ _sizing_eval(Evas_Object *obj)
    if (!wd->content) return;
    evas_object_size_hint_min_get(wd->content, &minw, &minh);
    evas_object_size_hint_max_get(wd->content, &maxw, &maxh);
-   evas_object_size_hint_min_set(obj, minw, minh);
+   if (wd->maxmin)
+     {
+        if (minw > wd->maxminw) wd->maxminw = minw;
+        if (minh > wd->maxminh) wd->maxminh = minh;
+        evas_object_size_hint_min_set(obj, wd->maxminw, wd->maxminh);
+     }
+   else
+     {
+        evas_object_size_hint_min_set(obj, minw, minh);
+     }
    evas_object_size_hint_max_set(obj, maxw, maxh);
+//   printf("FAC SZ: %i %i | %i %i\n", minw, minh, maxw, maxh);
 }
 
 static void
@@ -90,6 +122,7 @@ _eval(Evas_Object *obj)
      {
         if (!wd->content)
           {
+//             printf("                 + %i %i %ix%i <> %i %i %ix%i\n", x, y, w, h, cvx, cvy, cvw, cvh);
              evas_object_smart_callback_call(obj, SIG_REALIZE, NULL);
              if (wd->content)
                {
@@ -121,9 +154,13 @@ _changed(Evas_Object *obj)
    if (wd->eval)
      {
         _eval(obj);
-        _sizing_eval(obj);
         wd->eval = EINA_FALSE;
      }
+   if (wd->szeval)
+     {
+        _sizing_eval(obj);
+        wd->szeval = EINA_FALSE;
+     }
 }
 
 static void
@@ -150,6 +187,7 @@ _child_change(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj __UNUS
    Widget_Data *wd = elm_widget_data_get(data);
    if (!wd) return;
    wd->eval = EINA_TRUE;
+   wd->szeval = EINA_TRUE;
    evas_object_smart_changed(data);
 }
 
@@ -167,6 +205,8 @@ _child_del(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event_info __
                                        EVAS_CALLBACK_DEL,
                                        _child_del, obj);
    wd->content = NULL;
+   fac--;
+//   printf("FAC-- = %i\n", fac);
 }
 
 EAPI Evas_Object *
@@ -204,15 +244,35 @@ elm_factory_content_set(Evas_Object *obj, Evas_Object *content)
    Widget_Data *wd = elm_widget_data_get(obj);
    if (!wd) return;
    if (wd->content == content) return;
-   if (wd->content) evas_object_del(wd->content);
+   if (wd->content)
+      {
+         Evas_Object *o = wd->content;
+
+         evas_object_event_callback_del_full(wd->content,
+                                             EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                             _child_change, obj);
+         evas_object_event_callback_del_full(wd->content,
+                                             EVAS_CALLBACK_DEL,
+                                             _child_del, obj);
+         wd->content = NULL;
+         evas_object_del(o);
+         fac--;
+//         printf("FAC-- = %i\n", fac);
+      }
    wd->content = content;
-   elm_widget_resize_object_set(obj, wd->content);
-   evas_object_event_callback_add(wd->content, EVAS_CALLBACK_DEL,
-                                  _child_del, obj);
-   evas_object_event_callback_add(wd->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
-                                  _child_change, obj);
-   wd->eval = EINA_TRUE;
-   evas_object_smart_changed(obj);
+   if (wd->content)
+     {
+        fac++;
+//        printf("FAC++ = %i\n", fac);
+        elm_widget_resize_object_set(obj, wd->content);
+        evas_object_event_callback_add(wd->content, EVAS_CALLBACK_DEL,
+                                       _child_del, obj);
+        evas_object_event_callback_add(wd->content, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                       _child_change, obj);
+        wd->eval = EINA_TRUE;
+        wd->szeval = EINA_TRUE;
+        evas_object_smart_changed(obj);
+     }
 }
 
 EAPI Evas_Object *
@@ -223,3 +283,34 @@ elm_factory_content_get(const Evas_Object *obj)
    if (!wd) return NULL;
    return wd->content;
 }
+
+EAPI void
+elm_factory_maxmin_mode_set(Evas_Object *obj, Eina_Bool enabled)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->maxmin = !!enabled;
+}
+
+EAPI Eina_Bool
+elm_factory_maxmin_mode_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return EINA_FALSE;
+   return wd->maxmin;
+}
+
+EAPI void
+elm_factory_maxmin_reset_set(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+   if (!wd) return;
+   wd->maxminw = 0;
+   wd->maxminh = 0;
+   wd->eval = EINA_TRUE;
+   wd->szeval = EINA_TRUE;
+   evas_object_smart_changed(obj);
+}
index 5bc6bed..adb1f40 100644 (file)
@@ -249,7 +249,7 @@ static void
 _sizing_eval(Evas_Object *obj)
 {
    Widget_Data *wd = elm_widget_data_get(obj);
-   Evas_Coord  vw, vh, minw = 0, minh = 0, maxw = 0, maxh = 0, w, h, vmw, vmh;
+   Evas_Coord  vw = 0, vh = 0, minw = 0, minh = 0, maxw = 0, maxh = 0, w, h, vmw, vmh;
    double xw = 0.0, yw = 0.0;
 
    if (!wd) return;
index 79c8da0..e2d406e 100644 (file)
@@ -4,14 +4,15 @@
 static void
 _smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horizontal, int homogeneous)
 {
-   Evas_Coord minw, minh, mnw, mnh;
+   Evas_Coord minw, minh, mnw, mnh, maxw, maxh;
    const Eina_List *l;
    Evas_Object_Box_Option *opt;
    int c;
 
-   /* FIXME: need to calc max */
    minw = 0;
    minh = 0;
+   maxw = -1;
+   maxh = -1;
    if (homogeneous)
      {
         EINA_LIST_FOREACH(priv->children, l, opt)
@@ -19,11 +20,33 @@ _smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horiz
              evas_object_size_hint_min_get(opt->obj, &mnw, &mnh);
              if (minh < mnh) minh = mnh;
              if (minw < mnw) minw = mnw;
+             
+             evas_object_size_hint_max_get(opt->obj, &mnw, &mnh);
+             if (mnh >= 0)
+               {
+                  if (maxw == -1) maxh = mnh;
+                  else if (maxh > mnh) maxh = mnh;
+               }
+             if (mnw >= 0)
+               {
+                  if (maxw == -1) maxw = mnw;
+                  else if (maxw > mnw) maxw = mnw;
+               }
           }
         if (horizontal)
-          minw *= eina_list_count(priv->children);
+          {
+             minw *= eina_list_count(priv->children);
+             if (maxw != -1)
+                maxw *= eina_list_count(priv->children);
+             else maxw = -1;
+          }
         else
-          minh *= eina_list_count(priv->children);
+          {
+             minh *= eina_list_count(priv->children);
+             if (maxh != -1)
+                maxh *= eina_list_count(priv->children);
+             else maxh = -1;
+          }
      }
    else
      {
@@ -40,15 +63,43 @@ _smart_extents_calculate(Evas_Object *box, Evas_Object_Box_Data *priv, int horiz
                   if (minw < mnw) minw = mnw;
                   minh += mnh;
                }
+             evas_object_size_hint_max_get(opt->obj, &mnw, &mnh);
+             if (horizontal)
+               {
+                  if (mnw < 0) maxw = -1;
+                  if (maxw != -1)
+                    {
+                       if (maxw > mnw) maxw = mnw;
+                       maxw += mnw;
+                    }
+               }
+             else
+               {
+                  if (mnh < 0) maxh = -1;
+                  if (maxh != -1)
+                    {
+                       if (maxh > mnh) maxh = mnh;
+                       maxh += mnh;
+                    }
+               }
           }
      }
    c = eina_list_count(priv->children) - 1;
    if (c > 0)
      {
-        if (horizontal) minw += priv->pad.h * c;
-        else            minh += priv->pad.v * c;
+        if (horizontal)
+          {
+             minw += priv->pad.h * c;
+             if (maxw != -1) maxw += priv->pad.h * c;
+          }
+        else
+          {
+             minh += priv->pad.v * c;
+             if (maxh != -1) maxh += priv->pad.v * c;
+          }
      }
    evas_object_size_hint_min_set(box, minw, minh);
+   evas_object_size_hint_max_set(box, maxw, maxh);
 }
 
 void
@@ -69,6 +120,8 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int
 
    evas_object_size_hint_min_get(o, &minw, &minh);
    evas_object_size_hint_align_get(o, &ax, &ay);
+   if ((w < minw) || (h < minh)) return;
+//   printf("====== %i %i | %ix%i | %ix%i | %1.3f %1.3f\n", x, y, w, h, minw, minh, ax, ay);
    count = eina_list_count(priv->children);
    if (rtl) ax = 1.0 - ax;
 
@@ -115,6 +168,7 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int
    hdif = h - minh;
    xx = x;
    yy = y;
+//   printf("-------- SZ %ix%i | MIN %ix%i | POS %i %i\n", w, h, minw, minh, x, y);
    EINA_LIST_FOREACH(priv->children, l, opt)
      {
         Evas_Coord mnw, mnh, mxw, mxh;
@@ -193,6 +247,8 @@ _els_box_layout(Evas_Object *o, Evas_Object_Box_Data *priv, int horizontal, int
              oh = mnh;
              if (fh) oh = hh;
              if ((mxh >= 0) && (mxh < oh)) oh = mxh;
+//             printf("mv: %p %i\n", obj,
+//                    yy + (Evas_Coord)(((double)(hh - oh)) * ay));
              evas_object_move(obj,
                               xx + (Evas_Coord)(((double)(ww - ow)) * ax),
                               yy + (Evas_Coord)(((double)(hh - oh)) * ay));