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.DivWidget;
019import com.github.gwtbootstrap.client.ui.base.DropdownBase;
020import com.github.gwtbootstrap.client.ui.base.MarkupWidget;
021import com.github.gwtbootstrap.client.ui.constants.Constants;
022import com.github.gwtbootstrap.client.ui.constants.ToggleType;
023import com.google.gwt.user.client.ui.IsWidget;
024import com.google.gwt.user.client.ui.Widget;
025
026//@formatter:off
027/**
028 * ButtonGroups take buttons and combine them to one optically integrated
029 * widget.
030 * 
031 * <p>
032 * <h3>UiBinder Usage:</h3>
033 * 
034 * <pre>
035 * {@code 
036 * <b:ButtonGroup>
037 *     <b:Button>First Button</b:Button>
038 *     <b:Button>Second Button</b:Button>
039 *     <b:Button>Third Button</b:Button>
040 * </b:ButtonGroup>}
041 * </pre>
042 * 
043 * You can also use the buttons as checkboxes or radio buttons:
044 * 
045 * <pre>
046 * {@code
047 * <b:ButtonGroup toggle="radio">
048 *      <b:Button text="1" />
049 *              <b:Button text="2" />
050 *      <b:Button text="3" />
051 *      <b:Button text="4" />
052 * </b:ButtonGroup>
053 * }
054 * </pre>
055 * 
056 * @since 2.0.4.0
057 * 
058 * @author Carlos Alexandro Becker
059 * @author ohashi keisuke
060 * 
061 * @see <a
062 *      href="http://getbootstrap.com/2.3.2/components.html#buttonGroups">Bootstrap
063 *      documentation</a>
064 * @see Button
065 * @see ButtonToolbar
066 */
067// @formatter:on
068public class ButtonGroup extends DivWidget {
069
070    /**
071     * Creates an empty ButtonGroup.
072     */
073    public ButtonGroup() {
074        setStyleName(Constants.BTN_GROUP);
075    }
076
077    /**
078     * Creates a ButtonGroup containing the provided Buttons.
079     * 
080     * @param buttons
081     *            the widgets to be added to the ButtonGroup
082     */
083    public ButtonGroup(Button... buttons) {
084        this();
085        for (Button btn : buttons) {
086            add(btn);
087        }
088    }
089    
090    @Override
091    public void add(IsWidget child) {
092        
093        Widget widget = asWidgetOrNull(child);
094        if(child instanceof MarkupWidget && widget instanceof DropdownButton) {
095            MarkupWidget markup = (MarkupWidget) child;
096            DropdownButton dropdownBase = (DropdownButton) widget;
097            
098            markup.setWidget(dropdownBase.getTriggerWidget());
099            markup.asWidget();
100        }
101        
102        
103        this.add(widget);
104    }
105
106    /**
107     * Adds a new {@link Button} to the group.
108     * 
109     * @param widget
110     *            the Button to be added.
111     */
112    @Override
113    public void add(Widget widget) {
114
115        if(widget instanceof Button) {
116            super.add(widget);
117            return;
118        }
119        
120        if(widget instanceof DropdownButton) {
121            this.add((DropdownButton)widget);
122            return;
123        }
124        
125        throw new IllegalArgumentException(
126                "A ButtonGroup can only contain Buttons or DropdownButton. You added " + widget);
127        
128        
129    }
130    
131    /**
132     * Add dropdown widget
133     * @param dropdown dropdown widget
134     */
135    private void add(DropdownBase dropdown) {
136        
137        super.add(dropdown.getTriggerWidget());
138        super.add(dropdown.getMenuWiget());
139        
140        this.setStyleName(Constants.DROPUP, dropdown.isDropup());
141        
142    }
143    
144    @Override
145    public boolean remove(Widget w) {
146        
147        if(!(w instanceof DropdownBase)) {
148            return super.remove(w);
149        }
150        
151        DropdownBase dropdown = (DropdownBase) w;
152        
153        super.remove(dropdown.getTriggerWidget());
154        return super.remove(dropdown.getMenuWiget());
155    }
156
157    /**
158     * Set/unset the data-toggle behavior.
159     * 
160     * @param type
161     */
162    public void setToggle(ToggleType type) {
163        if (type == null || type == ToggleType.NONE) {
164            getElement().removeAttribute(Constants.DATA_TOGGLE);
165            return;
166        }
167        getElement().setAttribute(Constants.DATA_TOGGLE, type.get());
168
169    }
170
171    /**
172     * Set/unset the data-toggle behavior.
173     * 
174     * @param toggle
175     */
176    public void setToggle(String toggle) {
177        try {
178            setToggle(ToggleType.valueOf(toggle.toUpperCase()));
179        } catch (Exception e) {
180            throw new IllegalArgumentException("Invalid toggle option.");
181        }
182    }
183    
184    /**
185     * Set vertical style
186     * @param vertical true:Set , false:Unset
187     */
188    public void setVertical(boolean vertical) {
189        setStyleName(Constants.BTN_GROUP_VERTICAL, vertical);
190    }
191}