| /* |
| * Copyright 2010 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.user.client.ui; |
| |
| import com.google.gwt.dom.client.Style.Unit; |
| import com.google.gwt.event.logical.shared.BeforeSelectionEvent; |
| import com.google.gwt.event.logical.shared.BeforeSelectionHandler; |
| import com.google.gwt.event.logical.shared.SelectionEvent; |
| import com.google.gwt.event.logical.shared.SelectionHandler; |
| import com.google.gwt.safehtml.shared.SafeHtmlUtils; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| /** |
| * Tests for {@link StackLayoutPanel}. |
| */ |
| public class StackLayoutPanelTest extends WidgetTestBase { |
| static class Adder implements HasWidgetsTester.WidgetAdder { |
| public void addChild(HasWidgets container, Widget child) { |
| ((StackLayoutPanel) container).add(child, new Label("Header"), 1); |
| } |
| } |
| |
| private static final String html = "<b>hello</b><i>world</i>"; |
| |
| private class TestSelectionHandler implements |
| BeforeSelectionHandler<Integer>, SelectionHandler<Integer> { |
| private boolean onBeforeSelectionFired; |
| private boolean onSelectionFired; |
| |
| public void assertOnBeforeSelectionFired(boolean expected) { |
| assertEquals(expected, onBeforeSelectionFired); |
| } |
| |
| public void assertOnSelectionFired(boolean expected) { |
| assertEquals(expected, onSelectionFired); |
| } |
| |
| public void onBeforeSelection(BeforeSelectionEvent<Integer> event) { |
| assertFalse(onSelectionFired); |
| onBeforeSelectionFired = true; |
| } |
| |
| public void onSelection(SelectionEvent<Integer> event) { |
| assertTrue(onBeforeSelectionFired); |
| onSelectionFired = true; |
| } |
| } |
| |
| /** |
| * Tests {@link StackLayoutPanel#add(Widget, String, boolean, double)}. |
| */ |
| public void testAddWithTextHeader() { |
| StackLayoutPanel panel = createStackLayoutPanel(Unit.EM); |
| Widget widget = new Label("foo"); |
| |
| panel.add(widget, "header", false, 1); |
| |
| assertLogicalPaternityOfChild(panel, widget); |
| } |
| |
| /** |
| * Tests {@link StackLayoutPanel#add(IsWidget, String, boolean, double)}. |
| */ |
| public void testAddWithTextHeaderAsIsWidget() { |
| StackLayoutPanel panel = createStackLayoutPanel(Unit.EM); |
| Widget widget = new Label("foo"); |
| |
| // IsWidget cast to call the overloaded version |
| panel.add((IsWidget) widget, "header", false, 1); |
| |
| assertLogicalPaternityOfChild(panel, widget); |
| } |
| |
| /** |
| * Tests {@link StackLayoutPanel#add(Widget, Widget, double)}. |
| */ |
| public void testAddWithWidgetHeader() { |
| StackLayoutPanel panel = createStackLayoutPanel(Unit.EM); |
| Widget header = new Label("foo"); |
| Widget widget = new Label("bar"); |
| |
| panel.add(widget, header, 1); |
| |
| assertLogicalPaternityOfChild(panel, widget); |
| assertLogicalPaternityOfHeader(panel, widget, header); |
| } |
| |
| /** |
| * Tests {@link StackLayoutPanel#add(IsWidget, IsWidget, double)}. |
| */ |
| public void testAddWithWidgetHeaderAsIsWidget() { |
| StackLayoutPanel panel = createStackLayoutPanel(Unit.EM); |
| Widget header = new Label("foo"); |
| Widget widget = new Label("bar"); |
| |
| // IsWidget casts to call the overloaded version |
| panel.add((IsWidget) widget, (IsWidget) header, 1); |
| |
| assertLogicalPaternityOfChild(panel, widget); |
| assertLogicalPaternityOfHeader(panel, widget, header); |
| } |
| |
| public void testAddWithSafeHtml() { |
| StackLayoutPanel panel = new StackLayoutPanel(Unit.EM); |
| panel.add(new HTML("foo"), SafeHtmlUtils.fromSafeConstant(html), 1.0); |
| |
| assertEquals(1, panel.getWidgetCount()); |
| assertEquals(html, |
| panel.getHeaderWidget(0).getElement().getInnerHTML().toLowerCase()); |
| } |
| |
| public void testAttachDetachOrder() { |
| HasWidgetsTester.testAll(new StackLayoutPanel(Unit.EM), new Adder(), true); |
| } |
| |
| public void testEmptyAdd() { |
| // Issue 4414: Attaching an empty StackLayoutPanel caused an exception. |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| RootPanel.get().add(p); |
| } |
| |
| public void testInsertMultipleTimes() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| |
| TextBox tb = new TextBox(); |
| p.add(tb, "Title", 1); |
| p.add(tb, "Title", 1); |
| p.add(tb, "Title3", 1); |
| |
| assertEquals(1, p.getWidgetCount()); |
| assertEquals(0, p.getWidgetIndex(tb)); |
| Iterator<Widget> i = p.iterator(); |
| assertTrue(i.hasNext()); |
| assertTrue(tb.equals(i.next())); |
| assertFalse(i.hasNext()); |
| |
| Label l = new Label(); |
| p.add(l, "Title", 1); |
| p.add(l, "Title", 1); |
| p.add(l, "Title3", 1); |
| assertEquals(2, p.getWidgetCount()); |
| assertEquals(0, p.getWidgetIndex(tb)); |
| assertEquals(1, p.getWidgetIndex(l)); |
| |
| p.insert(l, "Title", 1, 0); |
| assertEquals(2, p.getWidgetCount()); |
| assertEquals(0, p.getWidgetIndex(l)); |
| assertEquals(1, p.getWidgetIndex(tb)); |
| |
| p.insert(l, "Title", 1, 1); |
| assertEquals(2, p.getWidgetCount()); |
| assertEquals(0, p.getWidgetIndex(l)); |
| assertEquals(1, p.getWidgetIndex(tb)); |
| |
| p.insert(l, "Title", 1, 2); |
| assertEquals(2, p.getWidgetCount()); |
| assertEquals(0, p.getWidgetIndex(tb)); |
| assertEquals(1, p.getWidgetIndex(l)); |
| } |
| |
| public void testInsertSafeHtml() { |
| StackLayoutPanel panel = new StackLayoutPanel(Unit.EM); |
| panel.insert(new HTML("foo"), SafeHtmlUtils.fromSafeConstant(html), 1.0, 0); |
| |
| assertEquals(1, panel.getWidgetCount()); |
| assertEquals(html, |
| panel.getHeaderWidget(0).getElement().getInnerHTML().toLowerCase()); |
| } |
| |
| public void testInsertWithHTML() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| Label l = new Label(); |
| p.add(l, "three", 1); |
| p.insert(new HTML("<b>hello</b>"), "two", true, 1, 0); |
| p.insert(new HTML("goodbye"), "one", false, 1, 0); |
| assertEquals(3, p.getWidgetCount()); |
| } |
| |
| /** |
| * Tests to ensure that arbitrary widgets can be added/inserted effectively. |
| */ |
| public void testInsertWithWidgets() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| |
| TextBox wa = new TextBox(); |
| CheckBox wb = new CheckBox(); |
| VerticalPanel wc = new VerticalPanel(); |
| wc.add(new Label("First")); |
| wc.add(new Label("Second")); |
| |
| Label contentA = new Label("Content A"); |
| Label contentB = new Label("Content B"); |
| Label contentC = new Label("Content C"); |
| |
| p.add(contentC, wc, 1); |
| p.insert(contentB, wb, 1, 0); |
| p.showWidget(1); |
| |
| // Insert before the visible widget. |
| p.insert(contentA, wa, 1, 0); |
| |
| // Check that the visible widget index has been incremented. |
| assertEquals(2, p.getVisibleIndex()); |
| |
| // Call these to ensure we don't throw an exception. |
| assertEquals(wa, p.getHeaderWidget(0)); |
| assertEquals(wb, p.getHeaderWidget(1)); |
| assertEquals(wc, p.getHeaderWidget(2)); |
| assertEquals(contentA, p.getWidget(0)); |
| assertEquals(contentB, p.getWidget(1)); |
| assertEquals(contentC, p.getWidget(2)); |
| assertEquals(3, p.getWidgetCount()); |
| } |
| |
| public void testIterator() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| HTML foo = new HTML("foo"); |
| HTML bar = new HTML("bar"); |
| HTML baz = new HTML("baz"); |
| p.add(foo, "foo", 1); |
| p.add(bar, "bar", 1); |
| p.add(baz, "baz", 1); |
| |
| // Iterate over the entire set and make sure it stops correctly. |
| Iterator<Widget> it = p.iterator(); |
| assertTrue(it.hasNext()); |
| assertTrue(it.next() == foo); |
| assertTrue(it.hasNext()); |
| assertTrue(it.next() == bar); |
| assertTrue(it.hasNext()); |
| assertTrue(it.next() == baz); |
| assertFalse(it.hasNext()); |
| |
| // Test removing using the iterator. |
| it = p.iterator(); |
| it.next(); |
| it.remove(); |
| assertTrue(it.next() == bar); |
| assertTrue(p.getWidgetCount() == 2); |
| assertTrue(p.getWidget(0) == bar); |
| assertTrue(p.getWidget(1) == baz); |
| } |
| |
| public void testRemoveBeforeSelectedWidget() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| p.add(new Label("Content 0"), "Header 0", 1); |
| p.add(new Label("Content 1"), "Header 0", 1); |
| p.add(new Label("Content 2"), "Header 2", 1); |
| p.showWidget(2); |
| assertEquals(2, p.getVisibleIndex()); |
| |
| // Remove a widget before the selected index. |
| p.remove(1); |
| assertEquals(1, p.getVisibleIndex()); |
| } |
| |
| public void testRemoveSelectedWidget() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| p.add(new Label("Content 0"), "Header 0", 1); |
| p.add(new Label("Content 1"), "Header 0", 1); |
| p.add(new Label("Content 2"), "Header 2", 1); |
| p.showWidget(1); |
| assertEquals(1, p.getVisibleIndex()); |
| |
| // Remove the selected widget. |
| p.remove(1); |
| assertEquals(0, p.getVisibleIndex()); |
| } |
| |
| public void testSelectionEvents() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| RootPanel.get().add(p); |
| |
| p.add(new Button("foo"), "foo", 1); |
| p.add(new Button("bar"), "bar", 1); |
| |
| // Make sure selecting a stack fires both events in the right order. |
| TestSelectionHandler handler = new TestSelectionHandler(); |
| p.addBeforeSelectionHandler(handler); |
| p.addSelectionHandler(handler); |
| p.showWidget(1); |
| handler.assertOnBeforeSelectionFired(true); |
| handler.assertOnSelectionFired(true); |
| } |
| |
| public void testSelectionEventsNoFire() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| RootPanel.get().add(p); |
| |
| p.add(new Button("foo"), "foo", 1); |
| p.add(new Button("bar"), "bar", 1); |
| |
| TestSelectionHandler handler = new TestSelectionHandler(); |
| p.addBeforeSelectionHandler(handler); |
| p.addSelectionHandler(handler); |
| p.showWidget(1, false); |
| handler.assertOnBeforeSelectionFired(false); |
| handler.assertOnSelectionFired(false); |
| } |
| |
| public void testSetHeaderSafeHtml() { |
| StackLayoutPanel panel = new StackLayoutPanel(Unit.PX); |
| RootPanel.get().add(panel); |
| panel.add(new HTML("bar"), "foo", 1.0); |
| panel.setHeaderHTML(0, SafeHtmlUtils.fromSafeConstant(html)); |
| Widget header = panel.getHeaderWidget(0); |
| |
| assertEquals(html, header.getElement().getInnerHTML().toLowerCase()); |
| } |
| |
| /** |
| * For legacy reasons, {@link StackLayoutPanel#showWidget(Widget)} should call |
| * {@link StackLayoutPanel#showWidget(int)}. |
| */ |
| public void testShowWidgetLegacy() { |
| final List<Integer> called = new ArrayList<Integer>(); |
| StackLayoutPanel panel = new StackLayoutPanel(Unit.PX) { |
| @Override |
| public void showWidget(int index) { |
| called.add(index); |
| super.showWidget(index); |
| } |
| }; |
| Label stack1 = new Label("Stack 1"); |
| panel.add(new Label("Stack 0"), "Stack 0", 100); |
| panel.add(stack1, "Stack 1", 100); |
| panel.add(new Label("Stack 2"), "Stack 2", 100); |
| called.clear(); |
| |
| panel.showWidget(stack1); |
| assertEquals(1, called.size()); |
| assertEquals(1, called.get(0).intValue()); |
| } |
| |
| public void testVisibleWidget() { |
| StackLayoutPanel p = new StackLayoutPanel(Unit.EM); |
| assertNull(p.getVisibleWidget()); |
| |
| Label l0 = new Label("foo"); |
| Label l1 = new Label("bar"); |
| Label l2 = new Label("baz"); |
| |
| // Add one widget, and ensure that it's visible. |
| p.add(l0, new Label("header"), 1); |
| assertEquals(l0, p.getVisibleWidget()); |
| |
| // Remove the same, and ensure that there's no visible widget. |
| p.remove(l0); |
| assertNull(p.getVisibleWidget()); |
| |
| // Add all three. |
| p.add(l0, new Label("header"), 1); |
| p.add(l1, new Label("header"), 1); |
| p.add(l2, new Label("header"), 1); |
| |
| // l0 should be visible by default. |
| assertEquals(l0, p.getVisibleWidget()); |
| |
| // Removing l0 (currently visible) should cause l1 to be shown. |
| p.remove(l0); |
| assertEquals(l1, p.getVisibleWidget()); |
| |
| // Now ensure that showing l2 works properly. |
| p.showWidget(l2); |
| assertEquals(l2, p.getVisibleWidget()); |
| } |
| |
| /** |
| * Asserts that <b>widget</b> is attached to <b>panel</b> as a child in the |
| * logical representation of <b>panel</b>. |
| * |
| * @param panel the parent panel |
| * @param child a expected child of <b>panel</b> |
| */ |
| private void assertLogicalPaternityOfChild(StackLayoutPanel panel, |
| Widget child) { |
| assertTrue("The widget should be a child of the panel", |
| panel.getWidgetIndex(child) >= 0); |
| } |
| |
| /** |
| * Asserts that <b>header</b> is attached to <b>panel</b> as a header of |
| * <b>widget</b> in the logical representation of <b>panel</b>. |
| * |
| * @param panel the parent panel |
| * @param child the child whose header is being tested |
| * @param header the expected header of <b>child</b> |
| */ |
| private void assertLogicalPaternityOfHeader(StackLayoutPanel panel, |
| Widget child, Widget header) { |
| assertSame("The header should be attached to the panel.", header, |
| panel.getHeaderWidget(child)); |
| } |
| |
| private StackLayoutPanel createStackLayoutPanel(Unit unit) { |
| return new StackLayoutPanel(unit); |
| } |
| } |