package votorola.s.gwt.stage.vote; // Copyright 2013, Michael Allan. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Votorola Software"), to deal in the Votorola Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicence, and/or sell copies of the Votorola Software, and to permit persons to whom the Votorola Software is furnished to do so, subject to the following conditions: The preceding copyright notice and this permission notice shall be included in all copies or substantial portions of the Votorola Software. THE VOTOROLA SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE VOTOROLA SOFTWARE OR THE USE OR OTHER DEALINGS IN THE VOTOROLA SOFTWARE. import org.vectomatic.dom.svg.*; import votorola.g.web.gwt.svg.*; import static com.google.gwt.dom.client.Style.Display.INLINE; /** A view of a count node that may appear in "broken" form.
* * +---------------------+ +-------------------+ * \ \ \ \ * \ + + \ * + / / + * / + + / * / \ \ / * +-----------------------+ +-----------------+* * @see Acknowledgement to Thomas von der Elbe */ final class BreakableNodeV extends NodeV { /** Constructs a BreakableNodeV. * * @see #box() * @see #dartSector() */ BreakableNodeV( Box _box, int _dartSector, VoteTrack _track ) { super( _box, _dartSector, _track ); insertBefore( new BreakLine(), getLastChild() ); } // ------------------------------------------------------------------------------------ /** @throws UnsupportedOperationException because you should instead use the other * repaint method. */ @Override void repaint( float _x, float _length, float _protrusion, int _y, float _halfThickness ) { throw new UnsupportedOperationException(); } /** Redraws this view according to the provided parameters. The view never * automatically initiates a repaint, but depends entirely on its MajorV ancestor for * this. * * @param lengthMax the maximum allowable length. If the requested length is * greater, then the view is truncated and painted in broken form. */ void repaint( final float x, float length, final float protrusion, final int y, final float halfThickness, final float lengthMax ) { if( length > lengthMax ) { length = lengthMax; setBroken(); breakLine().repaint( x, length, protrusion, y, halfThickness ); } else clearBroken(); super.repaint( x, length, protrusion, y, halfThickness ); } //// P r i v a t e /////////////////////////////////////////////////////////////////////// private BreakLine breakLine() { return (BreakLine)getFirstChild().getNextSibling(); } /** Answers whether the view is to appear in broken form. */ private boolean isBroken; private void clearBroken() { if( !isBroken ) return; breakLine().getStyle().clearDisplay(); // default to "none" as set in vote/track.css isBroken = false; } private void setBroken() { if( isBroken ) return; breakLine().getStyle().setDisplay( INLINE ); // as cycler isBroken = true; } // ==================================================================================== private final class BreakLine extends OMSVGPathElement { BreakLine() { addClassNameBaseVal( "BreakLine" ); final OMSVGPathSegList sL = getPathSegList(); /*0*/sL.appendItem( createSVGPathSegMovetoAbs( 0,0 )); /*1*/sL.appendItem( createSVGPathSegLinetoRel( 0,0 )); /*2*/sL.appendItem( createSVGPathSegLinetoRel( 0,0 )); /*3*/sL.appendItem( createSVGPathSegLinetoRel( 0,0 )); } void repaint( final float x, final float length, final float protrusion, final int y, float halfThickness ) { final OMSVGPathSegList sL = getPathSegList(); final int xMid = Math.round( x + length - length/4 ); final int halfProtrusion = Math.round( protrusion / 2 ); final int smallDrop = Math.round( halfThickness / 2 ); // final float bigDrop = /*full*/halfThickness * 2 - /*used*/smallDrop * 2; /// or eqivalently: final float bigDrop = 2 * (halfThickness - smallDrop); // 0 // +---------------+ +-------------+ // \ \ \ \ // \ + + 1 \ // + / / + // / 2 + + / // / \ \ / // +-----------------+ +-----------+ // 3 PathSeg.movetoAbs( sL, 0, xMid, y ); PathSeg.lineToRel( sL, 1, -halfProtrusion, smallDrop ); PathSeg.lineToRel( sL, 2, protrusion, smallDrop ); PathSeg.lineToRel( sL, 3, -halfProtrusion, bigDrop ); } } }