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
-~----------~----~----~----~------~----~------~--~---

Reply via email to