X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FSurface.java;h=962a426b7acb768559fd08fcc323387aafadd794;hb=e58686eae8a823ed64ed0ec92c2274c41d90ec93;hp=58339c86f7959ba34da198f95a76c7a47cda149b;hpb=c9f6b3dd256396e17df86a371a27baa794c534ce;p=org.ibex.core.git diff --git a/src/org/xwt/Surface.java b/src/org/xwt/Surface.java index 58339c8..962a426 100644 --- a/src/org/xwt/Surface.java +++ b/src/org/xwt/Surface.java @@ -48,11 +48,11 @@ public abstract class Surface { /** true iff button 3 is depressed, in MessageQueue-time */ public static boolean button3 = false; + /** true iff all surfaces created from now on should be scarred */ + public static boolean scarAllSurfacesFromNowOn = false; - // Public Members and State Variables ///////////////////////////////////////////////////////// - /** this is the box on this surface which the mouse was inside at the time that the currently-executing event was enqueued */ - public Box boxContainingMouse = null; + // Public Members and State Variables ///////////////////////////////////////////////////////// /** false if the surface has never been rendered; used to determine if the surface should be repositioned to be centered on the screen */ public boolean centerSurfaceOnRender = true; @@ -92,7 +92,12 @@ public abstract class Surface { /** the y-position of the mouse the last time a Press message was enqueued */ int last_press_y = Integer.MAX_VALUE; + /** the last button to recieve a Click message; used for simulating DoubleClick's */ + static int lastClickButton = 0; + /** the last time a Click message was processed; used for simulating DoubleClick's */ + static long lastClickTime = 0; + // Methods to be overridden by subclasses /////////////////////////////////////////////////////// @@ -132,6 +137,9 @@ public abstract class Surface { /** Destroy the surface */ public abstract void _dispose(); + /** Notifies the surface that limits have been imposed on the surface's size */ + public void setLimits(int min_width, int min_height, int max_width, int max_height) { } + // Helper methods for subclasses //////////////////////////////////////////////////////////// @@ -148,9 +156,8 @@ public abstract class Surface { else if (button == 3) { final Box who = root.whoIs(mousex, mousey); MessageQueue.add(new Message() { public void perform() { - Surface.this.boxContainingMouse = who; Platform.clipboardReadEnabled = true; - root.put("Press1", null, Boolean.TRUE); + root.put("Press3", Boolean.TRUE); Platform.clipboardReadEnabled = false; }}); } @@ -174,6 +181,12 @@ public abstract class Surface { if (button == 1) new SimpleMessage("Click1", Boolean.TRUE, root.whoIs(mousex, mousey)); else if (button == 2) new SimpleMessage("Click2", Boolean.TRUE, root.whoIs(mousex, mousey)); else if (button == 3) new SimpleMessage("Click3", Boolean.TRUE, root.whoIs(mousex, mousey)); + if (Platform.needsAutoDoubleClick()) { + long now = System.currentTimeMillis(); + if (lastClickButton == button && now - lastClickTime < 350) DoubleClick(button); + lastClickButton = button; + lastClickTime = now; + } } protected final void DoubleClick(int button) { @@ -185,16 +198,16 @@ public abstract class Surface { /** sends a KeyPressed message; subclasses should not add the C- or A- prefixes, nor should they capitalize alphabet characters */ protected final void KeyPressed(String key) { if (key == null) return; - - if (key.equals("alt")) alt = true; + + if (key.toLowerCase().endsWith("shift")) shift = true; + else if (shift) key = key.toUpperCase(); + + if (key.toLowerCase().equals("alt")) alt = true; else if (alt) key = "A-" + key; - if (key.endsWith("control")) control = true; + if (key.toLowerCase().endsWith("control")) control = true; else if (control) key = "C-" + key; - if (key.endsWith("shift")) shift = true; - else if (shift) key = key.toUpperCase(); - final String fkey = key; MessageQueue.add(new KMessage(key)); } @@ -205,8 +218,12 @@ public abstract class Surface { public KMessage(String k) { key = k; } public void perform() { if (key.equals("C-v") || key.equals("A-v")) Platform.clipboardReadEnabled = true; - for(int i=0; i= width - 1 || h >= height - 1)) return; screenDirtyRegions.dirty(x, y, w, h); - blitDirtyScreenRegions(); + Refresh(); } @@ -305,12 +326,6 @@ public abstract class Surface { /** A list of all the Boxes on this Surface that should be notified of keyboard events */ Vec keywatchers = new Vec(); - /** - * this is incremented every time we render; it acts as a sort of 'timestamp' to let Boxes to know if they have - * been dirtied since the last rendering began (and hence should not propagate up dirty() requests from their children) - */ - volatile int dirtiedTimeStamp = 0; - /** When set to true, render() should abort as soon as possible and restart the rendering process */ volatile boolean abort = false; @@ -320,6 +335,8 @@ public abstract class Surface { /** a striped 100x100 double buffer */ private DoubleBuffer showRenderBuf2 = null; + /** true iff this window should be scarred */ + private boolean scarred = true; // Other Methods /////////////////////////////////////////////////////////////////////////////// @@ -340,23 +357,27 @@ public abstract class Surface { /** wrapper for setSize() which makes sure to dirty the place where the scar used to be */ void _setSize(int width, int height) { - dirty(hscar, - root.size(1) - vscar - scarPicture.getHeight(), - scarPicture.getWidth(), scarPicture.getHeight()); + if (scarred) { + width = Math.max(width, scarPicture.getWidth()); + height = Math.max(height, scarPicture.getHeight()); + dirty(hscar, + root.size(1) - vscar - scarPicture.getHeight(), + scarPicture.getWidth(), scarPicture.getHeight()); + } setSize(width, height); this.width = width; this.height = height; } /** Indicates that the Surface is no longer needed */ - public final void dispose() { + public final void dispose(boolean quitIfAllSurfacesGone) { if (root == null) return; if (Log.on) Log.log(this, "disposing " + this); allSurfaces.removeElement(this); _dispose(); // quit when all windows are closed - if (allSurfaces.size() == 0) { + if (allSurfaces.size() == 0 && quitIfAllSurfacesGone && Main.doneInitializing) { if (Log.on) { if (refreshableSurfaceWasCreated) Log.log(this, "exiting because last remaining surface was disposed"); else Log.log(this, "exiting because no surface was ever created"); @@ -372,9 +393,14 @@ public abstract class Surface { } public Surface(Box root) { + this.scarred = scarAllSurfacesFromNowOn; + scarAllSurfacesFromNowOn = true; this.root = root; - if (root.surface != null && root.surface.root == root) root.surface.dispose(); - root.remove(); + if (root.surface != null && root.surface.root == root) { + root.surface.dispose(false); + } else { + root.remove(); + } root.setSurface(this); // make sure the root is properly sized @@ -394,22 +420,20 @@ public abstract class Surface { /** runs the prerender() and render() pipelines in the root Box to regenerate the backbuffer, then blits it to the screen */ public synchronized void render() { - if (++dirtiedTimeStamp == Integer.MAX_VALUE - 1) dirtiedTimeStamp = 0; - // if the window size changed as a result of a user action, we have to update the root box's size if (root.size(0) != width || root.size(1) != height) { // since the scar will be moving, dirty the place it used to be - dirty(hscar, - root.size(1) - vscar - scarPicture.getHeight(), - scarPicture.getWidth(), scarPicture.getHeight()); + if (scarred) dirty(hscar, + root.size(1) - vscar - scarPicture.getHeight(), + scarPicture.getWidth(), scarPicture.getHeight()); // sort of ugly; we can't use set() here because it will cause an infinite mutual recursion - root._size_0 = (short)width; - root._size_1 = (short)height; + root._size_0 = (int)width; + root._size_1 = (int)height; root.mark_for_prerender(); - root.put("SizeChange", null, Boolean.TRUE); + root.put("SizeChange", Boolean.TRUE); } while (root.needs_prerender || abort) { @@ -449,7 +473,7 @@ public abstract class Surface { root.render(x, y, w, h, backbuffer); // if any area under the scar was repainted, rescar that area - if (x < hscar + scarPicture.getWidth() && + if (scarred && x < hscar + scarPicture.getWidth() && y + h > height - scarPicture.getHeight() - vscar) { int _x1 = Math.max(x, hscar); int _x2 = Math.min(x + w, hscar + scarPicture.getWidth()); @@ -548,11 +572,11 @@ public abstract class Surface { } // FEATURE: reinstate recycler - private class SimpleMessage implements Message { + public class SimpleMessage implements Message { private Box boxContainingMouse; private Object value; - private String name; + public String name; SimpleMessage(String name, Object value, Box boxContainingMouse) { this.boxContainingMouse = boxContainingMouse; @@ -561,14 +585,8 @@ public abstract class Surface { MessageQueue.add(this); } - public void perform() { - Surface.this.boxContainingMouse = this.boxContainingMouse; - root.put(name, root, value); - } - - public String toString() { - return "SimpleMessage [name=" + name + ", value=" + value + "]"; - } + public void perform() { boxContainingMouse.put(name, value); } + public String toString() { return "SimpleMessage [name=" + name + ", value=" + value + "]"; } }