Skip to content

Commit

Permalink
Grid's columns hidable with toggles in the sidebar (#17023)
Browse files Browse the repository at this point in the history
There is know issue with hidden columns and reordering columns.

Change-Id: If308c84aed5dd23c2c00cb38ed6bba41c6f1a28e
  • Loading branch information
pleku authored and Henrik Paul committed Mar 18, 2015
1 parent 93e879a commit 4e26f15
Show file tree
Hide file tree
Showing 4 changed files with 504 additions and 75 deletions.
233 changes: 190 additions & 43 deletions client/src/com/vaadin/client/widgets/Grid.java
Expand Up @@ -66,6 +66,7 @@
import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant; import com.google.gwt.user.client.ui.HasHorizontalAlignment.HorizontalAlignmentConstant;
import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.ResizeComposite; import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.ToggleButton;
import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo; import com.vaadin.client.BrowserInfo;
Expand Down Expand Up @@ -2791,6 +2792,11 @@ public boolean isScheduled() {
/** /**
* Sidebar displaying toggles for hidable columns and additional custom * Sidebar displaying toggles for hidable columns and additional custom
* widgets. * widgets.
* <p>
* The button for opening the sidebar is automatically visible inside the
* grid, if it contains any column hiding options or custom widgets. The
* column hiding toggles and custom widgets become visible once the sidebar
* has been opened.
* *
* @since * @since
*/ */
Expand All @@ -2808,13 +2814,23 @@ public void onClick(ClickEvent event) {
} }
}; };


/**
* Contains all the widgets which should be shown once the sidebar is
* opened
*/
private final List<Widget> widgets = new ArrayList<Widget>();

private final VerticalPanel rootContainer; private final VerticalPanel rootContainer;


private final VButton openCloseButton; private final VButton openCloseButton;


private final Grid<?> grid;

private boolean open; private boolean open;


public Sidebar() { public Sidebar(Grid<?> grid) {
this.grid = grid;

rootContainer = new VerticalPanel(); rootContainer = new VerticalPanel();
initWidget(rootContainer); initWidget(rootContainer);


Expand All @@ -2838,6 +2854,9 @@ public void open() {
if (!open) { if (!open) {
addStyleName("opened"); addStyleName("opened");
open = true; open = true;
for (Widget w : widgets) {
rootContainer.add(w);
}
} }
} }


Expand All @@ -2850,6 +2869,8 @@ public void close() {
if (open) { if (open) {
removeStyleName("opened"); removeStyleName("opened");
open = false; open = false;
rootContainer.clear();
rootContainer.add(openCloseButton);
} }
} }


Expand All @@ -2866,12 +2887,158 @@ public boolean isOpen() {
return open; return open;
} }


/**
* Adds or moves the given widget to the end of the sidebar.
*
* @param widget
* the widget to add or move
*/
public void add(Widget widget) {
widgets.remove(widget);
widgets.add(widget);
if (open) {
rootContainer.add(widget);
}
updateVisibility();
}

/**
* Removes the given widget from the sidebar.
*
* @param widget
* the widget to remove
*/
public void remove(Widget widget) {
widgets.remove(widget);
if (open) {
rootContainer.remove(widget);
}
updateVisibility();
}

/**
* Inserts given widget to the given index inside the sidebar. If the
* 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)}
* for further details.
*
* @param widget
* the widget to insert
* @param beforeIndex
* 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);
}
updateVisibility();
}

@Override @Override
public void setStylePrimaryName(String styleName) { public void setStylePrimaryName(String styleName) {
super.setStylePrimaryName(styleName); super.setStylePrimaryName(styleName);
openCloseButton.setStylePrimaryName(styleName + "-button"); openCloseButton.setStylePrimaryName(styleName + "-button");
} }


private void updateVisibility() {
final boolean hasWidgets = widgets.size() > 0;
final boolean isVisible = getParent() != null;
if (isVisible && !hasWidgets) {
getElement().removeFromParent();
removeFromParent();
} else if (!isVisible && hasWidgets) {
grid.getElement().appendChild(getElement());
Grid.setParent(this, grid);
}
}

}

/**
* UI and functionality related to hiding columns with toggles in the
* sidebar.
*/
private final class ColumnHider extends VerticalPanel {

ColumnHider() {
setStyleName("column-hiding-panel");
}

/** Map from columns to their hiding toggles, component might change */
private HashMap<Column<?, T>, ToggleButton> columnToHidingToggleMap = new HashMap<Grid.Column<?, T>, ToggleButton>();

private void updateColumnHidable(final Column<?, T> column) {
if (column.isHidable()) {
ToggleButton cb = columnToHidingToggleMap.get(column);
if (cb == null) {
cb = createToggle(column);
}
updateToggleValue(cb, column.isHidden());
} else if (columnToHidingToggleMap.containsValue(column)) {
((Widget) columnToHidingToggleMap.remove(column))
.removeFromParent();
}
updateTogglesOrder();
updatePanelVisibility();
}

private ToggleButton createToggle(final Column<?, T> column) {
ToggleButton toggle = new ToggleButton(column.headerCaption);
toggle.addStyleName("column-hiding-toggle");
toggle.addValueChangeHandler(new ValueChangeHandler<Boolean>() {

@Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
column.setHidden(!event.getValue(), true);
}
});
columnToHidingToggleMap.put(column, toggle);
return toggle;
}

private void updateTogglesOrder() {
clear();
for (Column<?, T> c : getColumns()) {
if (c.isHidable()) {
add(columnToHidingToggleMap.get(c));
}
}
}

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);

if (columnHidable && !columnTogglesPanelIsVisible) {
sidebar.insert(this, 0);
} else if (!columnHidable && columnTogglesPanelIsVisible) {
sidebar.remove(this);
}
}

private void updateToggleValue(Column<?, T> column) {
if (column.isHidable()) {
updateToggleValue(columnToHidingToggleMap.get(column),
column.isHidden());
} // else we can just ignore
}

private void updateToggleValue(ToggleButton hasValue, boolean hidden) {
hasValue.setValue(!hidden, false);
hasValue.setStyleName("hidden", hidden);
}

private void updateColumnHidingToggleCaption(Column<?, T> column) {
columnToHidingToggleMap.get(column).setText(column.headerCaption);
}

} }


/** /**
Expand All @@ -2883,7 +3050,7 @@ public void setStylePrimaryName(String styleName) {


private final Footer footer = GWT.create(Footer.class); private final Footer footer = GWT.create(Footer.class);


private final Sidebar sidebar = GWT.create(Sidebar.class); private final Sidebar sidebar = new Sidebar(this);


/** /**
* List of columns in the grid. Order defines the visible order. * List of columns in the grid. Order defines the visible order.
Expand Down Expand Up @@ -2963,6 +3130,8 @@ public void setStylePrimaryName(String styleName) {


private boolean columnReorderingAllowed; private boolean columnReorderingAllowed;


private ColumnHider columnHider = new ColumnHider();

private DragAndDropHandler dndHandler = new DragAndDropHandler(); private DragAndDropHandler dndHandler = new DragAndDropHandler();


private AutoScroller autoScroller = new AutoScroller(this); private AutoScroller autoScroller = new AutoScroller(this);
Expand Down Expand Up @@ -3589,6 +3758,9 @@ private void updateHeader() {
HeaderRow row = grid.getHeader().getDefaultRow(); HeaderRow row = grid.getHeader().getDefaultRow();
if (row != null) { if (row != null) {
row.getCell(this).setText(headerCaption); row.getCell(this).setText(headerCaption);
if (isHidable()) {
grid.columnHider.updateColumnHidingToggleCaption(this);
}
} }
} }


Expand Down Expand Up @@ -3756,6 +3928,10 @@ public boolean isSortable() {
* to show * to show
*/ */
public void setHidden(boolean hidden) { public void setHidden(boolean hidden) {
setHidden(hidden, false);
}

private void setHidden(boolean hidden, boolean userOriginated) {
if (this.hidden != hidden) { if (this.hidden != hidden) {
if (hidden) { if (hidden) {
grid.escalator.getColumnConfiguration().removeColumns( grid.escalator.getColumnConfiguration().removeColumns(
Expand All @@ -3766,9 +3942,10 @@ public void setHidden(boolean hidden) {
grid.escalator.getColumnConfiguration().insertColumns( grid.escalator.getColumnConfiguration().insertColumns(
grid.getVisibleColumns().indexOf(this), 1); grid.getVisibleColumns().indexOf(this), 1);
} }
grid.columnHider.updateToggleValue(this);
scheduleColumnWidthRecalculator(); scheduleColumnWidthRecalculator();
this.grid.fireEvent(new ColumnVisibilityChangeEvent<T>(this, this.grid.fireEvent(new ColumnVisibilityChangeEvent<T>(this,
hidden, false)); hidden, userOriginated));
} }
} }


Expand Down Expand Up @@ -3796,8 +3973,10 @@ public boolean isHidden() {
* <code>false</code> if not * <code>false</code> if not
*/ */
public void setHidable(boolean hidable) { public void setHidable(boolean hidable) {
this.hidable = hidable; if (this.hidable != hidable) {
grid.updateSideBarVisibility(); this.hidable = hidable;
grid.columnHider.updateColumnHidable(this);
}
} }


/** /**
Expand Down Expand Up @@ -6686,6 +6865,8 @@ public void setColumnOrder(Column<?, T>... orderedColumns) {
row.calculateColspans(); row.calculateColspans();
} }


columnHider.updateTogglesOrder();

fireEvent(new ColumnReorderEvent<T>()); fireEvent(new ColumnReorderEvent<T>());
} }


Expand Down Expand Up @@ -7039,51 +7220,17 @@ public void recalculateColumnWidths() {
autoColumnWidthsRecalculator.schedule(); autoColumnWidthsRecalculator.schedule();
} }


/**
* Setter for displaying the grid's {@link Sidebar}. The sidebar is visible
* automatically when there are {@link Column#setHidable(boolean) hidable
* columns}.
* <p>
* 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
* <code>true</code> for showing the sidebar, <code>false</code>
* 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. * Returns the sidebar for this grid.
* <p>
* The grid's sidebar shows the column hiding options for those columns that
* have been set as {@link Column#setHidable(boolean) hidable}.
* *
* @since * @since
* @return * @return the sidebar widget for this grid
*/ */
public Sidebar getSidebar() { public Sidebar getSidebar() {
return sidebar; return sidebar;
} }


private void updateSideBarVisibility() {
boolean visible = false;
for (Column<?, T> c : getColumns()) {
if (c.isHidable()) {
visible = true;
break;
}
}
setSidebarVisible(visible);
}

} }
Expand Up @@ -98,4 +98,9 @@ protected void assertColumnHeaderOrder(int... indices) {
assertColumnHeader("HEADER (0," + indices[i] + ")", headers.get(i)); assertColumnHeader("HEADER (0," + indices[i] + ")", headers.get(i));
} }
} }

protected void toggleColumnReorder() {
selectMenuPath("Component", "State", "Column Reordering");
}

} }

0 comments on commit 4e26f15

Please sign in to comment.