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