Sfoglia il codice sorgente

Helpers, IE fixes, possibility to align proxy image below cursor

svn changeset:11103/svn branch:6.3_dd
tags/6.7.0.beta1
Matti Tahvonen 14 anni fa
parent
commit
f9c180ebdd

+ 19
- 0
src/com/vaadin/terminal/gwt/client/Util.java Vedi File

@@ -37,6 +37,25 @@ public class Util {
debugger;
}-*/;

/**
*
* Returns the topmost element of from given coordinates.
*
* TODO fix crossplat issues clientX vs pageX. See quircksmode
*
* @param x
* @param y
* @return the element at given coordinates
*/
public static native Element getElementFromPoint(int clientX, int clientY)
/*-{
var el = $wnd.document.elementFromPoint(clientX, clientY);
if(el.nodeType == 3) {
el = el.parentNode;
}
return el;
}-*/;

private static final int LAZY_SIZE_CHANGE_TIMEOUT = 400;
private static Set<Paintable> latelyChangedWidgets = new HashSet<Paintable>();


+ 12
- 6
src/com/vaadin/terminal/gwt/client/ui/VDragDropPane.java Vedi File

@@ -11,6 +11,7 @@ import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.Container;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.Paintable;
@@ -44,11 +45,7 @@ public class VDragDropPane extends VAbsoluteLayout implements Container,
transferable.setComponent(paintable);
VDragEvent drag = VDragAndDropManager.get().startDrag(
transferable, event.getNativeEvent(), true);
Element cloneNode = (Element) ((Widget) paintable).getElement()
.cloneNode(true);
cloneNode.getStyle().setBackgroundColor("#999");
cloneNode.getStyle().setOpacity(0.4);
drag.setDragImage(cloneNode);
drag.createDragImage(((Widget) paintable).getElement(), true);
drag.getEventDetails().put(
"mouseDown",
new MouseEventDetails(event.getNativeEvent())
@@ -57,7 +54,10 @@ public class VDragDropPane extends VAbsoluteLayout implements Container,
}
}, MouseDownEvent.getType());

hookHtml5Events(getElement());
if (!BrowserInfo.get().isIE()) {
// TODO make this IE compatible
hookHtml5Events(getElement());
}
getStyleElement().getStyle().setBackgroundColor("yellow");

}
@@ -184,6 +184,12 @@ public class VDragDropPane extends VAbsoluteLayout implements Container,
if (dropHandler == null) {
dropHandler = new VAbstractDropHandler() {

@Override
public void dragEnter(VDragEvent drag) {
ApplicationConnection.getConsole().log("DDPane DragEnter");
super.dragEnter(drag);
}

@Override
public Paintable getPaintable() {
return VDragDropPane.this;

+ 6
- 4
src/com/vaadin/terminal/gwt/client/ui/VScrollTable.java Vedi File

@@ -2492,6 +2492,7 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
if (dragmode != 0) {
mDown = true;
event.preventDefault();
event.stopPropagation();
}
break;
case Event.ONMOUSEOUT:
@@ -2506,11 +2507,12 @@ public class VScrollTable extends FlowPanel implements Table, ScrollHandler {
// TODO propertyId
VDragEvent ev = VDragAndDropManager.get()
.startDrag(transferable, event, true);
Element cloneNode = (Element) getElement()
.cloneNode(true);
cloneNode.getStyle().setOpacity(0.4);
ev.setDragImage(cloneNode);
ev.createDragImage(getElement(), true);

mDown = false;
// prevent text selection
event.preventDefault();
event.stopPropagation();
}
default:
break;

+ 76
- 63
src/com/vaadin/terminal/gwt/client/ui/VTree.java Vedi File

@@ -11,11 +11,10 @@ import java.util.Set;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.SimplePanel;
@@ -161,7 +160,10 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {

}

private void updateTreeRelatedTransferData(VDragEvent drag) {
private void updateTreeRelatedDragData(VDragEvent drag) {

currentMouseOverKey = findCurrentMouseOverKey(drag.getElementOver());

drag.getEventDetails().put("itemIdOver", currentMouseOverKey);

if (currentMouseOverKey != null) {
@@ -177,13 +179,36 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
}
}

private String findCurrentMouseOverKey(Element elementOver) {
TreeNode treeNode = null;
Element curEl = elementOver;
while (curEl != null) {
try {
EventListener eventListener = Event.getEventListener(curEl);
if (eventListener != null) {
// found a widget
if (eventListener instanceof TreeNode) {
treeNode = (TreeNode) eventListener;
}
break;
} else {
curEl = (Element) curEl.getParentElement();
}
} catch (Exception e) {
ApplicationConnection.getConsole().log(e.getMessage());
e.printStackTrace();
}
}
return treeNode == null ? null : treeNode.key;
}

private void updateDropHandler(UIDL childUidl) {
if (dropHandler == null) {
dropHandler = new VAbstractDropHandler() {

@Override
public void dragEnter(VDragEvent drag) {
updateTreeRelatedTransferData(drag);
updateTreeRelatedDragData(drag);
super.dragEnter(drag);
}

@@ -197,59 +222,47 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
"itemIdOver");
final String oldDetail = (String) currentDrag
.getEventDetails().get("detail");
/*
* Using deferred command, so event bubbles to TreeNode
* event listener. Currently here via preview
*/
DeferredCommand.addCommand(new Command() {
public void execute() {
final String detail = getDropDetail(currentDrag
.getCurrentGwtEvent());
boolean nodeHasChanged = (currentMouseOverKey != null && currentMouseOverKey != oldIdOver)
|| (oldIdOver != null);
boolean detailHasChanded = !detail
.equals(oldDetail);

if (nodeHasChanged || detailHasChanded) {
ApplicationConnection.getConsole().log(
"Change in Transferable "
+ currentMouseOverKey + " "
+ detail);

updateTreeRelatedTransferData(currentDrag);
VAcceptCallback accpectedCb = new VAcceptCallback() {
public void handleResponse(
ValueMap responseData) {
if (responseData == null // via client
// side
// validation
|| responseData
.containsKey("accepted")) {
keyToNode.get(currentMouseOverKey)
.emphasis(detail);
}
}
};
if (validateOnServer()) {
VDragAndDropManager.get().visitServer(
DragEventType.OVER, accpectedCb);

} else {
if (validates(currentDrag)) {
accpectedCb.handleResponse(null);
} else {
keyToNode.get(currentMouseOverKey)
.emphasis(null);
}
if (oldIdOver != null
&& oldIdOver != currentMouseOverKey) {
keyToNode.get(oldIdOver).emphasis(null);
}

updateTreeRelatedDragData(currentDrag);
final String detail = getDropDetail(currentDrag
.getCurrentGwtEvent());
boolean nodeHasChanged = (currentMouseOverKey != null && currentMouseOverKey != oldIdOver)
|| (oldIdOver != null);
boolean detailHasChanded = !detail.equals(oldDetail);

if (nodeHasChanged || detailHasChanded) {
ApplicationConnection.getConsole().log(
"Change in Transferable " + currentMouseOverKey
+ " " + detail);
VAcceptCallback accpectedCb = new VAcceptCallback() {
public void handleResponse(ValueMap responseData) {
if (responseData == null // via client
// side
// validation
|| responseData.containsKey("accepted")) {
keyToNode.get(currentMouseOverKey)
.emphasis(detail);
}
}

};
if (validateOnServer()) {
VDragAndDropManager.get().visitServer(
DragEventType.OVER, accpectedCb);

} else {
if (validates(currentDrag)) {
accpectedCb.handleResponse(null);
} else {
keyToNode.get(currentMouseOverKey).emphasis(
null);
}
if (oldIdOver != null
&& oldIdOver != currentMouseOverKey) {
keyToNode.get(oldIdOver).emphasis(null);
}
}
});
}

}

@Override
@@ -385,9 +398,9 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
public void emphasis(String string) {
// ApplicationConnection.getConsole().log("OUTLINE" + string);
Style style = nodeCaptionDiv.getStyle();
String top = "Top".equals(string) ? "2px solid green" : null;
String bottom = "Bottom".equals(string) ? "2px solid green" : null;
String bg = "Center".equals(string) ? "green" : null;
String top = "Top".equals(string) ? "2px solid green" : "";
String bottom = "Bottom".equals(string) ? "2px solid green" : "";
String bg = "Center".equals(string) ? "green" : "";

style.setProperty("borderTop", top);
style.setProperty("borderBottom", bottom);
@@ -439,12 +452,10 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
VTransferable t = new VTransferable();
t.setComponent(VTree.this);
t.setItemId(key);
VDragEvent drag = VDragAndDropManager.get().startDrag(t,
mouseDownEvent, true);
Element node = (Element) nodeCaptionDiv.cloneNode(true);
node.getStyle().setOpacity(0.4);
node.getStyle().setBackgroundColor("#999");
drag.setDragImage(node);
VDragEvent drag = VDragAndDropManager.get().startDrag(
t, mouseDownEvent, true);

drag.createDragImage(nodeCaptionDiv, true);
event.stopPropagation();

mouseDownEvent = null;
@@ -453,6 +464,8 @@ public class VTree extends FlowPanel implements Paintable, VHasDropHandler {
mouseDownEvent = null;
}
if (type == Event.ONMOUSEOVER) {
ApplicationConnection.getConsole().log(
"Treenode mouse over");
mouseDownEvent = null;
currentMouseOverKey = key;
event.stopPropagation();

+ 82
- 11
src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java Vedi File

@@ -3,6 +3,7 @@ package com.vaadin.terminal.gwt.client.ui.dd;
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.Display;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.shared.HandlerRegistration;
@@ -16,6 +17,7 @@ import com.google.gwt.user.client.ui.Widget;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.Util;
import com.vaadin.terminal.gwt.client.ValueMap;

/**
@@ -32,22 +34,90 @@ public class VDragAndDropManager {

private final class DefaultDragAndDropEventHandler implements
NativePreviewHandler {

public void onPreviewNativeEvent(NativePreviewEvent event) {
updateCurrentEvent(event.getNativeEvent());
NativeEvent nativeEvent = event.getNativeEvent();
updateCurrentEvent(nativeEvent);
updateDragImagePosition();

NativeEvent nativeEvent = event.getNativeEvent();
int typeInt = event.getTypeInt();
Element targetElement = (Element) nativeEvent.getEventTarget()
.cast();
if (dragElement != null && targetElement.isOrHasChild(dragElement)) {
ApplicationConnection.getConsole().log(
"Event on dragImage, ignored");
event.cancel();
nativeEvent.stopPropagation();
return;
if (dragElement != null && dragElement.isOrHasChild(targetElement)) {

// to detect the "real" target, hide dragelement temporary and
// use elementFromPoint
String display = dragElement.getStyle().getDisplay();
dragElement.getStyle().setDisplay(Display.NONE);
try {
int x = nativeEvent.getClientX();
int y = nativeEvent.getClientY();
// Util.browserDebugger();
targetElement = Util.getElementFromPoint(x, y);
if (targetElement == null) {
ApplicationConnection.getConsole().log(
"Event on dragImage, ignored");
event.cancel();
nativeEvent.stopPropagation();
return;

} else {
ApplicationConnection.getConsole().log(
"Event on dragImage, target changed");
// special handling for events over dragImage
// pretty much all events are mousemove althout below
// kind of happens mouseover
switch (typeInt) {
case Event.ONMOUSEOVER:
case Event.ONMOUSEOUT:
ApplicationConnection
.getConsole()
.log(
"IGNORING proxy image event, fired because of hack or not significant");
// TODO consider if mouseover should actually do
// same as mouse move.
return;
case Event.ONMOUSEMOVE:
VDropHandler findDragTarget = findDragTarget(targetElement);
if (findDragTarget != currentDropHandler) {
// dragleave on old
if (currentDropHandler != null) {
currentDropHandler.dragLeave(currentDrag);
acceptCallback = null;
}
// dragenter on new
currentDropHandler = findDragTarget;
if (currentDropHandler != null) {
currentDrag
.setElementOver((com.google.gwt.user.client.Element) targetElement);
currentDropHandler.dragEnter(currentDrag);
}
} else if (findDragTarget != null) {
currentDrag
.setElementOver((com.google.gwt.user.client.Element) targetElement);
currentDropHandler.dragOver(currentDrag);
}
nativeEvent.preventDefault(); // prevent text
// selection on IE
return;
default:
// just update element over and let the actual
// handling code do the thing
currentDrag
.setElementOver((com.google.gwt.user.client.Element) targetElement);
break;
}

}
} catch (Exception e) {
ApplicationConnection.getConsole().log(
"FIXME : ERROR in elementFromPoint hack.");
e.printStackTrace();
} finally {
dragElement.getStyle().setProperty("display", display);
}
}

int typeInt = event.getTypeInt();
switch (typeInt) {
case Event.ONMOUSEOVER:
ApplicationConnection.getConsole().log(
@@ -99,6 +169,7 @@ public class VDragAndDropManager {
}

}

}

public enum DragEventType {
@@ -258,8 +329,8 @@ public class VDragAndDropManager {
private void updateDragImagePosition() {
if (currentDrag.currentGwtEvent != null && dragElement != null) {
Style style = dragElement.getStyle();
int clientY = currentDrag.currentGwtEvent.getClientY() + 6;
int clientX = currentDrag.currentGwtEvent.getClientX() + 6;
int clientY = currentDrag.currentGwtEvent.getClientY();
int clientX = currentDrag.currentGwtEvent.getClientX();
style.setTop(clientY, Unit.PX);
style.setLeft(clientX, Unit.PX);
}

+ 68
- 1
src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java Vedi File

@@ -5,7 +5,9 @@ import java.util.HashMap;
import java.util.Map;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.Element;
import com.vaadin.terminal.gwt.client.BrowserInfo;

/**
* DragEvent used by Vaadin client side engine. Supports components, items,
@@ -15,6 +17,8 @@ import com.google.gwt.user.client.Element;
*/
public class VDragEvent {

private static final int DEFAULT_OFFSET = 10;

private static int eventId = 0;

private VTransferable transferable;
@@ -29,6 +33,8 @@ public class VDragEvent {

private HashMap<String, Object> dropDetails = new HashMap<String, Object>();

private Element elementOver;

VDragEvent(VTransferable t, NativeEvent startEvent) {
transferable = t;
this.startEvent = startEvent;
@@ -52,6 +58,32 @@ public class VDragEvent {
return new Date().getTime() - start.getTime();
}

/**
* Detecting the element on which the the event is happening may be
* problematic during drag and drop operation. This is especially the case
* if a drag image (often called drag proxy) is kept under the mouse cursor
* (see {@link #createDragImage(Element, boolean)}. Drag and drop event
* handlers (like the one provided by {@link VDragAndDropManager} ) should
* set elmentOver field to reflect the the actual element on which the
* pointer currently is (drag image excluded). {@link VDropHandler}s can
* then more easily react properly on drag events by reading the element via
* this method.
*
* @return the element in {@link VDropHandler} on which mouse cursor is on
*/
public Element getElementOver() {
if (elementOver != null) {
return elementOver;
} else if (currentGwtEvent != null) {
return currentGwtEvent.getEventTarget().cast();
}
return null;
}

public void setElementOver(Element targetElement) {
elementOver = targetElement;
}

/**
* Sets the element that will be used as "drag icon".
*
@@ -64,7 +96,7 @@ public class VDragEvent {
* @param node
*/
public void setDragImage(Element node) {
VDragAndDropManager.get().setDragElement(node);
setDragImage(node, DEFAULT_OFFSET, DEFAULT_OFFSET);
}

/**
@@ -78,4 +110,39 @@ public class VDragEvent {
return dropDetails;
}

public void setDragImage(Element cloneNode, int offsetX, int offsetY) {
cloneNode.getStyle().setMarginLeft(offsetX, Unit.PX);
cloneNode.getStyle().setMarginTop(offsetY, Unit.PX);
VDragAndDropManager.get().setDragElement(cloneNode);

}

/**
* Automatically tries to create a proxy image from given element.
*
* @param element
* @param alignImageToEvent
* if true, proxy image is aligned to start event, else next to
* mouse cursor
*/
public void createDragImage(Element element, boolean alignImageToEvent) {
Element cloneNode = (Element) element.cloneNode(true);
cloneNode.getStyle().setOpacity(0.4);
if (BrowserInfo.get().isIE()) {
cloneNode.getStyle().setProperty("filter", "alpha(opacity=70)");
}
if (alignImageToEvent) {
int absoluteTop = element.getAbsoluteTop();
int absoluteLeft = element.getAbsoluteLeft();
int clientX = startEvent.getClientX();
int clientY = startEvent.getClientY();
int offsetX = absoluteLeft - clientX;
int offsetY = absoluteTop - clientY;
setDragImage(cloneNode, offsetX, offsetY);
} else {
setDragImage(cloneNode);
}

}

}

Loading…
Annulla
Salva