X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2FBox.java;h=2ada11fffc1d619f9040748ceba98d1f300e1712;hp=514d301a0fcbbe083566c2e5d983da51eefe152d;hb=ae0cd6164facf843cc136f52e3f78e3843191d61;hpb=7bfa509c88f79ec899e7e6ebdb775d3c83e420f9 diff --git a/src/org/ibex/Box.java b/src/org/ibex/Box.java index 514d301..2ada11f 100644 --- a/src/org/ibex/Box.java +++ b/src/org/ibex/Box.java @@ -214,11 +214,6 @@ public final class Box extends JSScope implements Scheduler.Task { // static stuff so we don't have to keep reallocating private static int[] numRowsInCol = new int[65535]; - private static LENGTH[] colWidth = new LENGTH[65535]; - private static LENGTH[] colMaxWidth = new LENGTH[65535]; - private static LENGTH[] rowHeight = new LENGTH[65535]; - private static LENGTH[] rowMaxHeight = new LENGTH[65535]; - static { for(int i=0; i i)) + rowcontentwidth += child.contentwidth; + contentwidth = max(contentwidth, rowcontentwidth); + } contentwidth = bound(minwidth, max(font == null || text == null ? 0 : font.textwidth(text), contentwidth), maxwidth); //#end } @@ -290,37 +293,60 @@ public final class Box extends JSScope implements Scheduler.Task { } } - void resize_children() { - - //#repeat col/row colspan/rowspan contentwidth/contentheight x/y width/height colMaxWidth/rowMaxHeight colWidth/rowHeight \ - // HSHRINK/VSHRINK maxwidth/maxheight cols/rows minwidth/minheight colWidth/rowHeight x_slack/y_slack - // PHASE 1: compute column min/max sizes - for(Box child = firstPackedChild(); child != null; child = child.nextPackedSibling()) - for(int i=child.col; i < child.col + child.colspan; i++) { - colWidth[i] = max(colWidth[i], child.contentwidth / child.colspan); - colMaxWidth[i] = max(colMaxWidth[i], (child.test(HSHRINK) ? child.contentwidth : child.maxwidth) / child.colspan); + private static float[] coeff = null; + private static LinearProgramming.Simplex lp_h = new LinearProgramming.Simplex(50, 50, 300); + private static LinearProgramming.Simplex lp_v = new LinearProgramming.Simplex(50, 50, 300); + + void place_children() { + int numkids = 0; for(Box c = firstPackedChild(); c != null; c = c.nextPackedSibling()) numkids++; + //#repeat col/row colspan/rowspan contentwidth/contentheight width/height \ + // maxwidth/maxheight cols/rows minwidth/minheight lp_h/lp_v lp_h/lp_v + do { + int nc = numkids * 2 + cols * 3 + 1 + 2; + if (coeff == null || nc+1>coeff.length) coeff = new float[nc+1]; + lp_h.init(nc, nc); + + // objective function + for(int i=0; i=child.col && i=child.col && i 0 && eligible > 0;) { - int increment = max(1, x_slack / eligible); - eligible = 0; - for(short col=0, count=0; col < cols; col++) { - if (colMaxWidth[col] <= colWidth[col]) continue; - if (slacklevel + increment < colWidth[col]) { eligible++; continue; } - int diff = min(increment, min(colMaxWidth[col] - colWidth[col], slacklevel + increment - colWidth[col])); - eligible++; - colWidth[col] += diff; - x_slack -= diff; + + // priority 3: equalize columns + for(int i=0 ; i unbounded) child_x -= (child_width - unbounded) / 2; + // child_width/child_height ALIGN_RIGHT/ALIGN_BOTTOM ALIGN_LEFT/ALIGN_TOP lp_h/lp_v + child_width = 0; + child_x = 0; + for(int i=0; i < child.col; i++) child_x += Math.round(lp_h.solution[lp_h.rows+i+1]); + for(int i = child.col; i 0) + child.place_children(); } @@ -408,13 +431,28 @@ public final class Box extends JSScope implements Scheduler.Task { 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 JSExn { - if (nargs != 1 || !"indexof".equals(method)) return super.callMethod(method, a0, a1, a2, rest, nargs); - Box b = (Box)a0; - if (b.parent != this) - return (redirect == null || redirect == this) ? - N(-1) : - redirect.callMethod(method, a0, a1, a2, rest, nargs); - return N(b.getIndexInParent()); + switch (nargs) { + case 1: { + //#switch(method) + case "indexof": + Box b = (Box)a0; + if (b.parent != this) + return (redirect == null || redirect == this) ? + N(-1) : + redirect.callMethod(method, a0, a1, a2, rest, nargs); + return N(b.getIndexInParent()); + + case "distanceto": + Box b = (Box)a0; + JS ret = new JS(); + ret.put("x", N(b.localToGlobalX(0) - localToGlobalX(0))); + ret.put("y", N(b.localToGlobalY(0) - localToGlobalY(0))); + return ret; + + //#end + } + } + return super.callMethod(method, a0, a1, a2, rest, nargs); } public Enumeration keys() { throw new Error("you cannot apply for..in to a " + this.getClass().getName()); } @@ -438,6 +476,7 @@ public final class Box extends JSScope implements Scheduler.Task { //#switch(name) case "surface": return parent == null ? null : parent.getAndTriggerTraps("surface"); case "indexof": return METHOD; + case "distanceto": return METHOD; case "text": return text; case "path": throw new JSExn("cannot read from the path property"); case "fill": return colorToString(fillcolor); @@ -548,6 +587,7 @@ public final class Box extends JSScope implements Scheduler.Task { case "Maximized": if (parent == null && getSurface() != null) getSurface().maximized = toBoolean(value); // FEATURE case "Close": if (parent == null && getSurface() != null) getSurface().dispose(true); case "redirect": + if (value == null) { redirect = null; return; } for(Box cur = (Box)value; cur != null; cur = cur.parent) if (cur == redirect) { redirect = (Box)value;