/**
* Copyright 2010 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.waveprotocol.wave.client.widget.button;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.ui.Widget;
import java.util.ArrayList;
import java.util.List;
/**
* Helper class for handling multiple orthogonal CSS classnames for an element
* simultaneously.
*
* The motivating case for this class is styles on a button. Buttons might have
* two CSS class names applied at any given time - one class to represent the
* button state (NORMAL, HOVER, DOWN) and one to represent the high level
* 'style' of the button (BLUE_BUTTON, ADD_BUTTON, etc) - and we achieve a
* different look by defining CSS classes like this:
*
* .normal.blue_button { // normal blue button style }
*
* .hover.blue_button { // hovered blue button style }
*
* With {@link StyleAxis} this would be represented as:
*
* StyleAxis buttonState = new StyleAxis(getElement()); StyleAxis buttonStyle =
* new StyleAxis(getElement());
*
* Then we can move along one axis without affecting the other:
*
* buttonState.setStyle("normal"); buttonStyle.setStyle("red_button");
*
*/
public class StyleAxis {
/**
* The element to apply styles to.
*/
private final List<Element> elements = new ArrayList<Element>();
/**
* The current style that is applied to the target element.
*/
private String currentStyle = null;
/**
* @param widgets The widgets to apply styles to.
*/
public StyleAxis(Widget... widgets) {
for (Widget w : widgets) {
if (w != null) {
elements.add(w.getElement());
}
}
}
/**
* @param elements The elements to apply styles to.
*/
public StyleAxis(Element... elements) {
for (Element e : elements) {
if (e != null) {
this.elements.add(e);
}
}
}
/**
* Replaces any current style that may be applied with the given style.
*
* @param styleName The CSS style to change to, or {@code null} to change to
* no style.
*/
public void setStyle(String styleName) {
if (!isEquivalentStyle(styleName)) {
/* Remove the current style if set */
if (currentStyle != null && currentStyle.trim().length() != 0) {
for (Element e : elements) {
e.removeClassName(currentStyle);
}
}
/* Add the new style if set */
if (styleName != null) {
for (Element e : elements) {
e.addClassName(styleName);
}
}
currentStyle = styleName;
}
}
/**
* Returns true if the provided style is equivalent to the current style.
*
* @param styleName The style name to compare to the current style
*/
private boolean isEquivalentStyle(String styleName) {
return ((styleName == null && currentStyle == null) || (styleName != null && styleName
.equals(currentStyle)));
}
}