001    /*
002     *  Copyright 2012 GWT-Bootstrap
003     *
004     *  Licensed under the Apache License, Version 2.0 (the "License");
005     *  you may not use this file except in compliance with the License.
006     *  You may obtain a copy of 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,
012     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     *  See the License for the specific language governing permissions and
014     *  limitations under the License.
015     */
016    package com.github.gwtbootstrap.client.ui;
017    
018    import com.github.gwtbootstrap.client.ui.base.IconAnchor;
019    import com.github.gwtbootstrap.client.ui.base.UnorderedList;
020    import com.github.gwtbootstrap.client.ui.event.HideEvent;
021    import com.github.gwtbootstrap.client.ui.event.HideHandler;
022    import com.github.gwtbootstrap.client.ui.event.ShowEvent;
023    import com.github.gwtbootstrap.client.ui.event.ShowHandler;
024    import com.google.gwt.dom.client.Style;
025    import com.google.gwt.event.dom.client.ClickEvent;
026    import com.google.gwt.event.dom.client.ClickHandler;
027    import com.google.gwt.event.shared.HandlerManager;
028    import com.google.gwt.event.shared.HandlerRegistration;
029    import com.google.gwt.user.client.ui.Widget;
030    
031    //@formatter:off
032    /**
033     * A dropdown that accepts any type of widget.
034     * <p>
035     * <h3>UiBinder Usage:</h3>
036     *
037     * <pre>
038     * {@code
039     * <b:DropdownContainer text="I am the Caption">
040     *     <b:NavHeader>Header</b:NavHeader>
041     *     <b:NavLink>Link 1</b:NavLink>
042     *     <b:NavLink>Link 2</b:NavLink>
043     *     <b:Button>Hey you, I'm a button</b:Button>
044     * </b:DropdownContainer>
045     * }
046     * </pre>
047     * </p>
048     *
049     * @since 2.0.4.0
050     *
051     * @author Carlos Alexandro Becker
052     * @author Cássio de Freitas e Silva
053     *
054     * @see <a href="http://twitter.github.com/bootstrap/javascript.html#dropdowns">Bootstrap documentation</a>
055     * @see DropdownButton
056     * @see SplitDropdownButton
057     * @see Dropdown
058     */
059    public class DropdownContainer extends Dropdown {
060    
061        private UnorderedList menu = new UnorderedList();
062        private boolean menuVisible;
063        private HandlerManager handlerManager;
064    
065        @Override
066        protected IconAnchor createTrigger() {
067            final IconAnchor trigger = super.createTrigger();
068            trigger.addDomHandler(new ClickHandler() {
069    
070                @Override
071                public void onClick(ClickEvent event) {
072                    if (menuVisible) {
073                        hideContainer();
074                    } else {
075                        showContainer();
076                    }
077                }
078            }, ClickEvent.getType());
079    
080            return trigger;
081        }
082    
083        public DropdownContainer() {
084            this("");
085        }
086    
087        public DropdownContainer(String caption) {
088            super(caption);
089            for (Widget widget : getChildren()) {
090                if (widget instanceof UnorderedList) {
091                    menu = (UnorderedList) widget;
092                    break;
093                }
094            }
095            menu.getElement().getStyle().clearDisplay();
096            menu.getElement().getStyle().setDisplay(Style.Display.NONE);
097    
098            handlerManager = createHandlerManager();
099        }
100    
101        protected void showContainer() {
102            menu.getElement().getStyle().setDisplay(Style.Display.BLOCK);
103            menuVisible = true;
104    
105            for (int i = 0; i < handlerManager.getHandlerCount(ShowEvent.getType()); i++) {
106                ShowHandler sh = handlerManager.getHandler(ShowEvent.getType(), i);
107                sh.onShow(new ShowEvent());
108            }
109        }
110    
111        protected void hideContainer() {
112            menu.getElement().getStyle().setDisplay(Style.Display.NONE);
113            menuVisible = false;
114    
115            for (int i = 0; i < handlerManager.getHandlerCount(HideEvent.getType()); i++) {
116                HideHandler hh = handlerManager.getHandler(HideEvent.getType(), i);
117                hh.onHide(new HideEvent());
118            }
119        }
120    
121        public HandlerRegistration addHideHandler(HideHandler hideHandler) {
122            return handlerManager.addHandler(HideEvent.getType(), hideHandler);
123        }
124    
125        public HandlerRegistration addShowHandler(ShowHandler showHandler) {
126            return handlerManager.addHandler(ShowEvent.getType(), showHandler);
127        }
128    }