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