blob: 95822131d2977b254bdb6bfc7e9c55cbf9fbce64 [file] [log] [blame]
/*******************************************************************************
* <copyright>
*
* Copyright (c) 2013, 2013 SAP AG.
* 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:
* SAP AG - initial API, implementation and documentation
*
* </copyright>
*
*******************************************************************************/
package org.eclipse.fmc.blockdiagram.editor.features.custom;
import org.eclipse.graphiti.features.IFeatureProvider;
import org.eclipse.graphiti.features.context.ICustomContext;
import org.eclipse.graphiti.mm.pictograms.Anchor;
import org.eclipse.graphiti.mm.pictograms.BoxRelativeAnchor;
import org.eclipse.graphiti.mm.pictograms.Connection;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.IPeLayoutService;
/**
* Layout feature which moves the source or target anchor in such a way that the
* connection line is straight.
*
* @author Benjamin Schmeling
*
*/
public class LayoutConnectionCustomFeature extends FMCCustomFeature {
/**
* Graphiti layout service.
*/
private IPeLayoutService pe = Graphiti.getPeLayoutService();
/**
* Default constructor.
*
* @param featureProvider
*/
public LayoutConnectionCustomFeature(IFeatureProvider featureProvider) {
super(featureProvider);
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.AbstractCustomFeature#canExecute
* (org.eclipse.graphiti.features.context.ICustomContext)
*/
@Override
public boolean canExecute(ICustomContext context) {
for (PictogramElement element : context.getPictogramElements()) {
if (!(element instanceof Connection)) {
return false;
} else {
Connection con = (Connection) element;
if (!(con.getStart() instanceof BoxRelativeAnchor && con
.getEnd() instanceof BoxRelativeAnchor))
return false;
}
}
return true;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.graphiti.features.custom.ICustomFeature#execute(org.eclipse
* .graphiti.features.context.ICustomContext)
*/
@Override
public void execute(ICustomContext context) {
for (PictogramElement element : context.getPictogramElements()) {
Connection con = (Connection) element;
Anchor start = con.getStart();
Anchor end = con.getEnd();
if (start instanceof BoxRelativeAnchor
|| end instanceof BoxRelativeAnchor) {
int difW = pe.getLocationRelativeToDiagram(end).getX()
- pe.getLocationRelativeToDiagram(start).getX();
int difH = pe.getLocationRelativeToDiagram(end).getY()
- pe.getLocationRelativeToDiagram(start).getY();
if (isVerticalAnchor(start) || isVerticalAnchor(end)) {
if (!(end instanceof BoxRelativeAnchor))
((BoxRelativeAnchor) start)
.setRelativeWidth(((BoxRelativeAnchor) start)
.getRelativeWidth()
+ getRelativeWidth(start, difW));
else
((BoxRelativeAnchor) end)
.setRelativeWidth(((BoxRelativeAnchor) end)
.getRelativeWidth()
- getRelativeWidth(end, difW));
} else if (isHorizontalAnchor(start) || isHorizontalAnchor(end)) {
if (!(end instanceof BoxRelativeAnchor))
((BoxRelativeAnchor) start)
.setRelativeHeight(((BoxRelativeAnchor) start)
.getRelativeHeight()
+ getRelativeHeight(start, difH));
else
((BoxRelativeAnchor) end)
.setRelativeHeight(((BoxRelativeAnchor) end)
.getRelativeHeight()
- getRelativeHeight(end, difH));
}
}
}
}
/**
* Checks whether the anchor is positioned along a vertical line.
*
* @param anchor
* The anchor to be checked.
* @return True if it is an anchor along a vertical line.
*/
private boolean isVerticalAnchor(Anchor anchor) {
if (anchor instanceof BoxRelativeAnchor) {
BoxRelativeAnchor boxAnchor = (BoxRelativeAnchor) anchor;
return boxAnchor.getRelativeHeight() == 0
|| boxAnchor.getRelativeHeight() == 1;
} else
return false;
}
/**
* Checks whether the anchor is positioned along a horizontal line.
*
* @param anchor
* The anchor to be checked.
* @return True if it is an anchor along a horizontal line.
*/
private boolean isHorizontalAnchor(Anchor anchor) {
if (anchor instanceof BoxRelativeAnchor) {
BoxRelativeAnchor boxAnchor = (BoxRelativeAnchor) anchor;
return boxAnchor.getRelativeWidth() == 0
|| boxAnchor.getRelativeWidth() == 1;
} else
return false;
}
/**
* Calculates the relative width of the given anchor.
*
* @param anchor
* The anchor the relative width is determined for.
* @param dist
* The horizontal anchor distance
* @return Relative width.
*/
private double getRelativeWidth(Anchor anchor, int dist) {
double width = anchor.getParent().getGraphicsAlgorithm().getWidth();
return dist / width;
}
/**
* Calculates the relative height of the given anchor.
*
* @param anchor
* The anchor the relative height is determined for.
* @param dist
* The vertical anchor distance.
* @return Relative height.
*/
private double getRelativeHeight(Anchor anchor, int num) {
double height = anchor.getParent().getGraphicsAlgorithm().getHeight();
return num / height;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.graphiti.features.impl.AbstractFeature#getName()
*/
@Override
public String getName() {
return "Layout Connection";
}
}