aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPekka Hyvönen <pekka@vaadin.com>2017-05-23 16:51:54 +0300
committerGitHub <noreply@github.com>2017-05-23 16:51:54 +0300
commitc7128c4c3e597724ff0ecf736b00877ea02de202 (patch)
tree11d1d1967ddc387e33385e92f8950f531efdcfcc
parent19a7e696fdca4d1d23624b1a39e6a5f34e982887 (diff)
downloadvaadin-framework-c7128c4c3e597724ff0ecf736b00877ea02de202.tar.gz
vaadin-framework-c7128c4c3e597724ff0ecf736b00877ea02de202.zip
Fix missing drag image on FF, Safari (#9409)
When CSS transform has been applied, the drag image is missing (safari), or gets offset (FF). Fixed by using custom drag image without transform, and checking for transforms on parent DOM tree. Does NOT fix #9408 When there are frozen columns used, the image needs should not look weird because of the frozen column transitions. The multiselection column is now not shown it is frozen. Fixes #9261
-rw-r--r--client/src/main/java/com/vaadin/client/WidgetUtil.java28
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java112
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java181
-rw-r--r--uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java24
-rw-r--r--uitest/src/main/java/com/vaadin/tests/dnd/DragImage.java18
5 files changed, 284 insertions, 79 deletions
diff --git a/client/src/main/java/com/vaadin/client/WidgetUtil.java b/client/src/main/java/com/vaadin/client/WidgetUtil.java
index 176f123d18..59fc922d82 100644
--- a/client/src/main/java/com/vaadin/client/WidgetUtil.java
+++ b/client/src/main/java/com/vaadin/client/WidgetUtil.java
@@ -794,7 +794,7 @@ public class WidgetUtil {
com.google.gwt.dom.client.Element el, String p)
/*-{
try {
-
+
if (el.currentStyle) {
// IE
return el.currentStyle[p];
@@ -809,7 +809,7 @@ public class WidgetUtil {
} catch (e) {
return "";
}
-
+
}-*/;
/**
@@ -823,7 +823,7 @@ public class WidgetUtil {
try {
el.focus();
} catch (e) {
-
+
}
}-*/;
@@ -1176,7 +1176,7 @@ public class WidgetUtil {
if ($wnd.document.activeElement) {
return $wnd.document.activeElement;
}
-
+
return null;
}-*/;
@@ -1247,11 +1247,11 @@ public class WidgetUtil {
/*-{
var top = elem.offsetTop;
var height = elem.offsetHeight;
-
+
if (elem.parentNode != elem.offsetParent) {
top -= elem.parentNode.offsetTop;
}
-
+
var cur = elem.parentNode;
while (cur && (cur.nodeType == 1)) {
if (top < cur.scrollTop) {
@@ -1260,12 +1260,12 @@ public class WidgetUtil {
if (top + height > cur.scrollTop + cur.clientHeight) {
cur.scrollTop = (top + height) - cur.clientHeight;
}
-
+
var offsetTop = cur.offsetTop;
if (cur.parentNode != cur.offsetParent) {
offsetTop -= cur.parentNode.offsetTop;
}
-
+
top += offsetTop - cur.scrollTop;
cur = cur.parentNode;
}
@@ -1705,7 +1705,7 @@ public class WidgetUtil {
}
var heightWithoutBorder = cloneElement.offsetHeight;
parentElement.removeChild(cloneElement);
-
+
return heightWithBorder - heightWithoutBorder;
}
}-*/;
@@ -1831,4 +1831,14 @@ public class WidgetUtil {
// 12 + int(30.6) / 60 = 12 + 30/60 = 12.5
return integerPart + ((int) nrFractions) / divisor;
}
+
+ public static int getRelativeX(Element element, NativeEvent event) {
+ int relativeLeft = element.getAbsoluteLeft() - Window.getScrollLeft();
+ return WidgetUtil.getTouchOrMouseClientX(event) - relativeLeft;
+ }
+
+ public static int getRelativeY(Element element, NativeEvent event) {
+ int relativeTop = element.getAbsoluteTop() - Window.getScrollTop();
+ return WidgetUtil.getTouchOrMouseClientY(event) - relativeTop;
+ }
}
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
index 6fe4fd03db..bc94293e78 100644
--- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
@@ -27,11 +27,11 @@ import java.util.stream.Stream;
import com.google.gwt.animation.client.AnimationScheduler;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
+import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Float;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Image;
import com.vaadin.client.BrowserInfo;
import com.vaadin.client.ServerConnector;
@@ -146,9 +146,8 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
}
// Construct style name to be added to dragged rows
- draggedStyleName =
- gridConnector.getWidget().getStylePrimaryName() + "-row"
- + STYLE_SUFFIX_DRAGGED;
+ draggedStyleName = gridConnector.getWidget().getStylePrimaryName()
+ + "-row" + STYLE_SUFFIX_DRAGGED;
super.onDragStart(event);
}
@@ -170,43 +169,99 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
} else {
Element draggedRowElement = (Element) dragStartEvent
.getEventTarget().cast();
+ Element badge;
if (draggedItems.size() > 1) {
-
- Element badge = DOM.createSpan();
+ badge = DOM.createSpan();
badge.setClassName(
gridConnector.getWidget().getStylePrimaryName() + "-row"
+ STYLE_SUFFIX_DRAG_BADGE);
badge.setInnerHTML(draggedItems.size() + "");
- if (BrowserInfo.get().isTouchDevice()) {
+ BrowserInfo browserInfo = BrowserInfo.get();
+ if (browserInfo.isTouchDevice()) {
// the drag image is centered on the touch coordinates
// -> show the badge on the right edge of the row
badge.getStyle().setFloat(Float.RIGHT);
badge.getStyle().setMarginRight(20, Unit.PX);
+ badge.getStyle().setMarginTop(-20, Unit.PX);
+ } else if (browserInfo.isSafari()) {
+ // On Safari, only the part of the row visible inside grid
+ // is shown, and also the badge needs to be totally on top
+ // of the row.
+ Element tableWrapperDiv = getGridBody().getElement()
+ .getParentElement().getParentElement();
+ int mouseXRelativeToGrid = WidgetUtil
+ .getRelativeX(tableWrapperDiv, dragStartEvent);
+ if (mouseXRelativeToGrid < (tableWrapperDiv.getClientWidth()
+ - 60)) {
+ badge.getStyle().setMarginLeft(
+ mouseXRelativeToGrid + 10, Unit.PX);
+ } else {
+ badge.getStyle().setMarginLeft(
+ mouseXRelativeToGrid - 60, Unit.PX);
+ }
+ badge.getStyle().setMarginTop(-32, Unit.PX);
} else {
- badge.getStyle().setMarginLeft(
- getRelativeX(draggedRowElement, dragStartEvent)
- + 10,
- Unit.PX);
+ badge.getStyle().setMarginLeft(WidgetUtil.getRelativeX(
+ draggedRowElement, dragStartEvent) + 10, Unit.PX);
+ badge.getStyle().setMarginTop(-20, Unit.PX);
}
- badge.getStyle().setMarginTop(-20, Unit.PX);
+ } else {
+ badge = null;
+ }
+
+ final int frozenColumnCount = getGrid().getFrozenColumnCount();
+ final Element selectionColumnCell = getGrid().getSelectionColumn()
+ .isPresent()
+ // -1 is used when even selection column is not frozen
+ && frozenColumnCount != -1 ? draggedRowElement
+ .removeChild(draggedRowElement.getFirstChild())
+ .cast() : null;
+
+ final List<String> frozenCellsTransforms = new ArrayList<>();
+ for (int i = 0; i < getGrid().getColumnCount(); i++) {
+ if (i >= frozenColumnCount) {
+ break;
+ }
+ if (getGrid().getColumn(i).isHidden()) {
+ frozenCellsTransforms.add(null);
+ continue;
+ }
+ Style style = ((Element) draggedRowElement.getChild(i).cast())
+ .getStyle();
+ frozenCellsTransforms.add(style.getProperty("transform"));
+ style.clearProperty("transform");
+ }
+ if (badge != null) {
draggedRowElement.appendChild(badge);
+ }
- // Remove badge on the next animation frame. Drag image will
- // still contain the badge.
- AnimationScheduler.get().requestAnimationFrame(timestamp -> {
+ // The following hack is used since IE11 doesn't support custom drag
+ // image.
+ // 1. Remove multiple rows drag badge, if used
+ // 2. add selection column cell back, if was removed
+ // 3. reset frozen column transitions, if were cleared
+ AnimationScheduler.get().requestAnimationFrame(timestamp -> {
+ if (badge != null) {
badge.removeFromParent();
- }, (Element) dragStartEvent.getEventTarget().cast());
- }
- fixDragImageForDesktopSafari(draggedRowElement);
+ }
+ for (int i = 0; i < frozenCellsTransforms.size(); i++) {
+ String transform = frozenCellsTransforms.get(i);
+ if (transform != null) {
+ ((Element) draggedRowElement.getChild(i).cast())
+ .getStyle().setProperty("transform", transform);
+ }
+ }
+ if (selectionColumnCell != null) {
+ draggedRowElement.insertFirst(selectionColumnCell);
+ }
+ }, (Element) dragStartEvent.getEventTarget().cast());
+
+ fixDragImageOffsetsForDesktop(dragStartEvent, draggedRowElement);
fixDragImageTransformForMobile(draggedRowElement);
}
- }
- private int getRelativeX(Element element, NativeEvent event) {
- int relativeLeft = element.getAbsoluteLeft() - Window.getScrollLeft();
- return WidgetUtil.getTouchOrMouseClientX(event) - relativeLeft;
}
@Override
@@ -223,8 +278,8 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
if (!dataMap.containsKey(type)) {
dataMap.put(type, data);
} else {
- // Separate data with new line character when multiple rows
- // are dragged
+ // Separate data with new line character when multiple
+ // rows are dragged
dataMap.put(type, dataMap.get(type) + "\n" + data);
}
}
@@ -290,8 +345,8 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
// Send server RPC with dragged item keys
getRpcProxy(GridDragSourceRpc.class).dragEnd(dropEffect,
- draggedItems.stream().map(row -> row
- .getString(DataCommunicatorConstants.KEY))
+ draggedItems.stream().map(
+ row -> row.getString(DataCommunicatorConstants.KEY))
.collect(Collectors.toList()));
}
@@ -367,7 +422,7 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
* Add {@code v-grid-row-dragged} class name to each row being dragged.
*
* @param event
- * The dragstart event.
+ * The dragstart event.
*/
@Override
protected void addDraggedStyle(NativeEvent event) {
@@ -379,7 +434,7 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
* Remove {@code v-grid-row-dragged} class name from dragged rows.
*
* @param event
- * The dragend event.
+ * The dragend event.
*/
@Override
protected void removeDraggedStyle(NativeEvent event) {
@@ -438,4 +493,5 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
public GridDragSourceState getState() {
return (GridDragSourceState) super.getState();
}
+
}
diff --git a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
index 5159b1e656..313c990074 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
@@ -17,6 +17,7 @@ package com.vaadin.client.extensions;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.logging.Logger;
import com.google.gwt.animation.client.AnimationScheduler;
import com.google.gwt.dom.client.DataTransfer;
@@ -27,7 +28,9 @@ import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
+import com.vaadin.client.ComputedStyle;
import com.vaadin.client.ServerConnector;
+import com.vaadin.client.WidgetUtil;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.shared.ui.Connect;
@@ -58,7 +61,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
/**
* Style suffix for indicating that the element is being dragged.
*/
- protected static final String STYLE_SUFFIX_DRAGGED= "-dragged";
+ protected static final String STYLE_SUFFIX_DRAGGED = "-dragged";
private static final String STYLE_NAME_DRAGGABLE = "v-draggable";
@@ -205,9 +208,9 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
.setData(type, data));
} else {
// IE11 accepts only data with type "text"
- nativeEvent.getDataTransfer()
- .setData(DragSourceState.DATA_TYPE_TEXT,
- dataMap.get(DragSourceState.DATA_TYPE_TEXT));
+ nativeEvent.getDataTransfer().setData(
+ DragSourceState.DATA_TYPE_TEXT,
+ dataMap.get(DragSourceState.DATA_TYPE_TEXT));
}
// Set style to indicate the element being dragged
@@ -228,47 +231,143 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
}
/**
- * Fixes missing drag image for desktop Safari by making the dragged element
- * position to relative if needed. Safari won't show drag image unless the
- * dragged element position is relative or absolute / fixed, but not with
- * display block for the latter.
+ * Fixes missing or offset drag image caused by using css transform:
+ * translate (or such) by using a cloned drag image element, for which the
+ * property has been cleared.
* <p>
- * This method is a NOOP for non-safari browser, or mobile safari which is
- * using the DnD Polyfill.
+ * This bug only occurs on Desktop with Safari (gets offset and clips the
+ * element for the parts that are not inside the element start & end
+ * coordinates) and Firefox (gets offset), and calling this method is NOOP
+ * for any other browser.
* <p>
- * This fix is not needed if a custom drag image is used on Safari.
+ * This fix is not needed if custom drag image has been used.
*
+ * @param dragStartEvent
+ * the drag start event
* @param draggedElement
- * the element that forms the drag image
+ * the element being dragged
*/
- protected void fixDragImageForDesktopSafari(Element draggedElement) {
- if (!BrowserInfo.get().isSafari()
- || BrowserInfo.get().isTouchDevice()) {
+ protected void fixDragImageOffsetsForDesktop(NativeEvent dragStartEvent,
+ Element draggedElement) {
+ BrowserInfo browserInfo = BrowserInfo.get();
+ final boolean isSafari = browserInfo.isSafari();
+ if (browserInfo.isTouchDevice()
+ || !(isSafari || browserInfo.isFirefox())) {
return;
}
- final Style style = draggedElement.getStyle();
- final String position = style.getPosition();
- // relative works always
- if ("relative".equalsIgnoreCase(position)) {
- return;
+ Element clonedElement = (Element) draggedElement.cloneNode(true);
+ Style clonedStyle = clonedElement.getStyle();
+ clonedStyle.clearProperty("transform");
+ // only relative, absolute and fixed positions work for safari or no
+ // drag image is set
+ clonedStyle.setPosition(Position.RELATIVE);
+
+ int transformXOffset = 0;
+ if (isSafari) {
+ transformXOffset = fixDragImageTransformForSafari(draggedElement,
+ clonedStyle);
}
- // absolute & fixed don't work when there is offset used
- if ("absolute".equalsIgnoreCase(position)
- || "fixed".equalsIgnoreCase(position)) {
- // FIXME #9261 need to figure out how to get absolute and fixed to
- // position work when there is offset involved, like in Grid.
- // The following hack with setting position to relative did not
- // work, nor did clearing top/right/bottom/left.
- }
+ // need to use z-index -1 or otherwise the cloned node will flash
+ clonedStyle.setZIndex(-1);
+ draggedElement.getParentElement().appendChild(clonedElement);
- // for all other positions, set the position to relative and revert it
- // in an animation frame
- draggedElement.getStyle().setPosition(Position.RELATIVE);
+ dragStartEvent.getDataTransfer().setDragImage(clonedElement,
+ WidgetUtil.getRelativeX(draggedElement, dragStartEvent)
+ - transformXOffset,
+ WidgetUtil.getRelativeY(draggedElement, dragStartEvent));
AnimationScheduler.get().requestAnimationFrame(timestamp -> {
- draggedElement.getStyle().setProperty("position", position);
- }, draggedElement);
+ clonedElement.removeFromParent();
+ }, clonedElement);
+ }
+
+ /**
+ * Fixes missing drag image on Safari when there is
+ * {@code transform: translate(x,y)} CSS used on the parent DOM for the
+ * dragged element. Safari apparently doesn't take those into account, and
+ * creates the drag image of the element's location without all the
+ * transforms.
+ * <p>
+ * This is required for e.g. Grid where transforms are used to position the
+ * rows and scroll the body.
+ *
+ * @param draggedElement
+ * the dragged element
+ * @param clonedStyle
+ * the style for the cloned element
+ * @return the amount of X offset that was applied to the dragged element
+ * due to transform X, needed for calculation the relative position
+ * of the drag image according to mouse position
+ */
+ private int fixDragImageTransformForSafari(Element draggedElement,
+ Style clonedStyle) {
+ int xTransformOffsetForSafari = 0;
+ int yTransformOffsetForSafari = 0;
+ Element parent = draggedElement.getParentElement();
+ /*
+ * Unfortunately, the following solution does not work when there are
+ * many nested layers of transforms. It seems that the outer transforms
+ * do not effect the cloned element the same way. #9408
+ */
+ while (parent != null) {
+ ComputedStyle computedStyle = new ComputedStyle(parent);
+ String transform = computedStyle.getProperty("transform");
+ computedStyle = new ComputedStyle(parent);
+ transform = computedStyle.getProperty("transform");
+ if (transform == null || transform.isEmpty()) {
+ transform = computedStyle.getProperty("-webkitTransform");
+ }
+ if (transform != null && !transform.isEmpty()
+ && !transform.equalsIgnoreCase("none")) {
+ // matrix format is "matrix(a,b,c,d,x,y)"
+ xTransformOffsetForSafari -= getMatrixValue(transform, 4);
+ yTransformOffsetForSafari -= getMatrixValue(transform, 5);
+ }
+ parent = parent.getParentElement();
+ }
+ if (xTransformOffsetForSafari != 0 || yTransformOffsetForSafari != 0) {
+ StringBuilder sb = new StringBuilder("translate(")
+ .append(xTransformOffsetForSafari).append("px,")
+ .append(yTransformOffsetForSafari).append("px)");
+ clonedStyle.setProperty("transform", sb.toString());
+ }
+ // the x-offset should be taken into account when the drag image is
+ // adjusted according to the mouse position. The Y-offset doesn't matter
+ // for some reason (TM), at least for grid DnD, and is probably related
+ // to #9408
+ return xTransformOffsetForSafari;
+ }
+
+ /**
+ * Parses 1-dimensional matrix (six values) values.
+ *
+ * @param matrix
+ * the matrix string of format {@code matrix(a,b,c,d,x,y)}
+ * @param n
+ * the Nth value to parse
+ * @return the value, which is in pixels, or 0 if not able to determine
+ * value from given matrix string
+ */
+ private static int getMatrixValue(String matrix, int n) {
+ if (matrix == null || matrix.isEmpty()
+ || matrix.equalsIgnoreCase("none")
+ || !matrix.startsWith("matrix(")) {
+ return 0;
+ }
+ try {
+ // the matrix is e.g. "matrix(x?, y?, 0, 0, tx, ty)" (note no unit
+ // postfix, e.g. 10 instead of 10px)
+ String x = matrix.substring(7, matrix.length() - 1).split(",")[n]
+ .trim();
+ return Integer.parseInt(x);
+ } catch (NumberFormatException nfe) {
+ Logger.getLogger(DragSourceExtensionConnector.class.getName())
+ .info("Unable to parse \"transform: translate(...)\" matrix "
+ + n + ". value from computed style, matrix \""
+ + matrix + "\", drag image might not be visible");
+ }
+ return 0;
}
/**
@@ -340,15 +439,17 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
*/
protected void setDragImage(NativeEvent dragStartEvent) {
String imageUrl = getResourceUrl(DragSourceState.RESOURCE_DRAG_IMAGE);
+ Element draggedElement = (Element) dragStartEvent
+ .getCurrentEventTarget().cast();
if (imageUrl != null && !imageUrl.isEmpty()) {
Image dragImage = new Image(
getConnection().translateVaadinUri(imageUrl));
- dragStartEvent.getDataTransfer()
- .setDragImage(dragImage.getElement(), 0, 0);
+ dragStartEvent.getDataTransfer().setDragImage(
+ dragImage.getElement(),
+ WidgetUtil.getRelativeX(draggedElement, dragStartEvent),
+ WidgetUtil.getRelativeY(draggedElement, dragStartEvent));
} else {
- Element draggedElement = (Element) dragStartEvent
- .getCurrentEventTarget().cast();
- fixDragImageForDesktopSafari(draggedElement);
+ fixDragImageOffsetsForDesktop(dragStartEvent, draggedElement);
fixDragImageTransformForMobile(draggedElement);
}
}
@@ -406,7 +507,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
* This method is called during the dragstart event.
*
* @param event
- * The drag start event.
+ * The drag start event.
*/
protected void addDraggedStyle(NativeEvent event) {
Element dragSource = getDraggableElement();
@@ -419,7 +520,7 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
* dragged. This method is called during the dragend event.
*
* @param event
- * The drag end element.
+ * The drag end element.
*/
protected void removeDraggedStyle(NativeEvent event) {
Element dragSource = getDraggableElement();
diff --git a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
index fedae64e7d..7ccb808618 100644
--- a/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
+++ b/uitest/src/main/java/com/vaadin/tests/components/grid/GridDragAndDrop.java
@@ -33,6 +33,7 @@ import com.vaadin.shared.ui.grid.DropMode;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.tests.util.Person;
import com.vaadin.tests.util.TestDataGenerator;
+import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Grid;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Layout;
@@ -60,6 +61,7 @@ public class GridDragAndDrop extends AbstractTestUIWithLog {
// Layout the two grids
Layout grids = new HorizontalLayout();
+
grids.addComponents(left, right);
grids.setWidth("100%");
@@ -80,10 +82,30 @@ public class GridDragAndDrop extends AbstractTestUIWithLog {
dropLocationSelect.addValueChangeListener(
event -> dropTarget.setDropMode(event.getValue()));
+ CheckBox transitionCheckBox = new CheckBox("Transition layout", false);
+ transitionCheckBox.addValueChangeListener(event -> {
+ if (event.getValue()) {
+ grids.addStyleName("transitioned");
+ } else {
+ grids.removeStyleName("transitioned");
+ }
+ });
+
+ RadioButtonGroup<Integer> frozenColumnSelect = new RadioButtonGroup<>(
+ "Frozen columns", Arrays.asList(new Integer[] { -1, 0, 1 }));
+ frozenColumnSelect.setValue(left.getFrozenColumnCount());
+ frozenColumnSelect.addValueChangeListener(event -> {
+ left.setFrozenColumnCount(event.getValue());
+ right.setFrozenColumnCount(event.getValue());
+ });
+
Layout controls = new HorizontalLayout(selectionModeSelect,
- dropLocationSelect);
+ dropLocationSelect, transitionCheckBox, frozenColumnSelect);
addComponents(controls, grids);
+
+ getPage().getStyles()
+ .add(".transitioned { transform: translate(-30px, 30px);}");
}
private Grid<Person> createGridAndFillWithData(int numberOfItems) {
diff --git a/uitest/src/main/java/com/vaadin/tests/dnd/DragImage.java b/uitest/src/main/java/com/vaadin/tests/dnd/DragImage.java
index fcac0b1743..624461a536 100644
--- a/uitest/src/main/java/com/vaadin/tests/dnd/DragImage.java
+++ b/uitest/src/main/java/com/vaadin/tests/dnd/DragImage.java
@@ -10,6 +10,7 @@ import com.vaadin.server.ThemeResource;
import com.vaadin.server.VaadinRequest;
import com.vaadin.tests.components.AbstractTestUIWithLog;
import com.vaadin.tests.components.uitest.TestSampler;
+import com.vaadin.ui.CheckBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.VerticalLayout;
@@ -63,7 +64,22 @@ public class DragImage extends AbstractTestUIWithLog {
new DragSourceExtension(gridRowLikeLabel);
styles.add(css);
- addComponent(new VerticalLayout(layout1, layout2, gridRowLikeLabel));
+ VerticalLayout layout = new VerticalLayout();
+ CheckBox transitionCheckBox = new CheckBox("Transition layout", false);
+ transitionCheckBox.addValueChangeListener(event -> {
+ if (event.getValue()) {
+ layout.addStyleName("transitioned");
+ } else {
+ layout.removeStyleName("transitioned");
+ }
+ });
+
+ layout.addComponents(transitionCheckBox, layout1, layout2,
+ gridRowLikeLabel);
+ addComponent(layout);
+ layout.addStyleName("transitioned");
+ getPage().getStyles()
+ .add(".transitioned {transform: translateX(50px);}");
}
}