Revision: 3954
          http://vexi.svn.sourceforge.net/vexi/?rev=3954&view=rev
Author:   clrg
Date:     2010-10-29 23:57:25 +0000 (Fri, 29 Oct 2010)

Log Message:
-----------
Fully fix Enter/Leave when Move is blocked (previous implementation wasn't 
bullet proof)
- also adds a test case

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

Added Paths:
-----------
    
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/lib/
    
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/lib/moveBlocked_template.t
    
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/moveBlocked.t

Modified: branches/vexi3_old_build/core/org.vexi.core/src/org/vexi/core/Box.jpp
===================================================================
--- branches/vexi3_old_build/core/org.vexi.core/src/org/vexi/core/Box.jpp       
2010-10-27 22:48:22 UTC (rev 3953)
+++ branches/vexi3_old_build/core/org.vexi.core/src/org/vexi/core/Box.jpp       
2010-10-29 23:57:25 UTC (rev 3954)
@@ -1373,11 +1373,14 @@
         // they may throw an exception which would leave this box
         // in an inconsistent state (!mouse.inside but no Leave)
         clear(MOUSEINSIDE);
-        if (!test(MOUSEINSIDE_BLOCKED) && test(LEAVE_TRAP)) {
+        // only fire Leave if not previously blocked; Leave event
+        // should always come only once Enter has been triggered
+        if (test(MOUSEINSIDE_BLOCKED)) {
             clear(MOUSEINSIDE_BLOCKED);
-            justTriggerTraps(SC_Leave, JSU.T);
         } else {
-            clear(MOUSEINSIDE_BLOCKED);
+            if (test(LEAVE_TRAP)) {
+                justTriggerTraps(SC_Leave, JSU.T);
+            }
         }
     }
 
@@ -1403,46 +1406,70 @@
         // to this box so we can not call propagateLeave() directly upon it
         int i;
         boolean interrupted = false;
-        boolean packedhit = false;
         
-        // absolute layout - allows for interruption by overlaying siblings
-        // packed layout - interrupted still applies, plus packedhit shortcut
-        for (Box b = getChild(i=treeSize()-1); b != null; b = getChild(--i)) {
-               if (!b.test(DISPLAY)) {
-                       continue;
-               }
-               if (interrupted || packedhit) {
-                b.propagateLeave();
-                       continue;
-               }
-            int b_mx = mousex-getXInParent(b);
-            int b_my = mousey-getYInParent(b);
-            if (b.inside(b_mx, b_my)) {
-               if (test(PACK)) {
-                       packedhit = true;
-               }
-                if (b.propagateMove(b_mx, b_my)) {
-                    interrupted = true;
+        if (!test(PACK)) {
+            // absolute layout - allows for interruption by overlaying siblings
+            for (Box b = getChild(i=treeSize()-1); b != null; b = 
getChild(--i)) {
+                if (!b.test(DISPLAY)) {
+                    continue;
                 }
-            } else {
-                b.propagateLeave();
+                if (interrupted) {
+                    b.propagateLeave();
+                    continue;
+                }
+                int b_mx = mousex-getXInParent(b);
+                int b_my = mousey-getYInParent(b);
+                if (b.inside(b_mx, b_my)) {
+                    if (b.propagateMove(b_mx, b_my)) {
+                        interrupted = true;
+                    }
+                } else {
+                    b.propagateLeave();
+                }
             }
+        } else {
+            // packed layout - interrupted still applies, plus packedhit 
shortcut
+            boolean packedhit = false;
+            for (Box b = getChild(i=treeSize()-1); b != null; b = 
getChild(--i)) {
+                if (!b.test(DISPLAY)) {
+                    continue;
+                }
+                if (packedhit) {
+                    b.propagateLeave();
+                    continue;
+                }
+                int b_mx = mousex-getXInParent(b);
+                int b_my = mousey-getYInParent(b);
+                if (b.inside(b_mx, b_my)) {
+                    packedhit = true;
+                    if (b.propagateMove(b_mx, b_my)) {
+                        interrupted = true;
+                    }
+                } else {
+                    b.propagateLeave();
+                }
+            }
         }
 
         // child prevented cascade during _Move/Move which blocks
         // Enter on this box - invoking Leave if necessary
         if (interrupted) {
-            if (!test(MOUSEINSIDE_BLOCKED)) {
+            if (test(MOUSEINSIDE)) {
+                if (!test(MOUSEINSIDE_BLOCKED)) {
+                    // mouse previously inside, now blocked so invoke Leave
+                    set(MOUSEINSIDE_BLOCKED);
+                    if (test(LEAVE_TRAP)) {
+                        justTriggerTraps(SC_Leave, JSU.T);
+                    }
+                }
+            } else {
+                // mouse not previously inside, Enter not yet triggered, so
+                // do not invoke Leave
+                set(MOUSEINSIDE);
                 set(MOUSEINSIDE_BLOCKED);
-                set(MOUSEINSIDE);
-                if (test(LEAVE_TRAP)) {
-                    justTriggerTraps(SC_Leave, JSU.T);
-                }
             }
             // propagate cascade prevention 
             return true;
-        } else {
-            clear(MOUSEINSIDE_BLOCKED);
         }
         
         // set cursor if applicable to this box

Added: 
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/lib/moveBlocked_template.t
===================================================================
--- 
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/lib/moveBlocked_template.t
                               (rev 0)
+++ 
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/lib/moveBlocked_template.t
       2010-10-29 23:57:25 UTC (rev 3954)
@@ -0,0 +1,30 @@
+<vexi xmlns:ui="vexi://ui">
+    <!--
+        Move/Enter/Leave test
+        
+        The blocking trap on Move should not interfere
+        with the Enter/Leave events in the topmost box
+        whilst blocking those directly beneath it
+    -->
+    
+    <ui:box width="300" height="300">
+        <ui:box layout="layer" shrink="true">
+            <ui:box width="100" height="100" fill="red">
+                thisbox.inside = false;
+                Enter ++= function(v) { inside = true; cascade = v; }
+                Leave ++= function(v) { inside = false; cascade = v; }
+                Move ++= function(v) { return; }
+            </ui:box>
+            thisbox.enterhit = false;
+            thisbox.leavehit = false;
+            // these should never fire because thisbox will be
+            // the same size as the blocking box it contains
+            Enter ++= function(v) { enterhit = true; cascade = v; }
+            Leave ++= function(v) { leavehit = true; cascade = v; }
+        </ui:box>
+        thisbox.inside = false;
+        Enter ++= function(v) { inside = true; cascade = v; }
+        Leave ++= function(v) { inside = false; cascade = v; }
+        //vexi.ui.frame = thisbox;
+    </ui:box>
+</vexi>

Added: 
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/moveBlocked.t
===================================================================
--- 
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/moveBlocked.t
                            (rev 0)
+++ 
branches/vexi3_old_build/core/org.vexi.core/src_junit/test/core/box/events/moveBlocked.t
    2010-10-29 23:57:25 UTC (rev 3954)
@@ -0,0 +1,44 @@
+<vexi xmlns:ui="vexi://ui">
+    <!--
+        Move/Enter/Leave test
+        
+        The blocking trap on Move should not interfere
+        with the Enter/Leave events in the topmost box
+        whilst blocking those directly beneath it
+    -->
+    
+    var test = new vexi..lib.moveBlocked_template();
+    test.forcereflow();
+    test.visible ++= function() { return true; }
+    assert(test[0].width == 100);
+    assert(test[0].height == 100);
+    
+    test.sendEvent("Move", 5, 5);
+    //assert(test.mouse.inside);
+    assert(test.inside);
+    assert(test[0].enterhit == false);
+    assert(test[0].leavehit == false);
+    
+    test.sendEvent("Move", 150, 150);
+    //assert(test.mouse.inside == false);
+    assert(test.inside == false);
+    assert(test[0].enterhit == false);
+    assert(test[0].leavehit == false);
+    //assert(test[0][0].mouse.inside);
+    assert(test[0][0].inside);
+    
+    <ui:box width="300" height="300">
+        <ui:box layout="layer" shrink="true">
+            <ui:box width="100" height="100" fill="red">
+                Enter ++= function(v) { vexi.trace("Enter"); cascade = v; }
+                Leave ++= function(v) { vexi.trace("Leave"); cascade = v; }
+                Move ++= function(v) { return; }
+            </ui:box>
+            thisbox.enterhit = false;
+            thisbox.leavehit = false;
+            Enter ++= function(v) { vexi.trace("Enter blocked"); enterhit = 
true; cascade = v; }
+            Leave ++= function(v) { vexi.trace("Leave blocked"); leavehit = 
true; cascade = v; }
+        </ui:box>
+        //vexi.ui.frame = thisbox;
+    </ui:box>
+</vexi>


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

------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in  U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store 
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to