Fix for issue 4596 (broken layout on tab visibility change in IE6). Changes
LayoutPanel to provide an explicit setWidgetVisible() method, which ensures
that the layout is properly updated on a visibility change. Also adds a test
to catch this particular flavor of failure on IE6.

Review at http://gwt-code-reviews.appspot.com/153820


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@7649 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/LayoutPanel.java b/user/src/com/google/gwt/user/client/ui/LayoutPanel.java
index 51543ff..94ba955 100644
--- a/user/src/com/google/gwt/user/client/ui/LayoutPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/LayoutPanel.java
@@ -333,6 +333,22 @@
     animate(0);
   }
 
+  /**
+   * Shows or hides the given widget and its layer. This method explicitly
+   * calls {@link UIObject#setVisible(boolean)} on the child widget and ensures
+   * that its associated layer is shown/hidden.
+   * 
+   * @param child
+   * @param visible
+   */
+  public void setWidgetVisible(Widget child, boolean visible) {
+    assertIsChild(child);
+    Element container = getWidgetContainerElement(child);
+    setVisible(container, visible);
+    child.setVisible(visible);
+    animate(0);
+  }
+
   @Override
   protected void onLoad() {
     layout.onAttach();
diff --git a/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java b/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java
index 961bb0f..00fa651 100644
--- a/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/TabLayoutPanel.java
@@ -386,16 +386,12 @@
     // Update the tabs being selected and unselected.
     if (selectedIndex != -1) {
       Widget child = children.get(selectedIndex);
-      Element container = panel.getWidgetContainerElement(child);
-      container.getStyle().setDisplay(Display.NONE);
-      child.setVisible(false);
+      panel.setWidgetVisible(child, false);
       tabs.get(selectedIndex).setSelected(false);
     }
 
     Widget child = children.get(index);
-    Element container = panel.getWidgetContainerElement(child);
-    container.getStyle().clearDisplay();
-    child.setVisible(true);
+    panel.setWidgetVisible(child, true);
     tabs.get(index).setSelected(true);
     selectedIndex = index;
 
diff --git a/user/test/com/google/gwt/user/client/ui/TabLayoutPanelTest.java b/user/test/com/google/gwt/user/client/ui/TabLayoutPanelTest.java
index e8c9f57..371375c 100644
--- a/user/test/com/google/gwt/user/client/ui/TabLayoutPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/TabLayoutPanelTest.java
@@ -23,6 +23,8 @@
 import com.google.gwt.junit.DoNotRunWith;
 import com.google.gwt.junit.Platform;
 import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.Command;
+import com.google.gwt.user.client.DeferredCommand;
 
 import java.util.Iterator;
 
@@ -59,6 +61,39 @@
     HasWidgetsTester.testAll(new TabLayoutPanel(1, Unit.EM), new Adder(), true);
   }
 
+  /**
+   * Ensures that hidden children are layed out properly when their tabs are
+   * selected. This has been a problem on IE6 (see issue 4596).
+   */
+  @DoNotRunWith({Platform.HtmlUnitBug})
+  public void testHiddenChildLayout() {
+    final TabLayoutPanel p = new TabLayoutPanel(32, Unit.PX);
+    p.setSize("128px", "128px");
+    RootPanel.get().add(p);
+
+    final Label foo = new Label("foo");
+    final Label bar = new Label("bar");
+    p.add(foo, new Label("foo"));
+    p.add(bar, new Label("bar"));
+
+    delayTestFinish(2000);
+    DeferredCommand.addCommand(new Command() {
+      public void execute() {
+        assertEquals(128, foo.getOffsetWidth());
+        assertEquals(128 - 32, foo.getOffsetHeight());
+
+        p.selectTab(1);
+        DeferredCommand.addCommand(new Command() {
+          public void execute() {
+            assertEquals(128, bar.getOffsetWidth());
+            assertEquals(128 - 32, bar.getOffsetHeight());
+            finishTest();
+          }
+        });
+      }
+    });
+  }
+
   public void testInsertBeforeSelected() {
     TabLayoutPanel p = new TabLayoutPanel(2, Unit.EM);
     p.add(new Label("foo"), "foo");