Revision: 3448
          http://vexi.svn.sourceforge.net/vexi/?rev=3448&view=rev
Author:   clrg
Date:     2009-03-25 23:28:47 +0000 (Wed, 25 Mar 2009)

Log Message:
-----------
Some more Surface event code refactoring
- split Message into InputMessage / EventMessage
- handle Press3 the same way other input events are handled
- ...which fixes Press3 only being fired on the root box

Modified Paths:
--------------
    trunk/core/org.vexi.core/src/org/vexi/core/Surface.java

Modified: trunk/core/org.vexi.core/src/org/vexi/core/Surface.java
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Surface.java     2009-03-25 
10:59:16 UTC (rev 3447)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Surface.java     2009-03-25 
23:28:47 UTC (rev 3448)
@@ -30,13 +30,11 @@
     
     
     // Static Data 
////////////////////////////////////////////////////////////////////////////////
-    private static final JS T = JSU.T;
-    private static final JS F = JSU.F;
 
     /** all instances of Surface which need to be refreshed by the 
Platform.Scheduler */
     public static Vec allSurfaces = new Vec();
     
-    /** When set to true, render() should abort as soon as possible and 
restart the rendering process */
+    /** when set to true, render() should abort as soon as possible and 
restart the rendering process */
     public volatile boolean abort = false;
 
     // these three variables are used to ensure that user resizes trump 
programmatic resizes
@@ -71,11 +69,12 @@
     public int newmousey = -1;                         ///< y position of the 
mouse, in real time; this lets us collapse Move's
     public boolean minimized = false;                  ///< True iff this 
surface is minimized, in real time
     public boolean maximized = false;                  ///< True iff this 
surface is maximized, in real time
-    DirtyList dirtyRegions = new DirtyList();          ///< Dirty regions on 
the surface
     protected Picture icon;
     private boolean visible = false;
     private boolean resizable = false;
 
+    final private DirtyList dirtyRegions = new DirtyList();          ///< 
Dirty regions on the surface
+
     public int topInset = 0;
     public int leftInset = 0;
     public int bottomInset = 0;
@@ -138,20 +137,20 @@
 
     // Event Handling Helper methods for subclasses ///////////////////
     
-    protected final void KeyPressed(String key) { new Message(SC_KeyPressed, 
SC__KeyPressed, JSU.S(key), true); }
-    protected final void KeyReleased(String key) { new Message(SC_KeyReleased, 
SC__KeyReleased, JSU.S(key), true); }
-    protected final void Close() { new Message(SC_Close, T); }
-    protected final void Minimized(boolean b) { minimized = b; new 
Message(SC_Minimized, b ? T : F); }
-    protected final void Maximized(boolean b) { maximized = b; new 
Message(SC_Maximized, b ? T : F); }
+    protected final void KeyPressed(String key) { new 
InputMessage(SC_KeyPressed, SC__KeyPressed, JSU.S(key), true); }
+    protected final void KeyReleased(String key) { new 
InputMessage(SC_KeyReleased, SC__KeyReleased, JSU.S(key), true); }
+    protected final void Close() { new EventMessage(SC_Close, JSU.T); }
+    protected final void Minimized(boolean b) { minimized = b; new 
EventMessage(SC_Minimized, b ? JSU.T : JSU.F); }
+    protected final void Maximized(boolean b) { maximized = b; new 
EventMessage(SC_Maximized, b ? JSU.T : JSU.F); }
     protected final void Focused(boolean b) {
         if (!b) { alt = control = shift = false; }
-        new Message(SC_Focused, b ? T : F);
+        new EventMessage(SC_Focused, b ? JSU.T : JSU.F);
     }
 
-    protected final void HScroll(int pixels) { new Message(SC_HScroll, 
SC__HScroll, JSU.N(pixels)); }
-    protected final void VScroll(int pixels) { new Message(SC_VScroll, 
SC__VScroll, JSU.N(pixels)); }
-    protected final void HScroll(float lines) { new Message(SC_HScroll, 
SC__HScroll, JSU.N(lines)); }
-    protected final void VScroll(float lines) { new Message(SC_VScroll, 
SC__VScroll, JSU.N(lines)); }
+    protected final void HScroll(int pixels) { new InputMessage(SC_HScroll, 
SC__HScroll, JSU.N(pixels)); }
+    protected final void VScroll(int pixels) { new InputMessage(SC_VScroll, 
SC__VScroll, JSU.N(pixels)); }
+    protected final void HScroll(float lines) { new InputMessage(SC_HScroll, 
SC__HScroll, JSU.N(lines)); }
+    protected final void VScroll(float lines) { new InputMessage(SC_VScroll, 
SC__VScroll, JSU.N(lines)); }
 
     protected final void Press(final int button) {
         last_press_x = mousex;
@@ -161,23 +160,13 @@
         else if (button == 2) button2 = true;
         else if (button == 3) button3 = true;
 
-        if (button == 3) {
-            Scheduler.add(new Callable() { public Object run(Object o) throws 
JSExn {
-                Platform.clipboardReadEnabled = true;
-                try {
-                    root.putAndTriggerTraps(SC__Press3, T);
-                } finally {
-                    Platform.clipboardReadEnabled = false;
-                }
-                return o;
-            }});
-        } else {
-            if (button==1)
-                new Message(SC_Press1, SC__Press1, JSU.T);
-            else if (button==2)
-                new Message(SC_Press2, SC__Press2, JSU.T);
-            else new Message(JSU.S("Press"+button), JSU.S("_Press"+button), 
JSU.T);
-        }
+        if (button==1)
+            new InputMessage(SC_Press1, SC__Press1, JSU.T);
+        else if (button==2)
+            new InputMessage(SC_Press2, SC__Press2, JSU.T);
+        else if (button==3)
+            new InputMessage(SC_Press3, SC__Press3, JSU.T);
+        else new InputMessage(JSU.S("Press"+button), JSU.S("_Press"+button), 
JSU.T);
     }
 
     protected final void Release(int button) {
@@ -186,12 +175,12 @@
         else if (button == 3) button3 = false;
 
         if (button==1)
-            new Message(SC_Release1, SC__Release1, JSU.T, true);
+            new InputMessage(SC_Release1, SC__Release1, JSU.T, true);
         else if (button==2)
-            new Message(SC_Release2, SC__Release2, JSU.T, true);
+            new InputMessage(SC_Release2, SC__Release2, JSU.T, true);
         else if (button==3)
-            new Message(SC_Release3, SC__Release3, JSU.T, true);
-        else new Message(JSU.S("Release"+button), JSU.S("_Release"+button), 
JSU.T, true);
+            new InputMessage(SC_Release3, SC__Release3, JSU.T, true);
+        else new InputMessage(JSU.S("Release"+button), 
JSU.S("_Release"+button), JSU.T, true);
         // invoke Click if platform requires it and release is sufficiently 
close to release
         if (Platform.needsAutoClick() && Math.abs(last_press_x - mousex) < 5 
&& Math.abs(last_press_y - mousey) < 5)
             Click(button);
@@ -201,12 +190,12 @@
 
     protected final void Click(int button) {
         if (button==1)
-            new Message(SC_Click1, SC__Click1, JSU.T);
+            new InputMessage(SC_Click1, SC__Click1, JSU.T);
         else if (button==2)
-            new Message(SC_Click2, SC__Click2, JSU.T);
+            new InputMessage(SC_Click2, SC__Click2, JSU.T);
         else if (button==3)
-            new Message(SC_Click3, SC__Click3, JSU.T);
-        else new Message(JSU.S("Click"+button), JSU.S("_Click"+button), JSU.T);
+            new InputMessage(SC_Click3, SC__Click3, JSU.T);
+        else new InputMessage(JSU.S("Click"+button), JSU.S("_Click"+button), 
JSU.T);
         if (Platform.needsAutoDoubleClick()) {
             long now = System.currentTimeMillis();
             if (lastClickButton == button && now - lastClickTime < 350) 
DoubleClick(button);
@@ -217,12 +206,12 @@
 
     protected final void DoubleClick(int button) {
         if (button==1)
-            new Message(SC_DoubleClick1, SC__DoubleClick1, JSU.T);
+            new InputMessage(SC_DoubleClick1, SC__DoubleClick1, JSU.T);
         else if (button==2)
-            new Message(SC_DoubleClick2, SC__DoubleClick2, JSU.T);
+            new InputMessage(SC_DoubleClick2, SC__DoubleClick2, JSU.T);
         else if (button==3)
-            new Message(SC_DoubleClick3, SC__DoubleClick3, JSU.T);
-        else new Message(JSU.S("DoubleClick"+button), 
JSU.S("_DoubleClick"+button), JSU.T);
+            new InputMessage(SC_DoubleClick3, SC__DoubleClick3, JSU.T);
+        else new InputMessage(JSU.S("DoubleClick"+button), 
JSU.S("_DoubleClick"+button), JSU.T);
     }
 
     /** we enqueue ourselves in the Platform.Scheduler when we have a Move 
message to deal with */
@@ -258,43 +247,42 @@
     }
 
     // FEATURE: reinstate recycler
-    public class Message implements Callable {
-        
+    /** Event notification for the root box of a Surface */
+    private class EventMessage implements Callable {
         private JS event;
-        private JS _event;
         private JS value;
-        private boolean inputEvent;
-        private boolean forceOnRoot;
-
-        Message(JS event, JS value) {
-            this(event, null, value, false, false);
+        EventMessage(JS event, JS value) {
+            this.event = event;
+            this.value = value;
+            Scheduler.add(this);
         }
-
-        Message(JS event, JS _event, JS value) {
-            this(event, _event, value, true, false);
+        public Object run(Object o) throws Exception {
+            JS ret = root.justTriggerTraps(event, value);
+            if (Interpreter.CASCADE_PREVENTED != ret && (event==SC_Close))
+                dispose(true);
+            return o;
         }
+        public String toString() { return "EventMessage [name=" + 
JSU.toString(event) + ", value=" + JSU.toString(value) + "]"; }
+    }
 
-        Message(JS event, JS _event, JS value, boolean forceOnRoot) {
-            this(event, _event, value, true, forceOnRoot);
-        }
-
-        Message(JS event, JS _event, JS value, boolean inputEvent, boolean 
forceOnRoot) {
+    // FEATURE: reinstate recycler
+    /** Input notification for the root box of a Surface
+     *  enabling clipboard access for specific conditions
+     */
+    private class InputMessage implements Callable {
+        private JS event;
+        private JS _event;
+        private JS value;
+        private boolean forceOnRoot;
+        InputMessage(JS event, JS _event, JS value) { this(event, _event, 
value, false); }
+        InputMessage(JS event, JS _event, JS value, boolean forceOnRoot) {
             this.event = event;
             this._event = _event;
             this.value = value;
-            this.inputEvent = inputEvent;
             this.forceOnRoot = forceOnRoot;
             Scheduler.add(this);
         }
-
-        public Object run(Object o) throws JSExn {
-            if (!inputEvent) {
-                JS ret = root.justTriggerTraps(event, value);
-                if (Interpreter.CASCADE_PREVENTED != ret && (event==SC_Close))
-                    dispose(true);
-                return o;
-            }
-
+        public Object run(Object o) throws Exception {
             if (event==SC_KeyPressed) {
                 String value = JSU.toString(this.value);
                 if (shift && !value.equals("shift")) value = 
value.toUpperCase();
@@ -304,11 +292,13 @@
                 this.value = JSU.S(value);
             }
             
+            if (event==SC_Press3) Platform.clipboardReadEnabled = true;
+            
             try { root.tryPropagateEvent(event, _event, value, forceOnRoot); }
             finally { Platform.clipboardReadEnabled = false; }
             return o;
         }
-        public String toString() { return "Message [name=" + 
JSU.toString(event) + ", value=" + JSU.toString(value) + "]"; }
+        public String toString() { return "InputMessage [name=" + 
JSU.toString(event) + ", value=" + JSU.toString(value) + "]"; }
     }
     
     
@@ -478,7 +468,7 @@
 
     public static Surface fromBox(Box b) {
         // FIXME: use a hash table here
-        for(int i=0; i<allSurfaces.size(); i++) {
+        for (int i=0; i<allSurfaces.size(); i++) {
             Surface s = (Surface)allSurfaces.elementAt(i);
             if (s.root == b) return s;
         }
@@ -536,33 +526,36 @@
                 setMinimumSize(root.contentwidth, root.contentheight);
         } while(abort);
 
-        int numregions = dirtyRegions.num();
-        int[] dirt = dirtyRegions.flush();
-
-        PixelBuffer buff = getPixelBuffer();
+        final int numregions = dirtyRegions.num();
+        final int[] dirt = dirtyRegions.flush();
         if (dirt!=null) {
+            final PixelBuffer buff = getPixelBuffer();
+            final int rwidth = root.width;
+            final int rheight = root.height;
+            final int scar_y = rheight-scarImage.height;
             for (int i = 0; dirt != null && i < numregions; i++) {
                 if (dirt[4*i]<0) continue;
                 int x = dirt[4*i], y = dirt[4*i+1], w = dirt[4*i+2], h = 
dirt[4*i+3];
                 if (x < 0) x = 0;
                 if (y < 0) y = 0;
-                if (w > root.width) w = root.width;
-                if (h > root.height) h = root.height;
+                if (w > rwidth) w = rwidth;
+                if (h > rheight) h = rheight;
                 if (w <= x || h <= y) continue;
 
                 root.render(0, 0, x, y, w, h, buff);
                 if (scarImage != null) {
-                    if (scarImage.width > x && root.height-scarImage.height < 
h)
-                        buff.drawPicture(scarImage, 0, 
root.height-scarImage.height, x, y, w, h);
+                    if (scarImage.width > x && scar_y < h)
+                        buff.drawPicture(scarImage, 0, scar_y, x, y, w, h);
                 }
 
                 if (abort) {
                     // x,y,w,h is only partially reconstructed, so we must be 
careful not to re-blit it
                     dirtyRegions.dirty(x, y, w, h);
                     // put back all the dirty regions we haven't yet processed 
(including the current one)
-                    for (int j=i; j<numregions; j++)
-                        if (dirt[4*j]>=0)
-                            dirtyRegions.dirty(dirt[4*j], dirt[4*j+1], 
dirt[4*j+2], dirt[4*j+3]);
+                    for (int j=i; j<numregions; j++) {
+                        int dx = dirt[4*j];
+                        if (dx >= 0) dirtyRegions.dirty(dx, dirt[4*j+1], 
dirt[4*j+2], dirt[4*j+3]);
+                    }
                     return;
                 }
             }
@@ -587,8 +580,8 @@
 
         public DoubleBufferedSurface(Box root) { super(root); }
         public PixelBuffer getPixelBuffer() { return this; }
-        protected PixelBuffer backbuffer = 
Platform.createPixelBuffer(Platform.getScreenWidth(), 
Platform.getScreenHeight(), this);
-        private DirtyList screenDirtyRegions = new DirtyList();
+        final protected PixelBuffer backbuffer = 
Platform.createPixelBuffer(Platform.getScreenWidth(), 
Platform.getScreenHeight(), this);
+        final private DirtyList screenDirtyRegions = new DirtyList();
 
         /** draw an unscaled image onto the backbuffer where:
          *  (dx,dy) is the offset within the picture from where to start 
sampling
@@ -616,18 +609,23 @@
 
         public void render() {
             super.render();
-            int numregions = screenDirtyRegions.num();
-            int[] dirt = screenDirtyRegions.flush();
-            for(int i = 0; dirt != null && i < numregions; i++) {
+            final int numregions = screenDirtyRegions.num();
+            final int[] dirt = screenDirtyRegions.flush();
+            if (dirt==null) return;
+            final int rwidth = root.width;
+            final int rheight = root.height;
+            for (int i = 0; i < numregions; i++) {
+                // consumed dirty areas are marked with a -1
                 if (dirt[4*i]<0) continue;
+                // handle confirmed dirty areas
                 int x = dirt[4*i];
                 int y = dirt[4*i+1];
                 int w = dirt[4*i+2];
                 int h = dirt[4*i+3];
                 if (x < 0) x = 0;
                 if (y < 0) y = 0;
-                if (w > root.width) w = root.width;
-                if (h > root.height) h = root.height;
+                if (w > rwidth) w = rwidth;
+                if (h > rheight) h = rheight;
                 if (w <= x || h <= y) continue;
                 blit(backbuffer, x, y, x, y, w, h);
             }


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

------------------------------------------------------------------------------
_______________________________________________
Vexi-svn mailing list
Vexi-svn@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to