Enlightenment CVS committal

Author  : rbdpngn
Project : e17
Module  : libs/ewl

Dir     : e17/libs/ewl/src/lib


Modified Files:
        ewl_container.c ewl_container.h ewl_embed.c ewl_image.c 
        ewl_image.h ewl_misc.c ewl_text.c ewl_text.h ewl_widget.c 
        ewl_widget.h 


Log Message:
Cache evas objects for widgets that go off screen and reuse them for objects 
that come on screen. This limits the number of evas objects to the maximum 
number of evas objects on screen at a single instance.
Re-use a single default context for the text widget.

===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_container.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -3 -r1.17 -r1.18
--- ewl_container.c     5 Nov 2005 03:07:10 -0000       1.17
+++ ewl_container.c     13 Nov 2005 06:48:55 -0000      1.18
@@ -41,6 +41,12 @@
         */
        ewl_callback_append(w, EWL_CALLBACK_CONFIGURE,
                            ewl_container_configure_cb, NULL);
+       ewl_callback_append(w, EWL_CALLBACK_OBSCURE,
+                           ewl_container_obscure_cb, NULL);
+       ewl_callback_append(w, EWL_CALLBACK_REVEAL,
+                           ewl_container_reveal_cb, NULL);
+       ewl_callback_append(w, EWL_CALLBACK_REALIZE,
+                           ewl_container_reveal_cb, NULL);
        ewl_callback_append(w, EWL_CALLBACK_REALIZE,
                            ewl_container_realize_cb, NULL);
        ewl_callback_append(w, EWL_CALLBACK_UNREALIZE,
@@ -1050,6 +1056,84 @@
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+void
+ewl_container_obscure_cb(Ewl_Widget * w, void *ev_data __UNUSED__,
+                        void *user_data __UNUSED__)
+{
+       Ewl_Embed *e;
+       Ewl_Container *c;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       c = EWL_CONTAINER(w);
+
+       /*
+        * Give up the clip box object in use.
+        */
+       e = ewl_embed_widget_find(EWL_WIDGET(w));
+       if (e && c->clip_box) {
+               evas_object_hide(c->clip_box);
+               ewl_embed_object_cache(e, c->clip_box);
+               c->clip_box = NULL;
+       }
+
+       /*
+        * Notify children that they are now obscured, they will not receive a
+        * configure event since the parent won't get configured while
+        * obscured.
+        */
+       if (c->children) {
+               ecore_list_goto_first(c->children);
+               while ((w = ecore_list_next(c->children))) {
+                       if (REALIZED(w))
+                               ewl_widget_obscure(w);
+               }
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+void 
+ewl_container_reveal_cb(Ewl_Widget * w, void *ev_data __UNUSED__, 
+                       void *user_data __UNUSED__)
+{
+       Ewl_Embed *e;
+       Ewl_Container *c;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       c = EWL_CONTAINER(w);
+
+       e = ewl_embed_widget_find(EWL_WIDGET(w));
+       if (e && !c->clip_box) {
+               c->clip_box = ewl_embed_object_request(e, "rectangle");
+       }
+
+       /*
+        * Create the clip box for this container, this keeps children clipped
+        * to the wanted area.
+        */
+       if (!c->clip_box)
+               c->clip_box = evas_object_rectangle_add(e->evas);
+
+       /*
+        * Setup the remaining properties for the clip box.
+        */
+       if (c->clip_box) {
+                evas_object_pass_events_set(c->clip_box, TRUE);
+
+               if (w->fx_clip_box) {
+                       evas_object_clip_set(c->clip_box, w->fx_clip_box);
+                       evas_object_layer_set(c->clip_box,
+                                       evas_object_layer_get(w->fx_clip_box));
+               }
+
+               evas_object_color_set(c->clip_box, 255, 255, 255, 255);
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
 /*
  * This is the default action to be taken by containers, it involves
  * creating and showing a clip box, as well as clipping the clip box to parent
@@ -1060,7 +1144,6 @@
                                                void *user_data __UNUSED__)
 {
        int i = 0;
-       Ewl_Embed *emb;
        Ewl_Container *c;
        Ewl_Widget *child;
 
@@ -1070,25 +1153,6 @@
 
        c = EWL_CONTAINER(w);
 
-       emb = ewl_embed_widget_find(w);
-
-       /*
-        * Create the clip box for this container, this keeps children clipped
-        * to the wanted area.
-        */
-       c->clip_box = evas_object_rectangle_add(emb->evas);
-       if (c->clip_box) {
-               evas_object_move(c->clip_box, CURRENT_X(w), CURRENT_Y(w));
-               evas_object_resize(c->clip_box, CURRENT_W(w), CURRENT_H(w));
-               evas_object_pass_events_set(c->clip_box, TRUE);
-       }
-
-       if (w->fx_clip_box) {
-               evas_object_clip_set(c->clip_box, w->fx_clip_box);
-               evas_object_layer_set(c->clip_box,
-                               evas_object_layer_get(w->fx_clip_box));
-       }
-
        if (!c->children || ecore_list_is_empty(c->children))
                DRETURN(DLEVEL_STABLE);
 
@@ -1165,4 +1229,3 @@
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
-
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_container.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -3 -r1.7 -r1.8
--- ewl_container.h     23 Oct 2005 17:50:13 -0000      1.7
+++ ewl_container.h     13 Nov 2005 06:48:55 -0000      1.8
@@ -149,6 +149,8 @@
 /*
  * Internally used callbacks, override at your own risk.
  */
+void ewl_container_reveal_cb(Ewl_Widget *w, void *ev_data, void *user_data);
+void ewl_container_obscure_cb(Ewl_Widget *w, void *ev_data, void *user_data);
 void ewl_container_realize_cb(Ewl_Widget *w, void *ev_data, void *user_data);
 void ewl_container_configure_cb(Ewl_Widget * w, void *ev_data, void 
*user_data);
 void ewl_container_reparent_cb(Ewl_Widget * w, void *ev_data, void *user_data);
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_embed.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -3 -r1.19 -r1.20
--- ewl_embed.c 2 Nov 2005 18:23:21 -0000       1.19
+++ ewl_embed.c 13 Nov 2005 06:48:55 -0000      1.20
@@ -838,20 +838,27 @@
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("e", e);
+       DCHECK_PARAM_PTR("obj", obj);
        DCHECK_TYPE("e", e, "embed");
 
-       type = evas_object_type_get(obj);
-       obj_list = ecore_hash_get(e->obj_cache, (void *)type);
-       if (!obj_list) {
-               obj_list = ecore_list_new();
-               ecore_hash_set(e->obj_cache, (void *)type, obj_list);
-       }
-
        evas_object_clip_unset(obj);
        evas_object_hide(obj);
-       ecore_list_prepend(obj_list, obj);
-/*     printf("%d nodes cached of type %s\n", ecore_list_nodes(obj_list),
-                       type); */
+
+       if (e->obj_cache) {
+               type = evas_object_type_get(obj);
+               obj_list = ecore_hash_get(e->obj_cache, (void *)type);
+               if (!obj_list) {
+                       obj_list = ecore_list_new();
+                       ecore_hash_set(e->obj_cache, (void *)type, obj_list);
+               }
+               ecore_list_prepend(obj_list, obj);
+
+               /* printf("%d nodes cached of type %s\n",
+                               ecore_list_nodes(obj_list), type); */
+       }
+       else {
+               ewl_evas_object_destroy(obj);
+       }
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
@@ -869,11 +876,15 @@
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR_RET("e", e, NULL);
+       DCHECK_PARAM_PTR_RET("type", type, NULL);
        DCHECK_TYPE_RET("e", e, "embed", NULL);
 
        obj_list = ecore_hash_get(e->obj_cache, type);
        if (obj_list) {
                obj = ecore_list_remove_first(obj_list);
+
+               /* printf("%d nodes remain cached of type %s\n",
+                               ecore_list_nodes(obj_list), type); */
        }
 
        DRETURN_PTR(obj, DLEVEL_STABLE);
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_image.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -3 -r1.18 -r1.19
--- ewl_image.c 29 Oct 2005 06:55:33 -0000      1.18
+++ ewl_image.c 13 Nov 2005 06:48:55 -0000      1.19
@@ -59,9 +59,9 @@
        /*
         * Append necessary callbacks.
         */
-       ewl_callback_append(w, EWL_CALLBACK_REALIZE, ewl_image_realize_cb,
+       ewl_callback_append(w, EWL_CALLBACK_REVEAL, ewl_image_reveal_cb,
                            NULL);
-       ewl_callback_append(w, EWL_CALLBACK_UNREALIZE, ewl_image_unrealize_cb,
+       ewl_callback_append(w, EWL_CALLBACK_OBSCURE, ewl_image_obscure_cb,
                            NULL);
        ewl_callback_prepend(w, EWL_CALLBACK_DESTROY, ewl_image_destroy_cb,
                            NULL);
@@ -109,7 +109,8 @@
  * @return Returns no value.
  * @brief Change the image file displayed by an image widget
  *
- * Set the image displayed by @a i to the one found at the path @a im.
+ * Set the image displayed by @a i to the one found at the path @a im. If an
+ * edje is used, a minimum size should be specified in the edje or the code.
  */
 void
 ewl_image_file_set(Ewl_Image *i, char *im, char *key)
@@ -145,24 +146,8 @@
         * Load the new image if widget has been realized
         */
        if (REALIZED(w)) {
-               /*
-                * Free the image if it had been loaded.
-                */
-               if (i->image) {
-                       /*
-                        * Type is important for using the correct free calls.
-                        */
-                       evas_object_hide(i->image);
-                       evas_object_clip_unset(i->image);
-                       ewl_evas_object_destroy(i->image);
-                       i->image = NULL;
-               }
-
-               /*
-                * Now draw the new image
-                */
-               ewl_image_realize_cb(w, NULL, NULL);
-               ewl_widget_configure(w);
+               ewl_widget_unrealize(w);
+               ewl_widget_realize(w);
        }
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
@@ -300,7 +285,7 @@
 }
 
 void
-ewl_image_realize_cb(Ewl_Widget *w, void *ev_data __UNUSED__,
+ewl_image_reveal_cb(Ewl_Widget *w, void *ev_data __UNUSED__,
                                        void *user_data __UNUSED__)
 {
        Ewl_Image *i;
@@ -317,7 +302,10 @@
         * Load the image based on the type.
         */
        if (i->type == EWL_IMAGE_TYPE_EDJE) {
-               i->image = edje_object_add(emb->evas);
+               if (!i->image)
+                       i->image = ewl_embed_object_request(emb, "edje");
+               if (!i->image)
+                       i->image = edje_object_add(emb->evas);
                if (!i->image)
                        DRETURN(DLEVEL_STABLE);
 
@@ -325,7 +313,10 @@
                        edje_object_file_set(i->image, i->path, i->key);
                edje_object_size_min_get(i->image, &i->ow, &i->oh);
        } else {
-               i->image = evas_object_image_add(emb->evas);
+               if (!i->image)
+                       i->image = ewl_embed_object_request(emb, "image");
+               if (!i->image)
+                       i->image = evas_object_image_add(emb->evas);
                if (!i->image)
                        DRETURN(DLEVEL_STABLE);
 
@@ -374,18 +365,21 @@
 }
 
 void
-ewl_image_unrealize_cb(Ewl_Widget *w, void *ev_data __UNUSED__,
+ewl_image_obscure_cb(Ewl_Widget *w, void *ev_data __UNUSED__,
                                                void *user_data __UNUSED__)
 {
        Ewl_Image *i;
+       Ewl_Embed *emb;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("w", w);
        DCHECK_TYPE("w", w, "widget");
 
+       emb = ewl_embed_widget_find(w);
+
        i = EWL_IMAGE(w);
        if (i->image) {
-               evas_object_del(i->image);
+               ewl_embed_object_cache(emb, i->image);
                i->image = NULL;
        }
 
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_image.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -3 -r1.8 -r1.9
--- ewl_image.h 29 Oct 2005 06:24:17 -0000      1.8
+++ ewl_image.h 13 Nov 2005 06:48:55 -0000      1.9
@@ -63,8 +63,8 @@
 /*
  * Internally used callbacks, override at your own risk.
  */
-void ewl_image_realize_cb(Ewl_Widget *w, void *ev_data, void *user_data);
-void ewl_image_unrealize_cb(Ewl_Widget *w, void *ev_data, void *user_data);
+void ewl_image_reveal_cb(Ewl_Widget *w, void *ev_data, void *user_data);
+void ewl_image_obscure_cb(Ewl_Widget *w, void *ev_data, void *user_data);
 void ewl_image_configure_cb(Ewl_Widget *w, void *ev_data, void *user_data);
 void ewl_image_mouse_down_cb(Ewl_Widget *w, void *ev_data, void *user_data);
 void ewl_image_mouse_up_cb(Ewl_Widget *w, void *ev_data, void *user_data);
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_misc.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -3 -r1.25 -r1.26
--- ewl_misc.c  1 Nov 2005 05:54:50 -0000       1.25
+++ ewl_misc.c  13 Nov 2005 06:48:55 -0000      1.26
@@ -22,6 +22,8 @@
 /*
  * Queues for scheduling various actions.
  */
+static Ecore_List *obscure_list = NULL;
+static Ecore_List *reveal_list = NULL;
 static Ecore_List *configure_list = NULL;
 static Ecore_List *realize_list = NULL;
 static Ecore_List *destroy_list = NULL;
@@ -97,6 +99,8 @@
                DRETURN_INT(--_ewl_init_count, DLEVEL_STABLE);
        }
 
+       reveal_list = ecore_list_new();
+       obscure_list = ecore_list_new();
        configure_list = ecore_list_new();
        realize_list = ecore_list_new();
        destroy_list = ecore_list_new();
@@ -242,6 +246,10 @@
                ecore_list_destroy(ewl_window_list);
                ewl_window_list = NULL;
        }
+       ecore_list_destroy(reveal_list);
+       reveal_list = NULL;
+       ecore_list_destroy(obscure_list);
+       obscure_list = NULL;
        ecore_list_destroy(configure_list);
        configure_list = NULL;
        ecore_list_destroy(realize_list);
@@ -297,11 +305,24 @@
  *
  * Renders updates to the evas's during idle event times. Should not be called
  * publically unless a re-render is absolutely necessary.
+ *
+ * Overall Application workflow:
+ * 1. Setup some widgets in the application.
+ * 2. Enter the main loop.
+ * 3. Realize widgets starting at the top working down.
+ * 4. Show widgets starting at the bottom and working to the top notifying each
+ *    parent of the childs size.
+ * 5. Hide obscured widgets.
+ * 6. Show revealed widgets.
+ * 7. Move widgets around and size them.
+ * 8. Render the display.
+ * 9. Repeat steps 2-6 until program exits.
  */
 int
 ewl_idle_render(void *data)
 {
-       Ewl_Embed *emb;
+       Ewl_Widget *w;
+       Ewl_Embed  *emb;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
 
@@ -313,6 +334,9 @@
        if (ecore_list_is_empty(ewl_embed_list))
                DRETURN_INT(TRUE, DLEVEL_STABLE);
 
+       /*
+        * Global freeze on edje events while edje's are being manipulated.
+        */
        edje_freeze();
 
        /*
@@ -343,12 +367,33 @@
                /*
                 * Reclaim obscured objects at this point
                 */
+               while ((w = ecore_list_remove_first(obscure_list))) {
+                       /*
+                        * Ensure the widget is still obscured, then mark it
+                        * revealed so that the obscure will succeed (and mark
+                        * it obscured again.
+                        */
+                       if (!OBSCURED(w)) {
+                               ewl_widget_obscure(w);
+                       }
+               }
 
                /*
                 * Allocate objects to revealed widgets.
                 */
+               while ((w = ecore_list_remove_first(reveal_list))) {
+                       /*
+                        * Follow the same logic as the obscure loop.
+                        */
+                       if (OBSCURED(w)) {
+                               ewl_widget_reveal(w);
+                       }
+               }
        }
 
+       /*
+        * Our work is done, allow edje events to be triggered.
+        */
        edje_thaw();
 
        /*
@@ -482,7 +527,6 @@
 void
 ewl_configure_request(Ewl_Widget * w)
 {
-       static int longest = 0;
        Ewl_Embed *emb;
        Ewl_Widget *search;
 
@@ -490,115 +534,30 @@
        DCHECK_PARAM_PTR("w", w);
        DCHECK_TYPE("w", w, "widget");
 
-       if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_DSCHEDULED))
-               DRETURN(DLEVEL_STABLE);
-
-       if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_CPROCESS))
+       if (!VISIBLE(w))
                DRETURN(DLEVEL_STABLE);
 
-       emb = ewl_embed_widget_find(w);
-       if (!emb)
-               DRETURN(DLEVEL_STABLE);
-
-       /*
-        * We don't need to configure if it's outside the viewable space in
-        * it's parent widget.
-        */
-       if (w->parent) {
-               int obscured = 0;
-               int x, y;
-               int width, height;
-               Ewl_Widget *p = w->parent;
-
-               ewl_object_current_geometry_get(EWL_OBJECT(w), &x, &y, &width,
-                               &height);
-
-               if ((x + width) < CURRENT_X(p))
-                       obscured = 1;
-
-               if (x > (CURRENT_X(p) + CURRENT_W(p)))
-                       obscured = 1;
-
-               if ((y + height) < CURRENT_Y(p))
-                       obscured = 1;
-
-               if (y > (CURRENT_Y(p) + CURRENT_H(p)))
-                       obscured = 1;
-
-               if ((x + width) < CURRENT_X(emb))
-                       obscured = 1;
-
-               if (x > (CURRENT_X(emb) + CURRENT_W(emb)))
-                       obscured = 1;
-
-               if ((y + height) < CURRENT_Y(emb))
-                       obscured = 1;
-
-               if (y > (CURRENT_Y(emb) + CURRENT_H(emb)))
-                       obscured = 1;
-
-               if (obscured) {
-                       ewl_object_visible_add(EWL_OBJECT(w),
-                                       EWL_FLAG_VISIBLE_OBSCURED);
-                       if (w->fx_clip_box)
-                               evas_object_hide(w->fx_clip_box);
-                       if (w->theme_object)
-                               evas_object_hide(w->theme_object);
-                       /* FIXME: This might be a good idea.
-                       if (w->theme_object)
-                               edje_object_freeze(w->theme_object);
-                       */
-               }
-               else {
-                       ewl_object_visible_remove(EWL_OBJECT(w),
-                                       EWL_FLAG_VISIBLE_OBSCURED);
-                       if (w->fx_clip_box)
-                               evas_object_show(w->fx_clip_box);
-                       if (w->theme_object)
-                               evas_object_show(w->theme_object);
-                       /* FIXME: This might be a good idea.
-                       if (w->theme_object)
-                               edje_object_thaw(w->theme_object);
-                       */
-               }
-       }
-
        /*
-        * Check this first, and remove an obscured widget from the configure
-        * list, if it's already scheduled.
+        * Widget scheduled for destruction
         */
-       if (ewl_object_visible_has(EWL_OBJECT(w), EWL_FLAG_VISIBLE_OBSCURED)) {
-               if (ewl_object_queued_has(EWL_OBJECT(w),
-                                       EWL_FLAG_QUEUED_CSCHEDULED)) {
-                       ecore_list_goto_first(configure_list);
-                       while ((search = ecore_list_current(configure_list))) {
-                               if (search == w) {
-                                       ewl_object_queued_remove(EWL_OBJECT(w),
-                                               EWL_FLAG_QUEUED_CSCHEDULED);
-                                       ecore_list_remove(configure_list);
-                                       break;
-                               }
-                               ecore_list_next(configure_list);
-                       }
-               }
-
-               DRETURN(DLEVEL_TESTING);
-       }
+       if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_DSCHEDULED))
+               DRETURN(DLEVEL_STABLE);
 
        /*
-        * Easy case, we know this is on the list already.
+        * Widget already scheduled for configure
         */
        if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_CSCHEDULED))
-               DRETURN(DLEVEL_TESTING);
+               DRETURN(DLEVEL_STABLE);
 
        /*
-        * Need to check if the embed that holds w is scheduled for
-        * configuration. This is the easiest way to test if we can avoid
-        * adding this widget to the configuration list.
+        * Widget already in configure callback
         */
-       if (ewl_object_queued_has(EWL_OBJECT(emb),
-                       EWL_FLAG_QUEUED_CSCHEDULED))
-               DRETURN(DLEVEL_TESTING);
+       if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_CPROCESS))
+               DRETURN(DLEVEL_STABLE);
+
+       emb = ewl_embed_widget_find(w);
+       if (!emb)
+               DRETURN(DLEVEL_STABLE);
 
        /*
         * Check for any parent scheduled for configuration.
@@ -616,37 +575,7 @@
         */
        ewl_object_queued_add(EWL_OBJECT(w), EWL_FLAG_QUEUED_CSCHEDULED);
        ecore_list_append(configure_list, w);
-
-       /*
-        * Now clean off any children of this widget, they will get added
-        * later.
-        */
-       /* FIXME: This is a big source of slow down on long lists of widgets,
-        * might not be worth it
-       ecore_list_goto_first(configure_list);
-       while ((search = ecore_list_current(configure_list))) {
-               Ewl_Widget *parent;
-
-               parent = search;
-               while ((parent = parent->parent)) {
-                       if (parent == w) {
-                               ewl_object_queued_remove(EWL_OBJECT(search),
-                                               EWL_FLAG_QUEUED_CSCHEDULED);
-                               ecore_list_remove(configure_list);
-                               break;
-                       }
-               }
-
-               ecore_list_next(configure_list);
-       }
-       */
-
-       /*
-        * FIXME: Remove this once we get things stabilize a bit more.
-        */
-       if (ecore_list_nodes(configure_list) > longest) {
-               longest = ecore_list_nodes(configure_list);
-       }
+       /* printf("*** Queued %s for configuration ***\n", w->appearance); */
 
        DLEAVE_FUNCTION(DLEVEL_TESTING);
 }
@@ -676,10 +605,32 @@
                ewl_object_queued_remove(EWL_OBJECT(w),
                                EWL_FLAG_QUEUED_CSCHEDULED);
 
-               ewl_object_queued_add(EWL_OBJECT(w), EWL_FLAG_QUEUED_CPROCESS);
-               ewl_callback_call(w, EWL_CALLBACK_CONFIGURE);
-               ewl_object_queued_remove(EWL_OBJECT(w),
-                                        EWL_FLAG_QUEUED_CPROCESS);
+               /*
+                * Items that are off screen should be queued to give up their
+                * evas objects for reuse. Items returning from offscreen are
+                * queued to receive new evas objects.
+                */
+               if (!ewl_widget_onscreen_is(w)) {
+                       if (!OBSCURED(w)) {
+                               ecore_list_prepend(obscure_list, w);
+                               /* printf("Flagging obscure:\n\t");
+                               ewl_widget_print(w); */
+                       }
+               }
+               else {
+                       if (OBSCURED(w)) {
+                               ecore_list_prepend(reveal_list, w);
+                               /* printf("Flagging revealed:\n\t");
+                               ewl_widget_print(w); */
+                       }
+
+                       ewl_object_queued_add(EWL_OBJECT(w),
+                                       EWL_FLAG_QUEUED_CPROCESS);
+                       if (REALIZED(w) && VISIBLE(w) && !OBSCURED(w))
+                               ewl_callback_call(w, EWL_CALLBACK_CONFIGURE);
+                       ewl_object_queued_remove(EWL_OBJECT(w),
+                                                EWL_FLAG_QUEUED_CPROCESS);
+               }
        }
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
@@ -722,7 +673,10 @@
                DRETURN(DLEVEL_STABLE);
 
        if (!ewl_object_flags_get(EWL_OBJECT(w), EWL_FLAG_PROPERTY_TOPLEVEL)) {
-               if (!w->parent || !REALIZED(w->parent))
+               Ewl_Object *o = EWL_OBJECT(w->parent);
+               if (!o|| (!ewl_object_queued_has(EWL_OBJECT(o),
+                                               EWL_FLAG_QUEUED_RSCHEDULED) &&
+                                       !REALIZED(o)))
                        DRETURN(DLEVEL_STABLE);
        }
 
@@ -771,7 +725,11 @@
        ecore_list_goto_first(realize_list);
        while ((w = ecore_list_remove_first(realize_list))) {
                if (VISIBLE(w) && !REALIZED(w)) {
+                       ewl_object_queued_add(EWL_OBJECT(w),
+                                             EWL_FLAG_QUEUED_RPROCESS);
                        ewl_widget_realize(EWL_WIDGET(w));
+                       ewl_object_queued_remove(EWL_OBJECT(w),
+                                                EWL_FLAG_QUEUED_RPROCESS);
                        ecore_list_prepend(child_add_list, w);
                }
        }
@@ -885,6 +843,11 @@
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+/**
+ * @param obj: evas to queue for destruction
+ * @return Returns no value.
+ * @brief Queues an evas to be destroyed at a later time.
+ */
 void
 ewl_evas_destroy(Evas *evas)
 {
@@ -896,6 +859,11 @@
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
+/**
+ * @param obj: evas object to queue for destruction
+ * @return Returns no value.
+ * @brief Queues an evas object to be destroyed at a later time.
+ */
 void
 ewl_evas_object_destroy(Evas_Object *obj)
 {
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_text.c,v
retrieving revision 1.46
retrieving revision 1.47
diff -u -3 -r1.46 -r1.47
--- ewl_text.c  4 Nov 2005 01:07:48 -0000       1.46
+++ ewl_text.c  13 Nov 2005 06:48:55 -0000      1.47
@@ -3,6 +3,8 @@
 #include "ewl_macros.h"
 #include "ewl_private.h"
 
+static Ewl_Text_Context *ewl_text_default_context = NULL;
+
 /* This counts how many deletes we have before trigger a condense operation
  * on the tree */
 #define EWL_TEXT_TREE_CONDENSE_COUNT  5
@@ -111,7 +113,9 @@
        }
 
        /* create the default context and stick it into the tree */
-       t->current_context = ewl_text_context_default_create(t);
+       if (!ewl_text_default_context)
+               ewl_text_default_context = ewl_text_context_default_create(t);
+       t->current_context = ewl_text_default_context;
        ewl_text_context_acquire(t->current_context);
 
        t->formatting->tx = t->current_context;
@@ -119,10 +123,10 @@
 
        ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_CONFIGURE, 
                                        ewl_text_cb_configure, NULL);
-       ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_REALIZE,
-                                       ewl_text_cb_realize, NULL);
-       ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_UNREALIZE,
-                                       ewl_text_cb_unrealize, NULL);
+       ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_REVEAL,
+                                       ewl_text_cb_reveal, NULL);
+       ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_OBSCURE,
+                                       ewl_text_cb_obscure, NULL);
        ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_SHOW,
                                        ewl_text_cb_show, NULL);
        ewl_callback_append(EWL_WIDGET(t), EWL_CALLBACK_HIDE,
@@ -377,8 +381,10 @@
                t->length = strlen(text);
                t->total_size = t->length + 1;
 
-               if (!t->current_context)
-                       t->current_context = ewl_text_context_default_create(t);
+               if (!t->current_context) {
+                       t->current_context = ewl_text_default_context;
+                       ewl_text_context_acquire(ewl_text_default_context);
+               }
 
                ewl_text_tree_text_context_insert(t->formatting, 
t->current_context, 
                                                                        idx, 
t->length);
@@ -386,8 +392,10 @@
        }
        else
        {
-               if (!t->current_context)
-                       t->current_context = ewl_text_context_default_create(t);
+               if (!t->current_context) {
+                       t->current_context = ewl_text_default_context;
+                       ewl_text_context_acquire(ewl_text_default_context);
+               }
 
                len = strlen(text);
                if ((t->length + len + 1) >= t->total_size)
@@ -753,8 +761,10 @@
        /* do we have a current context? */
        if (t->current_context)
                ctx = t->current_context;
-       else
-               ctx = ewl_text_context_default_create(t);
+       else {
+               ctx = ewl_text_default_context;
+               ewl_text_context_acquire(ctx);
+       }
 
        t->current_context = ewl_text_context_find(ctx, context_mask, 
tx_change);
        ewl_text_context_release(ctx);
@@ -2595,8 +2605,6 @@
        {
                evas_object_move(t->textblock, xx, yy);
                evas_object_resize(t->textblock, ww, hh);
-               evas_object_layer_set(t->textblock, 
-                                       ewl_widget_layer_sum_get(w));
 
                ewl_text_triggers_configure(t);
        }
@@ -2605,7 +2613,7 @@
 }
 
 void
-ewl_text_cb_realize(Ewl_Widget *w, void *ev __UNUSED__, void *data __UNUSED__)
+ewl_text_cb_reveal(Ewl_Widget *w, void *ev __UNUSED__, void *data __UNUSED__)
 {
        Ewl_Text *t;
        Ewl_Embed *emb;
@@ -2620,6 +2628,12 @@
 
        t = EWL_TEXT(w);
 
+       /* printf("Revealing text %p\n", w); */
+       if (t->textblock) {
+               ewl_print_warning();
+               DRETURN(DLEVEL_STABLE);
+       }
+
        /* find the embed so we know the evas */
        emb = ewl_embed_widget_find(w);
        if (!emb)
@@ -2627,7 +2641,8 @@
                DRETURN(DLEVEL_STABLE);
        }
 
-       ctx = ewl_text_context_default_create(t);
+       ctx = ewl_text_default_context;
+       ewl_text_context_acquire(ctx);
        fmt = ewl_text_format_get(ctx);
        ewl_text_context_release(ctx);
 
@@ -2637,28 +2652,41 @@
        FREE(fmt);
 
        /* create the textblock */
-       t->textblock = evas_object_textblock_add(emb->evas);
+       t->textblock = ewl_embed_object_request(emb, "textblock");
+       if (!t->textblock) {
+               t->textblock = evas_object_textblock_add(emb->evas);
+               /* printf("Created new textblock\n"); */
+       }
+
+       if (t->textblock) {
+               int sum;
 
-       st = evas_textblock_style_new();
-       evas_textblock_style_set(st, fmt2);
-       evas_object_textblock_style_set(t->textblock, st);
-       evas_textblock_style_free(st);
+               st = evas_textblock_style_new();
+               evas_textblock_style_set(st, fmt2);
+               evas_object_textblock_style_set(t->textblock, st);
+               evas_textblock_style_free(st);
 
-       FREE(fmt2);
+               FREE(fmt2);
 
-       if (w->fx_clip_box)
-               evas_object_clip_set(t->textblock, w->fx_clip_box);
+               sum = ewl_widget_layer_sum_get(w);
+               /* printf("Setting text layer %d\n", sum); */
+               evas_object_layer_set(t->textblock, sum + 1000);
+               if (w->fx_clip_box)
+                       evas_object_clip_set(t->textblock, w->fx_clip_box);
 
-       evas_object_pass_events_set(t->textblock, 1);
+               evas_object_pass_events_set(t->textblock, 1);
+
+               ewl_text_display(t);
+               evas_object_show(t->textblock);
+       }
 
-       ewl_text_display(t);
        ewl_text_triggers_realize(t);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
 void
-ewl_text_cb_unrealize(Ewl_Widget *w, void *ev __UNUSED__, 
+ewl_text_cb_obscure(Ewl_Widget *w, void *ev __UNUSED__, 
                                        void *data __UNUSED__)
 {
        Ewl_Text *t;
@@ -2669,11 +2697,16 @@
 
        t = EWL_TEXT(w);
 
-       evas_object_clip_unset(t->textblock);
+       /* printf("Obscuring text %p\n", w); */
+
+       if (t->textblock) {
+               Ewl_Embed *emb;
 
-       /* XXX this will need to change for obj cache */
-       evas_object_del(t->textblock);
-       t->textblock = NULL;
+               emb = ewl_embed_widget_find(w);
+               evas_object_textblock_clear(t->textblock);
+               ewl_embed_object_cache(emb, t->textblock);
+               t->textblock = NULL;
+       }
 
        ewl_text_triggers_unrealize(t);
 
@@ -2690,7 +2723,8 @@
        DCHECK_TYPE("w", w, "widget");
 
        t = EWL_TEXT(w);
-       evas_object_show(t->textblock);
+       if (t->textblock)
+               evas_object_show(t->textblock);
        ewl_text_triggers_show(t);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_text.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -3 -r1.19 -r1.20
--- ewl_text.h  4 Nov 2005 01:07:48 -0000       1.19
+++ ewl_text.h  13 Nov 2005 06:48:55 -0000      1.20
@@ -236,8 +236,8 @@
 void ewl_text_triggers_hide(Ewl_Text *t);
 
 void ewl_text_cb_configure(Ewl_Widget *w, void *ev, void *data);
-void ewl_text_cb_realize(Ewl_Widget *w, void *ev, void *data);
-void ewl_text_cb_unrealize(Ewl_Widget *w, void *ev, void *data);
+void ewl_text_cb_reveal(Ewl_Widget *w, void *ev, void *data);
+void ewl_text_cb_obscure(Ewl_Widget *w, void *ev, void *data);
 void ewl_text_cb_show(Ewl_Widget *w, void *ev, void *data);
 void ewl_text_cb_hide(Ewl_Widget *w, void *ev, void *data);
 void ewl_text_cb_destroy(Ewl_Widget *w, void *ev, void *data);
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_widget.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -3 -r1.35 -r1.36
--- ewl_widget.c        2 Nov 2005 06:35:02 -0000       1.35
+++ ewl_widget.c        13 Nov 2005 06:48:55 -0000      1.36
@@ -73,6 +73,9 @@
         */
        ewl_callback_append(w, EWL_CALLBACK_SHOW, ewl_widget_show_cb, NULL);
        ewl_callback_append(w, EWL_CALLBACK_HIDE, ewl_widget_hide_cb, NULL);
+       ewl_callback_append(w, EWL_CALLBACK_REVEAL, ewl_widget_reveal_cb, NULL);
+       ewl_callback_append(w, EWL_CALLBACK_OBSCURE, ewl_widget_obscure_cb,
+                               NULL);
        ewl_callback_append(w, EWL_CALLBACK_REALIZE, ewl_widget_realize_cb,
                                NULL);
        ewl_callback_append(w, EWL_CALLBACK_UNREALIZE, ewl_widget_unrealize_cb,
@@ -181,7 +184,8 @@
        if (REALIZED(w))
                DRETURN(DLEVEL_STABLE);
 
-       if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_RSCHEDULED))
+       if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_RSCHEDULED)
+                       && !ewl_object_queued_has(EWL_OBJECT(w), 
EWL_FLAG_QUEUED_RPROCESS))
                ewl_realize_cancel_request(w);
 
        /*
@@ -193,6 +197,7 @@
                ewl_callback_call(w, EWL_CALLBACK_REALIZE);
                ewl_object_visible_add(EWL_OBJECT(w),
                                        EWL_FLAG_VISIBLE_REALIZED);
+               ewl_widget_obscure(w);
        }
 
        ewl_widget_show(w);
@@ -240,6 +245,9 @@
        DCHECK_PARAM_PTR("w", w);
        DCHECK_TYPE("w", w, "widget");
 
+       if (!OBSCURED(w))
+               DRETURN(DLEVEL_STABLE);
+
        ewl_object_visible_remove(EWL_OBJECT(w), EWL_FLAG_VISIBLE_OBSCURED);
 
        emb = ewl_embed_widget_find(w);
@@ -257,20 +265,21 @@
  * @return Returns no value.
  * @brief Indicate a widget is obscured.
  */
-void
-ewl_widget_obscure(Ewl_Widget *w)
+void ewl_widget_obscure(Ewl_Widget *w)
 {
-       DENTER_FUNCTION(DLEVEL_STABLE);
-       DCHECK_PARAM_PTR("w", w);
-       DCHECK_TYPE("w", w, "widget");
+        DENTER_FUNCTION(DLEVEL_STABLE);
+        DCHECK_PARAM_PTR("w", w);
 
-       ewl_object_visible_add(EWL_OBJECT(w), EWL_FLAG_VISIBLE_OBSCURED);
+       if (OBSCURED(w))
+               DRETURN(DLEVEL_STABLE);
 
-       if (REALIZED(w) || ewl_object_queued_has(EWL_OBJECT(w),
-                               EWL_FLAG_QUEUED_RSCHEDULED))
-               ewl_callback_call(w, EWL_CALLBACK_OBSCURE);
+        ewl_object_visible_add(EWL_OBJECT(w), EWL_FLAG_VISIBLE_OBSCURED);
 
-       DLEAVE_FUNCTION(DLEVEL_STABLE);
+        if (REALIZED(w) || ewl_object_queued_has(EWL_OBJECT(w),
+                                EWL_FLAG_QUEUED_RSCHEDULED))
+                ewl_callback_call(w, EWL_CALLBACK_OBSCURE);
+
+        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
 
 /**
@@ -574,6 +583,40 @@
 
 /**
  * @param w: the widget to retrieve the full appearance key
+ * @param size: pointer to an int indicating the string length
+ * @return Returns a pointer to the full appearance path string on success, 
NULL on
+ * failure.
+ * @brief Retrieve the appearance path key of the widget
+ */
+static char *
+ewl_widget_appearance_path_size_get(Ewl_Widget *w, int *size)
+{
+       char *ret = NULL;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR_RET("w", w, NULL);
+       DCHECK_TYPE("w", w, "widget");
+
+       /*
+        * Allocate enough for the appearance plus a leading "/"
+        */
+       *size += (w->appearance ? strlen(w->appearance) : 0) + 1;
+       if (w->parent) {
+               ret = ewl_widget_appearance_path_size_get(w->parent, size);
+       }
+       else {
+               ret = NEW(char, *size + 1);
+       }
+
+       strcat(ret, "/");
+       if (w->appearance)
+               strcat(ret, w->appearance);
+
+       DRETURN_PTR(ret, DLEVEL_STABLE);
+}
+
+/**
+ * @param w: the widget to retrieve the full appearance key
  * @return Returns a pointer to the full appearance path string on success, 
NULL on
  * failure.
  * @brief Retrieve the appearance path key of the widget
@@ -581,25 +624,32 @@
 char *
 ewl_widget_appearance_path_get(Ewl_Widget * w)
 {
-       char *ret = NULL, *tmp;
-       int len;
+       char *ret = NULL;
+       int len = 0;
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR_RET("w", w, NULL);
        DCHECK_TYPE("w", w, "widget");
 
+       ret = ewl_widget_appearance_path_size_get(w, &len);
+
+       /*
        if (w->parent)
                tmp = ewl_widget_appearance_path_get(w->parent);
        else
                tmp = strdup("");
+               */
 
-       len = strlen(tmp) + 2; /* one for the / one for the \0 */
+        /* one for the / one for the \0 */
+       /*
+       len = strlen(tmp) + 2;
        len += (w->appearance ? strlen(w->appearance) : 0);
 
        ret = malloc(sizeof(char) * len);
        snprintf(ret, len, "%s/%s", tmp, 
                        (w->appearance ? w->appearance : ""));
        FREE(tmp);
+       */
 
        DRETURN_PTR(ret, DLEVEL_STABLE);
 }
@@ -919,16 +969,11 @@
        DCHECK_PARAM_PTR_RET("w", w, 0);
        DCHECK_TYPE_RET("w", w, "widget", 0);
 
-       while (!REALIZED(w) && w->parent) {
+       while (w) {
                sum += LAYER(w);
                w = w->parent;
        }
 
-       if (REALIZED(w) && w->fx_clip_box)
-               sum += evas_object_layer_get(w->fx_clip_box);
-       else
-               sum += LAYER(w);
-
        DRETURN_INT(sum, DLEVEL_STABLE);
 }
 
@@ -1270,6 +1315,65 @@
        DRETURN_INT(FALSE, DLEVEL_STABLE);
 }
 
+unsigned int
+ewl_widget_onscreen_is(Ewl_Widget *w)
+{
+       int onscreen = FALSE;
+       Ewl_Embed *emb;
+
+       DCHECK_PARAM_PTR_RET("w", w, 0);
+       DCHECK_TYPE("w", w, "widget");
+
+       /*
+        * Until an embed is present, the widget is off screen by default.
+        */
+       emb = ewl_embed_widget_find(w);
+       if (emb) {
+               onscreen = TRUE;
+       }
+
+       /*
+        * We don't need to configure if it's outside the viewable space in
+        * it's parent widget. This does not recurse upwards to determine
+        * ancestor clipped areas, but does obscure items that are outside the
+        * top level container.
+        */
+       if (w->parent) {
+               int x, y;
+               int width, height;
+               Ewl_Widget *p = w->parent;
+
+               ewl_object_current_geometry_get(EWL_OBJECT(w), &x, &y, &width,
+                               &height);
+
+               if ((x + width) < CURRENT_X(p))
+                       onscreen = FALSE;
+
+               if (x > (CURRENT_X(p) + CURRENT_W(p)))
+                       onscreen = FALSE;
+
+               if ((y + height) < CURRENT_Y(p))
+                       onscreen = FALSE;
+
+               if (y > (CURRENT_Y(p) + CURRENT_H(p)))
+                       onscreen = FALSE;
+
+               if ((x + width) < CURRENT_X(emb))
+                       onscreen = FALSE;
+
+               if (x > (CURRENT_X(emb) + CURRENT_W(emb)))
+                       onscreen = FALSE;
+
+               if ((y + height) < CURRENT_Y(emb))
+                       onscreen = FALSE;
+
+               if (y > (CURRENT_Y(emb) + CURRENT_H(emb)))
+                       onscreen = FALSE;
+       }
+
+       return onscreen;
+}
+
 /**
  * @param w: the widget to mark as unclipped
  * @param val: the state of the clipping flag
@@ -1396,7 +1500,7 @@
        color->a = a;
        ewl_attach_color_set(w, color);
 
-       if (REALIZED(w))
+       if (w->fx_clip_box)
                evas_object_color_set(w->fx_clip_box, r, g, b, a);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
@@ -1534,17 +1638,11 @@
        DCHECK_PARAM_PTR("w", w);
        DCHECK_TYPE("w", w, "widget");
 
-       /*
-        * Hide the visible evas objects.
-        */
-       if (w->fx_clip_box)
-               evas_object_hide(w->fx_clip_box);
-       if (w->theme_object)
-               evas_object_hide(w->theme_object);
-
        if (ewl_object_queued_has(EWL_OBJECT(w), EWL_FLAG_QUEUED_RSCHEDULED))
                ewl_realize_cancel_request(w);
 
+       ewl_widget_obscure(w);
+
        /*
         * Notify parent of hidden state.
         */
@@ -1559,57 +1657,210 @@
 }
 
 /*
- * Perform the basic operations necessary for realizing a widget
+ * Request a new set of evas objects now that we're back on screen
  */
-void
-ewl_widget_realize_cb(Ewl_Widget * w, void *ev_data __UNUSED__,
-                       void *user_data __UNUSED__)
+void ewl_widget_reveal_cb(Ewl_Widget * w, void *ev_data __UNUSED__,
+                                          void *user_data __UNUSED__)
 {
-       int l = 0, r = 0, t = 0, b = 0;
-       int i_l = 0, i_r = 0, i_t = 0, i_b = 0;
-       int p_l = 0, p_r = 0, p_t = 0, p_b = 0;
-       char *i = NULL;
-       char *group = NULL;
-       Evas_Coord width, height;
-       Ewl_Embed *emb = NULL;
-       Ewl_Container *pc = NULL;
+       int sum;
+       Ewl_Embed *emb;
+
+       /* printf("Revealing %s\n", w->appearance); */
 
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("w", w);
-       DCHECK_TYPE("w", w, "widget");
 
        emb = ewl_embed_widget_find(w);
+       if (!emb || !emb->evas)
+               DRETURN(DLEVEL_STABLE);
 
        /*
-        * Create the fx clip box where special fx can be drawn to affect the
-        * entire contents of the widget
+        * No object allocated yet for this widget
         */
-       if (!ewl_object_flags_get(EWL_OBJECT(w), EWL_FLAG_VISIBLE_NOCLIP)) {
-               w->fx_clip_box = evas_object_rectangle_add(emb->evas);
+       if (!w->theme_object && w->bit_path && w->bit_group) {
+               /*
+                * Attempt to load a cached object first, fallback to adding a
+                * new one.
+                 */
+               w->theme_object = ewl_embed_object_request(emb, "edje");
+               if (!w->theme_object) {
+                       w->theme_object = edje_object_add(emb->evas);
+                       evas_object_repeat_events_set(w->theme_object, 1);
+                       /*
+                       printf("Created edje %d: %s\n", ++edjes,
+                                       w->bit_group);
+                                       */
+               }
+
+               /*
+                * Attempt to load the theme object
+                */
+               evas_object_repeat_events_set(w->theme_object, 1);
+               edje_object_file_set(w->theme_object, w->bit_path,
+                               w->bit_group);
+               /*
+                * If the file failed to load, destroy the unnecessary evas
+                * object.
+                */
+               if (edje_object_load_error_get(w->theme_object)) {
+                       evas_object_del(w->theme_object);
+                       w->theme_object = NULL;
+               }
+
+               /*
+                * Set the state of the theme object
+                */
+               if (w->bit_state)
+                       ewl_widget_state_set(w, w->bit_state);
+
+               if (ewl_object_state_has(EWL_OBJECT(w),
+                                       EWL_FLAG_STATE_DISABLED))
+                       ewl_widget_state_set(w, "disabled");
+
+               /*
+                * Apply any text overrides
+                * FIXME: These should probably be ported to an array rather
+                * than a full hash.
+                */
+               if (w->theme_object && w->theme_text) {
+                      char *key;
+                      Ecore_List *keys = ecore_hash_keys(w->theme_text);
+
+                      ecore_list_goto_first(keys);
+                      while ((key = (char *)ecore_list_next(keys))) {
+                              char *value = ecore_hash_get(w->theme_text, key);
+                              /* printf("Setting text %s: %s\n", key, value); 
*/
+                              ewl_widget_appearance_part_text_apply(w, key, 
value);
+                      }
+                      ecore_list_destroy(keys);
+              }
+       }
+
+       /*
+        * Create clip box if necessary
+        */
+       if (!w->fx_clip_box && !ewl_object_flags_get(EWL_OBJECT(w), 
EWL_FLAG_VISIBLE_NOCLIP)) {
+               w->fx_clip_box = ewl_embed_object_request(emb, "rectangle");
+               if (!w->fx_clip_box) {
+                       w->fx_clip_box = evas_object_rectangle_add(emb->evas);
+                       /* printf("Created rectangle %d\n", ++rects); */
+               }
                evas_object_pass_events_set(w->fx_clip_box, TRUE);
        }
 
+       if (w->theme_object && w->fx_clip_box)
+               evas_object_clip_set(w->theme_object, w->fx_clip_box);
+
+       /*
+        * Setup the appropriate clippings.
+        */
+       if (w->parent && EWL_CONTAINER(w->parent)->clip_box && w->fx_clip_box) {
+               evas_object_clip_set(w->fx_clip_box,
+                               EWL_CONTAINER(w->parent)->clip_box);
+               evas_object_show(EWL_CONTAINER(w->parent)->clip_box);
+       }
+
+       /*
+        * Set the layer of the clip box and theme object
+        */
+       sum = ewl_widget_layer_sum_get(w);
+       if (sum > ewl_embed_max_layer_get(emb))
+               ewl_embed_max_layer_set(emb, sum);
+       if (w->theme_object) {
+               evas_object_layer_set(w->theme_object, sum);
+               /* printf("Setting layer %d on %s\n", sum, w->appearance); */
+       }
+
        if (w->fx_clip_box) {
-               int sum;
-               int r, g, b, a;
+               Ewl_Color_Set *color;
 
-               sum = ewl_widget_layer_sum_get(w);
-               if (sum > ewl_embed_max_layer_get(emb))
-                       ewl_embed_max_layer_set(emb, sum);
                evas_object_layer_set(w->fx_clip_box, sum);
 
-               r = g = b = a = 255;
-               ewl_widget_color_get(w, &r, &g, &b, &a);
-               evas_object_color_set(w->fx_clip_box, r, g, b, a);
+               color = ewl_attach_color_get(w);
+               if (color)
+                       evas_object_color_set(w->fx_clip_box, color->r,
+                                               color->g, color->b, color->a);
        }
 
+       /*
+        * Show the theme and clip box if widget is visible
+        */
+       if (VISIBLE(w)) {
+               evas_object_show(w->fx_clip_box);
+               evas_object_show(w->theme_object);
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+/*
+ * Give up unnecessary objects when we're offscreen
+ */
+void ewl_widget_obscure_cb(Ewl_Widget * w, void *ev_data __UNUSED__,
+                                           void *user_data __UNUSED__)
+{
+       Ewl_Embed *emb;
+       Ewl_Container *pc;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+
+       /* printf("Obscuring %s\n", w->appearance); */
+
+       emb = ewl_embed_widget_find(w);
+       if (!emb)
+               DRETURN(DLEVEL_STABLE);
+
        pc = EWL_CONTAINER(w->parent);
 
        /*
-        * Clip the fx_clip_box to the parent clip_box.
+        * Remove all properties on the edje and hand it back to the embed for
+        * caching.
         */
-       if (pc && pc->clip_box && w->fx_clip_box)
-               evas_object_clip_set(w->fx_clip_box, pc->clip_box);
+       if (w->theme_object) {
+               ewl_embed_object_cache(emb, w->theme_object);
+               w->theme_object = NULL;
+       }
+
+       /*
+        * Repeat the process for the clip rect, but also hide the parent clip
+        * box if there are no visible children. If we don't hide it, there
+        * will be a white rectangle displayed.
+        */
+       if (w->fx_clip_box) {
+               if (pc && pc->clip_box) {
+                       if (!evas_object_clipees_get(pc->clip_box))
+                               evas_object_hide(pc->clip_box);
+               }
+               evas_object_hide(w->fx_clip_box);
+               evas_object_clip_unset(w->theme_object);
+               ewl_embed_object_cache(emb, w->fx_clip_box);
+               w->fx_clip_box = NULL;
+       }
+
+       DLEAVE_FUNCTION(DLEVEL_STABLE);
+}
+
+
+/*
+ * Perform the basic operations necessary for realizing a widget
+ */
+void
+ewl_widget_realize_cb(Ewl_Widget * w, void *ev_data __UNUSED__,
+                       void *user_data __UNUSED__)
+{
+       int l = 0, r = 0, t = 0, b = 0;
+       int i_l = 0, i_r = 0, i_t = 0, i_b = 0;
+       int p_l = 0, p_r = 0, p_t = 0, p_b = 0;
+       char *i = NULL;
+       char *group = NULL;
+       Evas_Coord width, height;
+       Ewl_Embed *emb = NULL;
+
+       DENTER_FUNCTION(DLEVEL_STABLE);
+       DCHECK_PARAM_PTR("w", w);
+       DCHECK_TYPE("w", w, "widget");
+
+       emb = ewl_embed_widget_find(w);
 
        /*
         * Retrieve the path to the theme file that will be loaded
@@ -1619,31 +1870,28 @@
        i = ewl_theme_image_get(w, "file");
        group = ewl_theme_data_str_get(w, "group");
 
-       if (group) {
-               emb = ewl_embed_widget_find(w);
-               if (!emb)
-                       DRETURN(DLEVEL_STABLE);
+       if (i)
+               w->bit_path = ecore_string_instance(i);
 
-               /*
-                * Load the theme object
-                */
-               w->theme_object = edje_object_add(emb->evas);
-               evas_object_repeat_events_set(w->theme_object, 1);
-               if (!edje_object_file_set(w->theme_object, i, group)) {
-                       evas_object_del(w->theme_object);
-                       w->theme_object = NULL;
-               }
-               FREE(group);
-       }
+       if (group)
+               w->bit_group = ecore_string_instance(group);
 
        IF_FREE(i);
+       IF_FREE(group);
+
+       /*
+        * Reveal is done in this part of the callback to avoid duplicate code
+        * for creating the evas objects. Must be done in the callback so that
+        * prepended callbacks in the embed can create the evas, windows,
+        * etc.
+        */
+       ewl_object_visible_add(EWL_OBJECT(w), EWL_FLAG_VISIBLE_OBSCURED);
+       ewl_widget_reveal(w);
 
        /*
         * Set up the theme object on the widgets evas
         */
        if (w->theme_object) {
-               if (w->bit_state)
-                       ewl_widget_state_set(w, w->bit_state);
 
                ewl_widget_theme_insets_get(w, &i_l, &i_r, &i_t, &i_b);
                ewl_widget_theme_padding_get(w, &p_l, &p_r, &p_t, &p_b);
@@ -1674,15 +1922,6 @@
                        p_b = b;
 
                /*
-                * Determine the evas layer for the objects and set clipping.
-                */
-               evas_object_layer_set(w->theme_object,
-                               ewl_widget_layer_sum_get(w));
-               if (w->fx_clip_box)
-                       evas_object_clip_set(w->theme_object, w->fx_clip_box);
-               evas_object_show(w->theme_object);
-
-               /*
                 * Assign the relevant insets and padding.
                 */
                ewl_object_insets_set(EWL_OBJECT(w), i_l, i_r, i_t, i_b);
@@ -1693,10 +1932,6 @@
                ewl_object_x_request(EWL_OBJECT(w), i_l);
                ewl_object_y_request(EWL_OBJECT(w), i_t);
 
-               if (ewl_object_state_has(EWL_OBJECT(w),
-                                       EWL_FLAG_STATE_DISABLED))
-                       ewl_widget_state_set(w, "disabled");
-
                /*
                 * Propagate minimum sizes from the bit theme to the widget.
                 */
@@ -1730,30 +1965,8 @@
                                && i_t >= EWL_OBJECT_MIN_SIZE
                                && i_t < EWL_OBJECT_MAX_SIZE)
                        ewl_object_maximum_h_set(EWL_OBJECT(w), i_t);
-
-               /*
-                * Apply any text overrides
-                * FIXME: These should probably be ported to an array rather
-                * than a full hash.
-                */
-               if (w->theme_text) {
-                       char *key;
-                       Ecore_List *keys = ecore_hash_keys(w->theme_text);
-
-                       ecore_list_goto_first(keys);
-                       while ((key = (char *)ecore_list_next(keys))) {
-                               char *value = ecore_hash_get(w->theme_text, 
key);
-                               ewl_widget_appearance_part_text_apply(w, key,
-                                                                       value);
-                       }
-                       ecore_list_destroy(keys);
-               }
-
        }
 
-       ewl_object_visible_add(EWL_OBJECT(w), EWL_FLAG_VISIBLE_REALIZED);
-       ewl_widget_configure(w);
-
        DRETURN(DLEVEL_STABLE);
 }
 
@@ -1764,32 +1977,15 @@
 ewl_widget_unrealize_cb(Ewl_Widget * w, void *ev_data __UNUSED__,
                        void *user_data __UNUSED__)
 {
-       Ewl_Embed *emb;
-
        DENTER_FUNCTION(DLEVEL_STABLE);
        DCHECK_PARAM_PTR("w", w);
        DCHECK_TYPE("w", w, "widget");
 
-       /*
-        * First find it's parent embed so we can destroy the evas objects.
-        */
-       emb = ewl_embed_widget_find(w);
-
-       /*
-        * Destroy the clip box used for fx.
-        */
-       if (w->fx_clip_box) {
-               ewl_evas_object_destroy(w->fx_clip_box);
-               w->fx_clip_box = NULL;
-       }
-
-       /*
-        * Destroy old image (if any) 
-        */
-       if (w->theme_object) {
-               ewl_evas_object_destroy(w->theme_object);
-               w->theme_object = NULL;
-       }
+        /*
+         * We can just use an obscure since it's a very similar operation.
+         * Keep this event for widgets that keep extra visual data around.
+         */
+        ewl_widget_obscure(w);
 
        DLEAVE_FUNCTION(DLEVEL_STABLE);
 }
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewl/src/lib/ewl_widget.h,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -3 -r1.19 -r1.20
--- ewl_widget.h        4 Nov 2005 04:34:48 -0000       1.19
+++ ewl_widget.h        13 Nov 2005 06:48:55 -0000      1.20
@@ -70,10 +70,12 @@
        Evas_Object     *fx_clip_box;  /**< Clipping rectangle of widget */
 
        Evas_Object     *theme_object; /**< Appearance shown on canvas */
-       char            *bit_state;    /**< State of the appaarance */
+       char            *bit_path;     /**< Path to the file for loading */
+       char            *bit_group;    /**< Group in theme to use */
+       char            *bit_state;    /**< State of the appearance */
        char            *appearance;   /**< Key to lookup appearance in theme */
        char            *inheritance;  /**< Inheritance of path widget */
-       int              layer; /**< Current layer of widget on canvas */
+       int              layer;        /**< Current layer of widget on canvas */
 
        Ecore_Hash       *theme; /**< Overriding theme settings of this widget 
*/
        Ecore_Hash       *theme_text; /**< Overriding text in widgets theme */
@@ -116,13 +118,13 @@
 void            ewl_widget_unrealize(Ewl_Widget * w);
 
 /*
- *  * Mark the widget to be revealed.
- *   */
+ * Mark the widget to be revealed.
+ */
 void            ewl_widget_reveal(Ewl_Widget *w);
 
 /*      
- *       * Mark the widget to be obscured.    
- *        */     
+ * Mark the widget to be obscured.    
+ */     
 void            ewl_widget_obscure(Ewl_Widget *w);
 
 /*
@@ -203,6 +205,8 @@
 
 unsigned int    ewl_widget_type_is(Ewl_Widget *widget, char *type);
 
+unsigned int    ewl_widget_onscreen_is(Ewl_Widget *widget);
+
 /*
  * Change the parent of a widget.
  */
@@ -266,6 +270,10 @@
                        void *user_data);
 void ewl_widget_hide_cb(Ewl_Widget * w, void *ev_data,
                        void *user_data);
+void ewl_widget_reveal_cb(Ewl_Widget * w, void *ev_data,
+                         void *user_data);
+void ewl_widget_obscure_cb(Ewl_Widget * w, void *ev_data,
+                          void *user_data);
 void ewl_widget_realize_cb(Ewl_Widget * w, void *ev_data,
                           void *user_data);
 void ewl_widget_unrealize_cb(Ewl_Widget * w, void *ev_data,




-------------------------------------------------------
SF.Net email is sponsored by:
Tame your development challenges with Apache's Geronimo App Server. Download
it for free - -and be entered to win a 42" plasma tv or your very own
Sony(tm)PSP.  Click here to play: http://sourceforge.net/geronimo.php
_______________________________________________
enlightenment-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs

Reply via email to