/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.internal.tools;
import static org.xmind.ui.mindmap.MindMapUI.SOURCE_ANCHOR;
import static org.xmind.ui.mindmap.MindMapUI.SOURCE_CONTROL_POINT;
import static org.xmind.ui.mindmap.MindMapUI.TARGET_ANCHOR;
import static org.xmind.ui.mindmap.MindMapUI.TARGET_CONTROL_POINT;
import org.eclipse.core.runtime.Assert;
import org.eclipse.draw2d.Cursors;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Layer;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.swt.graphics.Cursor;
import org.xmind.core.IRelationshipEnd;
import org.xmind.gef.GEF;
import org.xmind.gef.Request;
import org.xmind.gef.draw2d.IReferencedFigure;
import org.xmind.gef.draw2d.SelectionFigure;
import org.xmind.gef.draw2d.geometry.PrecisionPoint;
import org.xmind.gef.event.MouseDragEvent;
import org.xmind.gef.part.IGraphicalEditPart;
import org.xmind.gef.part.IGraphicalPart;
import org.xmind.gef.part.IPart;
import org.xmind.gef.service.IFeedbackService;
import org.xmind.ui.decorations.IRelationshipDecoration;
import org.xmind.ui.internal.figures.RelationshipFigure;
import org.xmind.ui.mindmap.IConnectionPart;
import org.xmind.ui.mindmap.INodePart;
import org.xmind.ui.mindmap.IRelationshipPart;
import org.xmind.ui.mindmap.MindMapUI;
import org.xmind.ui.tools.DummyMoveTool;
import org.xmind.ui.util.MindMapUtils;
public class RelationshipMoveTool extends DummyMoveTool {
// private static final Double DEFAULT_AMOUNT = Double
// .valueOf(Styles.DEF_CONTROL_POINT_AMOUNT);
private int pointId = -1;
private RelationshipDummy relDummy = null;
// private Double newAngle = null;
//
// private Double newAmount = null;
private Point newPosition = null;
private IPart newNode = null;
private IFeedbackService feedbackService = null;
public void setSource(IGraphicalEditPart source) {
Assert.isTrue(source instanceof IRelationshipPart);
super.setSource(source);
}
protected IRelationshipPart getSourceRelationship() {
return (IRelationshipPart) super.getSource();
}
protected IFigure createDummy() {
IRelationshipPart sourceRel = getSourceRelationship();
if (sourceRel == null)
return null;
Point pos = getStartingPosition();
if (pos != null) {
pointId = sourceRel.getPointId(pos);
}
if (pointId == -1)
return null;
if (relDummy == null) {
Layer layer = getTargetViewer().getLayer(GEF.LAYER_PRESENTATION);
if (layer != null) {
relDummy = createRelationshipDummy(layer, sourceRel);
}
}
if (relDummy != null)
return relDummy.getRelDummy().getFigure();
return null;
}
protected RelationshipDummy createRelationshipDummy(IFigure layer,
IRelationshipPart sourceRel) {
return new RelationshipDummy(layer, sourceRel, pointId,
getTargetViewer());
}
protected void destroyDummy() {
pointId = -1;
newPosition = null;
// newAngle = null;
// newAmount = null;
setNewNode(null);
feedbackService = null;
if (relDummy != null) {
relDummy.dispose();
relDummy = null;
}
super.destroyDummy();
}
private void setNewNode(IPart node) {
IPart oldNode = this.newNode;
if (node == oldNode)
return;
if (oldNode != null) {
removeNodeFeedback(oldNode);
}
this.newNode = node;
if (node != null) {
addNodeFeedback(node);
}
}
private void addNodeFeedback(IPart node) {
if (node instanceof IGraphicalPart) {
IFigure nodeFigure = ((IGraphicalPart) node).getFigure();
if (nodeFigure != null) {
if (feedbackService == null) {
feedbackService = (IFeedbackService) getTargetViewer()
.getService(IFeedbackService.class);
}
if (feedbackService != null) {
SelectionFigure figure = feedbackService
.addSelection(nodeFigure);
figure.setPreselected(true);
}
}
}
}
private void removeNodeFeedback(IPart node) {
if (feedbackService != null) {
if (node instanceof IGraphicalPart) {
IFigure nodeFigure = ((IGraphicalPart) node).getFigure();
if (nodeFigure != null) {
feedbackService.removeSelection(nodeFigure);
}
}
}
}
private IPart findRelationshipEndPart(IPart part) {
if (part != null) {
IConnectionPart rel = getSourceRelationship();
if (part == rel.getSourceNode() || part == rel.getTargetNode())
return null;
Object m = MindMapUtils.getRealModel(part);
if (m instanceof IRelationshipEnd) {
return (IPart) part;
}
}
return null;
}
protected void onMoving(Point currentPos, MouseDragEvent me) {
super.onMoving(currentPos, me);
if (pointId == SOURCE_ANCHOR || pointId == TARGET_ANCHOR) {
setNewNode(findRelationshipEndPart(me.target));
}
}
protected void updateDummyPosition(Point pos) {
if (relDummy == null)
return;
if (pointId == SOURCE_ANCHOR || pointId == TARGET_ANCHOR) {
INodePart node;
if (pointId == SOURCE_ANCHOR) {
node = relDummy.getSourceNodeDummy();
} else {
node = relDummy.getTargetNodeDummy();
}
if (node != null) {
IFigure fig = node.getFigure();
if (fig instanceof IReferencedFigure) {
((IReferencedFigure) fig).setReference(pos);
} else {
fig.setLocation(pos);
}
}
} else if (pointId == SOURCE_CONTROL_POINT
|| pointId == TARGET_CONTROL_POINT) {
IFigure fig = relDummy.getRelDummy().getFigure();
if (fig != null && fig instanceof RelationshipFigure) {
RelationshipFigure rf = (RelationshipFigure) fig;
IRelationshipDecoration dec = rf.getDecoration();
if (dec != null) {
boolean sourceOrTarget = pointId == SOURCE_CONTROL_POINT;
updateControlPointPosition(pos, rf, dec, sourceOrTarget);
}
}
}
relDummy.refreshFeedback();
}
private void updateControlPointPosition(Point pos,
RelationshipFigure figure, IRelationshipDecoration decoration,
boolean sourceOrTarget) {
PrecisionPoint ref;
if (sourceOrTarget)
ref = figure.getSourceAnchor().getReferencePoint();
else
ref = figure.getTargetAnchor().getReferencePoint();
newPosition = new Point((int) (pos.x - ref.x), (int) (pos.y - ref.y));
if (sourceOrTarget) {
decoration.setRelativeSourceControlPoint(figure, newPosition);
} else {
decoration.setRelativeTargetControlPoint(figure, newPosition);
}
relDummy.getRelDummy().getRelationship()
.getControlPoint(sourceOrTarget ? 0 : 1)
.setPosition(newPosition.x, newPosition.y);
//
// PrecisionPoint ref1 = figure.getSourceAnchor().getReferencePoint();
// PrecisionPoint ref2 = figure.getTargetAnchor().getReferencePoint();
// newAngle = Double
// .valueOf(calcNewAngle(pos, ref1, ref2, sourceOrTarget));
//
// if (sourceOrTarget) {
// decoration.setSourceControlPointHint(figure, newAngle,
// DEFAULT_AMOUNT);
// } else {
// decoration.setTargetControlPointHint(figure, newAngle,
// DEFAULT_AMOUNT);
// }
//
// PrecisionPoint ancPonit1 = decoration.getSourcePosition(figure);
// PrecisionPoint ancPoint2 = decoration.getTargetPosition(figure);
// newAmount = Double.valueOf(calcNewAmount(pos, ancPonit1, ancPoint2,
// sourceOrTarget));
//
// relDummy.getRelDummy().getRelationship().setControlPoint(
// sourceOrTarget ? 0 : 1, newAngle, newAmount);
}
// private double calcNewAmount(Point cursorPos,
// PrecisionPoint sourceAnchorPoint, PrecisionPoint targetAnchorPoint,
// boolean sourceOrTarget) {
// if (sourceOrTarget) {
// return Geometry.getAmount(cursorPos.x, cursorPos.y,
// sourceAnchorPoint.x, sourceAnchorPoint.y,
// targetAnchorPoint.x, targetAnchorPoint.y);
// }
// return Geometry.getAmount(cursorPos.x, cursorPos.y,
// targetAnchorPoint.x, targetAnchorPoint.y, sourceAnchorPoint.x,
// sourceAnchorPoint.y);
// }
//
// private double calcNewAngle(Point cursorPos,
// PrecisionPoint sourceReference, PrecisionPoint targetReference,
// boolean sourceOrTarget) {
// if (sourceOrTarget) {
// return Geometry.getDeltaAngle(cursorPos.x, cursorPos.y,
// sourceReference.x, sourceReference.y, targetReference.x,
// targetReference.y);
// }
// return Geometry.getDeltaAngle(cursorPos.x, cursorPos.y,
// targetReference.x, targetReference.y, sourceReference.x,
// sourceReference.y);
// }
public Cursor getCurrentCursor(Point pos, IPart host) {
if (pointId == SOURCE_ANCHOR || pointId == TARGET_ANCHOR) {
return Cursors.HAND;
} else if (pointId == SOURCE_CONTROL_POINT
|| pointId == TARGET_CONTROL_POINT) {
return Cursors.CROSS;
}
return super.getCurrentCursor(pos, host);
}
protected Request createRequest() {
Request request = null;
if (pointId == SOURCE_ANCHOR || pointId == TARGET_ANCHOR) {
if (newNode != null) {
request = new Request(MindMapUI.REQ_RETARGET_REL);
request.setParameter(MindMapUI.PARAM_MOVE_REL_NEW_NODE, newNode);
// MoveRelationshipRequest req = new MoveRelationshipRequest(
// MindMapUI.REQ_RETARGET_REL, getSourceRelationship(),
// pointId);
// req.setNewNode(newNode);
// return req;
}
} else if (pointId == SOURCE_CONTROL_POINT
|| pointId == TARGET_CONTROL_POINT) {
if (newPosition != null) {
request = new Request(MindMapUI.REQ_MOVE_CONTROL_POINT);
request.setParameter(GEF.PARAM_POSITION, newPosition);
}
// if (newAngle != null && newAmount != null) {
// request = new Request(MindMapUI.REQ_MOVE_CONTROL_POINT);
// request.setParameter(MindMapUI.PARAM_MOVE_REL_NEW_ANGLE,
// newAngle);
// request.setParameter(MindMapUI.PARAM_MOVE_REL_NEW_AMOUNT,
// newAmount);
//// MoveRelationshipRequest req = new MoveRelationshipRequest(
//// MindMapUI.REQ_MOVE_CONTROL_POINT,
//// getSourceRelationship(), pointId);
//// req.setNewAngle(newAngle);
//// req.setNewAmount(newAmount);
//// return req;
// }
}
if (request != null) {
request.setPrimaryTarget(getSourceRelationship());
request.setDomain(getDomain());
request.setViewer(getTargetViewer());
request.setParameter(MindMapUI.PARAM_MOVE_REL_POINT_ID,
Integer.valueOf(pointId));
}
return request;
}
}