Revision: 3823 http://vexi.svn.sourceforge.net/vexi/?rev=3823&view=rev Author: clrg Date: 2010-03-26 06:35:59 +0000 (Fri, 26 Mar 2010)
Log Message: ----------- Finish up the Surface.abort implementation - move setConstrain/Place calls ahead of put logic (so abort prevents the put) - smarter setting of CONSTRAIN/PLACE in constrain()/place() - previously JSExn was thrown by abort would repeat after next reflow() but now it aborts fully Modified Paths: -------------- trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp Modified: trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp =================================================================== --- trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp 2010-03-24 17:24:20 UTC (rev 3822) +++ trunk/core/org.vexi.core/src/org/vexi/core/Box.jpp 2010-03-26 06:35:59 UTC (rev 3823) @@ -374,7 +374,10 @@ // FIXME: this is the wrong place to do this - should // prerender enlarged image at time of render and then // just paint the relevant part of the enlarged image - x = 0; y = 0; w = cur.width; h = cur.height; + x = 0; + y = 0; + w = cur.width; + h = cur.height; } else { x = max(x, 0); y = max(y, 0); @@ -430,8 +433,12 @@ dirtyInPlace(clean); //#repeat width/height WIDTH/HEIGHT if (width != this.width) { + // already in parent.place() or acting on root + set(PLACE); + if (parent!=null) { + parent.set(PLACE_DESCENDENT); + } PUT_BOX_FIELD(SC_width,JSU.N(width),this.width = width,WIDTH_TRAP) - setPlaceAndCatchExceptions(); } //#end dirtyInPlace(clean); @@ -450,8 +457,12 @@ //#end //#repeat width/height WIDTH/HEIGHT if (width != this.width) { + // already in parent.place() + set(PLACE); + if (parent!=null) { + parent.set(PLACE_DESCENDENT); + } PUT_BOX_FIELD(SC_width,JSU.N(width),this.width = width,WIDTH_TRAP) - setPlaceAndCatchExceptions(); } //#end dirtyInPlace(clean); @@ -459,6 +470,16 @@ // Reflow //////////////////////////////////////////////////////////////////////////////////////// + + /** + * Note that it is important to call these functions before doing other logic + * to enforce an abort-related exception, should it get thrown. That is, if a + * box has e.g. its minwidth set in a contentwidth trap that affects the box's + * contentwidth, if the assignment happened before the exception, the cycle + * would continue and contentwidth would grow again during subsequent reflow. + * + * This note applies to all setPlace/Constrain functions and requestReflow(). + */ private final void setConstrain() throws JSExn { set(CONSTRAIN); setConstrainInTree(); } private final void setParentConstrain() throws JSExn { @@ -466,15 +487,6 @@ parent.setConstrain(); } } - private final void setConstrainAndCatchExceptions () { - try { - set(CONSTRAIN); - setConstrainInTree(); - } catch(JSExn e) { - Log.warn(Box.class,"Caught exception due to Surface.abort during constrain"); - e.printStackTrace(Logger.WARN, Log.user, Box.class); - } - } private final void setConstrainInTree() throws JSExn { Box b=this; // FIXME: box tree is getting into inconsistent states with CONSTRAIN_DESCENDENT @@ -494,15 +506,6 @@ parent.setPlace(); } } - private final void setPlaceAndCatchExceptions () { - try { - set(PLACE); - setPlaceInTree(); - } catch(JSExn e) { - Log.warn(Box.class,"Caught exception due to Surface.abort during place"); - e.printStackTrace(Logger.WARN, Log.user, Box.class); - } - } private final void setPlaceInTree() throws JSExn { Box b=this; while (b.test(DISPLAY) && b.parent!=null && !b.parent.test(PLACE_DESCENDENT)) { @@ -514,6 +517,13 @@ s.abortReflow(); } } + private final void setPlaceNoAbort () { + Box b=this; + while (b.test(DISPLAY) && b.parent!=null && !b.parent.test(PLACE_DESCENDENT)) { + b = b.parent; + b.set(PLACE_DESCENDENT); + } + } private final void requestReflow() throws JSExn { if (test(CONSTRAIN) || test(CONSTRAIN_DESCENDENT)) { @@ -652,18 +662,18 @@ // assign contentwidth and mark for place in parent and placing of children if (newwidth != contentwidth) { if (parent != null) { + setPlaceNoAbort(); + parent.set(PLACE); + parent.set(CONSTRAIN); // parent already in constrain() PUT_BOX_FIELD(SC_contentwidth,JSU.N(newwidth),contentwidth=newwidth,CONTENTWIDTH_TRAP) - setPlaceAndCatchExceptions(); - parent.set(PLACE); - parent.setConstrainAndCatchExceptions(); } else { // constrain contentwidth to frame width if (getSurface()!=null && !test(SHRINK)) { newwidth = min(getSurface().pendingWidth, newwidth); } if (newwidth != contentwidth) { + setPlaceNoAbort(); PUT_BOX_FIELD(SC_contentwidth,JSU.N(newwidth),contentwidth=newwidth,CONTENTWIDTH_TRAP) - setPlaceAndCatchExceptions(); } } } @@ -1123,15 +1133,14 @@ } /** execute trap JS up until the put, giving extra control over the put - * it must ALWAYS be followed by a postPutTriggerTraps */ + * it must ALWAYS be followed by a postPutTriggerTrapsAndCatchExceptions */ private final JSExn prePutTriggerTrapsAndCatchExceptions(Trap t, JS name, JS val) { try { if (t != null) { Main.SCHEDULER.runBeforePut(t, val); } } catch (JSExn e) { - Log.warn(Box.class,"Caught JS Exception while putting to trap \""+name+"\""); - e.printStackTrace(Logger.WARN, Log.user, Box.class); + // exception printed by postPutTriggerTrapsAndCatchExceptions return e; } return null; @@ -1170,6 +1179,12 @@ if (minwidth<0 || minwidth>MAX_DIMENSION) { throw new JSExn("Attempt to set minwidth to a value outside the range 0-"+MAX_DIMENSION); } + // initiate reflow + setConstrain(); + // in box tree + if (parent != null) { + parent.set(CONSTRAIN); + } if (firetraps && test(MINWIDTH_TRAP)) { Trap t = wtrap(SC_minwidth); // FIXME: verify / investigate this or delete it if not reported @@ -1185,12 +1200,6 @@ } else { this.minwidth = minwidth; } - // initiate reflow - setConstrain(); - // in box tree - if (parent != null) { - parent.set(CONSTRAIN); - } } //#end @@ -1203,6 +1212,12 @@ if (maxwidth<0 || maxwidth>MAX_DIMENSION) { throw new JSExn("Attempt to set maxwidth to a value outside the range 0-"+MAX_DIMENSION); } + // initiate reflow + setConstrain(); + // in box tree + if (parent != null) { + parent.set(CONSTRAIN); + } if (firetraps && test(MAXWIDTH_TRAP)) { Trap t = wtrap(SC_maxwidth); // FIXME: verify / investigate this or delete it if not reported @@ -1218,12 +1233,6 @@ } else { this.maxwidth = maxwidth; } - // initiate reflow - setConstrain(); - // in box tree - if (parent != null) { - parent.set(CONSTRAIN); - } } //#end @@ -1260,8 +1269,8 @@ if (value==null) { // special case null value if (curalign!=0) { + setPlace(); clear(ALIGNS); - setPlace(); dirty(); } return; @@ -1278,9 +1287,9 @@ case "center": if (curalign == 0) return; newalign = 0; default: throw new JSExn("Invalid alignment \"" + value + "\" put to a box"); //#end + setPlace(); clear(ALIGNS); set(newalign); - setPlace(); dirty(); } @@ -2406,6 +2415,7 @@ if (test(HSHRINK) == shr) { return; } + setParentPlace(); if (shr) { set(HSHRINK); } else { @@ -2415,12 +2425,12 @@ if (test(VSHRINK) && test(SHRINK_TRAP)) { justTriggerTraps(SC_shrink, value); } - setParentPlace(); case "vshrink": boolean shr = JSU.toBoolean(value); if (test(VSHRINK) == shr) { return; } + setParentPlace(); if (shr) { set(VSHRINK); } else { @@ -2430,7 +2440,6 @@ if (test(HSHRINK) && test(SHRINK_TRAP)) { justTriggerTraps(SC_shrink, value); } - setParentPlace(); case "width": setMinMaxWidth(JSU.toInt(value), JSU.toInt(value)); case "height": setMinMaxHeight(JSU.toInt(value), JSU.toInt(value)); case "maxwidth": setMaxWidth(JSU.toInt(value), false); @@ -2440,6 +2449,8 @@ case "display": boolean display = JSU.toBoolean(value); if (test(DISPLAY) != display) { + setParentConstrain(); + setParentPlace(); // fire pre-cascade visible traps WriteTrapChain trapchain = get(SC_visible) == value ? null : fireVisibleTraps(display); if (display) { @@ -2457,8 +2468,6 @@ if (trapchain!=null) { trapchain.finishTraps(); } - setParentConstrain(); - setParentPlace(); } case "visible": isReadOnly(name); case "numchildren": isReadOnly(name); @@ -2508,42 +2517,52 @@ if (!test(PACK) && test(CLIP)) { return; } + setConstrain(); + setPlace(); clear(PACK); set(CLIP); } else if (SC_layer.equals(value)) { if (!test(PACK) && !test(CLIP)) { return; } + setConstrain(); + setPlace(); clear(PACK); clear(CLIP); } else if (SC_pack.equals(value)) { if (test(PACK)) { return; } + setConstrain(); + setPlace(); set(PACK); clear(CLIP); } else { throw new JSExn("Attempt to set Box property 'layout' to unsupported value '"+JSU.toString(value)+"'"); } - setConstrain(); - setPlace(); case "orient": if (JSU.toString(value).equals("horizontal")) { if (test(ORIENT)) { return; } else { + if (test(PACK)) { + setConstrain(); + setPlace(); + } set(ORIENT); } } else if (JSU.toString(value).equals("vertical")) { if (test(ORIENT)) { + if (test(PACK)) { + setConstrain(); + setPlace(); + } clear(ORIENT); } else { return; } - } else throw new JSExn("Attempt to set Box property 'orient' to unsupported value '"+JSU.toString(value)+"'"); - if (test(PACK)) { - setConstrain(); - setPlace(); + } else { + throw new JSExn("Attempt to set Box property 'orient' to unsupported value '"+JSU.toString(value)+"'"); } case "redirect": if (value == null) { @@ -2571,12 +2590,12 @@ } else if (!parent.test(PACK)) { boolean visible = isVisible(); if (visible) { + setParentPlace(); dirty(); } this.x = JSU.toInt(value); if (visible) { dirty(); - setParentPlace(); } } case "y": @@ -2590,12 +2609,12 @@ } else if (!parent.test(PACK)) { boolean visible = isVisible(); if (visible) { + setParentPlace(); dirty(); } this.y = JSU.toInt(value); if (visible) { dirty(); - setParentPlace(); } } @@ -2963,13 +2982,13 @@ /** change the parent of the box and fire relevant traps */ protected final void removeFromParent() throws JSExn { - parent.deleteNode(parent.indexNode(this)); if (test(DISPLAY)) { if (parent.test(PACK) || !parent.test(CLIP)) { parent.setConstrain(); } parent.setPlace(); } + parent.deleteNode(parent.indexNode(this)); parent = null; } @@ -2986,13 +3005,11 @@ return; } if (test(DISPLAY)) { + oldparent.setPlace(); dirty(); } oldparent.deleteNode(ind); oldparent.insertNode(i, this); - if (test(DISPLAY)) { - oldparent.setPlace(); - } return; } // check validity of new parent assignment @@ -3032,8 +3049,9 @@ propagateLeave(); } } - // assign new parent - parent = newparent; + // NOTE by now removeFromParent()* has assigned parent=null + // * also called by put(index, null...) + if (newparent != null) { newparent.insertNode(i, this); if (test(DISPLAY)) { @@ -3047,6 +3065,8 @@ } newparent.setPlace(); } + // assign new parent + parent = newparent; } // call post-cascade traps if (trapchain!=null) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Download Intel® Parallel Studio Eval Try the new software tools for yourself. Speed compiling, find bugs proactively, and fine-tune applications for parallel performance. See why Intel Parallel Studio got high marks during beta. http://p.sf.net/sfu/intel-sw-dev _______________________________________________ Vexi-svn mailing list Vexi-svn@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vexi-svn