001package votorola.s.gwt.stage.poll; // 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.core.client.GWT;
004import com.google.gwt.uibinder.client.*;
005import com.google.gwt.user.client.ui.*;
006import com.google.web.bindery.event.shared.HandlerRegistration;
007import java.util.*;
008import votorola.a.count.*;
009import votorola.g.hold.*;
010import votorola.g.lang.*;
011import votorola.g.web.gwt.*;
012import votorola.g.web.gwt.event.*;
013import votorola.s.gwt.stage.*;
014
015
016/** A view of a {@linkplain Polltrack polltrack}.  It comprises a sequence of compressed
017  * {@linkplain PollV poll views} (one per poll), ordered alphabetically from left to
018  * right according to the last component of the poll name ("sandbox" in the illustration
019  * below).  When a poll is {@linkplain Stage#getPollName() staged} or cued by the mouse,
020  * the corresponding view expands (X).<pre>
021  *
022  *                                     {@linkplain HeadsUpDisplay heads up display}
023  *    staged poll                       /
024  *             \                       /
025  *              \          Sys/p/sandbox
026  -   ------------X---------------X--------------------
027  *                                \
028  *                                 \
029  *                                 poll cued by mouse</pre>
030  *
031  *     @see <a href='../../../../../../../s/gwt/stage/poll/PolltrackV.ui.xml'
032  *                                                        >PolltrackV.ui.xml</a>
033  */
034public final class PolltrackV extends Composite
035{
036
037
038    /** Constructs a PolltrackV.
039      */
040    PolltrackV( Polltrack _track )
041    {
042        track = _track;
043        new Modeller();
044    }
045
046
047
048    /** Returns the {@linkplain StageV staged instance} of PolltrackV, or null if none is
049      * staged.
050      */
051    public static PolltrackV i( final StageV stageV )
052    {
053        final Iterator<Widget> ww = stageV.iterator();
054        while( ww.hasNext() )
055        {
056            final Widget w = ww.next();
057            if( w instanceof PolltrackV ) return (PolltrackV)w;
058        }
059
060        return null;
061    }
062
063
064        private static PolltrackV instance; // not necessarily staged, though actually it will be
065
066        {
067            if( instance != null ) throw new IllegalStateException(); // grep "instance" for reason
068
069            instance = PolltrackV.this;
070        }
071
072
073
074   // ` e a r l y ````````````````````````````````````````````````````````````````````````
075
076
077    private final Spool spool = new Spool1();
078
079
080
081    @Warning("non-API") interface UiBinderI extends UiBinder<HTMLPanel,PolltrackV> {}
082
083        {
084            final UiBinderI uiBinder = GWT.create( UiBinderI.class );
085            initWidget( uiBinder.createAndBindUi( PolltrackV.this ));
086        }
087
088
089
090   // - C o m p o s i t e ----------------------------------------------------------------
091
092
093    protected @Override HTMLPanel getWidget() { return (HTMLPanel)super.getWidget(); }
094
095
096
097   // - W i d g e t ----------------------------------------------------------------------
098
099
100    protected @Override void onUnload()
101    {
102        super.onUnload();
103        spool.unwind();
104    }
105
106
107
108    public @Override void removeFromParent()
109    {
110        if( getParent() != null ) throw new UnsupportedOperationException();
111    }
112
113
114
115//// P r i v a t e ///////////////////////////////////////////////////////////////////////
116
117
118    @UiField @Warning("non-API") FlowPanel listV;
119
120
121
122      @UiFactory @Warning("non-API")
123    HeadsUpDisplay newHeadsUp() { return new HeadsUpDisplay( PolltrackV.this, spool ); }
124
125
126
127    private final Polltrack track;
128
129
130
131   // ====================================================================================
132
133
134    private final class Modeller implements ChangeHandler
135    {
136
137        Modeller()
138        {
139            spool.add( new Hold()
140            {
141                final HandlerRegistration hR = GWTX.i().bus().addHandlerToSource(
142                  Change.TYPE, /*source*/track.eventSource, Modeller.this );
143                public void release() { hR.removeHandler(); }
144            });
145            remodel();
146        }
147
148
149        public void onChange( Change _e ) { remodel(); }
150
151
152        private void remodel()
153        {
154            if( spool.isUnwinding() ) return;
155
156            int p = 0;
157            int pVN = listV.getWidgetCount();
158            final int pN = track.size();
159            for(; p < pN; ++p ) // for tracked polls, remodel the views
160            {
161                final PollV pollV;
162                if( p == pVN )
163                {
164                    pollV = new PollV( spool );
165                    listV.add( pollV );
166                    ++pVN;
167                }
168                else pollV = (PollV)listV.getWidget( p );
169                pollV.setPoll( track.get( p ));
170            }
171            for(; p < pVN; ++p ) // for remaining views, clear the models
172            {
173                final PollV pollV = (PollV)listV.getWidget( p );
174                pollV.setPoll( null );
175            }
176        }
177
178    }
179
180
181}