2003/12/22 04:50:08
[org.ibex.core.git] / src / org / xwt / Box.java
index 6b90368..98fb49e 100644 (file)
@@ -255,15 +255,28 @@ public final class Box extends JSScope implements Scheduler.Task {
     void resize(LENGTH x, LENGTH y, LENGTH width, LENGTH height) {
         // FEATURE reimplement, but we're destroying this
         // FIXME: uncommenting this breaks; see http://bugs.xwt.org/show_bug.cgi?id=345
-        //if (x != this.x || y != this.y || width != this.width || height != this.height) {
-            (parent == null ? this : parent).dirty(this.x, this.y, this.width, this.height);
+        if (x != this.x || y != this.y || width != this.width || height != this.height) {
             boolean sizechange = (this.width != width || this.height != height) && getTrap("SizeChange") != null;
             boolean poschange = (this.x != x || this.y != y) && getTrap("PosChange") != null;
+            do {
+                if (texture == null && (text == null || text.equals(""))) {
+                    if ((fillcolor & 0xff000000) == 0) break;
+                    // FEATURE: more optimizations here
+                    if (this.x == x && this.y == y) {
+                        Box who = (parent == null ? this : parent);
+                        who.dirty(min(this.x+this.width,x+width), y, Math.abs(width-this.width), max(this.height, height));
+                        who.dirty(x, min(this.y+this.height,y+height), max(this.width, width), Math.abs(height-this.height));
+                        break;
+                    }
+                }
+                (parent == null ? this : parent).dirty(this.x, this.y, this.width, this.height);
+                this.width = width; this.height = height; this.x = x; this.y = y;
+                dirty();
+            } while (false);
             this.width = width; this.height = height; this.x = x; this.y = y;
-            dirty();
             if (sizechange) putAndTriggerTrapsAndCatchExceptions("SizeChange", T);
             if (poschange)  putAndTriggerTrapsAndCatchExceptions("PosChange", T);
-            //}
+        }
     }
 
     void resize_children() {
@@ -349,7 +362,7 @@ public final class Box extends JSScope implements Scheduler.Task {
         }
 
         if ((fillcolor & 0xFF000000) != 0x00000000)
-            buf.fillTrapezoid(globalx, globalx + width, globaly, globalx, globalx + width, globaly + height, fillcolor);
+            buf.fillTrapezoid(cx1, cx2, cy1, cx1, cx2, cy2, fillcolor);
 
         // FIXME: do aspect in here
         if (texture != null && texture.isLoaded)
@@ -431,9 +444,11 @@ public final class Box extends JSScope implements Scheduler.Task {
         case "globalx": return N(localToGlobalX(0));
         case "globaly": return N(localToGlobalY(0));
         case "cursor": return test(CURSOR) ? boxToCursor.get(this) : null;
-        case "mousex": { Surface s = getSurface(); return N(s == null ? 0 : globalToLocalX(s.mousex)); }
-        case "mousey": { Surface s = getSurface(); return N(s == null ? 0 : globalToLocalY(s.mousey)); }
-        case "mouseinside": return B(test(MOUSEINSIDE));
+        case "mouse":
+            if (getSurface() == null) return null;
+            if (getSurface()._mousex == Integer.MAX_VALUE)
+                throw new JSExn("you cannot read from the box.mouse property in background thread context");
+            return new Mouse();
         case "numchildren": return redirect == null ? N(0) : redirect == this ? N(treeSize()) : redirect.get("numchildren");
         case "minwidth": return N(minwidth);
         case "maxwidth": return N(maxwidth);
@@ -446,6 +461,19 @@ public final class Box extends JSScope implements Scheduler.Task {
         throw new Error("unreachable"); // unreachable
     }
 
+    private class Mouse extends JS {
+        public Object get(Object key) {
+            //#switch(key)
+            case "x": return N(globalToLocalX(getSurface()._mousex));
+            case "y": return N(globalToLocalY(getSurface()._mousey));
+
+            // this might not get recomputed if we change mousex/mousey...
+            case "inside": return B(MOUSEINSIDE);
+            //#end
+            return null;
+        }
+    }
+
     void setMaxWidth(Object value) { do { CHECKSET_INT(maxwidth); MARK_RESIZE; } while(false); }
     void setMaxHeight(Object value) { do { CHECKSET_INT(maxheight); MARK_RESIZE; } while(false); }
 
@@ -479,6 +507,11 @@ public final class Box extends JSScope implements Scheduler.Task {
         case "align": clear(ALIGNS); setAlign(value == null ? "center" : value); MARK_RESIZE;
         case "cursor": setCursor(value);
         case "fill": setFill(value);
+        case "mouse":
+            int mousex = toInt(((JS)value).get("x"));
+            int mousey = toInt(((JS)value).get("y"));
+            getSurface()._mousex = localToGlobalX(mousex);
+            getSurface()._mousey = localToGlobalY(mousey);
         case "Minimized": if (parent == null && getSurface() != null) getSurface().minimized = toBoolean(value);  // FEATURE
         case "Maximized": if (parent == null && getSurface() != null) getSurface().maximized = toBoolean(value);  // FEATURE
         case "Close": if (parent == null && getSurface() != null) getSurface().dispose(true);
@@ -600,8 +633,8 @@ public final class Box extends JSScope implements Scheduler.Task {
 
         String name = (String)name_;
         if (getSurface() == null) return;
-        int x = globalToLocalX(getSurface().mousex);
-        int y = globalToLocalY(getSurface().mousey);
+        int x = globalToLocalX(getSurface()._mousex);
+        int y = globalToLocalY(getSurface()._mousey);
         boolean wasinside = test(MOUSEINSIDE);
         boolean isinside = test(VISIBLE) && inside(x, y) && !obscured;
         if (!wasinside && isinside) { set(MOUSEINSIDE);   putAndTriggerTrapsAndCatchExceptions("Enter", T); }