Call onLayout when there is no animation

In case of a layout without animation (duration = 0) make sure to call
onLayout with progress set to 1.0 after the layout was computed to make
sure that onResize is properly called.

Bug: #7185
Change-Id: Ieb0ebb2eeb055ad18ee84db23f4f5f786c107f45
Bug-Link: https://github.com/gwtproject/gwt/issues/7185
diff --git a/user/src/com/google/gwt/layout/client/Layout.java b/user/src/com/google/gwt/layout/client/Layout.java
index 218432a..c92e5b2 100644
--- a/user/src/com/google/gwt/layout/client/Layout.java
+++ b/user/src/com/google/gwt/layout/client/Layout.java
@@ -511,6 +511,9 @@
         l.heightUnit = l.targetHeightUnit;
 
         impl.layout(l);
+        if (callback != null) {
+          callback.onLayout(l, 1.0);
+        }
       }
 
       impl.finalizeLayout(parentElem);
diff --git a/user/test/com/google/gwt/layout/client/LayoutTest.java b/user/test/com/google/gwt/layout/client/LayoutTest.java
index a4a3098..9b7f595 100644
--- a/user/test/com/google/gwt/layout/client/LayoutTest.java
+++ b/user/test/com/google/gwt/layout/client/LayoutTest.java
@@ -38,6 +38,9 @@
 import com.google.gwt.user.client.ResizeHelper;
 import com.google.gwt.user.client.Window;
 
+import java.util.HashMap;
+import java.util.Map;
+
 /**
  * Tests for the {@link Layout} class.
  */
@@ -275,6 +278,28 @@
   }
 
   /**
+   * Make sure to call onLayout on the AnimationCallback, when there is
+   * no animation (duration =0). This will make sure that onResize will be
+   * called on the child panels.
+   */
+  public void testOnLayoutWhenNoAnimation() {
+    final Map<Layer,Double> called = new HashMap();
+    layout.layout(0, new Layout.AnimationCallback() {
+      @Override
+      public void onAnimationComplete() {
+      }
+
+      @Override
+      public void onLayout(Layer layer, double progress) {
+        called.put(layer,progress);
+      }
+    });
+    assertEquals(2,called.size());
+    assertEquals(1.0,called.get(layer0));
+    assertEquals(1.0,called.get(layer1));
+  }
+
+  /**
    * Ensures that two children laid out using various units in such a way that
    * they should abut one another actually do so.
    */
diff --git a/user/test/com/google/gwt/user/client/ui/DeckLayoutPanelTest.java b/user/test/com/google/gwt/user/client/ui/DeckLayoutPanelTest.java
index 5103ad6..e51d240 100644
--- a/user/test/com/google/gwt/user/client/ui/DeckLayoutPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/DeckLayoutPanelTest.java
@@ -16,6 +16,9 @@
 
 package com.google.gwt.user.client.ui;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Test for {@link DeckLayoutPanel}.
  */
@@ -49,6 +52,24 @@
     assertTrue(labels[1].isVisible());
   }
 
+  /**
+   * Test that forcing layout will call onResize only once.
+   */
+  public void testForceLayoutNoRedundantOnResize() {
+    final List<Boolean> called = new ArrayList<>();
+    DeckLayoutPanel deck = createPanel();
+    SimpleLayoutPanel child = new SimpleLayoutPanel() {
+      @Override
+      public void onResize() {
+        super.onResize();
+        called.add(true);
+      }
+    };
+    deck.add(child);
+    deck.forceLayout();
+    assertEquals(1,called.size());
+  }
+
   public void testSetWidget() {
     DeckLayoutPanel deck = createPanel();
     Label[] labels = new Label[2];
diff --git a/user/test/com/google/gwt/user/client/ui/DockLayoutPanelTest.java b/user/test/com/google/gwt/user/client/ui/DockLayoutPanelTest.java
index 9a8f702..fb03d0d 100644
--- a/user/test/com/google/gwt/user/client/ui/DockLayoutPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/DockLayoutPanelTest.java
@@ -18,6 +18,9 @@
 import com.google.gwt.dom.client.Style.Unit;
 import com.google.gwt.user.client.ui.DockLayoutPanel.Direction;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Tests for {@link DockLayoutPanel}.
  */
@@ -181,6 +184,24 @@
     assertEquals(Direction.LINE_START, panel.getWidgetDirection(widget));
   }
 
+  /**
+   * Test that forcing layout will call onResize only once.
+   */
+  public void testForceLayoutNoRedundantOnResize() {
+    final List<Boolean> called = new ArrayList<>();
+    DockLayoutPanel panel = createDockLayoutPanel();
+    SimpleLayoutPanel child = new SimpleLayoutPanel() {
+      @Override
+      public void onResize() {
+        super.onResize();
+        called.add(true);
+      }
+    };
+    panel.addWest(child,123.4);
+    panel.forceLayout();
+    assertEquals(1,called.size());
+  }
+
   protected DockLayoutPanel createDockLayoutPanel() {
     return new DockLayoutPanel(Unit.PX);
   }
diff --git a/user/test/com/google/gwt/user/client/ui/LayoutPanelTest.java b/user/test/com/google/gwt/user/client/ui/LayoutPanelTest.java
index 1999612..a6e1219 100644
--- a/user/test/com/google/gwt/user/client/ui/LayoutPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/LayoutPanelTest.java
@@ -25,6 +25,9 @@
 import com.google.gwt.layout.client.Layout.Layer;
 import com.google.gwt.user.client.Command;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * Tests for {@link LayoutPanel}. Note that this only tests LayoutPanel-specific
  * behavior, not general layout correctness, which is covered by
@@ -311,6 +314,24 @@
             Unit.PX));
   }
 
+  /**
+   * Test that forcing layout will call onResize only once.
+   */
+  public void testForceLayoutNoRedundantOnResize() {
+    final List<Boolean> called = new ArrayList<>();
+    LayoutPanel layoutPanel = new LayoutPanel();
+    SimpleLayoutPanel child = new SimpleLayoutPanel() {
+      @Override
+      public void onResize() {
+        super.onResize();
+        called.add(true);
+      }
+    };
+    layoutPanel.add(child);
+    layoutPanel.forceLayout();
+    assertEquals(1,called.size());
+  }
+
   protected LayoutPanel createLayoutPanel() {
     return new LayoutPanel();
   }
diff --git a/user/test/com/google/gwt/user/client/ui/SplitLayoutPanelTest.java b/user/test/com/google/gwt/user/client/ui/SplitLayoutPanelTest.java
index 6a6818e..3b4ff2b 100644
--- a/user/test/com/google/gwt/user/client/ui/SplitLayoutPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/SplitLayoutPanelTest.java
@@ -20,6 +20,8 @@
 import com.google.gwt.junit.DoNotRunWith;
 import com.google.gwt.junit.Platform;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -209,6 +211,24 @@
     assertEquals(390, west.getOffsetWidth());
   }
 
+  /**
+   * Test that forcing layout will call onResize only once.
+   */
+  public void testForceLayoutNoRedundantOnResize() {
+    final List<Boolean> called = new ArrayList<>();
+    SplitLayoutPanel panel = new SplitLayoutPanel();
+    SimpleLayoutPanel child = new SimpleLayoutPanel() {
+      @Override
+      public void onResize() {
+        super.onResize();
+        called.add(true);
+      }
+    };
+    panel.addWest(child,123.4);
+    panel.forceLayout();
+    assertEquals(1,called.size());
+  }
+
   @Override
   protected DockLayoutPanel createDockLayoutPanel() {
     return new SplitLayoutPanel();
diff --git a/user/test/com/google/gwt/user/client/ui/StackLayoutPanelTest.java b/user/test/com/google/gwt/user/client/ui/StackLayoutPanelTest.java
index ff4cfc6..969c069 100644
--- a/user/test/com/google/gwt/user/client/ui/StackLayoutPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/StackLayoutPanelTest.java
@@ -386,6 +386,24 @@
   }
 
   /**
+   * Test that forcing layout will call onResize only once.
+   */
+  public void testForceLayoutNoRedundantOnResize() {
+    final List<Boolean> called = new ArrayList<>();
+    StackLayoutPanel panel = new StackLayoutPanel(Unit.EM);
+    SimpleLayoutPanel child = new SimpleLayoutPanel() {
+      @Override
+      public void onResize() {
+        super.onResize();
+        called.add(true);
+      }
+    };
+    panel.add(child,"foo", 1);
+    panel.forceLayout();
+    assertEquals(1,called.size());
+  }
+
+  /**
    * Asserts that <b>widget</b> is attached to <b>panel</b> as a child in the
    * logical representation of <b>panel</b>.
    * 
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 570a53d..4646edc 100644
--- a/user/test/com/google/gwt/user/client/ui/TabLayoutPanelTest.java
+++ b/user/test/com/google/gwt/user/client/ui/TabLayoutPanelTest.java
@@ -508,4 +508,22 @@
 
     delayTestFinish(200);
   }
+
+  /**
+   * Test that forcing layout will call onResize only once.
+   */
+  public void testForceLayoutNoRedundantOnResize() {
+    final List<Boolean> called = new ArrayList<>();
+    final TabLayoutPanel panel = new TabLayoutPanel(2, Unit.EM);
+    SimpleLayoutPanel child = new SimpleLayoutPanel() {
+      @Override
+      public void onResize() {
+        super.onResize();
+        called.add(true);
+      }
+    };
+    panel.add(child,"Tab1");
+    panel.forceLayout();
+    assertEquals(1,called.size());
+  }
 }