X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fxwt%2FSurface.java;h=70dd5671d6ae6b5a3359d02200f1ec3adbb8c128;hb=16ad8b9430571d806f2aeb18ec472a277ff69423;hp=fe5844fb9d72910a06df48fda9b87d12886b5b8b;hpb=457660f731024833fc8aea9b0154eae578b51600;p=org.ibex.core.git diff --git a/src/org/xwt/Surface.java b/src/org/xwt/Surface.java index fe5844f..70dd567 100644 --- a/src/org/xwt/Surface.java +++ b/src/org/xwt/Surface.java @@ -1,4 +1,4 @@ -// Copyright 2003 Adam Megacz, see the COPYING file for licensing [GPL] +// Copyright 2004 Adam Megacz, see the COPYING file for licensing [GPL] package org.xwt; import org.bouncycastle.util.encoders.Base64; @@ -12,11 +12,6 @@ import java.util.*; * * Platform subclasses should include an inner class subclass of * Surface to return from the Platform._createSurface() method - * - * Note that the members in the section 'state variables' are either - * in real-time (the actual size/position/state), or in - * Scheduler-time (the size/position/state at the time that the - * now-executing message was enqueued). This distinction is important. */ public abstract class Surface extends PixelBuffer implements Scheduler.Task { @@ -29,28 +24,34 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { public static Vec allSurfaces = new Vec(); /** When set to true, render() should abort as soon as possible and restart the rendering process */ - static volatile boolean abort = false; + volatile boolean abort = false; + + // these three variables are used to ensure that user resizes trump programmatic resizes + volatile boolean syncRootBoxToSurface = false; + volatile int pendingWidth = 0; + volatile int pendingHeight = 0; - public static boolean alt = false; ///< true iff the alt button is pressed down, in real time - public static boolean control = false; ///< true iff the control button is pressed down, in real time - public static boolean shift = false; ///< true iff the shift button is pressed down, in real time - public static boolean button1 = false; ///< true iff button 1 is depressed, in Scheduler-time - public static boolean button2 = false; ///< true iff button 2 is depressed, in Scheduler-time - public static boolean button3 = false; ///< true iff button 3 is depressed, in Scheduler-tiem + public static boolean alt = false; ///< true iff the alt button is pressed down + public static boolean control = false; ///< true iff the control button is pressed down + public static boolean shift = false; ///< true iff the shift button is pressed down + public static boolean button1 = false; ///< true iff button 1 is depressed + public static boolean button2 = false; ///< true iff button 2 is depressed + public static boolean button3 = false; ///< true iff button 3 is depressed - // Instance Data /////////////////////////////////////////////////////////////////////// public Box root; ///< The Box at the root of this surface public String cursor = "default"; ///< The active cursor to switch to when syncCursor() is called - public int mousex; ///< x position of the mouse, in Scheduler-time - public int mousey; ///< y position of the mouse, in Scheduler-time - public int newmousex = -1; ///< x position of the mouse, in realtime - public int newmousey = -1; ///< y position of the mouse, in realtime + public int mousex; ///< x position of the mouse + public int mousey; ///< y position of the mouse + public int _mousex; ///< x position of the mouse FIXME + public int _mousey; ///< y position of the mouse FIXME + public int newmousex = -1; ///< x position of the mouse, in real time; this lets us collapse Move's + 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 - private DirtyList dirtyRegions = new DirtyList(); ///< Dirty regions on the *screen* + DirtyList dirtyRegions = new DirtyList(); ///< Dirty regions on the surface // Used For Simulating Clicks and DoubleClicks ///////////////////////////////////////////////// @@ -73,7 +74,8 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { public abstract void setTitleBarText(String s); ///< Sets the surface's title bar text, if applicable public abstract void setIcon(Picture i); ///< Sets the surface's title bar text, if applicable public abstract void _dispose(); ///< Destroy the surface - public void setLimits(int min_width, int min_height, int max_width, int max_height) { /* FIXME */ } + public void setMinimumSize(int minx, int miny, boolean resizable) { } + protected void setSize(int w, int h) { _setSize(w, h); } // Helper methods for subclasses //////////////////////////////////////////////////////////// @@ -86,8 +88,8 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { else if (button == 2) button2 = true; else if (button == 3) button3 = true; - if (button == 1) new SimpleMessage("_Press1", T, root); - else if (button == 2) new SimpleMessage("_Press2", T, root); + if (button == 1) new Message("_Press1", T, root); + else if (button == 2) new Message("_Press2", T, root); else if (button == 3) { final Box who = root; Scheduler.add(new Scheduler.Task() { public void perform() throws JSExn { @@ -106,9 +108,9 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { else if (button == 2) button2 = false; else if (button == 3) button3 = false; - if (button == 1) new SimpleMessage("_Release1", T, root); - else if (button == 2) new SimpleMessage("_Release2", T, root); - else if (button == 3) new SimpleMessage("_Release3", T, root); + if (button == 1) new Message("_Release1", T, root); + else if (button == 2) new Message("_Release2", T, root); + else if (button == 3) new Message("_Release3", T, root); if (Platform.needsAutoClick() && Math.abs(last_press_x - mousex) < 5 && Math.abs(last_press_y - mousey) < 5) Click(button); last_press_x = Integer.MAX_VALUE; @@ -116,9 +118,9 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { } protected final void Click(int button) { - if (button == 1) new SimpleMessage("_Click1", T, root); - else if (button == 2) new SimpleMessage("_Click2", T, root); - else if (button == 3) new SimpleMessage("_Click3", T, root); + if (button == 1) new Message("_Click1", T, root); + else if (button == 2) new Message("_Click2", T, root); + else if (button == 3) new Message("_Click3", T, root); if (Platform.needsAutoDoubleClick()) { long now = System.currentTimeMillis(); if (lastClickButton == button && now - lastClickTime < 350) DoubleClick(button); @@ -129,19 +131,13 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { /** we enqueue ourselves in the Scheduler when we have a Move message to deal with */ public void perform() { - inqueue = false; if (mousex == newmousex && mousey == newmousey) return; int oldmousex = mousex; mousex = newmousex; int oldmousey = mousey; mousey = newmousey; String oldcursor = cursor; cursor = "default"; // Root gets motion events outside itself (if trapped) if (!root.inside(oldmousex, oldmousey) && !root.inside(mousex, mousey) && (button1 || button2 || button3)) - try { - root.putAndTriggerTraps("_Move", T); - } catch (JSExn e) { - Log.log(Surface.class, "Exception thrown from Move message handler"); - Log.logJS(e); - } + root.putAndTriggerTrapsAndCatchExceptions("_Move", T); if (!cursor.equals(oldcursor)) syncCursor(); } @@ -154,31 +150,17 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { protected final void Move(final int newmousex, final int newmousey) { this.newmousex = newmousex; this.newmousey = newmousey; - if (!inqueue) Scheduler.add(this); - inqueue = true; + Scheduler.add(this); } - boolean inqueue = false; - Scheduler.Task nextSizeChange = null; - int nextWidth = 0; - int nextHeight = 0; - // FEATURE: can we avoid creating objects here? /** subclasses should invoke this method when the user resizes the window */ protected final void SizeChange(final int width, final int height) { - nextWidth = width; - nextHeight = height; - if (nextSizeChange != null) return; - if (root.maxwidth == width && root.maxheight == height) return; - nextSizeChange = new Scheduler.Task() { public void perform() { - if (nextSizeChange != this) return; - // dirty the place where the scar used to be - root.dirty(0, root.maxheight - Main.scarImage.height, Main.scarImage.width, Main.scarImage.height); - root.setMaxWidth(JS.N(nextWidth)); - root.setMaxHeight(JS.N(nextHeight)); - nextSizeChange = null; - }}; - Scheduler.add(nextSizeChange); + if (pendingWidth == width && pendingHeight == height) return; + pendingWidth = width; + pendingHeight = height; + syncRootBoxToSurface = true; abort = true; + Scheduler.renderAll(); } // FEATURE: can we avoid creating objects here? @@ -186,24 +168,19 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { Scheduler.add(new Scheduler.Task() { public void perform() throws JSExn { root.x = x; root.y = y; - root.putAndTriggerTraps("PosChange", T); + root.putAndTriggerTrapsAndCatchExceptions("PosChange", T); }}); } private final String[] doubleClick = new String[] { null, "_DoubleClick1", "_DoubleClick2", "_DoubleClick3" }; - protected final void DoubleClick(int button) { new SimpleMessage(doubleClick[button], T, root); } - protected final void KeyPressed(String key) { new SimpleMessage("_KeyPressed", key, root); } - protected final void KeyReleased(String key) { new SimpleMessage("_KeyReleased", key, root); } - protected final void Close() { new SimpleMessage("Close", T, root); } - protected final void Minimized(boolean b) { minimized = b; new SimpleMessage("Minimized", b ? T : F, root); } - protected final void Maximized(boolean b) { maximized = b; new SimpleMessage("Maximized", b ? T : F, root); } - protected final void Focused(boolean b) { new SimpleMessage("Focused", b ? T : F, root); } - public static void Refresh() { /*Scheduler.add(renderAll);*/ } - - public static final Scheduler.Task renderAll = new Scheduler.Task() { public void perform() { - for(int i=0; i root.width) w = root.width - x; if (y+h > root.height) h = root.height - y; if (w <= 0 || h <= 0) continue; + if (abort) return; blit(backbuffer, x, y, x, y, w + x, h + y); } } @@ -387,7 +361,12 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task { /** This is how subclasses signal a 'shallow dirty', indicating that although the backbuffer is valid, the screen is not */ public final void Dirty(int x, int y, int w, int h) { screenDirtyRegions.dirty(x, y, w, h); - Refresh(); + Scheduler.renderAll(); + } + + public void dirty(int x, int y, int w, int h) { + screenDirtyRegions.dirty(x, y, w, h); + super.dirty(x, y, w, h); } /** copies a region from the doublebuffer to this surface */