Java tutorial
/******************************************************************************* * Copyright (c) 2009, 2015 THALES GLOBAL SERVICES 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: * Obeo - initial API and implementation *******************************************************************************/ package org.eclipse.sirius.diagram.ui.tools.internal.layout; import java.text.MessageFormat; import java.util.Map; import org.eclipse.draw2d.geometry.Dimension; import org.eclipse.draw2d.geometry.PointList; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EObject; import org.eclipse.gef.ConnectionEditPart; import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil; import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart; import org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx; import org.eclipse.gmf.runtime.notation.Bounds; import org.eclipse.gmf.runtime.notation.ConnectorStyle; import org.eclipse.gmf.runtime.notation.Edge; import org.eclipse.gmf.runtime.notation.IdentityAnchor; import org.eclipse.gmf.runtime.notation.LayoutConstraint; import org.eclipse.gmf.runtime.notation.Node; import org.eclipse.gmf.runtime.notation.NotationPackage; import org.eclipse.gmf.runtime.notation.Size; import org.eclipse.sirius.diagram.DDiagramElement; import org.eclipse.sirius.diagram.business.api.query.DDiagramElementQuery; import org.eclipse.sirius.diagram.layoutdata.AbstractLayoutData; import org.eclipse.sirius.diagram.layoutdata.EdgeLayoutData; import org.eclipse.sirius.diagram.layoutdata.LayoutdataFactory; import org.eclipse.sirius.diagram.layoutdata.NodeLayoutData; import org.eclipse.sirius.diagram.layoutdata.Point; import org.eclipse.sirius.diagram.ui.business.api.query.NodeQuery; import org.eclipse.sirius.diagram.ui.provider.Messages; import org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutDataHelper; import org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutDataKey; import org.eclipse.sirius.diagram.ui.tools.internal.layout.semantic.SemanticEdgeLayoutDataKey; import org.eclipse.sirius.diagram.ui.tools.internal.layout.semantic.SemanticNodeLayoutDataKey; import org.eclipse.sirius.ext.base.Option; import org.eclipse.sirius.ext.draw2d.figure.FigureUtilities; import com.google.common.base.Predicate; import com.google.common.collect.Maps; /** * Helper to manage the layout data. * * @author <a href="mailto:laurent.redor@obeo.fr">Laurent Redor</a> */ public class LayoutDataHelperImpl implements LayoutDataHelper { private static final Predicate<EObject> ROOT_PREDICATE = new Predicate<EObject>() { /** * {@inheritDoc} */ @Override public boolean apply(final EObject input) { return input.eContainer() == null; } }; /** * Creates the default LayoutDataHelper implementation. */ public LayoutDataHelperImpl() { } /** * {@inheritDoc} * * @see org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutDataHelper#createNodeLayoutData(org.eclipse.gmf.runtime.notation.Node, * org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart, * org.eclipse.sirius.diagram.layoutdata.NodeLayoutData) */ @Override public NodeLayoutData createNodeLayoutData(final Node node, final IGraphicalEditPart editPart, final NodeLayoutData parentLayoutData) { final NodeLayoutData result = LayoutdataFactory.eINSTANCE.createNodeLayoutData(); Dimension primarySize = new Dimension(0, 0); // Compute the relative location from the parent layout data // 1-Get the relative location final org.eclipse.draw2d.geometry.Point relativeLocation = editPart.getFigure().getBounds().getLocation() .getCopy(); // 2-Transform to absolute location FigureUtilities.translateToAbsoluteByIgnoringScrollbar(editPart.getFigure(), relativeLocation); boolean isCollapsed = false; if (new DDiagramElementQuery((DDiagramElement) node.getElement()).isIndirectlyCollapsed()) { isCollapsed = true; } if (isCollapsed) { LayoutConstraint layoutConstraint = node.getLayoutConstraint(); if (layoutConstraint instanceof Bounds) { NodeQuery nodeQuery = new NodeQuery(node); Option<Bounds> option = nodeQuery.getExtendedBounds(); if (option.some()) { Bounds unCollapseBounds = option.get(); int deltaX = ((Bounds) layoutConstraint).getX() - unCollapseBounds.getX(); int deltaY = ((Bounds) layoutConstraint).getY() - unCollapseBounds.getY(); relativeLocation.setLocation(relativeLocation.x - deltaX, relativeLocation.y - deltaY); primarySize = new Dimension(unCollapseBounds.getWidth(), unCollapseBounds.getHeight()); } } } else { final Integer width = (Integer) ViewUtil.getStructuralFeatureValue(node, NotationPackage.eINSTANCE.getSize_Width()); final Integer height = (Integer) ViewUtil.getStructuralFeatureValue(node, NotationPackage.eINSTANCE.getSize_Height()); primarySize = new Dimension(width.intValue(), height.intValue()); if (width.intValue() == -1 || height.intValue() == -1) { primarySize = editPart.getFigure().getSize().getCopy(); } } // 3-Remove the parent absolute location if (parentLayoutData != null) { final Point parentAbsoluteLocation = LayoutDataHelper.INSTANCE.getAbsoluteLocation(parentLayoutData); relativeLocation.translate(-parentAbsoluteLocation.getX(), -parentAbsoluteLocation.getY()); } result.setHeight(primarySize.height); result.setWidth(primarySize.width); final Point location = LayoutdataFactory.eINSTANCE.createPoint(); location.setX(relativeLocation.x); location.setY(relativeLocation.y); result.setLocation(location); return result; } /** * {@inheritDoc} * * @see org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutDataHelper#createEdgeLayoutData(org.eclipse.gmf.runtime.notation.Edge) */ @Override public EdgeLayoutData createEdgeLayoutData(final Edge gmfEdge, final ConnectionEditPart connectionEditPart) { final EdgeLayoutData result = LayoutdataFactory.eINSTANCE.createEdgeLayoutData(); final ConnectorStyle connectorStyle = (ConnectorStyle) gmfEdge .getStyle(NotationPackage.eINSTANCE.getConnectorStyle()); if (connectorStyle != null) { result.setRouting(connectorStyle.getRouting().getValue()); result.setJumpLinkStatus(connectorStyle.getJumpLinkStatus().getValue()); result.setJumpLinkType(connectorStyle.getJumpLinkType().getValue()); result.setReverseJumpLink(connectorStyle.isJumpLinksReverse()); result.setSmoothness(connectorStyle.getSmoothness().getValue()); } if (connectionEditPart != null) { final PolylineConnectionEx polylineConnectionEx = (PolylineConnectionEx) connectionEditPart.getFigure(); polylineConnectionEx.getConnectionRouter().route(polylineConnectionEx); final org.eclipse.draw2d.geometry.Point originialSourceRefPoint = polylineConnectionEx.getSourceAnchor() .getReferencePoint().getCopy(); polylineConnectionEx.translateToRelative(originialSourceRefPoint); result.setSourceRefPoint(createPoint(originialSourceRefPoint)); final org.eclipse.draw2d.geometry.Point originialTargetRefPoint = polylineConnectionEx.getTargetAnchor() .getReferencePoint().getCopy(); polylineConnectionEx.translateToRelative(originialTargetRefPoint); result.setTargetRefPoint(createPoint(originialTargetRefPoint)); initPointList(result.getPointList(), polylineConnectionEx.getPoints().getCopy()); } if (gmfEdge.getSourceAnchor() instanceof IdentityAnchor) { result.setSourceTerminal(((IdentityAnchor) gmfEdge.getSourceAnchor()).getId()); } if (gmfEdge.getTargetAnchor() instanceof IdentityAnchor) { result.setTargetTerminal(((IdentityAnchor) gmfEdge.getTargetAnchor()).getId()); } return result; } /** * {@inheritDoc} * * @see org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutDataHelper#createLabelLayoutData(org.eclipse.gmf.runtime.notation.Node) */ @Override public NodeLayoutData createLabelLayoutData(final Node labelNode) { final NodeLayoutData result = LayoutdataFactory.eINSTANCE.createNodeLayoutData(); if (labelNode.getLayoutConstraint() instanceof Size) { final Integer width = (Integer) ViewUtil.getStructuralFeatureValue(labelNode, NotationPackage.eINSTANCE.getSize_Width()); final Integer height = (Integer) ViewUtil.getStructuralFeatureValue(labelNode, NotationPackage.eINSTANCE.getSize_Height()); result.setWidth(width); result.setHeight(height); } final Integer x = (Integer) ViewUtil.getStructuralFeatureValue(labelNode, NotationPackage.eINSTANCE.getLocation_X()); final Integer y = (Integer) ViewUtil.getStructuralFeatureValue(labelNode, NotationPackage.eINSTANCE.getLocation_Y()); final Point location = LayoutdataFactory.eINSTANCE.createPoint(); location.setX(x); location.setY(y); result.setLocation(location); return result; } /** * {@inheritDoc} * * @see org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutDataHelper#getAbsoluteLocation(org.eclipse.sirius.diagram.layoutdata.NodeLayoutData) */ @Override public Point getAbsoluteLocation(final NodeLayoutData nodeLayoutData) { Point result = getCopy(nodeLayoutData.getLocation()); if (nodeLayoutData.eContainer() instanceof NodeLayoutData) { result = getTranslated(result, getAbsoluteLocation((NodeLayoutData) nodeLayoutData.eContainer())); } return result; } /** * {@inheritDoc} * * @see org.eclipse.sirius.diagram.ui.tools.api.layout.LayoutDataHelper#getRelativeLocation(org.eclipse.sirius.diagram.layoutdata.NodeLayoutData, * org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart) */ @Override public Point getRelativeLocation(final NodeLayoutData layoutData, final IGraphicalEditPart editPart) { final Point result = getAbsoluteLocation(layoutData); final org.eclipse.draw2d.geometry.Point p = new org.eclipse.draw2d.geometry.Point(result.getX(), result.getY()); FigureUtilities.translateToRelativeByIgnoringScrollbar(editPart.getFigure(), p); result.setX(p.x); result.setY(p.y); return result; } /** * Create a new point from a draw2d point. * * @param draw2dPoint * The original point * @return A new point */ private Point createPoint(final org.eclipse.draw2d.geometry.Point draw2dPoint) { final Point newPoint = LayoutdataFactory.eINSTANCE.createPoint(); newPoint.setX(draw2dPoint.x); newPoint.setY(draw2dPoint.y); return newPoint; } /** * Initialize a list of {@link Point} from a {@link PointList}. * * @param pointsList * the list to initialize * @param draw2dPointsList * the original points of the line */ private void initPointList(final EList<Point> pointList, final PointList draw2dPointsList) { for (int i = 0; i < draw2dPointsList.size(); i++) { pointList.add(createPoint(draw2dPointsList.getPoint(i))); } } /** * Return a copy of this Point. * * @param point * the point to copy * @return a copy of this Point */ private Point getCopy(final Point point) { final Point copy = LayoutdataFactory.eINSTANCE.createPoint(); copy.setX(point.getX()); copy.setY(point.getY()); return copy; } /** * Creates a new Point which is translated by the values of the provided * Point. * * @param originalPoint * The point to translate. * @param pt * Point which provides the translation amounts. * @return A new Point */ protected Point getTranslated(final Point originalPoint, final Point pt) { final Point translatedPoint = LayoutdataFactory.eINSTANCE.createPoint(); translatedPoint.setX(originalPoint.getX() + pt.getX()); translatedPoint.setY(originalPoint.getY() + pt.getY()); return translatedPoint; } /** * Creates a new Point which is translated by the values of the provided * Point. * * @param originalPoint * The point to translate. * @param pt * Point which provides the translation amounts. * @return A new Point */ @Override public Point getTranslated(final Point originalPoint, final org.eclipse.draw2d.geometry.Point pt) { final Point translatedPoint = LayoutdataFactory.eINSTANCE.createPoint(); translatedPoint.setX(originalPoint.getX() + pt.x); translatedPoint.setY(originalPoint.getY() + pt.y); return translatedPoint; } /** * {@inheritDoc} */ @Override public Map<? extends LayoutDataKey, ? extends AbstractLayoutData> getRootLayoutData( final Map<? extends LayoutDataKey, ? extends AbstractLayoutData> collection) { return Maps.filterValues(collection, ROOT_PREDICATE); } /** * {@inheritDoc} */ @Override public LayoutDataKey createKey(final AbstractLayoutData layoutData) { LayoutDataKey result; if (layoutData instanceof NodeLayoutData) { result = new SemanticNodeLayoutDataKey(layoutData.getId()); } else if (layoutData instanceof EdgeLayoutData) { result = new SemanticEdgeLayoutDataKey(layoutData.getId()); } else { throw new IllegalArgumentException( MessageFormat.format(Messages.LayoutDataHelperImpl_unkownLayoutData, layoutData.getClass())); } return result; } }