2003/06/09 06:38:36
[org.ibex.core.git] / src / org / xwt / Surface.java
index d8b944d..962a426 100644 (file)
@@ -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 ///////////////////////////////////////////////////////
 
@@ -151,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;
             }});
         }
@@ -177,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) {
@@ -189,15 +199,15 @@ public abstract class Surface {
     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));
     }
@@ -212,7 +222,7 @@ public abstract class Surface {
                 Box b = (Box)keywatchers.elementAt(i);
                 for(Box cur = b; cur != null; cur = cur.getParent())
                     if (cur.invisible) continue outer;
-                b.put("KeyPressed", null, key);
+                b.put("KeyPressed", key);
             }
             Platform.clipboardReadEnabled = false;
         }
@@ -221,15 +231,15 @@ public abstract class Surface {
     /** sends a KeyReleased message; subclasses should not add the C- or A- prefixes, nor should they capitalize alphabet characters */
     protected final void KeyReleased(final String key) {
         if (key == null) return;
-        if (key.equals("alt")) alt = false;
-        else if (key.equals("control")) control = false;
-        else if (key.equals("shift")) shift = false;
+        if (key.toLowerCase().equals("alt")) alt = false;
+        else if (key.toLowerCase().equals("control")) control = false;
+        else if (key.toLowerCase().equals("shift")) shift = false;
         MessageQueue.add(new Message() { public void perform() {
             outer: for(int i=0; i<keywatchers.size(); i++) {
                 Box b = (Box)keywatchers.elementAt(i);
                 for(Box cur = b; cur != null; cur = cur.getParent())
                     if (cur.invisible) continue outer;
-                b.put("KeyReleased", null, key);
+                b.put("KeyReleased", key);
             }
         }});
     }
@@ -257,7 +267,7 @@ public abstract class Surface {
 
                 // Root gets motion events outside itself (if trapped, of course)
                 if (root.is_trapped("Move") && !root.inside(oldmousex, oldmousey) && !root.inside(mousex, mousey) && (button1 || button2 || button3))
-                    root.put("Move", null, Boolean.TRUE);
+                    root.put("Move", Boolean.TRUE);
 
                 root.Move(oldmousex, oldmousey, mousex, mousey);
                 if (!cursor.equals(oldcursor)) syncCursor();
@@ -278,13 +288,13 @@ public abstract class Surface {
     protected final void PosChange(int x, int y) {
         root.set(Box.abs, 0, x);
         root.set(Box.abs, 1, y);
-        new SimpleMessage("PosChange", Boolean.TRUE, null);
+        new SimpleMessage("PosChange", Boolean.TRUE, root);
     }
 
-    protected final void Close() { new SimpleMessage("Close", Boolean.TRUE, null); }
-    protected final void Minimized(boolean b) { minimized = b; new SimpleMessage("Minimized", b ? Boolean.TRUE : Boolean.FALSE, null); }
-    protected final void Maximized(boolean b) { maximized = b; new SimpleMessage("Maximized", b ? Boolean.TRUE : Boolean.FALSE, null); }
-    protected final void Focused(boolean b) { new SimpleMessage("Focused", b ? Boolean.TRUE : Boolean.FALSE, null); }
+    protected final void Close() { new SimpleMessage("Close", Boolean.TRUE, root); }
+    protected final void Minimized(boolean b) { minimized = b; new SimpleMessage("Minimized", b ? Boolean.TRUE : Boolean.FALSE, root); }
+    protected final void Maximized(boolean b) { maximized = b; new SimpleMessage("Maximized", b ? Boolean.TRUE : Boolean.FALSE, root); }
+    protected final void Focused(boolean b) { new SimpleMessage("Focused", b ? Boolean.TRUE : Boolean.FALSE, root); }
     public static void Refresh() { MessageQueue.refresh(); }
 
     // the following value is split into two int's to work around GCJ bug java/6393
@@ -325,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 ///////////////////////////////////////////////////////////////////////////////
@@ -345,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");
@@ -377,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
@@ -403,16 +424,16 @@ public abstract class Surface {
         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) {
@@ -452,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());
@@ -551,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;
@@ -564,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 + "]"; }
         
     }