diff --git a/WebContent/VAADIN/themes/base/grid/grid.scss b/WebContent/VAADIN/themes/base/grid/grid.scss index 20f84788854..eb6e0112ada 100644 --- a/WebContent/VAADIN/themes/base/grid/grid.scss +++ b/WebContent/VAADIN/themes/base/grid/grid.scss @@ -52,6 +52,8 @@ $v-grid-editor-background-color: $v-grid-row-background-color !default; .#{$primaryStyleName}-tablewrapper { border: $v-grid-border; } + + // Column drag and drop elements .#{$primaryStyleName} .header-drag-table { border-spacing: 0; @@ -76,6 +78,31 @@ $v-grid-editor-background-color: $v-grid-row-background-color !default; } } } + + // Sidebar + + .#{$primaryStyleName}-sidebar { + position: absolute; + top: 1px; + right : 0; + + background-color: $v-grid-header-background-color; + border-left: $v-grid-header-border; + border-bottom: $v-grid-header-border; + z-index: 5; + + .#{$primaryStyleName}-sidebar-button { + height: $v-grid-header-row-height; + + &:after { + content: "\f0c9"; + font-family: FontAwesome, sans-serif; + font-size: $v-grid-header-font-size; + line-height: $v-grid-header-row-height; + padding: 0 $v-grid-cell-padding-horizontal; + } + } + } // Common cell styles diff --git a/client/src/com/vaadin/client/widgets/Grid.java b/client/src/com/vaadin/client/widgets/Grid.java index f7744d52ae4..e84ea7d1f52 100644 --- a/client/src/com/vaadin/client/widgets/Grid.java +++ b/client/src/com/vaadin/client/widgets/Grid.java @@ -61,9 +61,12 @@ 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.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.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import com.vaadin.client.BrowserInfo; import com.vaadin.client.DeferredWorker; @@ -74,6 +77,7 @@ import com.vaadin.client.renderers.Renderer; import com.vaadin.client.renderers.WidgetRenderer; import com.vaadin.client.ui.SubPartAware; +import com.vaadin.client.ui.VButton; import com.vaadin.client.ui.dd.DragAndDropHandler; import com.vaadin.client.ui.dd.DragAndDropHandler.DragAndDropCallback; import com.vaadin.client.widget.escalator.Cell; @@ -2784,6 +2788,92 @@ public boolean isScheduled() { } } + /** + * Sidebar displaying toggles for hidable columns and additional custom + * widgets. + * + * @since + */ + public static class Sidebar extends Composite { + + private final ClickHandler openCloseButtonHandler = new ClickHandler() { + + @Override + public void onClick(ClickEvent event) { + if (!open) { + open(); + } else { + close(); + } + } + }; + + private final VerticalPanel rootContainer; + + private final VButton openCloseButton; + + private boolean open; + + public Sidebar() { + rootContainer = new VerticalPanel(); + initWidget(rootContainer); + + openCloseButton = new VButton(); + openCloseButton.addClickHandler(openCloseButtonHandler); + + rootContainer.add(openCloseButton); + rootContainer + .setCellHorizontalAlignment( + openCloseButton, + HorizontalAlignmentConstant + .endOf(com.google.gwt.i18n.client.HasDirection.Direction.LTR)); + } + + /** + * Opens the sidebar if not yet opened. + * + * @since + */ + public void open() { + if (!open) { + addStyleName("opened"); + open = true; + } + } + + /** + * Closes the sidebar if not yet closed. + * + * @since + */ + public void close() { + if (open) { + removeStyleName("opened"); + open = false; + } + } + + /** + * Returns whether the sidebar is open or not. + *

+ * Note: The sidebar can be in "open state" but not actually + * visible inside grid. See {@link #isVisibleInGrid()}. + * + * @since + * @return true if open, false if not + */ + public boolean isOpen() { + return open; + } + + @Override + public void setStylePrimaryName(String styleName) { + super.setStylePrimaryName(styleName); + openCloseButton.setStylePrimaryName(styleName + "-button"); + } + + } + /** * Escalator used internally by grid to render the rows */ @@ -2793,6 +2883,8 @@ public boolean isScheduled() { private final Footer footer = GWT.create(Footer.class); + private final Sidebar sidebar = GWT.create(Sidebar.class); + /** * List of columns in the grid. Order defines the visible order. */ @@ -3385,7 +3477,7 @@ public void render(RendererCellReference cell, Object data) { private boolean hidden = false; - private boolean hideable = false; + private boolean hidable = false; private String headerCaption = ""; @@ -3699,13 +3791,13 @@ public boolean isHidden() { * programmatically using {@link #setHidden(boolean)}. * * @since - * @param hideable + * @param hidable * true if the user can hide this column, * false if not */ - public void setHideable(boolean hideable) { - this.hideable = hideable; - // TODO update whether sidebar/popup can be opened + public void setHidable(boolean hidable) { + this.hidable = hidable; + grid.updateSideBarVisibility(); } /** @@ -3719,8 +3811,8 @@ public void setHideable(boolean hideable) { * @return true if the user can hide the column, * false if not */ - public boolean isHideable() { - return hideable; + public boolean isHidable() { + return hidable; } @Override @@ -4444,6 +4536,7 @@ public void setStylePrimaryName(String style) { super.setStylePrimaryName(style); escalator.setStylePrimaryName(style); editor.setStylePrimaryName(style); + sidebar.setStylePrimaryName(style + "-sidebar"); String rowStyle = getStylePrimaryName() + "-row"; rowHasDataStyleName = rowStyle + "-has-data"; @@ -6945,4 +7038,52 @@ public void resetSizesFromDom() { public void recalculateColumnWidths() { autoColumnWidthsRecalculator.schedule(); } + + /** + * Setter for displaying the grid's {@link Sidebar}. The sidebar is visible + * automatically when there are {@link Column#setHidable(boolean) hidable + * columns}. + *

+ * Setting the sidebar visible doens't open it - it only shows the button + * for opening it. For opening and closing the sidebar use + * {@link Sidebar#open()} and {@link Sidebar#close()}. + * + * @since + * @param visible + * true for showing the sidebar, false + * for removing it + */ + public void setSidebarVisible(boolean visible) { + if ((sidebar.getParent() != null) != visible) { + if (visible) { + getElement().appendChild(sidebar.getElement()); + setParent(sidebar, this); + } else { + sidebar.getElement().removeFromParent(); + sidebar.removeFromParent(); + } + } + } + + /** + * Returns the sidebar for this grid. + * + * @since + * @return + */ + public Sidebar getSidebar() { + return sidebar; + } + + private void updateSideBarVisibility() { + boolean visible = false; + for (Column c : getColumns()) { + if (c.isHidable()) { + visible = true; + break; + } + } + setSidebarVisible(visible); + } + } diff --git a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java index 6d38c25fb61..ba4468da2c0 100644 --- a/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java +++ b/uitest/src/com/vaadin/tests/components/grid/basicfeatures/GridColumnHidingTest.java @@ -16,7 +16,12 @@ package com.vaadin.tests.components.grid.basicfeatures; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; import org.junit.Before; import org.junit.Test; @@ -127,6 +132,85 @@ public void testColumnHiding_onVisibilityChange_triggersClientSideEvent() { assertEquals(false, hidden); } + @Test + public void testColumnHidability_onTriggerColumnHidability_showsSidebarButton() { + WebElement sidebar = getSidebar(); + assertNull(sidebar); + + toggleHidableColumn(0); + + sidebar = getSidebar(); + assertNotNull(sidebar); + } + + @Test + public void testColumnHidability_triggeringColumnHidabilityWithSeveralColumns_showsAndHidesSiderbarButton() { + verifySidebarNotVisible(); + + toggleHidableColumn(3); + toggleHidableColumn(4); + + verifySidebarVisible(); + + toggleHidableColumn(3); + + verifySidebarVisible(); + + toggleHidableColumn(4); + + verifySidebarNotVisible(); + } + + @Test + public void testColumnHidability_clickingSidebarButton_opensClosesSidebar() { + toggleHidableColumn(0); + verifySidebarClosed(); + + getSidebarOpenButton().click(); + + verifySidebarOpened(); + + getSidebarOpenButton().click(); + + verifySidebarClosed(); + } + + private void verifySidebarOpened() { + WebElement sidebar = getSidebar(); + assertTrue(sidebar.getAttribute("class").contains("opened")); + } + + private void verifySidebarClosed() { + WebElement sidebar = getSidebar(); + assertFalse(sidebar.getAttribute("class").contains("opened")); + } + + private void verifySidebarNotVisible() { + WebElement sidebar = getSidebar(); + assertNull(sidebar); + } + + private void verifySidebarVisible() { + WebElement sidebar = getSidebar(); + assertNotNull(sidebar); + } + + private WebElement getSidebar() { + List elements = findElements(By.className("v-grid-sidebar")); + return elements.isEmpty() ? null : elements.get(0); + } + + private WebElement getSidebarOpenButton() { + List elements = findElements(By + .className("v-grid-sidebar-button")); + return elements.isEmpty() ? null : elements.get(0); + } + + private void toggleHidableColumn(int columnIndex) { + selectMenuPath("Component", "Columns", "Column " + columnIndex, + "Hidable"); + } + private void toggleHideColumn(int columnIndex) { selectMenuPath("Component", "Columns", "Column " + columnIndex, "Hidden"); 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 9131a2bdbe1..1db3eebea67 100644 --- a/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java +++ b/uitest/src/com/vaadin/tests/widgetset/client/grid/GridBasicClientFeaturesWidget.java @@ -782,7 +782,12 @@ public void execute() { column.setHidden(!column.isHidden()); } }, "Component", "Columns", "Column " + i); - + addMenuCommand("Hidable", new ScheduledCommand() { + @Override + public void execute() { + column.setHidable(!column.isHidable()); + } + }, "Component", "Columns", "Column " + i); addMenuCommand("auto", new ScheduledCommand() { @Override public void execute() {