001package votorola.s.gwt.stage.talk; // Copyright 2012, Michael Allan. 2013 Christian Weilbach.  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.event.dom.client.*;
004import com.google.gwt.user.client.ui.*;
005import com.google.web.bindery.event.shared.HandlerRegistration;
006import votorola.a.count.*;
007import votorola.a.diff.DiffLookJS;
008import votorola.a.diff.DiffLook;
009import votorola.a.web.gwt.*;
010import votorola.g.hold.*;
011import votorola.g.web.gwt.*;
012import votorola.g.web.gwt.event.*;
013import votorola.s.gwt.stage.*;
014import votorola.s.gwt.stage.light.*;
015
016
017/** A talk view implemented as an HTML image.
018  */
019final class TalkV extends Image
020{
021
022    /** Constructs a PollV.
023      *
024      *     @param spool the spool for the release of associated holds.  When unwound it
025      *       releases the holds of the view and thereby disables it.
026      */
027    TalkV( final Spool spool )
028    {
029        addStyleName("talkV");
030        sensor = new Sensor( spool );
031        imager = new Imager( spool );
032        new Stager();
033    }
034    
035        private final Imager imager;
036
037        private final static String selectedLoc = App.getServletContextLocation() + "/stage/talk/selected.png";
038        private final static String cuedLoc = App.getServletContextLocation() + "/stage/talk/cued.png";
039        private final static String normalLoc = App.getServletContextLocation() + "/stage/talk/normal.png";
040            
041        static
042        {
043            prefetch( selectedLoc );
044            prefetch( cuedLoc );
045            prefetch( normalLoc );
046        }
047        
048   // ------------------------------------------------------------------------------------
049
050
051    /** The difference-message on which this view is modelled, or null if none is modelled.
052      *
053      *     @see #setMsg(DiffMessageJS)
054      */
055    DiffMessageJS getMsg() { return msg; }
056
057
058        private DiffMessageJS msg = null;
059
060
061        /** Sets the difference-message on which this view is modelled.
062          *
063          *     @see #getMsg()
064          */
065        void setMsg( final DiffMessageJS msgNew )
066        {
067            if( msgNew == null )
068            {
069                if( msg == null ) return; // very common, nothing to do
070
071                msg = null;
072            }
073            else
074            {
075                msg = msgNew;
076            }
077            
078            enabler.reEnable();
079            imager.reImage();
080            sensor.relight();
081        }
082        
083        
084        // ====================================================================================
085
086
087        private final class Imager implements MouseOutHandler, MouseOverHandler, PropertyChangeHandler
088        {
089
090            Imager( Spool _spool )
091            {
092                spool = _spool;
093                addMouseOutHandler( Imager.this ); // no need to unregister, registry does not outlive the handler
094                addMouseOverHandler( Imager.this ); // "
095                spool.add( new Hold()
096                {
097                    final HandlerRegistration hR = GWTX.i().bus().addHandlerToSource(
098                      PropertyChange.TYPE, /*source*/Stage.i(), Imager.this );
099                    public void release() { hR.removeHandler(); }
100                });
101                reImage();
102            }
103
104            private final Spool spool;
105
106            boolean isCued;
107
108
109            private void reImage()
110            {
111                if(isStaged()) {
112                    setUrl( selectedLoc );
113                } else if(isCued) {
114                    setUrl( cuedLoc );
115                } else {
116                    setUrl( normalLoc );
117                }
118            }
119
120
121           // - M o u s e - O u t - H a n d l e r --------------------------------------------
122
123
124            public void onMouseOut( MouseOutEvent _e )
125            {
126                isCued = false;
127                reImage();
128            }
129
130
131           // - M o u s e - O v e r - H a n d l e r ------------------------------------------
132
133
134            public void onMouseOver( MouseOverEvent _e )
135            {
136                isCued = true;
137                reImage();
138            }
139
140            // - P r o p e r t y - C h a n g e - H a n d l e r --------------------------------
141
142
143             public final void onPropertyChange( final PropertyChange e )
144             {
145                 if( ( "message".equals(e.propertyName()) 
146                         || "difference".equals(e.propertyName()) )
147                       && !spool.isUnwinding() ) 
148                     reImage();
149             }
150
151        }
152
153
154   // ====================================================================================
155
156
157    /** A lighting sensor for a poll view.
158      */
159    final class Sensor extends Sensor1 implements MouseOutHandler, MouseOverHandler
160    {
161
162        private Sensor( final Spool spool )
163        {
164            Stage.i().lightBank().addSensor( Sensor.this );
165            spool.add( new Hold()
166            {
167                public void release() { Stage.i().lightBank().removeSensor( Sensor.this ); }
168            });
169            addMouseOutHandler( Sensor.this ); // no need to unregister, registry does not outlive the handler
170            addMouseOverHandler( Sensor.this ); // "
171        }
172
173
174        private void relight() { changed(); }
175
176
177        /** The talk view associated with this lighting sensor.
178          */
179        TalkV view() { return TalkV.this; }
180
181
182       // - M o u s e - O u t - H a n d l e r --------------------------------------------
183
184
185        public void onMouseOut( MouseOutEvent _e ) { 
186            out(); 
187        }
188
189
190       // - M o u s e - O v e r - H a n d l e r ------------------------------------------
191
192
193        public void onMouseOver( MouseOverEvent _e ) { 
194            over(); 
195        }
196
197    }
198
199
200
201//// P r i v a t e ///////////////////////////////////////////////////////////////////////
202
203
204    private final Enabler enabler = new Enabler();
205
206
207
208    private final Sensor sensor;
209
210
211   // ====================================================================================
212
213
214    private final class Enabler
215    {
216
217        Enabler() { setVisible( false ); }
218
219
220        private boolean isEnabled;
221
222
223        void reEnable()
224        {
225            final boolean toEnable = msg != null;
226            if( toEnable )
227            {
228                if( !isEnabled )
229                {
230                    isEnabled = true;
231                    setVisible( true );
232                }
233            }
234            else if( isEnabled )
235            {
236                isEnabled = false;
237                setVisible( false );
238            }
239        }
240
241    }
242
243
244
245   // ====================================================================================
246
247
248    private final class Stager implements ClickHandler
249    {
250
251        Stager() { addClickHandler( Stager.this ); } // no need to unregister, registry does not outlive this listener
252        
253        private final Stage stage = Stage.i();
254        
255
256        public void onClick( ClickEvent _e )
257        {
258            Message newMsg = msg.message();
259            DiffLookJS newDiff = msg.difference();
260            if( isStaged() ) {
261                newMsg = null;
262                newDiff = null;
263            }
264            stage.setMessage( newMsg );
265            stage.setDifference( newDiff );
266        }
267
268    }
269    
270        private boolean isStaged() {
271            if( msg == null ) {
272                return false;
273            }
274            
275            final Message msgS = Stage.i().getMessage();
276            final DiffLook diffS = Stage.i().getDifference();
277            
278            return MessageJS.EQUATOR.equals(msg.message(), msgS)
279                    && DiffLookJS.EQUATOR.equals(msg.difference(), diffS);
280        }
281
282
283}