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.HasAlignment;
019import com.github.gwtbootstrap.client.ui.base.StyleHelper;
020import com.github.gwtbootstrap.client.ui.constants.*;
021import com.google.gwt.uibinder.client.UiConstructor;
022import com.google.gwt.user.client.DOM;
023import com.google.gwt.user.client.ui.Widget;
024
025//@formatter:off
026
027/**
028 * Widget with a black or white icon.
029 * <p>
030 * The icons are provided by <a href="http://glyphicons.com/">Glyphicons</a>
031 * and <a href="http://fortawesome.github.com/Font-Awesome/">Font Awesome</a>.
032 *
033 * <p/>
034 * <p>
035 * <h3>UiBinder Usage:</h3>
036 * <p/>
037 * <pre>
038 * {@code
039 * <b:Icon type="PLANE" />
040 * }
041 * </pre>
042 * </p>
043 *
044 * @author Carlos Alexandro Becker
045 * @author Dominik Mayer
046 * @author Sven Jacobs
047 * @see IconStack
048 * @see <a href="http://twitter.github.com/bootstrap/base-css.html#icons">Bootstrap documentation</a>
049 * @see <a href="http://fortawesome.github.com/Font-Awesome/">Font Awesome page</a>
050 * @since 2.0.4.0
051 */
052//@formatter:on
053public class Icon extends Widget implements HasAlignment {
054
055    private BaseIconType type;
056
057    /**
058     * Creates a widget but doesn't set an icon yet.
059     * <p/>
060     * (This is probably not what you want to do most of the time.)
061     */
062    public Icon() {
063        setElement(DOM.createElement("i"));
064    }
065
066    /**
067     * Creates a black icon of given type.
068     *
069     * @param type the icon type
070     */
071    @UiConstructor
072    public Icon(IconType type) {
073        this();
074        setBaseType(type);
075    }
076
077    /**
078     * Sets the icon type.
079     *
080     * @param type the icon type
081     */
082    public void setType(IconType type) {
083        setBaseType(type);
084    }
085
086    /**
087     * Sets the base icon type.
088     *
089     * @param type the icon type
090     */
091    public void setBaseType(BaseIconType type) {
092        if(this.type != null) {
093            StyleHelper.removeStyle(this, this.type);
094        }
095        this.type = type;
096        StyleHelper.addStyle(this, type);
097    }
098
099    /**
100     * Sets the icon size.
101     *
102     * @param size the icon size
103     */
104    public void setIconSize(IconSize size) {
105        StyleHelper.changeStyle(this, size, IconSize.class);
106    }
107    
108    /**
109     * Sets the icon size.
110     *
111     * @param size the icon size
112     */
113    public void setSize(IconSize size) {
114        setIconSize(size);
115    }
116    
117    /**
118     * Get the icon type
119     * 
120     * @return icon type, or null, if the Icon is no instance of {@link IconType}
121     */
122    public IconType getIconType() {
123        if(type instanceof IconType) {
124            return (IconType) type;
125        }
126        return null;
127    }
128
129    /**
130     * Get the base icon type
131     *
132     * @return base icon type
133     */
134    public BaseIconType getBaseIconType() {
135        return type;
136    }
137
138    /**
139     * Sets the base icon type.
140     *
141     * @param type the base icon type
142     */
143    public void setIcon(IconType type) {
144        setBaseType(type);
145    }
146
147    /**
148     * Sets whether this icon is a "light" (white) icon.
149     *
150     * @param light White icon if true
151     * @since 2.3.2.0
152     */
153    public void setLight(final boolean light) {
154        classNameToggle(light, Constants.ICON_LIGHT);
155    }
156
157    /**
158     * A muted icon is a grayed out icon.
159     *
160     * @param muted Is this icon muted (grayed out)?
161     * @since 2.3.2.0
162     */
163    public void setMuted(final boolean muted) {
164        classNameToggle(muted, Constants.ICON_MUTED);
165    }
166
167    /**
168     * Does this icon have a border?
169     *
170     * @param border True if icon has a border
171     * @since 2.3.2.0
172     */
173    public void setBorder(final boolean border) {
174        classNameToggle(border, Constants.ICON_BORDER);
175    }
176
177    /**
178     * Is the icon the base (bottom) icon of a {@link IconStack}?
179     * Only relevant if icon is a child element of {@link IconStack}.
180     *
181     * @param stackBase Is this icon the base (bottom icon) of an icon stack?
182     * @see IconStack
183     * @since 2.3.2.0
184     */
185    public void setStackBase(final boolean stackBase) {
186        classNameToggle(stackBase, Constants.ICON_STACK_BASE);
187    }
188
189    /**
190     * If true icon will spin.
191     * </p>
192     * Note: Uses CSS3 animations which aren't supported in IE7 - IE9.
193     *
194     * @param spin true if icon should spin
195     * @since 2.3.2.0
196     */
197    public void setSpin(final boolean spin) {
198        classNameToggle(spin, Constants.ICON_SPIN);
199    }
200
201    /**
202     * Pulls icon left or right.
203     *
204     * @param alignment Alignment of icon
205     * @since 2.3.2.0
206     */
207    @Override
208    public void setAlignment(final Alignment alignment) {
209        getElement().removeClassName(Alignment.LEFT.get());
210        getElement().removeClassName(Alignment.RIGHT.get());
211
212        if (alignment == null || alignment == Alignment.NONE) {
213            return;
214        }
215
216        getElement().addClassName(alignment.get());
217    }
218
219    /**
220     * Sets rotation of icon.
221     *
222     * @param iconRotate Rotation of icon
223     * @see com.github.gwtbootstrap.client.ui.constants.IconRotate
224     * @since 2.3.2.0
225     */
226    public void setRotate(final IconRotate iconRotate) {
227        getElement().removeClassName(IconRotate.ROTATE_90.get());
228        getElement().removeClassName(IconRotate.ROTATE_180.get());
229        getElement().removeClassName(IconRotate.ROTATE_270.get());
230
231        if (iconRotate == null || iconRotate == IconRotate.NONE) {
232            return;
233        }
234
235        getElement().addClassName(iconRotate.get());
236    }
237
238    /**
239     * Sets (horizontal or vertical) flip of icon.
240     *
241     * @param iconFlip Flip of icon
242     * @see com.github.gwtbootstrap.client.ui.constants.IconFlip
243     * @since 2.3.2.0
244     */
245    public void setFlip(final IconFlip iconFlip) {
246        getElement().removeClassName(IconFlip.HORIZONTAL.get());
247        getElement().removeClassName(IconFlip.VERTICAL.get());
248
249        if (iconFlip == null || iconFlip == IconFlip.NONE) {
250            return;
251        }
252
253        getElement().addClassName(iconFlip.get());
254    }
255
256    private void classNameToggle(final boolean value,
257                                 final String className) {
258        if (value) {
259            getElement().addClassName(className);
260        } else {
261            getElement().removeClassName(className);
262        }
263    }
264}