Revision: 3594
          http://vexi.svn.sourceforge.net/vexi/?rev=3594&view=rev
Author:   clrg
Date:     2009-08-10 11:24:48 +0000 (Mon, 10 Aug 2009)

Log Message:
-----------
Box clean up + Leave related fixes
- Leave not called when unassigned from parent
- Leave not called when undisplayed
- fixes inconsistent widget states caused by clear(MOUSEINSIDE) without calling 
Leave
- need to implement MOUSEINSIDE/Enter checking in place()
- other clean up / comments

Modified Paths:
--------------
    trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp

Modified: trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp  2009-08-10 10:32:26 UTC 
(rev 3593)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp  2009-08-10 11:24:48 UTC 
(rev 3594)
@@ -339,7 +339,7 @@
     private final void dirtyInPlace(boolean clean) { if (clean) { dirty(); 
clear(PLACE_CLEAN); } }
     private final void dirty() { dirty(0, 0, width, height); }
     private final void dirty(int x, int y, int w, int h) {
-        for(Box cur = this; cur != null; cur = cur.parent) {
+        for (Box cur = this; cur != null; cur = cur.parent) {
             if (!cur.test(DISPLAY)) return;
             x = max(x, 0);
             y = max(y, 0);
@@ -348,10 +348,13 @@
             if (w <= 0 || h <= 0) return;
             // get around sub-sampling of enlarged textures
             if (cur.texture != null && !cur.test(TILE_IMAGE)) {
-                // FIXME: inefficient but otherwise the consistency of
+                // REMARK: inefficient but otherwise the consistency of
                 // translating enlarged pixels to on-screen coordinates
                 // can not be guarranteed as it depends upon first
                 // rendering the image at the full size of its box
+                // FIXME: this is the wrong place to do this - should
+                // prerender enlarged image at time of render and then
+                // just paint the relevant part of the enlarged image
                 x = 0; y = 0; w = cur.width; h = cur.height;
             }
             // x and y have a different meaning on the root box
@@ -527,7 +530,7 @@
         
         //#repeat width/height WIDTH/HEIGHT
         if (test(CLIP)) {
-            if ( newwidth < maxwidth && newwidth < minwidth)
+            if (newwidth < maxwidth && newwidth < minwidth)
                 set(HAS_WIDTH_SLACK);
             else clear(HAS_WIDTH_SLACK);
         } else {
@@ -996,9 +999,9 @@
             throw new JSExn("Attempt to set minwidth to a value outside the 
range 0-"+MAX_DIMENSION);
         if (firetraps && test(MINWIDTH_TRAP)) {
             Trap t = wtrap(SC_minwidth);
-            // FIXME: investigate this
-            //if (t==null && test(MINWIDTH_TRAP))
-            //    System.err.println("Should not happen, MINWIDTH_TRAP set and 
t==null");
+            // FIXME: verify / investigate this or delete it if not reported
+            if (t==null && test(MINWIDTH_TRAP))
+                Log.uWarn(this, "Should not happen, MINWIDTH_TRAP set and 
t==null");
             if (t!=null) {
                 this.minwidth = JSU.toInt(Main.SCHEDULER.runBeforePut(t, 
JSU.N(minwidth)));
                 Main.SCHEDULER.runAfterPut(null);
@@ -1019,9 +1022,9 @@
             throw new JSExn("Attempt to set maxwidth to a value outside the 
range 0-"+MAX_DIMENSION);
         if (firetraps && test(MAXWIDTH_TRAP)) {
             Trap t = wtrap(SC_maxwidth);
-            // FIXME: investigate this
-            //if (t==null && test(MAXWIDTH_TRAP))
-            //    System.err.println("Should not happen, MAXWIDTH_TRAP set and 
t==null");
+            // FIXME: verify / investigate this or delete it if not reported
+            if (t==null && test(MAXWIDTH_TRAP))
+                Log.uWarn(this, "Should not happen, MAXWIDTH_TRAP set and 
t==null");
             if (t!=null) {
                 this.maxwidth = JSU.toInt(Main.SCHEDULER.runBeforePut(t, 
JSU.N(maxwidth)));
                 Main.SCHEDULER.runAfterPut(null);
@@ -1121,10 +1124,14 @@
 
     /** clear flag MOUSEINSIDE on self and descendents and fire Leave traps */
     private final void propagateLeave() throws JSExn {
-        clear(MOUSEINSIDE);
+        if (!test(MOUSEINSIDE)) return;
         int i = treeSize()-1;
         for (Box b = getChild(i); b != null; b = getChild(--i))
-            if (b.test(MOUSEINSIDE)) b.propagateLeave();
+            b.propagateLeave();
+        // REMARK: clear after calling leave on children because
+        // they may throw an exception which would leave this box
+        // in an inconsistent state (!mouse.inside but no Leave)
+        clear(MOUSEINSIDE);
         if (test(LEAVE_TRAP)) justTriggerTraps(SC_Leave, JSU.T);
     }
 
@@ -1139,15 +1146,15 @@
         // start with pre-event _Move which preceeds Enter/Leave
         if (test(_MOVE_TRAP)) {
             if (Interpreter.CASCADE_PREVENTED == justTriggerTraps(SC__Move, 
JSU.T)) {
-                // _Move cascade prevented induces Leave
-                if (test(MOUSEINSIDE)) propagateLeave();
+                // _Move cascade prevention induces Leave
+                propagateLeave();
                 // propagate cascade prevention
                 return true;
             }
         }
         
         // REMARK: anything from here on in is a partial interruption relative
-        // to the this box so we can not call propagateLeave directly upon it
+        // to this box so we can not call propagateLeave() directly upon it
         
         int i;
         boolean interrupted = false;
@@ -1157,8 +1164,9 @@
                 int b_mx = mousex-getXInParent(b);
                 int b_my = mousey-getYInParent(b);
                 if (!interrupted && b.inside(b_mx, b_my)) {
-                    if (b.propagateMove(b_mx, b_my)) interrupted = true;
-                } else if (b.test(MOUSEINSIDE)) b.propagateLeave();
+                    if (b.propagateMove(b_mx, b_my))
+                        interrupted = true;
+                } else b.propagateLeave();
             }
         
         // packed layout - siblings can not interrupt each other
@@ -1166,9 +1174,10 @@
             for (Box b = getChild(i=0); b != null; b = getChild(++i)) {
                 int b_mx = mousex-b.x;
                 int b_my = mousey-b.y;
-                if (!interrupted && b.inside(b_mx, b_my)) {
-                    if (b.propagateMove(b_mx, b_my)) interrupted = true;
-                } else if (b.test(MOUSEINSIDE)) b.propagateLeave();
+                if (b.inside(b_mx, b_my)) {
+                    if (b.propagateMove(b_mx, b_my))
+                        interrupted = true;
+                } else b.propagateLeave();
             }
         }
 
@@ -1277,18 +1286,18 @@
     private class Mouse extends JS.Immutable implements JS.Cloneable {
         public JS get(JS key) throws JSExn {
             //#switch (JSU.toString(key))
-               /*...@page(varname=mouse,humanname=Mouse Object)
-                * <p>The Mouse Object, accessed via the Box.mouse property, is 
immutable - that is you
-                * may not modify or add properties to this object.  However 
traps can be placed upon
-                * the object's properties.</p>
-                * 
-                * <p>Note that every time you access the Box.mouse property, 
it creates a different 
-                * object. </p>
-                * */
-               /* <em>Read only</em></span> property representing whether the 
mouse cursor is within
-                * the bounds of the owning box.
-                * 
-                * @type(Boolean) */
+            /*...@page(varname=mouse,humanname=Mouse Object)
+             * <p>The Mouse Object, accessed via the Box.mouse property, is 
immutable - that is you
+             * may not modify or add properties to this object.  However traps 
can be placed upon
+             * the object's properties.</p>
+             * 
+             * <p>Note that every time you access the Box.mouse property, it 
creates a different 
+             * object. </p>
+             * */
+            /* <em>Read only</em></span> property representing whether the 
mouse cursor is within
+             * the bounds of the owning box.
+             * 
+             * @type(Boolean) */
             case "inside": return JSU.B(test(MOUSEINSIDE) && isVisible());
             /* <em>Read only</em></span> property representing the mouse's 
current x-position/y-position
              * relative to the owning box.
@@ -1305,32 +1314,30 @@
     
     /** the distance between two boxes top-left corners */
     private class DistanceTo extends JS.Immutable implements JS.Cloneable {
-
-       
         private Box from;
         private Box to;
         DistanceTo(Box from, Box to) { this.from = from; this.to = to; }
         public JS get(JS key) throws JSExn {
             //#switch (JSU.toString(key))
-               /*...@page(varname=distanceto,humanname=DistanceTo Object)
-                * <p>The DistanceTo Object, returned via the 
Box.distanceto(Box) function, is mostly
-                * immutable - that is you may not modify or add properties to 
this object, with the
-                * exception of the properties 'from' and 'to'.  However traps 
can be placed upon the
-                * object's properties.</p>
-                * 
-                * <p>Note that every time you use the Box.distanceto(Box) 
function, it creates a
-                * different object. </p>
-                * */
-               /* The originating box. @type(Box)  */
+            /*...@page(varname=distanceto,humanname=DistanceTo Object)
+             * <p>The DistanceTo Object, returned via the Box.distanceto(Box) 
function, is mostly
+             * immutable - that is you may not modify or add properties to 
this object, with the
+             * exception of the properties 'from' and 'to'.  However traps can 
be placed upon the
+             * object's properties.</p>
+             * 
+             * <p>Note that every time you use the Box.distanceto(Box) 
function, it creates a
+             * different object. </p>
+             * */
+            /* The originating box. @type(Box)  */
             case "from": return from;
             /* The target box. @type(Box) */
             case "to": return to;
             /* <em>Read only</em> property representing the horizontal 
distance between target
-             * box\x92s (0,0) coordinate and the originating box\x92s (0,0) 
coordinate. 
+             * box�s (0,0) coordinate and the originating box�s (0,0) 
coordinate. 
              * @type(Number) */
             case "x": return JSU.N(localToGlobalX(to, 0) - 
localToGlobalX(from, 0));
             /* <em>Read only</em> property representing the vertical  distance 
between target
-             * box\x92s (0,0) coordinate and the originating box\x92s (0,0) 
coordinate. 
+             * box�s (0,0) coordinate and the originating box�s (0,0) 
coordinate. 
              * @type(Number) */
             case "y": return JSU.N(localToGlobalY(to, 0) - 
localToGlobalY(from, 0));
             //#end
@@ -1375,9 +1382,13 @@
                     }
                 case "indexof":
                     try {
+                        // FIXME: test for numchildren trap on redirects
                         Box b = (Box)args[0];
-                        if (b.parent != this)
-                            return (redirect==null || redirect==this) ? 
JSU.N(-1) : redirect.callMethod(null, method, args);
+                        Box p = this;
+                        while (b.parent != p) {
+                            if (p.redirect==null || p.redirect==p) return 
JSU.N(-1);
+                            p = p.redirect;
+                        }
                         return JSU.N(b.getIndexInParent());
                     } catch (ClassCastException cce) {
                         throw new JSExn("Cannot call Box."+method+"() with 
non-box argument");
@@ -1442,21 +1453,21 @@
          * */
         
/*****************************************************************************************/
         /*...@section(Rendering) The rendering properties affect what the box 
looks like visually.*/
-           case "fill": if (texture == null) return 
JSU.S(Color.colorToString(fillcolor)); return texture.stream;
-           /* <p>When an object is written to this property, its stream is 
read using the 
-            * <a href="http://www.freetype.org/"; target="_top">freetype2 
library</a>, and the
-            * resulting font is used to render the box's text.</p>
-            * 
-            * @type(Stream)
-            * @initial_value(vexi.ui.font.vera)
-            * @nofollow */
-           case "font": return text.font.stream;
-           /* <p>The size (in points) to render the text.</p>
-            * 
-            * @type(Number)
-            * @initial_value(10)
-            * */
-           case "fontsize": return Text.sizeToJS(text.pointsize);
+        case "fill": if (texture == null) return 
JSU.S(Color.colorToString(fillcolor)); return texture.stream;
+        /* <p>When an object is written to this property, its stream is read 
using the 
+         * <a href="http://www.freetype.org/"; target="_top">freetype2 
library</a>, and the
+         * resulting font is used to render the box's text.</p>
+         * 
+         * @type(Stream)
+         * @initial_value(vexi.ui.font.vera)
+         * @nofollow */
+        case "font": return text.font.stream;
+        /* <p>The size (in points) to render the text.</p>
+         * 
+         * @type(Number)
+         * @initial_value(10)
+         * */
+        case "fontsize": return Text.sizeToJS(text.pointsize);
         /* 
          * The text of a box. Visually null renders the same as the text to "" 
(i.e as nothing).
          * 
@@ -1949,6 +1960,7 @@
                     // force dirty in case parent size/position do not change
                     dirty();
                     clear(DISPLAY);
+                    propagateLeave();
                 }
                 // fire post-cascade visible traps
                 if (trapchain!=null) trapchain.finishTraps();
@@ -2339,8 +2351,8 @@
         if (newparent != null) {
             if (i<0) throw new JSExn("Illegal attempt to set the parent of a 
box");
         }
-        // FIXME handle Enter/Leave better
-        clear(MOUSEINSIDE);
+        // FIXME: test for Enter (but put where? in place()?)
+        propagateLeave();
         final boolean wasvisible = isVisible();
         final JS oldsurface = getSurfaceObject(oldparent);
         final JS newsurface = getSurfaceObject(newparent);
@@ -2380,8 +2392,8 @@
     private void put(int i, JS value) throws JSExn{ put(i,value,true,true); }
     
     /**  
-     * @param hasNewParent - if a child has a new parent and a previous parent 
then
-     * it is being moved from the old to the new. In this case we only want to
+     * @param fireTrapsOnRemove - if a child has a new parent and a previous 
parent
+     * then it is being moved from the old to the new. In this case we only 
want to
      * fire visible,surface,enter/leave traps once so it is not the same as 
      * removing and then adding in discrete steps.
      * 
@@ -2492,5 +2504,5 @@
     // JSArrayLike
     public JS getElement(int i) throws JSExn { return get(i); }
     public JS[] toArray() throws JSExn { throw new JSExn("Cannot convert box 
to an array"); }
-    public int length() throws JSExn{ return 
JSU.toInt(getAndTriggerTraps(SC_numchildren)); }
+    public int length() throws JSExn { return 
JSU.toInt(getAndTriggerTraps(SC_numchildren)); }
 }


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to