package org.objectstyle.wolips.componenteditor.inspector; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DragSource; import org.eclipse.swt.dnd.DragSourceEvent; import org.eclipse.swt.dnd.DragSourceListener; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.DropTargetListener; import org.eclipse.swt.dnd.Transfer; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TableItem; import org.eclipse.ui.internal.dnd.IDropTarget2; import org.objectstyle.wolips.bindings.wod.BindingValueKey; public class BindingsDragHandler implements DragSourceListener, IDropTarget2, PaintListener, DropTargetListener { private static final int endpointSize = 3; private WOBrowserColumn _browserColumn; private Point _startingPoint; private Point _currentPoint; private Canvas _lineCanvas; public BindingsDragHandler(WOBrowserColumn browserColumn) { _browserColumn = browserColumn; _browserColumn.getViewer().addDragSupport(DND.DROP_COPY, new Transfer[] { LocalSelectionTransfer.getTransfer() }, this); } public Shell getShell() { return _browserColumn.getShell(); } public void createCanvas() { Shell shell = getShell(); if (_lineCanvas == null) { _lineCanvas = new Canvas(shell, SWT.NO_BACKGROUND); _lineCanvas.setLocation(0, 0); _lineCanvas.setSize(shell.getSize()); _lineCanvas.moveAbove(null); _lineCanvas.addPaintListener(this); _lineCanvas.setCapture(false); _lineCanvas.setEnabled(false); DropTarget dropTarget = new DropTarget(_lineCanvas, DND.DROP_NONE | DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK); LocalSelectionTransfer transfer = LocalSelectionTransfer.getTransfer(); transfer.setSelection(new StructuredSelection("Test")); dropTarget.setTransfer(new Transfer[] { transfer }); dropTarget.addDropListener(this); } } public void disposeCanvas() { if (_lineCanvas != null) { if (!_lineCanvas.isDisposed()) { _lineCanvas.removePaintListener(this); _lineCanvas.dispose(); } _lineCanvas = null; } } public void paintControl(PaintEvent e) { if (_startingPoint != null && _currentPoint != null) { Point startingPoint = getShell().toControl(_startingPoint); Point currentPoint = getShell().toControl(_currentPoint); e.gc.setForeground(e.widget.getDisplay().getSystemColor(SWT.COLOR_BLACK)); e.gc.setBackground(e.widget.getDisplay().getSystemColor(SWT.COLOR_BLACK)); // e.gc.setAlpha(150); e.gc.setLineWidth(2); e.gc.setLineJoin(SWT.JOIN_ROUND); e.gc.drawOval(currentPoint.x - endpointSize, currentPoint.y - endpointSize, endpointSize * 2, endpointSize * 2); e.gc.drawLine(startingPoint.x, startingPoint.y, currentPoint.x, startingPoint.y); e.gc.drawLine(currentPoint.x, startingPoint.y, currentPoint.x, currentPoint.y); // e.gc.setAlpha(255); e.gc.fillRectangle(startingPoint.x - endpointSize, startingPoint.y - endpointSize, endpointSize * 2, endpointSize * 2); } } public void dispose() { disposeCanvas(); } public void dragEnter(DropTargetEvent event) { event.detail = DND.DROP_COPY; } public void dragLeave(DropTargetEvent event) { // TODO Auto-generated method stub } public void dragOperationChanged(DropTargetEvent event) { event.detail = DND.DROP_COPY; } public void dragOver(DropTargetEvent event) { Point lastPoint = _currentPoint; _currentPoint = new Point(event.x, event.y); Point startingPoint = getShell().toControl(_startingPoint); Point currentPoint = getShell().toControl(_currentPoint); int redrawX1 = Math.min(startingPoint.x, currentPoint.x); int redrawY1 = Math.min(startingPoint.y, currentPoint.y); int redrawX2 = Math.max(startingPoint.x, currentPoint.x); int redrawY2 = Math.max(startingPoint.y, currentPoint.y); if (lastPoint != null) { lastPoint = getShell().toControl(lastPoint); redrawX1 = Math.min(redrawX1, lastPoint.x); redrawY1 = Math.min(redrawY1, lastPoint.y); redrawX2 = Math.max(redrawX2, lastPoint.x); redrawY2 = Math.max(redrawY2, lastPoint.y); } int slop = 5 + endpointSize; redrawX1 -= slop; redrawY1 -= slop; redrawX2 += slop; redrawY2 += slop; _lineCanvas.redraw(redrawX1, redrawY1, redrawX2 - redrawX1, redrawY2 - redrawY1, true); event.detail = DND.DROP_COPY; if (_browserColumn.getDelegate() != null) { _browserColumn.getDelegate().bindingDragging(_browserColumn, _currentPoint); } } public void drop(DropTargetEvent event) { _currentPoint = new Point(event.x, event.y); } public void dropAccept(DropTargetEvent event) { event.detail = DND.DROP_COPY; } public void dragFinished(boolean dropPerformed) { disposeCanvas(); } public void drop() { // DO NOTHING } public Cursor getCursor() { return null; } public Rectangle getSnapRectangle() { return null; } public void bindingDropFinished() { disposeCanvas(); } public void dragFinished(DragSourceEvent event) { if (_browserColumn.getDelegate() != null) { if (event.doit) { boolean dropFinished = _browserColumn.getDelegate().bindingDropped(_browserColumn, _currentPoint, this); if (dropFinished) { disposeCanvas(); } } else { disposeCanvas(); _browserColumn.getDelegate().bindingDragCanceled(_browserColumn); } } else { disposeCanvas(); } } public void dragSetData(DragSourceEvent event) { event.data = _browserColumn.getSelection(); } public void dragStart(DragSourceEvent event) { DragSource dragSource = (DragSource) event.getSource(); Control control = dragSource.getControl(); _startingPoint = null; _currentPoint = null; event.detail = DND.DROP_COPY; event.doit = false; ISelection selection = _browserColumn.getSelection(); if (selection instanceof IStructuredSelection) { Object obj = ((IStructuredSelection) selection).getFirstElement(); if (obj instanceof BindingValueKey) { Control listControl = _browserColumn.getViewer().getControl(); Rectangle listBounds = listControl.getBounds(); TableItem itemControl = (TableItem) _browserColumn.getViewer().testFindItem(obj); Rectangle itemBounds = itemControl.getBounds(); int magicRightMarginOnMac = 27; _startingPoint = control.toDisplay(new Point(listBounds.x + listBounds.width - magicRightMarginOnMac, itemBounds.y + itemBounds.height / 2)); event.doit = true; } } if (event.doit) { createCanvas(); } } }