blob: 3a1bb923f74b69f6c3e4cb0a3e5193d527228755 [file] [log] [blame]
/*
* 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 com.google.gwt.cell.client;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment.VerticalAlignmentConstant;
import java.util.Set;
/**
* A {@link Cell} decorator that adds an icon to another {@link Cell}.
*
* <p>
* Note: This class is new and its interface subject to change.
* </p>
*
* @param <C> the type that this Cell represents
*/
public class IconCellDecorator<C> implements Cell<C> {
private final Cell<C> cell;
private final String iconHtml;
private final int imageWidth;
private final String placeHolderHtml;
/**
* Construct a new {@link IconCellDecorator}. The icon and the content will be
* middle aligned by default.
*
* @param icon the icon to use
* @param cell the cell to decorate
*/
public IconCellDecorator(ImageResource icon, Cell<C> cell) {
this(icon, cell, HasVerticalAlignment.ALIGN_MIDDLE, 6);
}
/**
* Construct a new {@link IconCellDecorator}.
*
* @param icon the icon to use
* @param cell the cell to decorate
* @param valign the vertical alignment attribute of the contents
* @param spacing the pixel space between the icon and the cell
*/
public IconCellDecorator(ImageResource icon, Cell<C> cell,
VerticalAlignmentConstant valign, int spacing) {
this.cell = cell;
this.iconHtml = getImageHtml(icon, valign, false);
this.imageWidth = icon.getWidth() + 6;
this.placeHolderHtml = getImageHtml(icon, valign, true);
}
public boolean dependsOnSelection() {
return cell.dependsOnSelection();
}
public Set<String> getConsumedEvents() {
return cell.getConsumedEvents();
}
public boolean handlesSelection() {
return cell.handlesSelection();
}
public boolean isEditing(Element element, C value, Object key) {
return cell.isEditing(element, value, key);
}
public void onBrowserEvent(Element parent, C value, Object key,
NativeEvent event, ValueUpdater<C> valueUpdater) {
cell.onBrowserEvent(getCellParent(parent), value, key, event, valueUpdater);
}
public void render(C value, Object key, StringBuilder sb) {
sb.append("<div style='position:relative;padding-left:");
sb.append(imageWidth);
sb.append("px;'>");
if (isIconUsed(value)) {
sb.append(getIconHtml(value));
} else {
sb.append(placeHolderHtml);
}
sb.append("<div>");
cell.render(value, key, sb);
sb.append("</div></div>");
}
public void setValue(Element parent, C value, Object key) {
cell.setValue(getCellParent(parent), value, key);
}
/**
* Get the HTML string that represents the icon. Override this method to
* change the icon based on the value.
*
* @param value the value being rendered
* @return the HTML string that represents the icon
*/
protected String getIconHtml(C value) {
return iconHtml;
}
/**
* Check if the icon should be used for the value. If the icon should not be
* used, a placeholder of the same size will be used instead. The default
* implementations returns true.
*
* @param value the value being rendered
* @return true to use the icon, false to use a placeholder
*/
protected boolean isIconUsed(C value) {
return true;
}
/**
* Get the HTML representation of an image. Visible for testing.
*
* @param res the {@link ImageResource} to render as HTML
* @param valign the vertical alignment
* @param isPlaceholder if true, do not include the background image
* @return the rendered HTML
*/
// TODO(jlabanca): Move this to a Utility class.
String getImageHtml(ImageResource res, VerticalAlignmentConstant valign,
boolean isPlaceholder) {
// Add the position and dimensions.
StringBuilder sb = new StringBuilder();
sb.append("<div style=\"position:absolute;left:0px;top:0px;height:100%;");
sb.append("width:").append(res.getWidth()).append("px;");
// Add the background, vertically centered.
if (!isPlaceholder) {
String vert = valign == HasVerticalAlignment.ALIGN_MIDDLE
? "center" : valign.getVerticalAlignString();
sb.append("background:url('").append(res.getURL()).append("') ");
sb.append("no-repeat scroll ").append(vert).append(
" center transparent;");
}
// Close the div and return.
sb.append("\"></div>");
return sb.toString();
}
/**
* Get the parent element of the decorated cell.
*
* @param parent the parent of this cell
* @return the decorated cell's parent
*/
private Element getCellParent(Element parent) {
return parent.getFirstChildElement().getChild(1).cast();
}
}