001    /*
002     * Copyright 2006 Mat Gessel <mat.gessel@gmail.com>
003     * 
004     * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005     * use this file except in compliance with the License. You may obtain a copy of
006     * the License at
007     * 
008     * http://www.apache.org/licenses/LICENSE-2.0
009     * 
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013     * License for the specific language governing permissions and limitations under
014     * the License.
015     */
016    package asquare.gwt.debug.client;
017    
018    import java.util.ArrayList;
019    
020    import com.google.gwt.user.client.DOM;
021    import com.google.gwt.user.client.Event;
022    import com.google.gwt.user.client.EventPreview;
023    
024    /**
025     * The {@link EventPreview} facility adds listeners to a stack, and only the
026     * listener on top of the stack previews events. This class distributes events
027     * to 1 or more listeners if it is on top of the stack. It will be pushed down
028     * the stack if a {@link com.google.gwt.user.client.ui.PopupPanel PopupPanel} or
029     * {@link com.google.gwt.user.client.ui.DialogBox DialogBox} is shown.
030     */
031    public final class EventPreviewDispatcher implements EventPreview
032    {
033            private static EventPreviewDispatcher s_instance = new EventPreviewDispatcher();
034            
035            private final ArrayList m_listeners = new ArrayList();
036            
037            private boolean m_installed = false;
038            
039            private EventPreviewDispatcher() {}
040            
041            /**
042             * Adds the specified listener. If <code>listener</code> is the first
043             * listener added, the dispatcher will be added to the top of the
044             * {@link DOM#addEventPreview(com.google.gwt.user.client.EventPreview) EventPreview}
045             * stack.
046             * 
047             * @param listener
048             */
049            public static void addListener(DebugEventListener listener)
050            {
051                    s_instance.m_listeners.add(listener);
052                    if (! s_instance.m_installed)
053                    {
054                            DOM.addEventPreview(s_instance);
055                            s_instance.m_installed = true;
056                    }
057            }
058            
059            /**
060             * Removes the specified listener. If <code>listener</code> is only
061             * remaining listener, the dispatcher will be removed from the
062             * {@link DOM#addEventPreview(com.google.gwt.user.client.EventPreview) EventPreview}
063             * stack.
064             * 
065             * @param listener
066             */
067            public static void removeListener(DebugEventListener listener)
068            {
069                    s_instance.m_listeners.remove(listener);
070                    if (s_instance.m_listeners.size() == 0)
071                    {
072                            DOM.removeEventPreview(s_instance);
073                            s_instance.m_installed = false;
074                    }
075            }
076            
077            // EventPreview listener method
078            public boolean onEventPreview(Event event)
079            {
080                    if (m_listeners.size() > 0)
081                    {
082                            Object[] listeners = m_listeners.toArray();
083                            for (int i = 0; i < listeners.length; i++)
084                            {
085                                    DebugEventListener listener = (DebugEventListener) listeners[i];
086                                    listener.eventDispatched(event);
087                            }
088                    }
089                    return true;
090            }
091    }