Revision: 6399 Author: [email protected] Date: Fri Oct 16 13:11:56 2009 Log: Adds TabLayoutPanelParser. Review: http://gwt-code-reviews.appspot.com/81802 http://code.google.com/p/google-web-toolkit/source/detail?r=6399
Added: /trunk/user/src/com/google/gwt/uibinder/parsers/TabLayoutPanelParser.java Modified: /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java /trunk/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java ======================================= --- /dev/null +++ /trunk/user/src/com/google/gwt/uibinder/parsers/TabLayoutPanelParser.java Fri Oct 16 13:11:56 2009 @@ -0,0 +1,151 @@ +/* + * Copyright 2009 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.uibinder.parsers; + +import com.google.gwt.core.ext.UnableToCompleteException; +import com.google.gwt.core.ext.typeinfo.JClassType; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.uibinder.rebind.UiBinderWriter; +import com.google.gwt.uibinder.rebind.XMLElement; +import com.google.gwt.user.client.ui.TabLayoutPanel; + +/** + * Parses {...@link TabLayoutPanel} widgets. + */ +public class TabLayoutPanelParser implements ElementParser { + + private static class Children { + XMLElement body; + XMLElement header; + XMLElement customHeader; + } + + private static final String CUSTOM = "customHeader"; + private static final String HEADER = "header"; + private static final String TAB = "tab"; + + public void parse(XMLElement panelElem, String fieldName, JClassType type, + UiBinderWriter writer) throws UnableToCompleteException { + // TabLayoutPanel requires tabBar size and unit ctor args. + double size = panelElem.consumeDoubleAttribute("barHeight"); + Unit unit = panelElem.consumeEnumAttribute("barUnit", Unit.class); + + String enumName = DockLayoutPanelParser.getFullyQualifiedEnumName(unit); + JClassType tlpType = writer.getOracle().findType( + TabLayoutPanel.class.getName()); + writer.setFieldInitializerAsConstructor(fieldName, tlpType, + Double.toString(size), enumName); + + // Parse children. + for (XMLElement tabElem : panelElem.consumeChildElements()) { + // Get the tab element. + if (!isElementType(panelElem, tabElem, TAB)) { + writer.die("In %s, only <%s:%s> children are allowed.", panelElem, + panelElem.getPrefix(), TAB); + } + + // Find all the children of the <tab>. + Children children = findChildren(tabElem, writer); + + // Parse the child widget. + if (children.body == null) { + writer.die("%s must have a child widget", tabElem); + } + if (!writer.isWidgetElement(children.body)) { + writer.die("In %s, %s must be a widget", tabElem, children.body); + } + String childFieldName = writer.parseElementToField(children.body); + + // Parse the header. + if (children.header != null) { + HtmlInterpreter htmlInt = HtmlInterpreter.newInterpreterForUiObject( + writer, fieldName); + String html = children.header.consumeInnerHtml(htmlInt); + writer.addStatement("%s.add(%s, \"%s\", true);", fieldName, + childFieldName, html); + } else if (children.customHeader != null) { + XMLElement headerElement = + children.customHeader.consumeSingleChildElement(); + + if (!writer.isWidgetElement(headerElement)) { + writer.die("In %s of %s, %s is not a widget", children.customHeader, + tabElem, headerElement); + } + + String headerField = writer.parseElementToField(headerElement); + writer.addStatement("%s.add(%s, %s);", fieldName, childFieldName, + headerField); + } else { + // Neither a header or customHeader. + writer.die("%1$s requires either a <%2$s:%3$s> or <%2$s:%4$s>", + tabElem, tabElem.getPrefix(), HEADER, CUSTOM); + } + } + } + + private Children findChildren(final XMLElement elem, + final UiBinderWriter writer) throws UnableToCompleteException { + final Children children = new Children(); + + elem.consumeChildElements(new XMLElement.Interpreter<Boolean>() { + public Boolean interpretElement(XMLElement child) + throws UnableToCompleteException { + + if (hasTag(child, HEADER)) { + assertFirstHeader(); + children.header = child; + return true; + } + + if (hasTag(child, CUSTOM)) { + assertFirstHeader(); + children.customHeader = child; + return true; + } + + // Must be the body, then + if (null != children.body) { + writer.die("In %s, may have only one body element", elem); + } + + children.body = child; + return true; + } + + void assertFirstHeader() throws UnableToCompleteException { + if ((null != children.header) && (null != children.customHeader)) { + writer.die("In %1$s, may have only one %2$s:header " + + "or %2$s:customHeader", elem, elem.getPrefix()); + } + } + + private boolean hasTag(XMLElement child, final String attribute) { + return rightNamespace(child) && child.getLocalName().equals(attribute); + } + + private boolean rightNamespace(XMLElement child) { + return child.getNamespaceUri().equals(elem.getNamespaceUri()); + } + }); + + return children; + } + + private boolean isElementType(XMLElement parent, XMLElement child, String type) { + return child.getNamespaceUri().equals(parent.getNamespaceUri()) + && type.equals(child.getLocalName()); + } +} ======================================= --- /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java Tue Oct 13 16:57:19 2009 +++ /trunk/user/src/com/google/gwt/uibinder/rebind/UiBinderWriter.java Fri Oct 16 13:11:56 2009 @@ -1117,6 +1117,7 @@ addWidgetParser("CustomButton"); addWidgetParser("DockLayoutPanel"); addWidgetParser("StackLayoutPanel"); + addWidgetParser("TabLayoutPanel"); addAttributeParser("boolean", "com.google.gwt.uibinder.parsers.BooleanAttributeParser"); ======================================= --- /trunk/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java Fri Oct 16 12:16:25 2009 +++ /trunk/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java Fri Oct 16 13:11:56 2009 @@ -63,6 +63,8 @@ RequiresResize, ProvidesResize, IndexedPanel, HasBeforeSelectionHandlers<Integer>, HasSelectionHandlers<Integer> { + private static final int BIG_ENOUGH_TO_NOT_WRAP = 16384; + private static class Tab extends SimplePanel { private Element anchor; @@ -106,20 +108,20 @@ private WidgetCollection children = new WidgetCollection(this); private FlowPanel tabBar = new FlowPanel(); private ArrayList<Tab> tabs = new ArrayList<Tab>(); - private final double tabBarSize; - private final Unit tabBarUnit; + private final double barHeight; + private final Unit barUnit; private LayoutPanel panel; private int selectedIndex = -1; /** * Creates an empty tab panel. * - * @param tabBarSize the size of the tab bar - * @param tabBarUnit the unit in which the tab bar size is specified + * @param barHeight the size of the tab bar + * @param barUnit the unit in which the tab bar size is specified */ - public TabLayoutPanel(double tabBarSize, Unit tabBarUnit) { - this.tabBarSize = tabBarSize; - this.tabBarUnit = tabBarUnit; + public TabLayoutPanel(double barHeight, Unit barUnit) { + this.barHeight = barHeight; + this.barUnit = barUnit; panel = new LayoutPanel(); initWidget(panel); @@ -127,11 +129,15 @@ panel.add(tabBar); Layer layer = panel.getLayer(tabBar); layer.setLeftRight(0, Unit.PX, 0, Unit.PX); - layer.setTopHeight(0, Unit.PX, tabBarSize, tabBarUnit); + layer.setTopHeight(0, Unit.PX, barHeight, barUnit); panel.layout(); panel.getLayer(tabBar).setChildVerticalPosition(Alignment.END); + // Make the tab bar extremely wide so that tabs themselves never wrap. + // (Its layout container is overflow:hidden) + tabBar.getElement().getStyle().setWidth(BIG_ENOUGH_TO_NOT_WRAP, Unit.PX); + tabBar.setStyleName("gwt-TabLayoutPanelTabs"); setStyleName("gwt-TabLayoutPanel"); } @@ -145,7 +151,7 @@ * moved to the right-most index. * * @param child the widget to be added - * @param tabText the text to be shown on its tab + * @param text the text to be shown on its tab */ public void add(Widget child, String text) { insert(child, text, getWidgetCount()); @@ -156,11 +162,11 @@ * moved to the right-most index. * * @param child the widget to be added - * @param tabText the text to be shown on its tab + * @param text the text to be shown on its tab * @param asHtml <code>true</code> to treat the specified text as HTML */ - public void add(Widget w, String text, boolean asHtml) { - insert(w, text, asHtml, getWidgetCount()); + public void add(Widget child, String text, boolean asHtml) { + insert(child, text, asHtml, getWidgetCount()); } /** @@ -241,11 +247,10 @@ * be moved to the requested index. * * @param child the widget to be added - * @param tab the widget to be placed in the associated tab * @param beforeIndex the index before which it will be inserted */ - public void insert(Widget w, int beforeIndex) { - insert(w, "", beforeIndex); + public void insert(Widget child, int beforeIndex) { + insert(child, "", beforeIndex); } /** @@ -253,18 +258,18 @@ * moved to the requested index. * * @param child the widget to be added - * @param tabText the text to be shown on its tab + * @param text the text to be shown on its tab * @param asHtml <code>true</code> to treat the specified text as HTML * @param beforeIndex the index before which it will be inserted */ - public void insert(Widget w, String text, boolean asHtml, int beforeIndex) { + public void insert(Widget child, String text, boolean asHtml, int beforeIndex) { Widget contents; if (asHtml) { contents = new HTML(text); } else { contents = new Label(text); } - insert(w, contents, beforeIndex); + insert(child, contents, beforeIndex); } /** @@ -272,7 +277,7 @@ * moved to the requested index. * * @param child the widget to be added - * @param tabText the text to be shown on its tab + * @param text the text to be shown on its tab * @param beforeIndex the index before which it will be inserted */ public void insert(Widget child, String text, int beforeIndex) { @@ -343,8 +348,8 @@ // Fire the before selection event, giving the recipients a chance to // cancel the selection. - BeforeSelectionEvent<Integer> event = BeforeSelectionEvent - .fire(this, index); + BeforeSelectionEvent<Integer> event = + BeforeSelectionEvent.fire(this, index); if ((event != null) && event.isCanceled()) { return; } @@ -384,9 +389,9 @@ * @param index the index of the tab whose HTML is to be set * @param html the tab's new HTML contents */ - public void setTabHTML(int index, String text) { + public void setTabHTML(int index, String html) { checkIndex(index); - tabs.get(index).setWidget(new HTML(text)); + tabs.get(index).setWidget(new HTML(html)); } /** @@ -442,7 +447,7 @@ private void layoutChild(Widget child) { Layer layer = panel.getLayer(child); layer.setLeftRight(0, Unit.PX, 0, Unit.PX); - layer.setTopBottom(tabBarSize, tabBarUnit, 0, Unit.PX); + layer.setTopBottom(barHeight, barUnit, 0, Unit.PX); layer.getContainerElement().getStyle().setVisibility(Visibility.HIDDEN); panel.layout(); } --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
