001    package org.gwtbootstrap3.client.ui.base.button;
002    
003    /*
004     * #%L
005     * GwtBootstrap3
006     * %%
007     * Copyright (C) 2013 GwtBootstrap3
008     * %%
009     * Licensed under the Apache License, Version 2.0 (the "License");
010     * you may not use this file except in compliance with the License.
011     * You may obtain a copy of the License at
012     * 
013     *      http://www.apache.org/licenses/LICENSE-2.0
014     * 
015     * Unless required by applicable law or agreed to in writing, software
016     * distributed under the License is distributed on an "AS IS" BASIS,
017     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018     * See the License for the specific language governing permissions and
019     * limitations under the License.
020     * #L%
021     */
022    
023    import org.gwtbootstrap3.client.ui.base.HasDataToggle;
024    import org.gwtbootstrap3.client.ui.base.mixin.DataToggleMixin;
025    import org.gwtbootstrap3.client.ui.constants.ButtonType;
026    import org.gwtbootstrap3.client.ui.constants.Styles;
027    import org.gwtbootstrap3.client.ui.constants.Toggle;
028    import org.gwtbootstrap3.client.ui.html.Text;
029    
030    import com.google.gwt.core.client.Scheduler;
031    import com.google.gwt.dom.client.Element;
032    
033    /**
034     * Base class for buttons that can be toggle buttons
035     *
036     * @author Sven Jacobs
037     * @see AbstractButton
038     * @see org.gwtbootstrap3.client.ui.constants.Toggle
039     */
040    public abstract class AbstractToggleButton extends AbstractIconButton implements HasDataToggle {
041    
042        private final DataToggleMixin<AbstractToggleButton> toggleMixin = new DataToggleMixin<AbstractToggleButton>(this);
043        private final Text separator = new Text(" ");
044        private final Caret caret = new Caret();
045    
046        protected AbstractToggleButton() {
047            this(ButtonType.DEFAULT);
048        }
049    
050        protected AbstractToggleButton(final ButtonType type) {
051            setType(type);
052            iconTextMixin.addTextWidgetToParent();
053        }
054    
055        /**
056         * Toggles the display of the caret for the button
057         * @param toggleCaret show/hide the caret for the button
058         */
059        public void setToggleCaret(final boolean toggleCaret) {
060            caret.setVisible(toggleCaret);
061        }
062    
063        /**
064         * Specifies that this button acts as a toggle, for instance for a parent {@link org.gwtbootstrap3.client.ui.DropDown}
065         * or {@link org.gwtbootstrap3.client.ui.ButtonGroup}
066         * <p/>
067         * Adds a {@link Caret} as a child widget.
068         *
069         * @param toggle Kind of toggle
070         */
071        @Override
072        public void setDataToggle(final Toggle toggle) {
073            toggleMixin.setDataToggle(toggle);
074    
075            // We defer to make sure the elements are available to manipulate their position
076            Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
077                @Override
078                public void execute() {
079                    separator.removeFromParent();
080                    caret.removeFromParent();
081    
082                    if (toggle == Toggle.DROPDOWN) {
083                        addStyleName(Styles.DROPDOWN_TOGGLE);
084    
085                        add(separator, (Element) getElement());
086                        add(caret, (Element) getElement());
087                    }
088                }
089            });
090        }
091    
092        @Override
093        public Toggle getDataToggle() {
094            return toggleMixin.getDataToggle();
095        }
096    }