/** * Copyright (c) 2013 committers of YAKINDU and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * Contributors: * committers of YAKINDU - initial API and implementation * */ package org.yakindu.base.xtext.utils.gmf.commands; import java.util.List; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.PrecisionPoint; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.transaction.TransactionalEditingDomain; import org.eclipse.gef.EditPart; import org.eclipse.gef.requests.ChangeBoundsRequest; import org.eclipse.gmf.runtime.common.core.command.CommandResult; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.draw2d.ui.figures.BaseSlidableAnchor; import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand; import org.eclipse.gmf.runtime.notation.Anchor; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.IdentityAnchor; import org.eclipse.gmf.runtime.notation.View; /** * EXPERIMENTAL !! * * Recalculates the {@link IdentityAnchor}s to recalculate connection anchors * when a node is resized * * @author andreas muelder - Initial contribution and API * */ public class AdjustIdentityAnchorCommand extends AbstractTransactionalCommand { private ChangeBoundsRequest request; private List<IGraphicalEditPart> editParts; @SuppressWarnings("unchecked") public AdjustIdentityAnchorCommand(TransactionalEditingDomain domain, ChangeBoundsRequest request) { super(domain, "Adjusting anchors", null); this.request = request; editParts = request.getEditParts(); } @Override protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException { for (EditPart editPart : editParts) { adjustAnchors(editPart); } return CommandResult.newOKCommandResult(); } @SuppressWarnings("unchecked") private void adjustAnchors(EditPart editPart) { if (editPart instanceof IGraphicalEditPart) { View view = ((IGraphicalEditPart) editPart).getNotationView(); EList<Edge> targetEdges = view.getTargetEdges(); for (Edge edge : targetEdges) { Anchor targetAnchor = edge.getTargetAnchor(); if (targetAnchor instanceof IdentityAnchor) { PrecisionPoint anchorPoint = BaseSlidableAnchor.parseTerminalString(((IdentityAnchor) targetAnchor) .getId()); IFigure figure = ((IGraphicalEditPart) editPart).getFigure(); Dimension sizeBefore = figure.getBounds().getSize(); float widthFactor = (float) (sizeBefore.width() + request.getSizeDelta().width()) / (float) sizeBefore.width(); float heightFactor = (float) (sizeBefore.height() + request.getSizeDelta().height()) / (float) sizeBefore.height(); PrecisionPoint newPoint = new PrecisionPoint(anchorPoint.preciseX() / widthFactor, anchorPoint.preciseY() / heightFactor); ((IdentityAnchor) targetAnchor).setId(composeTerminalString(newPoint)); } } } } // Copied from BaseSlideableAnchor final private static char TERMINAL_START_CHAR = '('; final private static char TERMINAL_DELIMITER_CHAR = ','; final private static char TERMINAL_END_CHAR = ')'; protected String composeTerminalString(PrecisionPoint p) { StringBuffer s = new StringBuffer(24); s.append(TERMINAL_START_CHAR); // 1 char s.append(p.preciseX()); // 10 chars s.append(TERMINAL_DELIMITER_CHAR); // 1 char s.append(p.preciseY()); // 10 chars s.append(TERMINAL_END_CHAR); // 1 char return s.toString(); // 24 chars max (+1 for safety, i.e. for string // termination) } }