package com.googlecode.gwt.test.uibinder.widget;
import java.util.List;
import java.util.Map;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.IsWidget;
import com.googlecode.gwt.test.uibinder.UiBinderXmlUtils;
import com.googlecode.gwt.test.uibinder.UiObjectTag;
import com.googlecode.gwt.test.uibinder.UiObjectTagFactory;
/**
* Handles subclasses of {@link Grid} (which declare <g:row>, <g:cell> and <g:customCell>
* tags).
*
* @author Gael Lazzari
*
*/
public class UiGridTagFactory implements UiObjectTagFactory<Grid> {
private static class GridTag extends UiObjectTag<Grid> {
private int currentRowIndex = 0;
private int numColumns;
@Override
protected void appendElement(Grid wrapped, Element element, String namespaceURI,
List<IsWidget> childWidgets) {
if (!ROW_TAG.equals(element.getTagName())
|| !UiBinderXmlUtils.CLIENTUI_NSURI.equals(namespaceURI)) {
super.appendElement(wrapped, element, namespaceURI, childWidgets);
} else {
// handle <g:row> tag
handleRow(wrapped, element);
currentRowIndex++;
}
}
@Override
protected void finalizeObject(Grid uiObject) {
// nothing to do
}
@Override
protected void initializeObject(Grid wrapped, Map<String, Object> attributes, Object owner) {
// nothing to do
}
private void checkGridSize(Grid wrapped, int columnIndex) {
if (numColumns <= columnIndex) {
numColumns = columnIndex + 1;
wrapped.resize(currentRowIndex + 1, numColumns);
}
}
private void handleCell(Grid wrapped, Element element, int columnIndex) {
checkGridSize(wrapped, columnIndex);
wrapped.setHTML(currentRowIndex, columnIndex, element.getInnerHTML());
handleCellStyle(wrapped, element, columnIndex);
}
private void handleCellStyle(Grid wrapped, Element element, int columnIndex) {
String styleName = element.getAttribute(STYLE_ATTR);
if (styleName.length() > 0) {
wrapped.getCellFormatter().setStyleName(currentRowIndex, columnIndex, styleName);
}
}
private void handleCustomCell(Grid wrapped, Element element, List<IsWidget> childWidgets,
int columnIndex) {
checkGridSize(wrapped, columnIndex);
// should only contains one widget per <g:customCell> tag
IsWidget w = (childWidgets.size() > 0) ? childWidgets.get(0) : null;
wrapped.setWidget(currentRowIndex, columnIndex, w);
handleCellStyle(wrapped, element, columnIndex);
}
private void handleRow(Grid wrapped, Element element) {
// 1. insert
wrapped.insertRow(currentRowIndex);
// 2. handle row style
String styleName = element.getAttribute(STYLE_ATTR);
if (styleName.length() > 0) {
wrapped.getRowFormatter().setStyleName(currentRowIndex, styleName);
}
// 3. handle child cells
handleRowCells(wrapped, element);
}
private void handleRowCells(Grid wrapped, Element element) {
int columnIndex = 0;
NodeList<Node> childs = element.getChildNodes();
for (int i = 0; i < childs.getLength(); i++) {
Element e = childs.getItem(i).cast();
if (CELL_TAG.equals(e.getTagName())) {
handleCell(wrapped, e, columnIndex++);
} else if (CUSTOMCELL_TAG.equals(e.getTagName())) {
handleCustomCell(wrapped, e, UiBinderXmlUtils.getChildWidgets(e), columnIndex++);
}
}
}
}
private static final String CELL_TAG = "cell";
private static final String CUSTOMCELL_TAG = "customCell";
private static final String ROW_TAG = "row";
private static final String STYLE_ATTR = "styleName";
/*
* (non-Javadoc)
*
* @see com.googlecode.gwt.test.uibinder.UiObjectTagFactory#createUiObjectTag( java.lang .Class,
* java.util.Map)
*/
public UiObjectTag<Grid> createUiObjectTag(Class<?> clazz, Map<String, Object> attributes) {
if (!Grid.class.isAssignableFrom(clazz)) {
return null;
}
return new GridTag();
}
}