aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2015-03-19 13:13:14 +0200
committerVaadin Code Review <review@vaadin.com>2015-03-20 11:33:07 +0000
commitf6a148783e898c828155aab59b97f7a52faa5129 (patch)
treee87a824ed91906884ed5ab5be08daf092739d230
parentc77b94560588320b2b0b746c17b9240f433475dc (diff)
downloadvaadin-framework-f6a148783e898c828155aab59b97f7a52faa5129.tar.gz
vaadin-framework-f6a148783e898c828155aab59b97f7a52faa5129.zip
Restructure sidebar widget handling to work with custom content (#17023)
Change-Id: Ib24d1536af89ce97b2117d813e0f75405df7dab7
-rw-r--r--client/src/com/vaadin/client/widgets/Grid.java129
-rw-r--r--uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridSidebarContentTest.java105
-rw-r--r--uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java39
3 files changed, 211 insertions, 62 deletions
diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java
index 174f2dde38..e9288a7ece 100644
--- a/client/src/com/vaadin/client/widgets/Grid.java
+++ b/client/src/com/vaadin/client/widgets/Grid.java
@@ -63,8 +63,8 @@ import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HasEnabled;
-import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.ToggleButton;
@@ -2887,8 +2887,8 @@ public class Grid<T> extends ResizeComposite implements
}
/**
- * Sidebar displaying toggles for hidable columns and additional custom
- * widgets.
+ * Sidebar displaying toggles for hidable columns and custom widgets
+ * provided by the application.
* <p>
* The button for opening the sidebar is automatically visible inside the
* grid, if it contains any column hiding options or custom widgets. The
@@ -2903,7 +2903,7 @@ public class Grid<T> extends ResizeComposite implements
@Override
public void onClick(ClickEvent event) {
- if (!open) {
+ if (!isOpen()) {
open();
} else {
close();
@@ -2911,77 +2911,67 @@ public class Grid<T> extends ResizeComposite implements
}
};
- /**
- * Contains all the widgets which should be shown once the sidebar is
- * opened
- */
- private final List<Widget> widgets = new ArrayList<Widget>();
+ private final FlowPanel rootContainer;
- private final VerticalPanel rootContainer;
+ private final FlowPanel content;
private final VButton openCloseButton;
private final Grid<?> grid;
- private boolean open;
-
- public Sidebar(Grid<?> grid) {
+ private Sidebar(Grid<?> grid) {
this.grid = grid;
- rootContainer = new VerticalPanel();
+ rootContainer = new FlowPanel();
initWidget(rootContainer);
openCloseButton = new VButton();
openCloseButton.addClickHandler(openCloseButtonHandler);
rootContainer.add(openCloseButton);
- rootContainer
- .setCellHorizontalAlignment(
- openCloseButton,
- HorizontalAlignmentConstant
- .endOf(com.google.gwt.i18n.client.HasDirection.Direction.LTR));
+
+ content = new FlowPanel() {
+ @Override
+ public boolean remove(Widget w) {
+ // Check here to catch child.removeFromParent() calls
+ boolean removed = super.remove(w);
+ if (removed) {
+ updateVisibility();
+ }
+
+ return removed;
+ }
+ };
}
/**
- * Opens the sidebar if not yet opened.
- *
- * @since
+ * Opens the sidebar if not yet opened. Opening the sidebar has no
+ * effect if it is empty.
*/
public void open() {
- if (!open) {
+ if (!isOpen() && isInDOM()) {
addStyleName("opened");
- open = true;
- for (Widget w : widgets) {
- rootContainer.add(w);
- }
+ rootContainer.add(content);
}
}
/**
* Closes the sidebar if not yet closed.
- *
- * @since
*/
public void close() {
- if (open) {
+ if (isOpen()) {
removeStyleName("opened");
- open = false;
- rootContainer.clear();
- rootContainer.add(openCloseButton);
+ content.removeFromParent();
}
}
/**
* Returns whether the sidebar is open or not.
- * <p>
- * <em>Note:</em> The sidebar can be in "open state" but not actually
- * visible inside grid. See {@link #isVisibleInGrid()}.
*
- * @since
* @return <code>true</code> if open, <code>false</code> if not
*/
public boolean isOpen() {
- return open;
+ return content.getParent() == rootContainer;
}
/**
@@ -2991,11 +2981,7 @@ public class Grid<T> extends ResizeComposite implements
* the widget to add or move
*/
public void add(Widget widget) {
- widgets.remove(widget);
- widgets.add(widget);
- if (open) {
- rootContainer.add(widget);
- }
+ content.add(widget);
updateVisibility();
}
@@ -3006,11 +2992,8 @@ public class Grid<T> extends ResizeComposite implements
* the widget to remove
*/
public void remove(Widget widget) {
- widgets.remove(widget);
- if (open) {
- rootContainer.remove(widget);
- }
- updateVisibility();
+ content.remove(widget);
+ // updateVisibility is called by remove listener
}
/**
@@ -3018,7 +3001,7 @@ public class Grid<T> extends ResizeComposite implements
* widget is already in the sidebar, then it is moved to the new index.
* <p>
* See
- * {@link VerticalPanel#insert(com.google.gwt.user.client.ui.IsWidget, int)}
+ * {@link FlowPanel#insert(com.google.gwt.user.client.ui.IsWidget, int)}
* for further details.
*
* @param widget
@@ -3027,33 +3010,34 @@ public class Grid<T> extends ResizeComposite implements
* 0-based index position for the widget.
*/
public void insert(Widget widget, int beforeIndex) {
- widgets.remove(widget);
- widgets.add(beforeIndex, widget);
- if (open) {
- // the first widget in the container is always the open button
- rootContainer.insert(widget, beforeIndex + 1);
- }
+ content.insert(widget, beforeIndex);
updateVisibility();
}
@Override
public void setStylePrimaryName(String styleName) {
super.setStylePrimaryName(styleName);
+ content.setStylePrimaryName(styleName + "-content");
openCloseButton.setStylePrimaryName(styleName + "-button");
}
private void updateVisibility() {
- final boolean hasWidgets = widgets.size() > 0;
- final boolean isVisible = getParent() != null;
+ final boolean hasWidgets = content.getWidgetCount() > 0;
+ final boolean isVisible = isInDOM();
if (isVisible && !hasWidgets) {
+ Grid.setParent(this, null);
getElement().removeFromParent();
- removeFromParent();
} else if (!isVisible && hasWidgets) {
+ close();
grid.getElement().appendChild(getElement());
Grid.setParent(this, grid);
}
}
+ private boolean isInDOM() {
+ return getParent() != null;
+ }
+
}
/**
@@ -3109,9 +3093,7 @@ public class Grid<T> extends ResizeComposite implements
private void updatePanelVisibility() {
final boolean columnHidable = getWidgetCount() > 0;
- // parent for the panel might be null sidebar is not open
- final boolean columnTogglesPanelIsVisible = sidebar.widgets
- .contains(this);
+ final boolean columnTogglesPanelIsVisible = getParent() != null;
if (columnHidable && !columnTogglesPanelIsVisible) {
sidebar.insert(this, 0);
@@ -3225,7 +3207,6 @@ public class Grid<T> extends ResizeComposite implements
private boolean enabled = true;
-
private DetailsGenerator detailsGenerator = DetailsGenerator.NULL;
private GridSpacerUpdater gridSpacerUpdater = new GridSpacerUpdater();
/** A set keeping track of the indices of all currently open details */
@@ -7246,6 +7227,30 @@ public class Grid<T> extends ResizeComposite implements
widget.@com.google.gwt.user.client.ui.Widget::setParent(Lcom/google/gwt/user/client/ui/Widget;)(parent);
}-*/;
+ private static native final void onAttach(Widget widget)
+ /*-{
+ widget.@Widget::onAttach()();
+ }-*/;
+
+ private static native final void onDetach(Widget widget)
+ /*-{
+ widget.@Widget::onDetach()();
+ }-*/;
+
+ @Override
+ protected void doAttachChildren() {
+ if (getSidebar().getParent() == this) {
+ onAttach(getSidebar());
+ }
+ }
+
+ @Override
+ protected void doDetachChildren() {
+ if (getSidebar().getParent() == this) {
+ onDetach(getSidebar());
+ }
+ }
+
/**
* Resets all cached pixel sizes and reads new values from the DOM. This
* methods should be used e.g. when styles affecting the dimensions of
diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridSidebarContentTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridSidebarContentTest.java
new file mode 100644
index 0000000000..563fe890ec
--- /dev/null
+++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/client/GridSidebarContentTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2000-2014 Vaadin Ltd.
+ *
+ * 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.vaadin.tests.components.grid.basicfeatures.client;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.openqa.selenium.By;
+import org.openqa.selenium.WebElement;
+
+import com.vaadin.tests.components.grid.basicfeatures.GridBasicClientFeaturesTest;
+import com.vaadin.tests.components.grid.basicfeatures.element.CustomGridElement;
+
+public class GridSidebarContentTest extends GridBasicClientFeaturesTest {
+
+ @Test
+ public void testSidebarWithHidableColumn() {
+ openTestURL();
+ CustomGridElement gridElement = getGridElement();
+
+ Assert.assertEquals("Sidebar should not be initially present", 0,
+ countBySelector(".v-grid-sidebar"));
+
+ selectMenuPath("Component", "Columns", "Column 0", "Hidable");
+
+ gridElement.findElement(By.className("v-grid-sidebar-button")).click();
+
+ WebElement toggle = gridElement.findElement(By
+ .className("column-hiding-toggle"));
+
+ Assert.assertEquals("Column 0 should be togglable", "Header (0,0)",
+ toggle.getText());
+
+ selectMenuPath("Component", "Columns", "Column 0", "Hidable");
+ Assert.assertEquals("Sidebar should disappear without toggable column",
+ 0, countBySelector(".v-grid-sidebar"));
+
+ }
+
+ @Test
+ public void testSidebarWithCustomContent() {
+ openTestURL();
+ CustomGridElement gridElement = getGridElement();
+
+ Assert.assertEquals("Sidebar should not be initially present", 0,
+ countBySelector(".v-grid-sidebar"));
+
+ selectMenuPath("Component", "Sidebar", "Toggle sidebar entry");
+
+ gridElement.findElement(By.className("v-grid-sidebar-button")).click();
+
+ WebElement sidebarButton = gridElement.findElement(By
+ .cssSelector(".v-grid-sidebar-content button"));
+
+ Assert.assertEquals("Sidebar button", sidebarButton.getText());
+
+ sidebarButton.click();
+
+ Assert.assertEquals("Click count: 1", sidebarButton.getText());
+
+ selectMenuPath("Component", "Sidebar", "Toggle sidebar entry");
+
+ Assert.assertEquals("Sidebar should disappear after content remove", 0,
+ countBySelector(".v-grid-sidebar"));
+ }
+
+ @Test
+ public void testProgrammaticSidebarToggle() {
+ openTestURL();
+
+ selectMenuPath("Component", "Sidebar", "Toggle sidebar visibility");
+
+ Assert.assertEquals("Toggling without content should't show anything",
+ 0, countBySelector(".v-grid-sidebar-content button"));
+
+ selectMenuPath("Component", "Sidebar", "Toggle sidebar entry");
+ selectMenuPath("Component", "Sidebar", "Toggle sidebar visibility");
+
+ Assert.assertEquals("Toggling with content should show sidebar", 1,
+ countBySelector(".v-grid-sidebar-content button"));
+
+ selectMenuPath("Component", "Sidebar", "Toggle sidebar visibility");
+
+ Assert.assertEquals("Toggling again should hide sidebar", 0,
+ countBySelector(".v-grid-sidebar-content button"));
+ }
+
+ private int countBySelector(String cssSelector) {
+ return getGridElement().findElements(By.cssSelector(cssSelector))
+ .size();
+ }
+
+}
diff --git a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
index 6615cda8da..97d1a50ff6 100644
--- a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
+++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java
@@ -80,6 +80,7 @@ import com.vaadin.client.widgets.Grid.Column;
import com.vaadin.client.widgets.Grid.FooterRow;
import com.vaadin.client.widgets.Grid.HeaderRow;
import com.vaadin.client.widgets.Grid.SelectionMode;
+import com.vaadin.client.widgets.Grid.Sidebar;
import com.vaadin.tests.widgetset.client.grid.GridBasicClientFeaturesWidget.Data;
/**
@@ -199,6 +200,17 @@ public class GridBasicClientFeaturesWidget extends
private boolean secondEditorError = false;
+ private Button sidebarEntry = new Button("Sidebar button",
+ new ClickHandler() {
+ private int count = 0;
+
+ @Override
+ public void onClick(ClickEvent event) {
+ count++;
+ sidebarEntry.setText("Click count: " + count);
+ }
+ });
+
/**
* Our basic data object
*/
@@ -408,6 +420,7 @@ public class GridBasicClientFeaturesWidget extends
createInternalsMenu();
createDataSourceMenu();
createDetailsMenu();
+ createSidebarMenu();
grid.getElement().getStyle().setZIndex(0);
@@ -1441,6 +1454,32 @@ public class GridBasicClientFeaturesWidget extends
grid.setDetailsVisible(100, visible);
}
}, menupath);
+ }
+ private void createSidebarMenu() {
+ String[] menupath = new String[] { "Component", "Sidebar" };
+
+ addMenuCommand("Toggle sidebar visibility", new ScheduledCommand() {
+ @Override
+ public void execute() {
+ Sidebar sidebar = grid.getSidebar();
+ if (sidebar.isOpen()) {
+ sidebar.close();
+ } else {
+ sidebar.open();
+ }
+ }
+ }, menupath);
+
+ addMenuCommand("Toggle sidebar entry", new ScheduledCommand() {
+ @Override
+ public void execute() {
+ if (sidebarEntry.getParent() != null) {
+ sidebarEntry.removeFromParent();
+ } else {
+ grid.getSidebar().add(sidebarEntry);
+ }
+ }
+ }, menupath);
}
}