How to change the mouse icon/feedback when we drag a node to the canvas from the tool palette in a GEF/GMF based editor
In this blog post I suggest a simple way to change the drag icon/feedback to indicate to the user that it is to drop or illegal to drop what they are dragging at the current location in a GEF or GMF based editor.
You can do it simply by implementing custom DragDropEditPolicy and installing to your EditPart.
a snippet of my code follows.
import java.awt.MouseInfo;
import java.awt.Point;
import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ImageFigure;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeCompartmentEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.DragDropEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.requests.CreateUnspecifiedTypeRequest;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Control;
import org.eclipse.wb.swt.SWTResourceManager;
/**
* Installing FeedbackIndicateDragDropEditPolicy will indicate a feedback when drag a node
* to the canvas from the tool palette
*/
public class FeedbackIndicateDragDropEditPolicy extends DragDropEditPolicy {
private IFigure feedbackFigure;
private Image feedbackImage;
private static final String ALLOW_DROP_ICON_PATH = "/icons/custom/check.png";
private static final String NOT_ALLOW_DROP_ICON_PATH = "/icons/custom/exclamation.png";
/**
* {@inheritDoc}
*/
protected Command getDropCommand(ChangeBoundsRequest request) {
if ((getHost() instanceof ShapeCompartmentEditPart)) {
//avoiding drag and drop nodes between compartments.
return null;
}
return super.getDragCommand(request);
}
/**
* {@inheritDoc}
*/
public void showTargetFeedback(Request request) {
super.showTargetFeedback(request);
if (request instanceof CreateUnspecifiedTypeRequest) {
if (getHost() instanceof ShapeCompartmentEditPart) {
ShapeCompartmentEditPart host = (ShapeCompartmentEditPart) getHost();
Command command = host.getCommand(request);
if (command != null) {
if (command.canExecute()) {
showFeedBackFigure(true);
} else {
showFeedBackFigure(false);
}
} else {
showFeedBackFigure(false);
}
} else {
showFeedBackFigure(false);
}
}
}
/**
* {@inheritDoc}
*/
public void eraseTargetFeedback(Request request) {
if (feedbackFigure != null) {
removeFeedback(feedbackFigure);
feedbackFigure = null;
}
super.eraseTargetFeedback(request);
}
/**
* Get feedback figure
* @param allowDrop
* @return
*/
public IFigure getFeedbackFigure(boolean allowDrop) {
if (feedbackFigure == null) {
Image feedbackImage = SWTResourceManager.getImage(this.getClass(),
(allowDrop) ? ALLOW_DROP_ICON_PATH : NOT_ALLOW_DROP_ICON_PATH);
IFigure figure = new ImageFigure(feedbackImage);
addFeedback(figure);
this.feedbackImage = feedbackImage;
feedbackFigure = figure;
}
return feedbackFigure;
}
/**
* Show feedback figure in canvas
* @param allowDrop
*/
private void showFeedBackFigure(boolean allowDrop) {
Point pointer = MouseInfo.getPointerInfo().getLocation();
IFigure feedbackFigure = getFeedbackFigure(allowDrop);
int x = (int) pointer.getX();
int y = (int) pointer.getY();
Control ctrl = getHost().getViewer().getControl();
FigureCanvas canvas = (FigureCanvas) ctrl;
int horizontal = canvas.getHorizontalBar().getSelection();
int vertical = canvas.getVerticalBar().getSelection();
horizontal += 15;
vertical -= 15;
org.eclipse.swt.graphics.Point p = canvas.toDisplay(0, 0);
feedbackFigure.setBounds(new Rectangle((x - p.x) + horizontal, (y - p.y) + vertical,
feedbackImage.getBounds().width, feedbackImage.getBounds().height));
}
}
Hi Melan,
ReplyDeleteDo you know how we can achieve the same feature with pure GEF editor?
Hi,
DeleteI didn't try to write a similar thing in GEF yet, similar approach may work on GEF like extending LayoutEditPolicy (org.eclipse.gef.editpolicies.LayoutEditPolicy) or GraphicalEditPolicy (org.eclipse.gef.editpolicies.GraphicalEditPolicy) and overriding showTargetFeedback, eraseTargetFeedback , etc
Hi Melan
DeleteGood post TFS