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 */
016package com.github.gwtbootstrap.client.ui;
017
018import com.github.gwtbootstrap.client.ui.base.IconAnchor;
019import com.github.gwtbootstrap.client.ui.base.UnorderedList;
020import com.github.gwtbootstrap.client.ui.event.HideEvent;
021import com.github.gwtbootstrap.client.ui.event.HideHandler;
022import com.github.gwtbootstrap.client.ui.event.ShowEvent;
023import com.github.gwtbootstrap.client.ui.event.ShowHandler;
024import com.google.gwt.dom.client.Style;
025import com.google.gwt.event.dom.client.ClickEvent;
026import com.google.gwt.event.dom.client.ClickHandler;
027import com.google.gwt.event.shared.HandlerManager;
028import com.google.gwt.event.shared.HandlerRegistration;
029import 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 */
059public 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    public 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(null));
108        }
109    }
110
111    public 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(null));
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}