}
}
+ // Column resize mode
+ if (stateChangeEvent.hasPropertyChanged("columnResizeMode")) {
+ getWidget().setColumnResizeMode(getState().columnResizeMode);
+ }
+
// Header and footer
if (stateChangeEvent.hasPropertyChanged("header")) {
updateHeaderFromState(getState().header);
/**
* Called when dragging starts
*/
- public void onStart();
+ void onStart();
/**
* Called when the drag handle has moved.
* @param deltaY
* change in Y direction since start
*/
- public void onUpdate(double deltaX, double deltaY);
+ void onUpdate(double deltaX, double deltaY);
/**
* Called when the drag operation has been cancelled (usually by
* pressing ESC)
*/
- public void onCancel();
+ void onCancel();
/**
* Called when the drag operation completes successfully
*/
- public void onComplete();
+ void onComplete();
}
private DragHandleCallback userCallback;
+ /**
+ * Creates a new DragHandle.
+ *
+ * @param baseName
+ * CSS style name to use for this DragHandle element. This
+ * parameter is supplied to the constructor (rather than added
+ * later) both to provide the "-dragged" style and to make sure
+ * that the drag handle can be properly styled (it's otherwise
+ * invisible)
+ */
+ public DragHandle(String baseName) {
+ this(baseName,null);
+ }
+
/**
* Creates a new DragHandle.
*
@Override
public void onDrop() {
removeDraggingStyle();
- userCallback.onComplete();
+ if(userCallback != null) {
+ userCallback.onComplete();
+ }
}
@Override
public void onDragUpdate(Event e) {
- double dx = WidgetUtil.getTouchOrMouseClientX(e) - startX;
- double dy = WidgetUtil.getTouchOrMouseClientY(e) - startY;
- userCallback.onUpdate(dx, dy);
+ if(userCallback != null) {
+ double dx = WidgetUtil.getTouchOrMouseClientX(e) - startX;
+ double dy = WidgetUtil.getTouchOrMouseClientY(e) - startY;
+ userCallback.onUpdate(dx, dy);
+ }
}
@Override
public boolean onDragStart(Event e) {
addDraggingStyle();
- startX = WidgetUtil.getTouchOrMouseClientX(e);
- startY = WidgetUtil.getTouchOrMouseClientY(e);
- userCallback.onStart();
+ if(userCallback != null) {
+ startX = WidgetUtil.getTouchOrMouseClientX(e);
+ startY = WidgetUtil.getTouchOrMouseClientY(e);
+ userCallback.onStart();
+ }
return true;
}
@Override
public void onDragCancel() {
removeDraggingStyle();
- userCallback.onCancel();
+ if(userCallback != null) {
+ userCallback.onCancel();
+ }
}
private void addDraggingStyle() {
});
}
+ /**
+ * Sets the user-facing drag handle callback method. This allows
+ * code using the DragHandle to react to the situations where a
+ * drag handle first touched, when it's moved and when it's released.
+ *
+ * @param dragHandleCallback the callback object to use (can be null)
+ */
+ public void setCallback(DragHandleCallback dragHandleCallback) {
+ userCallback = dragHandleCallback;
+ }
+
/**
* Returns the current parent element for this drag handle. May be null.
*
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ResizeComposite;
import com.google.gwt.user.client.ui.Widget;
+
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.DeferredWorker;
import com.vaadin.client.Focusable;
import com.vaadin.client.widgets.Grid.StaticSection.StaticCell;
import com.vaadin.client.widgets.Grid.StaticSection.StaticRow;
import com.vaadin.shared.data.sort.SortDirection;
+import com.vaadin.shared.ui.grid.ColumnResizeMode;
import com.vaadin.shared.ui.grid.GridConstants;
import com.vaadin.shared.ui.grid.GridConstants.Section;
import com.vaadin.shared.ui.grid.GridStaticCellType;
&& staticRow instanceof HeaderRow
&& ((HeaderRow) staticRow).isDefault()) {
+ final DivElement resizeElement = Document.get().createDivElement();
+ resizeElement.addClassName(getStylePrimaryName() + "-column-resize-simple-indicator");
+
final int column = cell.getColumn();
- DragHandle dragger = new DragHandle(
- getStylePrimaryName() + "-column-resize-handle",
- new DragHandleCallback() {
-
- private Column<?, T> col = getVisibleColumn(
- column);
- private double initialWidth = 0;
- private double minCellWidth;
-
- @Override
- public void onUpdate(double deltaX,
- double deltaY) {
- col.setWidth(Math.max(minCellWidth,
- initialWidth + deltaX));
- }
+ final DragHandle dragger = new DragHandle(getStylePrimaryName() + "-column-resize-handle");
+ dragger.addTo(td);
- @Override
- public void onStart() {
- initialWidth = col.getWidthActual();
-
- minCellWidth = escalator.getMinCellWidth(
- getVisibleColumns().indexOf(col));
- for (Column<?, T> c : getVisibleColumns()) {
- if (selectionColumn == c) {
- // Don't modify selection column.
- continue;
- }
-
- if (c.getWidth() < 0) {
- c.setWidth(c.getWidthActual());
- fireEvent(new ColumnResizeEvent<T>(
- c));
- }
- }
+ // Common functionality for drag handle callback implementations
+ abstract class AbstractDHCallback implements DragHandleCallback {
+ protected Column<?, T> col = getVisibleColumn(column);
+ protected double initialWidth = 0;
+ protected double minCellWidth;
+ protected double width;
+
+ protected void dragStarted() {
+ initialWidth = col.getWidthActual();
+ width = initialWidth;
+
+ minCellWidth = escalator.getMinCellWidth(getVisibleColumns().indexOf(col));
+ for (Column<?, T> c : getVisibleColumns()) {
+ if (selectionColumn == c) {
+ // Don't modify selection column.
+ continue;
+ }
- WidgetUtil.setTextSelectionEnabled(
- getElement(), false);
+ if (c.getWidth() < 0) {
+ c.setWidth(c.getWidthActual());
+ fireEvent(new ColumnResizeEvent<T>(c));
}
+ }
- @Override
- public void onComplete() {
- fireEvent(new ColumnResizeEvent<T>(col));
+ WidgetUtil.setTextSelectionEnabled(getElement(), false);
+ }
- WidgetUtil.setTextSelectionEnabled(
- getElement(), true);
- }
+ protected void dragEnded() {
+ WidgetUtil.setTextSelectionEnabled(getElement(), true);
+ }
+ }
- @Override
- public void onCancel() {
- col.setWidth(initialWidth);
+ final DragHandleCallback simpleResizeMode = new AbstractDHCallback() {
+ protected void dragEnded() {
+ super.dragEnded();
+ dragger.getElement().removeChild(resizeElement);
+ }
- WidgetUtil.setTextSelectionEnabled(
- getElement(), true);
- }
- });
- dragger.addTo(td);
+ @Override
+ public void onStart() {
+ dragStarted();
+ dragger.getElement().appendChild(resizeElement);
+ resizeElement.getStyle().setLeft((dragger.getElement().getOffsetWidth() - resizeElement.getOffsetWidth()) * .5, Unit.PX);
+ resizeElement.getStyle().setHeight(col.grid.getOffsetHeight(), Unit.PX);
+ }
+
+ @Override
+ public void onUpdate(double deltaX, double deltaY) {
+ width = Math.max(minCellWidth, initialWidth + deltaX);
+ resizeElement.getStyle().setLeft((dragger.getElement().getOffsetWidth() - resizeElement.getOffsetWidth()) * .5 + (width - initialWidth), Unit.PX);
+ }
+
+ @Override
+ public void onCancel() {
+ dragEnded();
+ }
+
+ @Override
+ public void onComplete() {
+ dragEnded();
+
+ col.setWidth(width);
+ fireEvent(new ColumnResizeEvent<T>(col));
+ }
+ };
+
+ final DragHandleCallback animatedResizeMode = new AbstractDHCallback() {
+ @Override
+ public void onStart() {
+ dragStarted();
+ }
+
+ @Override
+ public void onUpdate(double deltaX, double deltaY) {
+ width = Math.max(minCellWidth, initialWidth + deltaX);
+ col.setWidth(width);
+ }
+
+ @Override
+ public void onCancel() {
+ dragEnded();
+ col.setWidth(initialWidth);
+ }
+
+ @Override
+ public void onComplete() {
+ dragEnded();
+ col.setWidth(width);
+ fireEvent(new ColumnResizeEvent<T>(col));
+ }
+ };
+
+ // DragHandle gets assigned a 'master callback' that delegates
+ // functionality to the correct case-specific implementation
+ dragger.setCallback(new DragHandleCallback() {
+
+ private DragHandleCallback currentCallback;
+
+ @Override
+ public void onStart() {
+ switch(getColumnResizeMode()) {
+ case SIMPLE:
+ currentCallback = simpleResizeMode;
+ break;
+ case ANIMATED:
+ currentCallback = animatedResizeMode;
+ break;
+ default:
+ throw new UnsupportedOperationException("Support for current column resize mode is not yet implemented");
+ }
+
+ currentCallback.onStart();
+ }
+
+ @Override
+ public void onUpdate(double deltaX, double deltaY) {
+ currentCallback.onUpdate(deltaX,deltaY);
+ }
+
+ @Override
+ public void onCancel() {
+ currentCallback.onCancel();
+ }
+
+ @Override
+ public void onComplete() {
+ currentCallback.onComplete();
+ }
+ });
}
cellFocusHandler.updateFocusedCellStyle(cell, container);
fireEvent(new GridEnabledEvent(enabled));
}
+ private ColumnResizeMode columnResizeMode = ColumnResizeMode.ANIMATED;
+
+ /**
+ * Sets the column resize mode to use. The default mode is {@link ColumnResizeMode.ANIMATED}.
+ *
+ * @param mode a ColumnResizeMode value
+ */
+ public void setColumnResizeMode(ColumnResizeMode mode) {
+ columnResizeMode = mode;
+ }
+
+ /**
+ * Returns the current column resize mode. The default mode is {@link ColumnResizeMode.ANIMATED}.
+ *
+ * @return a ColumnResizeMode value
+ */
+ public ColumnResizeMode getColumnResizeMode() {
+ return columnResizeMode;
+ }
+
@Override
public void setStylePrimaryName(String style) {
super.setStylePrimaryName(style);
import com.vaadin.server.communication.data.RpcDataProviderExtension;
import com.vaadin.shared.MouseEventDetails;
import com.vaadin.shared.data.sort.SortDirection;
+import com.vaadin.shared.ui.grid.ColumnResizeMode;
import com.vaadin.shared.ui.grid.EditorClientRpc;
import com.vaadin.shared.ui.grid.EditorServerRpc;
import com.vaadin.shared.ui.grid.GridClientRpc;
private Object editedItemId = null;
private boolean editorActive = false;
+
/**
* True while the editor is storing the field values, i.e. commiting the
* field group.
if (column != null && column.isResizable()) {
column.getState().width = pixels;
fireColumnResizeEvent(column, true);
- markAsDirty();
}
}
});
return (GridState) super.getState(markAsDirty);
}
+ /**
+ * Sets the column resize mode to use. The default mode is {@link ColumnResizeMode#ANIMATED}.
+ *
+ * @param mode a ColumnResizeMode value
+ */
+ public void setColumnResizeMode(ColumnResizeMode mode) {
+ getState().columnResizeMode = mode;
+ }
+
+ /**
+ * Returns the current column resize mode. The default mode is {@link ColumnResizeMode#ANIMATED}.
+ *
+ * @return a ColumnResizeMode value
+ */
+ public ColumnResizeMode getColumnResizeMode() {
+ return getState(false).columnResizeMode;
+ }
+
/**
* Creates a new column based on a property id and appends it as the last
* column.
--- /dev/null
+/*
+ * Copyright 2000-2016 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.shared.ui.grid;
+
+/**
+ * Collection of modes used for resizing columns in the Grid.
+ */
+public enum ColumnResizeMode {
+
+ /**
+ * When column resize mode is set to Animated, columns
+ * are resized as they are dragged.
+ */
+ ANIMATED,
+
+ /**
+ * When column resize mode is set to Simple, dragging to resize
+ * a column will show a marker, and the column will resize only
+ * after the mouse button or touch is released.
+ */
+ SIMPLE
+
+}
primaryStyleName = "v-grid";
}
+ /**
+ * Column resize mode in grid.
+ */
+ public ColumnResizeMode columnResizeMode = ColumnResizeMode.ANIMATED;
+
/**
* Columns in grid.
*/
user-select: none;
}
+ .#{$primaryStyleName}-column-resize-simple-indicator {
+ position: absolute;
+ width: 3px;
+ top: 0px;
+ left: $v-grid-cell-padding-horizontal;
+ z-index: 9001;
+ background: #fff;
+ box-shadow: 0px 0px 5px #000;
+
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ }
+
// Footer
.#{$primaryStyleName}-footer {
import com.vaadin.event.SortEvent;
import com.vaadin.event.SortEvent.SortListener;
import com.vaadin.shared.data.sort.SortDirection;
+import com.vaadin.shared.ui.grid.ColumnResizeMode;
import com.vaadin.shared.ui.grid.GridStaticCellType;
import com.vaadin.shared.ui.grid.HeightMode;
import com.vaadin.tests.components.AbstractComponentTest;
grid.getColumns().get(0).setMaximumWidth(30);
}
}, null);
+
+ createBooleanAction("Simple resize mode", "Columns", false, new Command<Grid, Boolean>() {
+ @Override
+ public void execute(Grid g, Boolean value, Object data) {
+ g.setColumnResizeMode(value ? ColumnResizeMode.SIMPLE : ColumnResizeMode.ANIMATED);
+ }
+ });
}
private static String getColumnProperty(int c) {
--- /dev/null
+package com.vaadin.tests.components.grid.basicfeatures;/*
+ * Copyright 2000-2016 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.
+ */
+
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.openqa.selenium.WebElement;
+import org.openqa.selenium.interactions.Actions;
+
+import com.vaadin.testbench.By;
+import com.vaadin.testbench.parallel.TestCategory;
+import com.vaadin.tests.components.grid.basicfeatures.element.CustomGridElement;
+
+@TestCategory("grid")
+public class GridColumnResizeModeTest extends GridBasicFeaturesTest {
+
+ @Before
+ public void before() {
+ openTestURL();
+ }
+
+ @Test
+ public void testSimpleResizeModeToggle() throws Exception {
+
+ CustomGridElement grid = getGridElement();
+
+ List<WebElement> handles = grid.findElements(By.className("v-grid-column-resize-handle"));
+ WebElement handle = handles.get(1);
+
+ Actions drag1 = new Actions(getDriver()).moveToElement(handle).clickAndHold();
+ Actions drag2 = new Actions(getDriver()).moveByOffset(-50, 0);
+ Actions drag3 = new Actions(getDriver()).moveByOffset(100, 0);
+ Actions dragEndAction = new Actions(getDriver()).release().moveToElement(grid);
+
+ selectMenuPath("Component", "Columns", "Simple resize mode");
+ sleep(250);
+
+ drag1.perform();
+ sleep(500);
+ drag2.perform();
+ sleep(500);
+ drag3.perform();
+ sleep(500);
+
+ // Make sure we find at least one simple resize mode splitter
+ assertElementPresent(By.className("v-grid-column-resize-simple-indicator"));
+
+ dragEndAction.perform();
+
+ // Make sure it went away
+ assertElementNotPresent(By.className("v-grid-column-resize-simple-indicator"));
+
+ // See that we got a resize event
+ sleep(500);
+ Assert.assertEquals("Log shows resize event", getLogRow(0), "3. ColumnResizeEvent: isUserOriginated? true");
+
+ }
+
+}