001package org.gwtbootstrap3.client.ui.base.helper;
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
023import org.gwtbootstrap3.client.ui.constants.DeviceSize;
024import org.gwtbootstrap3.client.ui.constants.Responsiveness;
025
026import com.google.gwt.dom.client.Style;
027import com.google.gwt.user.client.ui.UIObject;
028
029/**
030 * Helper methods regarding CSS styling of UIObjects.
031 *
032 * @author Sven Jacobs
033 * @author Joshua Godi
034 */
035public final class StyleHelper {
036
037    /**
038     * Convenience method for first removing all enum style constants and then adding the single one.
039     *
040     * @see #removeEnumStyleNames(com.google.gwt.user.client.ui.UIObject, Class)
041     * @see #addEnumStyleName(com.google.gwt.user.client.ui.UIObject, com.google.gwt.dom.client.Style.HasCssName)
042     */
043    public static <E extends Style.HasCssName, F extends Enum<? extends Style.HasCssName>> void addUniqueEnumStyleName(final UIObject uiObject,
044                                                                                                                       final Class<F> enumClass,
045                                                                                                                       final E style) {
046        removeEnumStyleNames(uiObject, enumClass);
047        addEnumStyleName(uiObject, style);
048    }
049
050    /**
051     * Removes all CSS style names specified by an enum that implements {@link Style.HasCssName} from an UIObject.
052     *
053     * @param uiObject  Object to remove CSS class names from
054     * @param enumClass Enum representing CSS class names
055     * @param <E>       Enum type implementing {@link Style.HasCssName}
056     */
057    public static <E extends Enum<? extends Style.HasCssName>> void removeEnumStyleNames(final UIObject uiObject,
058                                                                                         final Class<E> enumClass) {
059
060        for (final Enum<? extends Style.HasCssName> constant : enumClass.getEnumConstants()) {
061            final String cssClass = ((Style.HasCssName) constant).getCssName();
062
063            if (cssClass != null && !cssClass.isEmpty()) {
064                uiObject.removeStyleName(cssClass);
065            }
066        }
067    }
068
069    /**
070     * Adds enum value style name to UIObject unless style is {@code null}.
071     *
072     * @param uiObject Object to add style to
073     * @param style    Style name
074     */
075    public static <E extends Style.HasCssName> void addEnumStyleName(final UIObject uiObject,
076                                                                     final E style) {
077
078        if (style != null && style.getCssName() != null && !style.getCssName().isEmpty()) {
079            uiObject.addStyleName(style.getCssName());
080        }
081    }
082
083    /**
084     * Removes enum value style name from UIObject unless style is {@code null}.
085     *
086     * @param uiObject Object to remove style from
087     * @param style    Style name
088     */
089    public static <E extends Style.HasCssName> void removeEnumStyleName(final UIObject uiObject,
090                                                                        final E style) {
091
092        if (style != null && style.getCssName() != null && !style.getCssName().isEmpty()) {
093            uiObject.removeStyleName(style.getCssName());
094        }
095    }
096
097    /**
098     * Returns {@code true} if specified style is contained in space-separated list of styles
099     *
100     * @param styleNames Space-separated list of styles
101     * @param style      Style to look for
102     * @return True if contains style
103     */
104    public static boolean containsStyle(final String styleNames,
105                                        final String style) {
106
107        if (styleNames == null || style == null) {
108            return false;
109        }
110
111        final String[] styles = styleNames.split("\\s");
112
113        for (final String s : styles) {
114            if (style.equals(s)) {
115                return true;
116            }
117        }
118
119        return false;
120    }
121
122    /**
123     * Toggles a style name on a ui object
124     *
125     * @param uiObject    Object to toggle style on
126     * @param toggleStyle whether or not to toggle the style name on the object
127     * @param styleName   Style name
128     */
129    public static void toggleStyleName(final UIObject uiObject,
130                                       final boolean toggleStyle,
131                                       final String styleName) {
132        if (toggleStyle) {
133            uiObject.addStyleName(styleName);
134        } else {
135            uiObject.removeStyleName(styleName);
136        }
137    }
138
139    /**
140     * Sets the ui object to be hidden on the device size
141     *
142     * @param uiObject   object to be hidden on the device size
143     * @param deviceSize device size
144     */
145    public static void setHiddenOn(final UIObject uiObject,
146                                   final DeviceSize deviceSize) {
147        // Split the enum up by _ to get the different devices
148        // Separates the SM_MD into [SM, MD] so we can add the right styles
149        final String[] deviceString = deviceSize.name().split("_");
150
151        for (final String device : deviceString) {
152            // Case back to basic enum (PRINT, XS, SM, MD, LG)
153            final DeviceSize size = DeviceSize.valueOf(device);
154            switch (size) {
155                case PRINT:
156                    addEnumStyleName(uiObject, Responsiveness.HIDDEN_PRINT);
157                    break;
158                case XS:
159                    addEnumStyleName(uiObject, Responsiveness.HIDDEN_XS);
160                    break;
161                case SM:
162                    addEnumStyleName(uiObject, Responsiveness.HIDDEN_SM);
163                    break;
164                case MD:
165                    addEnumStyleName(uiObject, Responsiveness.HIDDEN_MD);
166                    break;
167                case LG:
168                    addEnumStyleName(uiObject, Responsiveness.HIDDEN_LG);
169                    break;
170                default:
171                    break;
172            }
173        }
174    }
175
176    /**
177     * Sets the ui object to be visible on the device size
178     *
179     * @param uiObject   object to be visible on the device size
180     * @param deviceSize device size
181     */
182    public static void setVisibleOn(final UIObject uiObject,
183                                    final DeviceSize deviceSize) {
184        // Split the enum up by _ to get the different devices
185        // Separates the SM_MD into [SM, MD] so we can add the right styles
186        final String[] deviceString = deviceSize.name().split("_");
187
188        for (final String device : deviceString) {
189            // Case back to basic enum (PRINT, XS, SM, MD, LG)
190            final DeviceSize size = DeviceSize.valueOf(device);
191            switch (size) {
192                case PRINT:
193                    addEnumStyleName(uiObject, Responsiveness.VISIBLE_PRINT);
194                    break;
195                case XS:
196                    addEnumStyleName(uiObject, Responsiveness.VISIBLE_XS);
197                    break;
198                case SM:
199                    addEnumStyleName(uiObject, Responsiveness.VISIBLE_SM);
200                    break;
201                case MD:
202                    addEnumStyleName(uiObject, Responsiveness.VISIBLE_MD);
203                    break;
204                case LG:
205                    addEnumStyleName(uiObject, Responsiveness.VISIBLE_LG);
206                    break;
207                default:
208                    break;
209            }
210        }
211    }
212
213    private StyleHelper() {
214    }
215}