diff options
author | Camille Letavernier | 2018-07-03 11:04:47 +0000 |
---|---|---|
committer | Camille Letavernier | 2018-07-30 12:20:33 +0000 |
commit | 2f8f0d9e7dca31bd12707c360ef871687c21990b (patch) | |
tree | dc8c12a1459c7b2d6e641a17852e7cc3ffbd035f | |
parent | 6f5f42f3f9bf6b04397ab67263ba8f8233d9a3af (diff) | |
download | org.eclipse.papyrus-2f8f0d9e7dca31bd12707c360ef871687c21990b.tar.gz org.eclipse.papyrus-2f8f0d9e7dca31bd12707c360ef871687c21990b.tar.xz org.eclipse.papyrus-2f8f0d9e7dca31bd12707c360ef871687c21990b.zip |
Bug 536632: [Sequence Diagram] Create the edit parts & basic figure for
DurationConstraint/DurationObservation
https://bugs.eclipse.org/bugs/show_bug.cgi?id=536632
- Initial implementation of the DurationLinkFigure
Change-Id: I9cc2b0e7a354eb689cd2698320b37a74cbcdf884
Signed-off-by: Camille Letavernier <cletavernier@eclipsesource.com>
3 files changed, 247 insertions, 12 deletions
diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/DurationLinkFigure.java b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/DurationLinkFigure.java index 9bcf9fb6c8f..babfbb5dfd0 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/DurationLinkFigure.java +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/DurationLinkFigure.java @@ -13,8 +13,243 @@ package org.eclipse.papyrus.uml.diagram.sequence.figures; +import org.eclipse.draw2d.ColorConstants; +import org.eclipse.draw2d.Graphics; +import org.eclipse.draw2d.PolylineConnection; +import org.eclipse.draw2d.PolylineDecoration; +import org.eclipse.draw2d.geometry.Point; +import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.papyrus.uml.diagram.common.figure.edge.UMLEdgeFigure; +import org.eclipse.swt.SWT; +import org.eclipse.uml2.uml.DurationConstraint; +import org.eclipse.uml2.uml.DurationObservation; +/** + * <p> + * A Figure for Durations ({@link DurationObservation Observation} or {@link DurationConstraint Constraint}) + * represented as an arrow between two events. The figure consists of two horizontal dashed lines, + * with a vertical arrow between them: + * </p> + * <img src="./doc-files/DurationLinkFigure.png" /> + * <p> + * The horizontal lines are <code>anchored</code> to the source/target of the link. By default, the vertical line will + * be placed in the middle of the bounds formed by these two anchors, although the figure supports a horizontal delta, + * to position the arrow closer to one or the other anchor. + * </p> + * + * <p> + * The figure can also be rotated 90° (i.e. vertical dashed lines and horizontal arrow), + * when the source and target points are on the same Y coordinate (Typically for horizontal messages) + * </p> + */ public class DurationLinkFigure extends UMLEdgeFigure { + /** + * The horizontal dashed line will be drawn slightly further + * than the arrow, by this amount of pixels. + */ + private static final int ARROW_PADDING = 15; + private Orientation arrowOrientation = Orientation.VERTICAL; // TODO Orientation is not supported yet (Bug 536637) + private int arrowPositionDelta = 0; + + /** + * Thin lines may be difficult to select, so we add a tolerance area around it + * to make selection easier. + * + * @see #containsPoint(int, int) + */ + private static final int SELECTION_TOLERANCE = 3; + + @Override + protected void outlineShape(Graphics graphics) { + // Skip super; we're not drawing a polyline connection + paintStartLine(graphics); + paintEndLine(graphics); + paintArrow(graphics); + } + + /** + * Paint the line from this figure to the start point/event (Typically a horizontal line) + * + * @param graphics + */ + protected void paintStartLine(Graphics graphics) { + graphics.pushState(); + graphics.setLineStyle(SWT.LINE_DASH); + try { + Point startLineStart = getStart(); + Point startLineEnd = getTopLineEnd(); + + graphics.drawLine(startLineStart, startLineEnd); + } finally { + graphics.popState(); + } + } + + /** + * @return + */ + private int getArrowLineX() { + if (getPoints().size() < 2) { + // The connection is not configured yet + return 0; + } + return (getStart().x() + getEnd().x()) / 2 + arrowPositionDelta; + } + + /** + * Paint the line from this figure to the end point/event (Typically a horizontal line) + * + * @param graphics + */ + protected void paintEndLine(Graphics graphics) { + graphics.pushState(); + graphics.setLineStyle(SWT.LINE_DASH); + try { + Point endLineStart = getEnd(); + Point endLineEnd = getBottomLineEnd(); + + graphics.drawLine(endLineStart, endLineEnd); + } finally { + graphics.popState(); + } + } + + /** + * Paint the arrow between the start line and end line (Typically a vertical arrow) + * + * @param graphics + */ + protected void paintArrow(Graphics graphics) { + PolylineConnection arrowLine = new PolylineConnection(); + + Point arrowStart = getStart().getCopy().setX(getArrowLineX()); + Point arrowEnd = arrowStart.getCopy().setY(getEnd().y()); + + arrowLine.setStart(arrowStart); + arrowLine.setEnd(arrowEnd); + + // FIXME Decorations won't be painted? + PolylineDecoration source = new PolylineDecoration(); + PolylineDecoration target = new PolylineDecoration(); + + source.setForegroundColor(ColorConstants.black); + + source.setLineWidth(1); + target.setLineWidth(1); + + arrowLine.setSourceDecoration(source); + arrowLine.setTargetDecoration(target); + + arrowLine.paint(graphics); + } + + private Point getArrowTop() { + Rectangle defaultBounds = new Rectangle(getStart(), getEnd()); + return defaultBounds.getTop().getCopy().setX(getArrowLineX()); + } + + private Point getArrowBottom() { + Rectangle defaultBounds = new Rectangle(getStart(), getEnd()); + return defaultBounds.getBottom().getCopy().setX(getArrowLineX()).translate(0, -1); + } + + private Point getTopLineEnd() { + int arrowLinePosition = getArrowLineX(); + + Point startLineEnd = getStart().getCopy(); + if (arrowLinePosition > getStart().x()) { + startLineEnd.setX(arrowLinePosition + ARROW_PADDING); + } else { + startLineEnd.setX(arrowLinePosition - ARROW_PADDING); + } + + return startLineEnd; + } + + private Point getBottomLineEnd() { + int arrowLinePosition = getArrowLineX(); + Point endLineEnd = getEnd().getCopy(); + if (arrowLinePosition < getEnd().x()) { + endLineEnd.setX(arrowLinePosition - ARROW_PADDING); + } else { + endLineEnd.setX(arrowLinePosition + ARROW_PADDING); + } + + return endLineEnd; + } + + /** + * {@inheritDoc} + * <p> + * Override containsPoint to handle clicks on any of the 3 lines (start, end and arrow line) + * </p> + */ + @Override + public boolean containsPoint(int x, int y) { + Rectangle topLine = new Rectangle(getStart(), getTopLineEnd()); + topLine.expand(SELECTION_TOLERANCE, SELECTION_TOLERANCE); + if (topLine.contains(x, y)){ + return true; + } + + Rectangle bottomLine = new Rectangle(getEnd(), getBottomLineEnd()); + bottomLine.expand(SELECTION_TOLERANCE, SELECTION_TOLERANCE); + if (bottomLine.contains(x, y)) { + return true; + } + + Rectangle arrowLine = new Rectangle(getArrowTop(), getArrowBottom()); + arrowLine.expand(SELECTION_TOLERANCE, SELECTION_TOLERANCE); + return arrowLine.contains(x, y); + } + + /** + * <p> + * By default, the arrow is centered between its start and end point (delta = 0). The position + * delta can be used to move it to the right (delta > 0) or to the left (delta < 0). + * </p> + * + * @param delta + */ + public void setArrowPositionDelta(int delta) { + if (delta != this.arrowPositionDelta) { + this.arrowPositionDelta = delta; + revalidate(); + } + } + + @Override + public Rectangle getBounds() { + Rectangle bounds = super.getBounds(); + + // The arrow may be moved outside of the bounds defined by (start, end). + // In that case, we need to update the bounds, to make sure we can draw + // everything + if (getPoints().size() >= 2) { + bounds.union(getTopLineEnd()); + bounds.union(getBottomLineEnd()); + } + return bounds; + } + + /** + * <p> + * Set the orientation of the arrow (Orientation#VERTICAL or Orientation#HORIZONTAL). + * </p> + * <p> + * By default, the arrow is vertical. + * </p> + * + * @param orientation + */ + // TODO Orientation is not supported yet (Bug 536637) + public void setArrowOrientation(Orientation orientation) { + this.arrowOrientation = orientation; + } + + // TODO Orientation is not supported yet (Bug 536637) + public static enum Orientation { + VERTICAL, HORIZONTAL; + } } diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/doc-files/DurationLinkFigure.png b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/doc-files/DurationLinkFigure.png Binary files differnew file mode 100644 index 00000000000..99d9ffac56c --- /dev/null +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/custom-src/org/eclipse/papyrus/uml/diagram/sequence/figures/doc-files/DurationLinkFigure.png diff --git a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/PapyrusUMLSequenceDiagram.paletteconfiguration b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/PapyrusUMLSequenceDiagram.paletteconfiguration index faa1eb11242..76aa8f1c09b 100644 --- a/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/PapyrusUMLSequenceDiagram.paletteconfiguration +++ b/plugins/uml/diagram/org.eclipse.papyrus.uml.diagram.sequence/model/PapyrusUMLSequenceDiagram.paletteconfiguration @@ -131,6 +131,18 @@ <elementType xmi:type="elementtypesconfigurations:SpecializationTypeConfiguration" href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#org.eclipse.papyrus.umldi.GeneralOrdering_Edge"/> </elementDescriptors> </ownedConfigurations> + <ownedConfigurations xmi:type="paletteconfiguration:ToolConfiguration" id="createDurationConstraintEdgeTool" label="Duration Constraint" description="Create a Duration Constraint between two elements" kind="ConnectionTool"> + <icon xmi:type="paletteconfiguration:IconDescriptor" pluginID="org.eclipse.uml2.uml.edit" iconPath="/icons/full/obj16/DurationConstraint.gif"/> + <elementDescriptors xmi:type="paletteconfiguration:ElementDescriptor"> + <elementType xmi:type="elementtypesconfigurations:SpecializationTypeConfiguration" href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#_zZRfUH3REeiyRednYY2ROQ"/> + </elementDescriptors> + </ownedConfigurations> + <ownedConfigurations xmi:type="paletteconfiguration:ToolConfiguration" id="createDurationObservationEdgeTool" label="Duration Observation" description="Create a Duration Observation between two elements" kind="ConnectionTool"> + <icon xmi:type="paletteconfiguration:IconDescriptor" pluginID="org.eclipse.uml2.uml.edit" iconPath="/icons/full/obj16/DurationObservation.gif"/> + <elementDescriptors xmi:type="paletteconfiguration:ElementDescriptor"> + <elementType xmi:type="elementtypesconfigurations:SpecializationTypeConfiguration" href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#__qpi0H38EeiKffoiPArZXg"/> + </elementDescriptors> + </ownedConfigurations> <ownedConfigurations xmi:type="paletteconfiguration:ToolConfiguration" id="createCommentlink9CreationTool" label="Comment link" description="Create a comment link" kind="ConnectionTool"> <icon xmi:type="paletteconfiguration:IconDescriptor" pluginID="org.eclipse.uml2.uml.edit" iconPath="/icons/full/obj16/Comment.gif"/> <elementDescriptors xmi:type="paletteconfiguration:ElementDescriptor"> @@ -149,17 +161,5 @@ <elementType xmi:type="elementtypesconfigurations:SpecializationTypeConfiguration" href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#org.eclipse.papyrus.umldi.Constraint_ContextEdge"/> </elementDescriptors> </ownedConfigurations> - <ownedConfigurations xmi:type="paletteconfiguration:ToolConfiguration" id="createDurationConstraintEdgeTool" label="Duration Constraint" description="Create a Duration Constraint between two elements" kind="ConnectionTool"> - <icon xmi:type="paletteconfiguration:IconDescriptor" pluginID="org.eclipse.uml2.uml.edit" iconPath="/icons/full/obj16/DurationConstraint.gif"/> - <elementDescriptors xmi:type="paletteconfiguration:ElementDescriptor"> - <elementType xmi:type="elementtypesconfigurations:SpecializationTypeConfiguration" href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#_zZRfUH3REeiyRednYY2ROQ"/> - </elementDescriptors> - </ownedConfigurations> - <ownedConfigurations xmi:type="paletteconfiguration:ToolConfiguration" id="createDurationObservationEdgeTool" label="Duration Observation" description="Create a Duration Observation between two elements" kind="ConnectionTool"> - <icon xmi:type="paletteconfiguration:IconDescriptor" pluginID="org.eclipse.uml2.uml.edit" iconPath="/icons/full/obj16/DurationObservation.gif"/> - <elementDescriptors xmi:type="paletteconfiguration:ElementDescriptor"> - <elementType xmi:type="elementtypesconfigurations:SpecializationTypeConfiguration" href="platform:/plugin/org.eclipse.papyrus.uml.service.types/model/umldi.elementtypesconfigurations#__qpi0H38EeiKffoiPArZXg"/> - </elementDescriptors> - </ownedConfigurations> </drawerConfigurations> </paletteconfiguration:PaletteConfiguration> |