preliminary core conversion
[org.ibex.core.git] / src / org / ibex / core / Box.java
index bb8a27b..29cd9bc 100644 (file)
@@ -57,7 +57,7 @@ public final class Box extends JSScope implements Task {
     // FIXME memory leak
     static Hash boxToCursor = new Hash(500, 3);
 
-    static final Font DEFAULT_FONT = Font.getFont((Stream)Main.builtin.get("fonts/vera/Vera.ttf"), 10);
+    static final Font DEFAULT_FONT = Font.getFont((Stream)Main.builtin.get(JS.S("fonts/vera/Vera.ttf")), 10);
 
 
     // Flags //////////////////////////////////////////////////////////////////////
@@ -230,9 +230,11 @@ public final class Box extends JSScope implements Task {
         set(REPLACE); // FIXME: be smarter / more incremental
     }
     
+    private final static JS SIZECHANGE = JS.S("SizeChange");
+    
     void resize(int x, int y, int width, int height) {
         if (x == this.x && y == this.y && width == this.width && height == this.height) return;
-        boolean sizechange = (this.width != width || this.height != height) && hasTrap("SizeChange");
+        boolean sizechange = (this.width != width || this.height != height) && hasTrap(SIZECHANGE);
         int thisx = parent == null ? 0 : this.x;
         int thisy = parent == null ? 0 : this.y;
         Box who = (parent == null ? this : parent);
@@ -248,7 +250,7 @@ public final class Box extends JSScope implements Task {
             this.width = width; this.height = height; this.x = x; this.y = y;
             dirty();
         }
-        if (sizechange) putAndTriggerTrapsAndCatchExceptions("SizeChange", T);
+        if (sizechange) putAndTriggerTrapsAndCatchExceptions(SIZECHANGE, T);
     }
 
     private float targetColumnSize = (float)0.0;
@@ -434,10 +436,10 @@ public final class Box extends JSScope implements Task {
     // Methods to implement org.ibex.js.JS //////////////////////////////////////
 
   
-    public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
+    public JS callMethod(JS method, JS a0, JS a1, JS a2, JS[] rest, int nargs) throws JSExn {
         switch (nargs) {
             case 1: {
-                //#switch(method)
+                //#switch(JS.toString(method))
                 case "indexof":
                     Box b = (Box)a0;
                     if (b.parent != this)
@@ -449,8 +451,8 @@ public final class Box extends JSScope implements Task {
                 case "distanceto":
                     Box b = (Box)a0;
                     JS ret = new JS.O();
-                    ret.put("x", N(b.localToGlobalX(0) - localToGlobalX(0)));
-                    ret.put("y", N(b.localToGlobalY(0) - localToGlobalY(0)));
+                    ret.put(JS.S("x"), N(b.localToGlobalX(0) - localToGlobalX(0)));
+                    ret.put(JS.S("y"), N(b.localToGlobalY(0) - localToGlobalY(0)));
                     return ret;
 
                 //#end
@@ -459,29 +461,30 @@ public final class Box extends JSScope implements Task {
         return super.callMethod(method, a0, a1, a2, rest, nargs);
     }
 
-    public Object get(Object name) throws JSExn {
-        if (name instanceof Number)
-            return redirect == null ? null : redirect == this ? getChild(toInt(name)) : redirect.get(name);
+    public JS get(JS name) throws JSExn {
+        if (JS.isInt(name))
+            return redirect == null ? null : redirect == this ? getChild(JS.toInt(name)) : redirect.get(name);
 
-        //#switch(name)
-        case "surface": return parent == null ? null : parent.getAndTriggerTraps("surface");
+        //#switch(JS.toString(name))
+        case "surface": return parent == null ? null : parent.getAndTriggerTraps(name);
         case "indexof": return METHOD;
         case "distanceto": return METHOD;
-        case "text": return text;
-        case "path": 
-            if (path != null) return path.toString();
+        case "text": return JS.S(text);
+        case "path": {
+            if (path != null) return JS.S(path.toString());
             if (text == null) return null;
             if (font == null) return null;
             String ret = "";
             for(int i=0; i<text.length(); i++) ret += font.glyphs[text.charAt(i)].path;
-            return ret;
-        case "fill": return Color.colorToString(fillcolor);
-        case "strokecolor": return Color.colorToString(strokecolor);
-        case "textcolor": return Color.colorToString(strokecolor);
+            return JS.S(ret);
+        }
+        case "fill": return JS.S(Color.colorToString(fillcolor));
+        case "strokecolor": return JS.S(Color.colorToString(strokecolor));
+        case "textcolor": return JS.S(Color.colorToString(strokecolor));
         case "font": return font == null ? null : font.stream;
         case "fontsize": return font == null ? N(10) : N(font.pointsize);
         case "strokewidth": return N(strokewidth);
-        case "align": return alignToString();
+        case "align": return JS.S(alignToString());
         case "thisbox": return this;
         case "shrink": return B(test(HSHRINK) || test(VSHRINK));
         case "hshrink": return B(test(HSHRINK));
@@ -500,18 +503,18 @@ public final class Box extends JSScope implements Task {
         case "minheight": return N(minheight);
         case "maxheight": return N(maxheight);
         case "clip": return B(test(CLIP));
-        case "visible": return B(test(VISIBLE) && (parent == null || (parent.get("visible") == T)));
+        case "visible": return B(test(VISIBLE) && (parent == null || (parent.get(JS.S("visible")) == T)));
         case "packed": return B(test(PACKED));
         case "globalx": return N(localToGlobalX(0));
         case "globaly": return N(localToGlobalY(0));
-        case "cursor": return test(CURSOR) ? boxToCursor.get(this) : null;
+        case "cursor": return test(CURSOR) ? JS.S((String)boxToCursor.get(this)) : null;
         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 "redirect": return redirect == null ? null : redirect == this ? T : redirect.get("redirect");
+        case "numchildren": return redirect == null ? N(0) : redirect == this ? N(treeSize()) : redirect.get(JS.S("numchildren"));
+        case "redirect": return redirect == null ? null : redirect == this ? T : redirect.get(JS.S("redirect"));
         case "Minimized": if (parent == null && getSurface() != null) return B(getSurface().minimized);
         default: return super.get(name);
         //#end
@@ -519,8 +522,8 @@ public final class Box extends JSScope implements Task {
     }
 
     private class Mouse extends JS implements JS.Cloneable {
-        public Object get(Object key) {
-            //#switch(key)
+        public JS get(JS key) throws JSExn {
+            //#switch(JS.toString(key))
             case "x": return N(globalToLocalX(getSurface()._mousex));
             case "y": return N(globalToLocalY(getSurface()._mousey));
 
@@ -546,13 +549,13 @@ public final class Box extends JSScope implements Task {
     }
     //#end
 
-    public void put(Object name, Object value) throws JSExn {
-        if (name instanceof Number) { put(toInt(name), value); return; }
-        //#switch(name)
+    public void put(JS name, JS value) throws JSExn {
+        if (JS.isInt(name)) { put(JS.toInt(name), value); return; }
+        //#switch(JS.toString(name))
         case "thisbox":     if (value == null) removeSelf();
-        case "text":        if (value == null) value = ""; CHECKSET_STRING(text); RECONSTRAIN(); dirty();
-        case "strokecolor": value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); dirty();
-        case "textcolor":   value = N(Color.stringToColor((String)value)); CHECKSET_INT(strokecolor); dirty();
+        case "text":        { String s = value == null ?  "" : JS.toString(value); CHECKSET_STRING(text); RECONSTRAIN(); dirty(); }
+        case "strokecolor": value = N(Color.stringToColor(JS.toString(value))); CHECKSET_INT(strokecolor); dirty();
+        case "textcolor":   value = N(Color.stringToColor(JS.toString(value))); CHECKSET_INT(strokecolor); dirty();
         case "strokewidth": CHECKSET_SHORT(strokewidth); dirty();
         case "shrink":      CHECKSET_FLAG(HSHRINK | VSHRINK); RECONSTRAIN();
         case "hshrink":     CHECKSET_FLAG(HSHRINK); RECONSTRAIN();
@@ -568,8 +571,8 @@ public final class Box extends JSScope implements Task {
         case "rowspan":     if (toInt(value) > 0) { CHECKSET_SHORT(rowspan); if (parent != null) parent.REPACK(); }
         case "visible":     CHECKSET_FLAG(VISIBLE); RECONSTRAIN(); dirty();
         case "packed":      CHECKSET_FLAG(PACKED); if (parent != null) { parent.REPACK(); } else { REPACK(); }
-        case "align":       clear(ALIGNS); setAlign(value == null ? "center" : value); REPLACE();
-        case "cursor":      setCursor(value);
+        case "align":       clear(ALIGNS); setAlign(value == null ? "center" : JS.toString(value)); REPLACE();
+        case "cursor":      setCursor(JS.toString(value));
         case "fill":        setFill(value);
         case "clip":        CHECKSET_FLAG(CLIP); if (parent == null) dirty(); else parent.dirty();
         case "rows": CHECKSET_SHORT(rows); if (rows==0){set(FIXED, COLS);if(cols==0)cols=1;} else set(FIXED, ROWS); REPACK();
@@ -577,8 +580,8 @@ public final class Box extends JSScope implements Task {
 
         // FIXME: remove
         case "mouse":
-            int mousex = toInt(((JS)value).get("x"));
-            int mousey = toInt(((JS)value).get("y"));
+            int mousex = toInt(((JS)value).get(JS.S("x")));
+            int mousey = toInt(((JS)value).get(JS.S("y")));
             getSurface()._mousex = localToGlobalX(mousex);
             getSurface()._mousey = localToGlobalY(mousey);
 
@@ -592,7 +595,7 @@ public final class Box extends JSScope implements Task {
         case "fontsize": font = Font.getFont(font == null ? null : font.stream, toInt(value)); RECONSTRAIN(); dirty();
         case "font":
             if(!(value instanceof Stream)) throw new JSExn("You can only put streams to the font property");
-            if (font == value) return;  // FIXME: unclone()
+            //FIXME: if (font == value) return;  // FIXME: unclone()
             font = value == null ? null : Font.getFont((Stream)value, font == null ? 10 : font.pointsize);
             RECONSTRAIN();
             dirty();
@@ -629,9 +632,9 @@ public final class Box extends JSScope implements Task {
         case "KeyReleased":   if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
         case "Move":          if (!test(STOP_UPWARD_PROPAGATION) && parent != null) parent.putAndTriggerTraps(name, value);
         case "HScroll":       if (!test(STOP_UPWARD_PROPAGATION) && parent != null)
-            parent.putAndTriggerTraps(name, N(((Number)value).floatValue() * ((float)parent.fontSize()) / ((float)fontSize())));
+            parent.putAndTriggerTraps(name, N(JS.toFloat(value) * ((float)parent.fontSize()) / ((float)fontSize())));
         case "VScroll":       if (!test(STOP_UPWARD_PROPAGATION) && parent != null)
-            parent.putAndTriggerTraps(name, N(((Number)value).floatValue() * ((float)parent.fontSize()) / ((float)fontSize())));
+            parent.putAndTriggerTraps(name, N(JS.toFloat(value) * ((float)parent.fontSize()) / ((float)fontSize())));
 
         case "_Move":         propagateDownward(name, value, false);
         case "_Press1":       propagateDownward(name, value, false);
@@ -675,7 +678,7 @@ public final class Box extends JSScope implements Task {
         }
     }
 
-    private void setAlign(Object value) {
+    private void setAlign(String value) {
         clear(ALIGNS);
         //#switch(value)
         case "topleft": set(ALIGN_TOP | ALIGN_LEFT);
@@ -690,7 +693,7 @@ public final class Box extends JSScope implements Task {
         //#end
     }
     
-    private void setCursor(Object value) {
+    private void setCursor(String value) throws JSExn {
         if (value == null) { clear(CURSOR); boxToCursor.remove(this); return; }
         if (value.equals(boxToCursor.get(this))) return;
         set(CURSOR);
@@ -702,24 +705,22 @@ public final class Box extends JSScope implements Task {
         if (surface.cursor != tempcursor) surface.syncCursor();
     }
 
-    private void setFill(Object value) throws JSExn {
+    private void setFill(JS value) throws JSExn {
         if (value == null) {
             if (texture == null && fillcolor == 0) return;
             texture = null;
             fillcolor = 0;
-        } else if (value instanceof String) {
-            int newfillcolor = Color.stringToColor((String)value);
+        } else if (JS.isString(value)) {
+            int newfillcolor = Color.stringToColor(JS.toString(value));
             if (newfillcolor == fillcolor) return;
             fillcolor = newfillcolor;
             texture = null;
-        } else if (value instanceof JS) {
+        } else {
             Picture newtex = Picture.load((JS)value, this);
             if (texture == newtex) return;
             texture = newtex;
             fillcolor = 0;
             if (texture != null && texture.isLoaded) perform();
-        } else {
-            throw new JSExn("fill must be null, a String, or a stream, not a " + value.getClass());
         }
         dirty();
     }
@@ -728,9 +729,9 @@ public final class Box extends JSScope implements Task {
      *  Handles events which propagate down the box tree.  If obscured
      *  is set, then we merely check for Enter/Leave.
      */
-    private void propagateDownward(Object name_, Object value, boolean obscured) {
+    private void propagateDownward(JS name_, JS value, boolean obscured) throws JSExn {
 
-        String name = (String)name_;
+        String name = JS.toString(name_);
         if (getSurface() == null) return;
         int x = globalToLocalX(getSurface()._mousex);
         int y = globalToLocalY(getSurface()._mousey);
@@ -738,28 +739,28 @@ public final class Box extends JSScope implements Task {
         boolean isinside = test(VISIBLE) && inside(x, y) && !obscured;
         if (!wasinside && isinside) {
             set(MOUSEINSIDE);
-            putAndTriggerTrapsAndCatchExceptions("Enter", T);
+            putAndTriggerTrapsAndCatchExceptions(JS.S("Enter"), T);
         }
         if (isinside && test(CURSOR)) getSurface().cursor = (String)boxToCursor.get(this);
         if (wasinside && !isinside) {
             clear(MOUSEINSIDE);
-            putAndTriggerTrapsAndCatchExceptions("Leave", T);
+            putAndTriggerTrapsAndCatchExceptions(JS.S("Leave"), T);
         }
 
         boolean found = false;
         if (wasinside || isinside)
             for(Box child = getChild(treeSize() - 1); child != null; child = child.prevSibling()) {
                 boolean save_stop = child.test(STOP_UPWARD_PROPAGATION);
-                Object value2 = value;
+                JS value2 = value;
                 if (name.equals("_HScroll") || name.equals("_VScroll"))
-                    value2 = N(((Number)value).floatValue() * ((float)child.fontSize()) / (float)fontSize());
+                    value2 = N(JS.toFloat(value) * ((float)child.fontSize()) / (float)fontSize());
                 if (obscured || !child.inside(x - child.x, y - child.y)) {
-                    child.propagateDownward(name, value2, true);
+                    child.propagateDownward(name_, value2, true);
                 } else try {
                     found = true;
                     child.clear(STOP_UPWARD_PROPAGATION);
-                    if (name != null) child.putAndTriggerTrapsAndCatchExceptions(name, value2);
-                    else child.propagateDownward(name, value2, obscured);
+                    if (name != null) child.putAndTriggerTrapsAndCatchExceptions(name_, value2);
+                    else child.propagateDownward(name_, value2, obscured);
                 } finally {
                     if (save_stop) child.set(STOP_UPWARD_PROPAGATION); else child.clear(STOP_UPWARD_PROPAGATION);
                 }
@@ -771,7 +772,7 @@ public final class Box extends JSScope implements Task {
         if (!obscured && !found)
             if ("_Move".equals(name) || name.startsWith("_Release") || wasinside)
                 if (name != null)
-                    putAndTriggerTrapsAndCatchExceptions(name.substring(1), value);
+                    putAndTriggerTrapsAndCatchExceptions(JS.S(name.substring(1)), value);
     }
 
     /** figures out what box in this subtree of the Box owns the pixel at x,y relitave to the Surface */
@@ -862,10 +863,10 @@ public final class Box extends JSScope implements Task {
         deleteNode(i);
         b.parent = null;
         REPACK();
-        putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+        putAndTriggerTrapsAndCatchExceptions(JS.S("ChildChange"), b);
     }
     
-    public void put(int i, Object value) throws JSExn {
+    public void put(int i, JS value) throws JSExn {
         if (i < 0) return;
             
         if (value != null && !(value instanceof Box)) {
@@ -874,22 +875,22 @@ public final class Box extends JSScope implements Task {
         }
 
         if (redirect == null) {
-            if (value == null) putAndTriggerTrapsAndCatchExceptions("ChildChange", getChild(i));
+            if (value == null) putAndTriggerTrapsAndCatchExceptions(JS.S("ChildChange"), getChild(i));
             else JS.warn("attempt to add/remove children to/from a node with a null redirect");
 
         } else if (redirect != this) {
-            if (value != null) putAndTriggerTrapsAndCatchExceptions("ChildChange", value);
+            if (value != null) putAndTriggerTrapsAndCatchExceptions(JS.S("ChildChange"), value);
             redirect.put(i, value);
             if (value == null) {
-                Box b = (Box)redirect.get(new Integer(i));
-                if (b != null) putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+                Box b = (Box)redirect.get(JS.N(i));
+                if (b != null) putAndTriggerTrapsAndCatchExceptions(JS.S("ChildChange"), b);
             }
 
         } else if (value == null) {
             if (i < 0 || i > treeSize()) return;
             Box b = getChild(i);
             removeChild(i);
-            putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+            putAndTriggerTrapsAndCatchExceptions(JS.S("ChildChange"), b);
 
         } else {
             Box b = (Box)value;
@@ -918,26 +919,19 @@ public final class Box extends JSScope implements Task {
             REPACK();
             
             b.dirty(); 
-            putAndTriggerTrapsAndCatchExceptions("ChildChange", b);
+            putAndTriggerTrapsAndCatchExceptions(JS.S("ChildChange"), b);
         }
     }
     
-    public void putAndTriggerTrapsAndCatchExceptions(Object name, Object val) {
+    public void putAndTriggerTrapsAndCatchExceptions(JS name, JS val) {
         try {
             putAndTriggerTraps(name, val);
         } catch (JSExn e) {
-            JS.log("caught js exception while putting to trap \""+name+"\"");
+            JS.log("caught js exception while putting to trap \""+ JS.debugToString(name)+"\"");
             JS.log(e);
         } catch (Exception e) {
-            JS.log("caught exception while putting to trap \""+name+"\"");
+            JS.log("caught exception while putting to trap \""+ JS.debugToString(name)+"\"");
             JS.log(e);
         }
     }
-
 }
-
-
-
-
-
-