* SizeChanges trigger an Surface.abort; if rendering were done in the same
* pass, rendering work done prior to the Surface.abort would be wasted.
*/
-public final class Box extends JSScope implements JSTrap.JSTrappable {
+public final class Box extends JSScope {
// Macros //////////////////////////////////////////////////////////////////////
}
}
- public void putAndTriggerJSTraps(Object key, Object value) {
- JSContext.invokeTrap(this, key, value);
- }
-
/** update MOUSEINSIDE, check for Enter/Leave/Move */
void Move(int oldmousex, int oldmousey, int mousex, int mousey) { Move(oldmousex, oldmousey, mousex, mousey, false); }
void Move(int oldmousex, int oldmousey, int mousex, int mousey, boolean forceleave) {
if (!wasinside && !isinside) return;
if (isinside && test(CURSOR)) Surface.fromBox(getRoot()).cursor = (String)boxToCursor.get(this);
- if (!wasinside && isinside && getTrap("Enter") != null) putAndTriggerJSTraps("Enter", T);
- else if (wasinside && !isinside && getTrap("Leave") != null) putAndTriggerJSTraps("Leave", T);
+ if (!wasinside && isinside && getTrap("Enter") != null) putAndTriggerTraps("Enter", T);
+ else if (wasinside && !isinside && getTrap("Leave") != null) putAndTriggerTraps("Leave", T);
else if (wasinside && isinside && (mousex != oldmousex || mousey != oldmousey) && getTrap("Move")!= null)
- putAndTriggerJSTraps("Move", T);
+ putAndTriggerTraps("Move", T);
for(Box b = getChild(numchildren - 1); b != null; b = b.prevSibling()) {
b.Move(oldmousex - b.x, oldmousey - b.y, mousex - b.x, mousey - b.y, forceleave);
if (b.inside(mousex - b.x, mousey - b.y)) forceleave = true;
boolean poschange = (this.x != x || this.y != y) && getTrap("PosChange") != null;
this.width = width; this.height = height; this.x = x; this.y = y;
dirty();
- try { if (sizechange) putAndTriggerJSTraps("SizeChange", T); /*Surface.abort = true;*/ }
+ try { if (sizechange) putAndTriggerTraps("SizeChange", T); /*Surface.abort = true;*/ }
catch (Exception e) { Log.log(this, e); }
- try { if (poschange) putAndTriggerJSTraps("PosChange", T); /*Surface.abort = true;*/ }
+ try { if (poschange) putAndTriggerTraps("PosChange", T); /*Surface.abort = true;*/ }
catch (Exception e) { Log.log(this, e); }
}
}
public int localToGlobalX(int x) { return parent == null ? x : parent.globalToLocalX(x + this.x); }
public int localToGlobalY(int y) { return parent == null ? y : parent.globalToLocalY(y + this.y); }
- public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JS.Exn {
+ public Object callMethod(Object method, Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn {
if (nargs != 1 || !"indexof".equals(method)) return super.callMethod(method, a0, a1, a2, rest, nargs);
Box b = (Box)a0;
if (b.parent != this)
/** to be filled in by the Tree implementation */
public int numchildren = 0;
- public Object get(Object name) { return get(name, false); }
- public Object get(Object name, boolean ignoretraps) {
+ protected boolean isTrappable() { return true; }
+ public Object get(Object name) {
if (name instanceof Number)
return redirect == null ? null : redirect == this ? getChild(toInt(name)) : redirect.get(name);
//#switch(name)
case "indexof": return METHOD;
case "text": return text;
- case "path": throw new JS.Exn("cannot read from the path property");
+ case "path": throw new JSExn("cannot read from the path property");
case "fill": return colorToString(fillcolor);
case "strokecolor": return colorToString(strokecolor);
case "textcolor": return colorToString(strokecolor);
case "Minimized": if (parent == null && getSurface() != null) return B(getSurface().minimized);
default: return super.get(name);
//#end
- return null;
+ throw new Error("unreachable"); // unreachable
}
- public void put(Object name, Object value) { put(name, value, false); }
- public void put(Object name, Object value, boolean ignoretraps) {
+ public void put(Object name, Object value) {
if (name instanceof Number) { put(toInt(name), value); return; }
-
//#switch(name)
case "text": CHECKSET_STRING(text); MARK_RESIZE; dirty();
case "strokecolor": value = N(stringToColor((String)value)); CHECKSET_INT(strokecolor); MARK_RESIZE; dirty();
case "fontsize": font = Font.getFont(font == null ? null : font.res, toInt(value)); MARK_RESIZE; dirty();
case "x": if (test(PACKED) && parent != null) return; CHECKSET_INT(x); dirty(); MARK_RESIZE; dirty();
case "y": if (test(PACKED) && parent != null) return; CHECKSET_INT(y); dirty(); MARK_RESIZE; dirty();
- case "KeyPressed": // prevent stuff from hitting the Hash
- case "KeyReleased": // prevent stuff from hitting the Hash
- case "PosChange": // prevent stuff from hitting the Hash
- case "SizeChange": // prevent stuff from hitting the Hash
- case "childadded": // prevent stuff from hitting the Hash
- case "childremoved": // prevent stuff from hitting the Hash
+ case "KeyPressed": return; // prevent stuff from hitting the Hash
+ case "KeyReleased": return; // prevent stuff from hitting the Hash
+ case "PosChange": return; // prevent stuff from hitting the Hash
+ case "SizeChange": return; // prevent stuff from hitting the Hash
+ case "childadded": return; // prevent stuff from hitting the Hash
+ case "childremoved": return; // prevent stuff from hitting the Hash
+ default: super.put(name, value);
//#end
}
int mousex = globalToLocalX(surface.mousex);
int mousey = globalToLocalY(surface.mousey);
for(Box c = prevSibling(); c != null; c = c.prevSibling())
- if (c.inside(mousex - c.x, mousey - c.y)) { c.putAndTriggerJSTraps(name, value); return; }
- if (parent != null) parent.putAndTriggerJSTraps(name, value);
+ if (c.inside(mousex - c.x, mousey - c.y)) { c.putAndTriggerTraps(name, value); return; }
+ if (parent != null) parent.putAndTriggerTraps(name, value);
}
private static int stringToColor(String s) {
public final Box peerTree_rightmost() { for (Box p = this; ; p = p.right) if (p.right == null) return p; }
static Box peerTree_parent(Box p) { return (p == null)? null: p.peerTree_parent; }
- public Box insertBeforeMe(Box cell) { left = cell; cell.peerTree_parent = this; return cell.fixAfterInsertion(); }
- public Box insertAfterMe(Box cell) { right = cell; cell.peerTree_parent = this; return cell.fixAfterInsertion(); }
+ public void insertBeforeMe(Box cell) { left = cell; cell.peerTree_parent = this; cell.fixAfterInsertion(); }
+ public void insertAfterMe(Box cell) { right = cell; cell.peerTree_parent = this; cell.fixAfterInsertion(); }
static boolean colorOf(Box p) { return (p == null) ? BLACKbool : p.test(BLACK); }
static void setColor(Box p, boolean c) { if (p != null) { if (c) p.set(BLACK); else p.clear(BLACK); } }
}
}
- public Box removeNode() {
- Box root = peerTree_parent.rootChild;
+ public void removeNode() {
// handle case where we are only node
- if (left == null && right == null && peerTree_parent == null) return null;
+ if (left == null && right == null && peerTree_parent == null) return;
// if strictly internal, swap places with a successor
if (left != null && right != null) {
// To work nicely with arbitrary subclasses of Box, we don't want to
// just copy successor's fields. since we don't know what
// they are. Instead we swap positions in the tree.
- root = swapPosition(this, s);
+ swapPosition(this, s);
}
// Start fixup at replacement node (normally a child).
if (left == null && right == null) {
- if (test(BLACK)) root = this.fixAfterDeletion();
+ if (test(BLACK)) fixAfterDeletion();
// Unlink (Couldn't before since fixAfterDeletion needs peerTree_parent ptr)
// link replacement to peerTree_parent
replacement.peerTree_parent = peerTree_parent;
- if (peerTree_parent == null) root = replacement;
+ if (peerTree_parent == null) parent.rootChild = replacement;
else if (this == peerTree_parent.left) peerTree_parent.left = replacement;
- else peerTree_parent.right = replacement;
+ else peerTree_parent.right = replacement;
left = null;
right = null;
peerTree_parent = null;
// fix replacement
- if (test(BLACK)) root = replacement.fixAfterDeletion();
+ if (test(BLACK)) replacement.fixAfterDeletion();
}
-
- return root;
}
/**
* Swap the linkages of two nodes in a tree.
* Return new root, in case it changed.
**/
- Box swapPosition(Box x, Box y) {
- Box root = peerTree_parent.rootChild;
+ void swapPosition(Box x, Box y) {
/* Too messy. TODO: find sequence of assigments that are always OK */
if (y.test(BLACK)) x.set(BLACK); else x.clear(BLACK);
if (c) y.set(BLACK); else y.clear(BLACK);
- if (root == x) root = y;
- else if (root == y) root = x;
- return parent.rootChild = root;
+ if (parent.rootChild == x) parent.rootChild = y;
+ else if (parent.rootChild == y) parent.rootChild = x;
}
- Box rotateLeft() {
- Box root = parent.rootChild;
+ void rotateLeft() {
Box r = right;
right = r.left;
if (r.left != null) r.left.peerTree_parent = this;
r.peerTree_parent = peerTree_parent;
- if (peerTree_parent == null) root = r;
+ if (peerTree_parent == null) parent.rootChild = r;
else if (peerTree_parent.left == this) peerTree_parent.left = r;
else peerTree_parent.right = r;
r.left = this;
peerTree_parent = r;
- return parent.rootChild = root;
}
- Box rotateRight() {
- Box root = parent.rootChild;
+ void rotateRight() {
Box l = left;
left = l.right;
if (l.right != null) l.right.peerTree_parent = this;
l.peerTree_parent = peerTree_parent;
- if (peerTree_parent == null) root = l;
+ if (peerTree_parent == null) parent.rootChild = l;
else if (peerTree_parent.right == this) peerTree_parent.right = l;
else peerTree_parent.left = l;
l.right = this;
peerTree_parent = l;
- return parent.rootChild;
}
- Box fixAfterInsertion() {
- Box root = parent.rootChild;
+ void fixAfterInsertion() {
clear(BLACK);
Box x = this;
- while (x != null && x != root && !x.peerTree_parent.test(BLACK)) {
+ while (x != null && x != parent.rootChild && !x.peerTree_parent.test(BLACK)) {
if (peerTree_parent(x) == leftOf(peerTree_parent(peerTree_parent(x)))) {
Box y = rightOf(peerTree_parent(peerTree_parent(x)));
if (colorOf(y) == REDbool) {
else {
if (x == rightOf(peerTree_parent(x))) {
x = peerTree_parent(x);
- root = x.rotateLeft();
+ x.rotateLeft();
}
setColor(peerTree_parent(x), BLACKbool);
setColor(peerTree_parent(peerTree_parent(x)), REDbool);
if (peerTree_parent(peerTree_parent(x)) != null)
- root = peerTree_parent(peerTree_parent(x)).rotateRight();
+ peerTree_parent(peerTree_parent(x)).rotateRight();
}
}
else {
else {
if (x == leftOf(peerTree_parent(x))) {
x = peerTree_parent(x);
- root = x.rotateRight();
+ x.rotateRight();
}
setColor(peerTree_parent(x), BLACKbool);
setColor(peerTree_parent(peerTree_parent(x)), REDbool);
if (peerTree_parent(peerTree_parent(x)) != null)
- root = peerTree_parent(peerTree_parent(x)).rotateLeft();
+ peerTree_parent(peerTree_parent(x)).rotateLeft();
}
}
}
- root.set(BLACK);
- return parent.rootChild = root;
+ parent.rootChild.set(BLACK);
}
/** From CLR **/
- Box fixAfterDeletion() {
- Box root = peerTree_parent.rootChild;
+ void fixAfterDeletion() {
Box x = this;
- while (x != root && colorOf(x) == BLACKbool) {
+ while (x != parent.rootChild && colorOf(x) == BLACKbool) {
if (x == leftOf(peerTree_parent(x))) {
Box sib = rightOf(peerTree_parent(x));
if (colorOf(sib) == REDbool) {
setColor(sib, BLACKbool);
setColor(peerTree_parent(x), REDbool);
- root = peerTree_parent(x).rotateLeft();
+ peerTree_parent(x).rotateLeft();
sib = rightOf(peerTree_parent(x));
}
if (colorOf(leftOf(sib)) == BLACKbool && colorOf(rightOf(sib)) == BLACKbool) {
if (colorOf(rightOf(sib)) == BLACKbool) {
setColor(leftOf(sib), BLACKbool);
setColor(sib, REDbool);
- root = sib.rotateRight();
+ sib.rotateRight();
sib = rightOf(peerTree_parent(x));
}
setColor(sib, colorOf(peerTree_parent(x)));
setColor(peerTree_parent(x), BLACKbool);
setColor(rightOf(sib), BLACKbool);
- root = peerTree_parent(x).rotateLeft();
- x = root;
+ peerTree_parent(x).rotateLeft();
+ x = parent.rootChild;
}
}
else {
if (colorOf(sib) == REDbool) {
setColor(sib, BLACKbool);
setColor(peerTree_parent(x), REDbool);
- root = peerTree_parent(x).rotateRight();
+ peerTree_parent(x).rotateRight();
sib = leftOf(peerTree_parent(x));
}
if (colorOf(rightOf(sib)) == BLACKbool && colorOf(leftOf(sib)) == BLACKbool) {
if (colorOf(leftOf(sib)) == BLACKbool) {
setColor(rightOf(sib), BLACKbool);
setColor(sib, REDbool);
- root = sib.rotateLeft();
+ sib.rotateLeft();
sib = leftOf(peerTree_parent(x));
}
setColor(sib, colorOf(peerTree_parent(x)));
setColor(peerTree_parent(x), BLACKbool);
setColor(leftOf(sib), BLACKbool);
- root = peerTree_parent(x).rotateRight();
- x = root;
+ peerTree_parent(x).rotateRight();
+ x = parent.rootChild;
}
}
}
setColor(x, BLACKbool);
- return parent.rootChild = root;
}
// Tree Manipulation /////////////////////////////////////////////////////////////////////
removeNode();
parent = null;
if (oldparent != null) { Box b = oldparent; MARK_REFLOW_b; }
- if (oldparent != null) oldparent.putAndTriggerJSTraps("childremoved", this);
+ if (oldparent != null) oldparent.putAndTriggerTraps("childremoved", this);
}
/** Returns ith child */
}
if (redirect == null) {
- if (value == null) putAndTriggerJSTraps("childremoved", getChild(i));
+ if (value == null) putAndTriggerTraps("childremoved", getChild(i));
else Log.logJS(this, "attempt to add/remove children to/from a node with a null redirect");
} else if (redirect != this) {
- if (value != null) putAndTriggerJSTraps("childadded", value);
+ if (value != null) putAndTriggerTraps("childadded", value);
redirect.put(i, value);
if (value == null) {
Box b = (Box)redirect.get(new Integer(i));
- if (b != null) putAndTriggerJSTraps("childremoved", b);
+ if (b != null) putAndTriggerTraps("childremoved", b);
}
} else if (value == null) {
if (i < 0 || i > numchildren) return;
Box b = getChild(i);
b.remove();
- putAndTriggerJSTraps("childremoved", b);
+ putAndTriggerTraps("childremoved", b);
} else {
Box b = (Box)value;
MARK_REFLOW;
b.dirty();
- putAndTriggerJSTraps("childadded", b);
+ putAndTriggerTraps("childadded", b);
}
}