new linear constraint solver for layout
[org.ibex.core.git] / src / org / ibex / Surface.java
index 2d577e6..b553056 100644 (file)
@@ -126,16 +126,17 @@ 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() {
-        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))
-            root.putAndTriggerTrapsAndCatchExceptions("_Move", T);
-        if (!cursor.equals(oldcursor)) syncCursor();
-    }
+    private Scheduler.Task mover = new Scheduler.Task() {
+            public void perform() {
+                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))
+                    root.putAndTriggerTrapsAndCatchExceptions("_Move", T);
+                if (!cursor.equals(oldcursor)) syncCursor();
+            } };
 
     /**
      *  Notify Ibex that the mouse has moved. If the mouse leaves the
@@ -146,9 +147,14 @@ 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;
-        Scheduler.add(this);
+        Scheduler.add(mover);
     }
 
+    protected final void HScroll(int pixels) { new Message("_HScroll", new Integer(pixels), root); }
+    protected final void VScroll(int pixels) { new Message("_VScroll", new Integer(pixels), root); }
+    protected final void HScroll(float lines) { new Message("_HScroll", new Float(lines), root); }
+    protected final void VScroll(float lines) { new Message("_VScroll", new Float(lines), root); }
+
     /** subclasses should invoke this method when the user resizes the window */
     protected final void SizeChange(final int width, final int height) {
         if (pendingWidth == width && pendingHeight == height) return;
@@ -176,7 +182,10 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task {
     protected final void Minimized(boolean b) { minimized = b; new Message("Minimized", b ? T : F, root); }
     protected final void Maximized(boolean b) { maximized = b; new Message("Maximized", b ? T : F, root); }
     protected final void Focused(boolean b) { new Message("Focused", b ? T : F, root); }
-    public void Refresh() { Scheduler.add(new Scheduler.Task() { public void perform() { } }); }
+
+    private boolean scheduled = false;
+    public void Refresh() { if (!scheduled) Scheduler.add(this); scheduled = true; }
+    public void perform() { scheduled = false; Scheduler.renderAll(); }
 
     public final void setMaximized(boolean b) { if (b != maximized) _setMaximized(maximized = b); }
     public final void setMinimized(boolean b) { if (b != minimized) _setMinimized(minimized = b); }
@@ -223,7 +232,7 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task {
 
     /** runs the prerender() and render() pipelines in the root Box to regenerate the backbuffer, then blits it to the screen */
     public synchronized void render() {
-
+        scheduled = false;
         // make sure the root is properly sized
         do {
             abort = false;
@@ -239,7 +248,7 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task {
                 dirty(0, root.maxheight - Main.scarImage.height, Main.scarImage.width, Main.scarImage.height);
             }
             root.resize(root.x, root.y, root.maxwidth, root.maxheight);
-            root.resize_children();
+            root.place_children();
             setSize(root.width, root.height);
             String oldcursor = cursor;
             cursor = "default";
@@ -300,6 +309,10 @@ public abstract class Surface extends PixelBuffer implements Scheduler.Task {
                 else if (value.toLowerCase().equals("control")) control = false;
                 else if (value.toLowerCase().equals("shift")) shift = false;
                 this.value = value;
+            } else if (name.equals("_HScroll") || name.equals("_VScroll")) {
+                // FIXME: technically points != pixels
+                if (value instanceof Integer)
+                    value = new Float(((Integer)value).intValue() * root.fontSize());
             }
             try {
                 boxContainingMouse.putAndTriggerTrapsAndCatchExceptions(name, value);