001package votorola.s.gwt.wic; // Copyright 2012, 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. 002 003import com.google.gwt.dom.client.*; 004import org.vectomatic.dom.svg.*; 005import votorola.g.web.gwt.*; 006import votorola.g.web.gwt.event.*; 007import votorola.g.web.gwt.svg.*; 008import votorola.s.gwt.stage.vote.*; 009 010import static votorola.s.gwt.stage.vote.PeerBoardV.PIN_IMG_WIDTH; 011 012 013/** A component of the bridge/stage {@linkplain DIn tie overlay} that visually ties the 014 * selected drafter's link (sLink) at top left of the bridge scene to the pin indicator 015 * in the vote track.<pre> 016 * 017 * pin + 018 * indicator / \ 019 * +-+-+ 020 * | 021 * | 022 * sLink +-------------------------------------+</pre> 023 */ 024final class AnchorLine extends Connector 025{ 026 027 028 /** Creates an AnchorLine. Create at most one for the entire life of the document as 029 * currently it does not unregister its listeners or otherwise clean up after itself. 030 */ 031 AnchorLine( final VoteTrackV trackV ) 032 { 033 super( "sLink" ); // invisible pending first repaint 034 peersBoardV = trackV.peersBoardV(); 035 addClassNameBaseVal( "AnchorLine" ); 036 new Painter(); 037 } 038 039 040 041 private static AnchorLine instance; 042 043 { 044 if( instance != null ) throw new IllegalStateException(); 045 046 instance = AnchorLine.this; 047 } 048 049 050 051//// P r i v a t e /////////////////////////////////////////////////////////////////////// 052 053 054 055 private final PeerBoardV peersBoardV; 056 057 058 059 private void repaint() 060 { 061 final ImageElement pinImg = peersBoardV.pinImg(); 062 if( pinImg == null ) 063 { 064 assert false: "track is pinned"; 065 assert !isVisible(); 066 return; 067 } 068 069 final int linkHeight = link().getOffsetHeight(); 070 final int linkRight = link().getAbsoluteRight(); 071 final int x0 = linkRight + /*margin*/(int)(linkHeight * 0.4f); 072 final int midX = pinImg.getAbsoluteLeft() + PIN_IMG_WIDTH / 2; 073 // image's absolute position readable even though it was set just now and is 074 // probably not yet rendered, because it really *is* absolutely positioned 075 if( isLongEnough( x0, midX, linkHeight )) setVisible( true ); 076 else 077 { 078 setVisible( false ); 079 return; 080 } 081 082 // - - ---+---+----------------+---+---+---+ 083 // \ \ \ \ \ \ 084 // + + + + + + + 085 // / / / \ / / / / 086 // - - ---+---+-------/ \----+---+---+---+ 087 // margin / \ 088 // | pinImg +---+---+ 089 // |-| | 2 090 // | 091 // link +-------------------------------------+ 1 (midX,y) 092 // 0 093 094 final int y = link().getAbsoluteTop() + linkSink(linkHeight); 095 final OMSVGPathSegList sL = getPathSegList(); 096 PathSeg.movetoAbs( sL, 0, x0, y ); 097 PathSeg.lineToAbs( sL, 1, midX, y ); 098 PathSeg.lineToAbs( sL, 2, midX, pinImg.getAbsoluteBottom() ); 099 } 100 101 102 103 // ==================================================================================== 104 105 106 private final class Painter implements ChangeHandler 107 { 108 109 Painter() 110 { 111 GWTX.i().bus().addHandlerToSource( Change.TYPE, /*source*/peersBoardV.painter(), 112 Painter.this ); // no need to unregister, registry does not outlive this listener 113 if( peersBoardV.isVisible() ) repaint(); // init 114 } 115 116 117 public final void onChange( Change _e ) { repaint(); } 118 119 } 120 121 122}