Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 227462 Details for
Bug 281246
Draw2d Enhancement - Labeled Polylines
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Further modification with zest changes
zest.patch (text/plain), 19.47 KB, created by
Anton Tanasenko
on 2013-02-22 08:42:46 EST
(
hide
)
Description:
Further modification with zest changes
Filename:
MIME Type:
Creator:
Anton Tanasenko
Created:
2013-02-22 08:42:46 EST
Size:
19.47 KB
patch
obsolete
>diff --git a/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/GraphConnection.java b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/GraphConnection.java >index 26c458f..2824312 100644 >--- a/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/GraphConnection.java >+++ b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/GraphConnection.java >@@ -17,12 +17,9 @@ > import org.eclipse.draw2d.Graphics; > import org.eclipse.draw2d.IFigure; > import org.eclipse.draw2d.Label; >-import org.eclipse.draw2d.Locator; >-import org.eclipse.draw2d.MidpointLocator; > import org.eclipse.draw2d.PolygonDecoration; > import org.eclipse.draw2d.PolylineConnection; > import org.eclipse.draw2d.Shape; >-import org.eclipse.draw2d.geometry.Point; > import org.eclipse.swt.graphics.Color; > import org.eclipse.swt.graphics.Font; > import org.eclipse.swt.widgets.Display; >@@ -59,7 +56,7 @@ > private int curveDepth; > private boolean isDisposed = false; > >- private Label connectionLabel = null; >+ private PolylineLabelDecoration connectionLabel = null; > private PolylineArcConnection connectionFigure = null; > private PolylineArcConnection cachedConnectionFigure = null; > private Connection sourceContainerConnectionFigure = null; >@@ -474,20 +471,18 @@ > * The depth of the curve > */ > public void setCurveDepth(int depth) { >- if (this.curveDepth == 0 && depth != 0 || this.curveDepth != 0 >- && depth == 0) { >- // There is currently no curve, so we have to create >- // a curved connection >- this.cachedConnectionFigure = connectionFigure; >- graph.removeConnection(this); >- this.curveDepth = depth; >- this.connectionFigure = doCreateFigure(); >- registerConnection(sourceNode, destinationNode); >- updateFigure(this.connectionFigure); >- } else { >- this.curveDepth = depth; >- updateFigure(this.connectionFigure); >- } >+ /* >+ * if (this.curveDepth == 0 && depth != 0 || this.curveDepth != 0 && >+ * depth == 0) { // There is currently no curve, so we have to create // >+ * a curved connection this.cachedConnectionFigure = connectionFigure; >+ * graph.removeConnection(this); this.curveDepth = depth; >+ * this.connectionFigure = doCreateFigure(); >+ * registerConnection(sourceNode, destinationNode); >+ * updateFigure(this.connectionFigure); } else { >+ */ >+ this.curveDepth = depth; >+ updateFigure(this.connectionFigure); >+ // } > } > > /* >@@ -651,24 +646,15 @@ > PolylineArcConnection connectionFigure = cachedOrNewConnectionFigure(); > ChopboxAnchor sourceAnchor = null; > ChopboxAnchor targetAnchor = null; >- this.connectionLabel = new Label(); >- Locator labelLocator = null; >+ this.connectionLabel = new PolylineLabelDecoration(); >+ connectionLabel.setTextPosition(PolylineLabelDecoration.POSITION_DEST); > > if (getSource() == getDestination()) { > // If this is a self loop, create a looped arc and put the locator > // at the top of the connection > sourceAnchor = new LoopAnchor(getSource().getNodeFigure()); > targetAnchor = new LoopAnchor(getDestination().getNodeFigure()); >- labelLocator = new MidpointLocator(connectionFigure, 0) { >- protected Point getReferencePoint() { >- Point p = Point.SINGLETON; >- p.x = getConnection().getPoints().getPoint(getIndex()).x; >- p.y = (int) (getConnection().getPoints().getPoint( >- getIndex()).y - (curveDepth * 1.5)); >- getConnection().translateToAbsolute(p); >- return p; >- } >- }; >+ connectionLabel.setTrimText(false); > } else { > if (curveDepth != 0) { > connectionFigure.setDepth(this.curveDepth); >@@ -678,14 +664,14 @@ > getSource().getNodeFigure(), 8); > targetAnchor = new RoundedChopboxAnchor(getDestination() > .getNodeFigure(), 8); >- labelLocator = new MidpointLocator(connectionFigure, 0); > } > > connectionFigure.setSourceAnchor(sourceAnchor); > connectionFigure.setTargetAnchor(targetAnchor); >- connectionFigure.add(this.connectionLabel, labelLocator); > > doUpdateFigure(connectionFigure); >+ connectionFigure.add(this.connectionLabel, new PolylineLabelLocator( >+ connectionFigure)); > return connectionFigure; > } > >diff --git a/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/PolylineLabelDecoration.java b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/PolylineLabelDecoration.java >new file mode 100644 >index 0000000..1e4b23b >--- /dev/null >+++ b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/PolylineLabelDecoration.java >@@ -0,0 +1,445 @@ >+package org.eclipse.zest.core.widgets; >+ >+import org.eclipse.draw2d.AbstractBackground; >+import org.eclipse.draw2d.ColorConstants; >+import org.eclipse.draw2d.Graphics; >+import org.eclipse.draw2d.Label; >+import org.eclipse.draw2d.PolylineConnection; >+import org.eclipse.draw2d.RotatableDecoration; >+import org.eclipse.draw2d.geometry.Dimension; >+import org.eclipse.draw2d.geometry.Point; >+import org.eclipse.draw2d.geometry.PointList; >+import org.eclipse.draw2d.geometry.Rectangle; >+import org.eclipse.swt.graphics.Font; >+import org.eclipse.swt.graphics.Image; >+ >+/** >+ * A decorative label Figure intended to be placed on a >+ * {@link PolylineConnection}. >+ * >+ * @since 3.5 >+ */ >+public class PolylineLabelDecoration extends Label implements >+ RotatableDecoration { >+ >+ private static final int ICON_SPACER = 5; >+ private static final int TEXT_MARGINS = 5; // 2 pixels from both ends >+ >+ public static final int POSITION_CENTER = 0; >+ public static final int POSITION_SOURCE = 1; >+ public static final int POSITION_DEST = 2; >+ >+ private Point location = new Point(); >+ private Point refPoint = new Point(); >+ private double angle; >+ private int curveDepth; >+ private int textPosition = POSITION_CENTER; >+ >+ private boolean trimText = true; >+ >+ private Rectangle segmentBase; >+ private Point[] unalignedBounds; >+ private String subStringText; >+ >+ public PolylineLabelDecoration() { >+ super(); >+ } >+ >+ public PolylineLabelDecoration(Image i) { >+ super(i); >+ } >+ >+ public PolylineLabelDecoration(String s) { >+ super(s); >+ } >+ >+ public PolylineLabelDecoration(String s, Image i) { >+ super(s, i); >+ } >+ >+ /** >+ * Find the bounding box that encloses the two reference points ( >+ * {@link #refPoint} and {@link #location}). >+ */ >+ private Rectangle getSegmentBase() { >+ if (segmentBase == null) { >+ >+ int xDiff = refPoint.x - location.x; >+ int yDiff = refPoint.y - location.y; >+ int length = length(xDiff, yDiff); >+ int textLength = getSubStringTextSize().width; >+ if (getIconSize().width > 0) >+ textLength += getIconSize().width + ICON_SPACER; >+ >+ // extend boundingBox to contain whole textSubstring >+ int xInc = 0; >+ int yInc = 0; >+ if (textLength > 0) { >+ if (length == 0) { >+ xInc = textLength; >+ yInc = 0; >+ } else { >+ xInc = xDiff * (textLength - length) / length; >+ yInc = yDiff * (textLength - length) / length; >+ } >+ } >+ >+ // text positioning >+ int offsetLength = 0; >+ if (textPosition == POSITION_SOURCE) { >+ offsetLength = -(length - textLength - (TEXT_MARGINS * 2)) / 2; >+ } else if (textPosition == POSITION_DEST) { >+ offsetLength = (length - textLength - (TEXT_MARGINS * 2)) / 2; >+ } >+ >+ int xOffset = length == 0 ? 0 : (xDiff * offsetLength / length); >+ int yOffset = length == 0 ? 0 : (yDiff * offsetLength / length); >+ >+ int width = Math.abs(xDiff + xInc); >+ int height = Math.abs(yDiff + yInc); >+ >+ int x, y; >+ if (xDiff >= 0) { >+ // width = (int) (xDiff + xInc); >+ x = location.x - (xInc / 2) + xOffset; >+ } else { >+ // width = (int) (-xDiff - xInc); >+ x = refPoint.x + (xInc / 2) + xOffset; >+ } >+ if (yDiff >= 0) { >+ // height = (int) (yDiff + yInc); >+ y = location.y - (yInc / 2) + yOffset; >+ } else { >+ // height = (int) (-yDiff - yInc); >+ y = refPoint.y + (yInc / 2) + yOffset; >+ } >+ >+ segmentBase = new Rectangle(x, y, width, height); >+ } >+ return segmentBase; >+ } >+ >+ public void setFont(Font f) { >+ super.setFont(f); >+ } >+ >+ /** >+ * Oriented rectangular polygon which contains whole label >+ */ >+ protected Point[] getUnalignedBounds() { >+ if (unalignedBounds == null) { >+ >+ int textWidth = getSubStringTextSize().width; >+ if (getIconSize().width > 0) >+ textWidth += getIconSize().width + ICON_SPACER; >+ >+ int textHeight = getSubStringTextSize().height; >+ if (getIconSize().height > textHeight) >+ textHeight = getIconSize().height; >+ >+ Point topLeft = getSegmentBase().getTopLeft(); >+ >+ if (angle < 0) { >+ topLeft.translate(0, getSegmentBase().height); >+ } >+ if (angle < -90.0 || angle > 90.0) { >+ topLeft.translate(0, angle < 0 ? -getSegmentBase().height >+ : getSegmentBase().height); >+ translate(topLeft, textHeight - curveDepth, >+ Math.toRadians(angle) + Math.PI / 2); >+ } else { >+ translate(topLeft, -textHeight - curveDepth, >+ Math.toRadians(angle) + Math.PI / 2); >+ } >+ >+ double radians = Math.toRadians(angle); >+ if (angle > 90.0 || angle < -90.0) >+ radians = radians - Math.PI; >+ >+ Point bottomLeft = topLeft.getCopy(); >+ translate(bottomLeft, textHeight, radians + Math.PI / 2); >+ >+ Point topRight = topLeft.getCopy(); >+ translate(topRight, textWidth, radians); >+ >+ Point bottomRight = bottomLeft.getCopy(); >+ translate(bottomRight, textWidth, radians); >+ >+ unalignedBounds = new Point[] { topLeft, topRight, bottomRight, >+ bottomLeft }; >+ } >+ return unalignedBounds; >+ } >+ >+ /** >+ * Axis-aligned rectangle which fully contains unalignedBounds >+ */ >+ public Rectangle getBounds() { >+ if (bounds == null) { >+ // heightDiff = 0; >+ >+ Point[] ubox = getUnalignedBounds(); >+ >+ // The four points represent a rectangle that contains only the >+ // text. However, its coordinate is at an angle >+ // with the absolute coordinate, so it cannot be set as the bounds. >+ // Need to compute the bounds by searching >+ // for the leftmost x, rightmost x, highest y and lowest y >+ >+ int xLeft = ubox[0].x; >+ int xRight = ubox[0].x; >+ int yTop = ubox[0].y; >+ int yBottom = ubox[0].y; >+ for (int i = 1; i < ubox.length; i++) { >+ Point point = ubox[i]; >+ if (point.x < xLeft) { >+ xLeft = point.x; >+ } else if (point.x > xRight) { >+ xRight = point.x; >+ } >+ >+ // Don't forget that (0,0) is the top left point of the screen! >+ if (point.y < yTop) { >+ yTop = point.y; >+ } else if (point.y > yBottom) { >+ yBottom = point.y; >+ } >+ } >+ Rectangle rectangle = new Rectangle(xLeft, yTop, xRight - xLeft, >+ yBottom - yTop); >+ // if (rectangle.height < textSize.height) { >+ // heightDiff = textSize.height - rectangle.height; >+ // rectangle.height = textSize.height; >+ // } >+ // If the rectangle's width is small, then it means that it is >+ // nearly vertical. For proper behavior, it must >+ // be at least the textSize's height. >+ Dimension textSize = getSubStringTextSize(); >+ if (rectangle.width < textSize.height) { >+ rectangle.width = textSize.height; >+ } >+ bounds = rectangle; >+ } >+ return super.getBounds(); >+ } >+ >+ // location of icon within bounds >+ protected Point getIconLocation() { >+ int linkLength = length(getSegmentBase().width, getSegmentBase().height); >+ >+ int iconWidth = getIconSize().width; >+ if (iconWidth > 0) >+ iconWidth += ICON_SPACER; >+ >+ int x; >+ switch (getTextAlignment()) { >+ case LEFT: >+ x = 0; >+ break; >+ case RIGHT: >+ x = (int) (linkLength - (getSubStringTextSize().width + iconWidth)); >+ break; >+ default: >+ x = (int) (linkLength - (getSubStringTextSize().width + iconWidth)) / 2; >+ } >+ if (x < 0) { >+ x = 0; >+ } >+ >+ int y = 0; >+ if (getIconSize().height < getSubStringTextSize().height) >+ y = getIconSize().height - getSubStringTextSize().height; >+ >+ return new Point(x, y); >+ } >+ >+ // shift of text within bounds >+ protected Point getTextLocation() { >+ int linkLength = length(getSegmentBase().width, getSegmentBase().height); >+ >+ int iconWidth = getIconSize().width; >+ if (iconWidth > 0) >+ iconWidth += ICON_SPACER; >+ >+ int x; >+ switch (getTextAlignment()) { >+ case LEFT: >+ x = iconWidth; >+ break; >+ case RIGHT: >+ x = (int) (linkLength - getSubStringTextSize().width); >+ break; >+ default: >+ x = ((int) (linkLength - (getSubStringTextSize().width + iconWidth)) / 2) >+ + iconWidth; >+ } >+ >+ if (x < 0) >+ x = 0; >+ >+ int y = 0; >+ if (getIconSize().height > getSubStringTextSize().height) >+ y = getIconSize().height - getSubStringTextSize().height; >+ >+ return new Point(x, y); >+ } >+ >+ public String getSubStringText() { >+ if (subStringText != null) { >+ return subStringText; >+ } >+ >+ String text = getText(); >+ subStringText = text; >+ >+ if (!trimText) { >+ return subStringText; >+ } >+ >+ int xDiff = refPoint.x - location.x; >+ int yDiff = refPoint.y - location.y; >+ int maxtextLength = length(xDiff, yDiff) - (TEXT_MARGINS * 2); >+ >+ if (getIconSize().width > 0) { >+ maxtextLength -= getIconSize().width + ICON_SPACER; >+ } >+ >+ int widthShrink = (int) (getTextSize().width - maxtextLength); >+ if (widthShrink <= 0) { >+ return subStringText; >+ } >+ >+ Dimension effectiveSize = getTextSize().getExpanded(-widthShrink, 0); >+ Font currentFont = getFont(); >+ int dotsWidth = getTextUtilities().getTextExtents( >+ getTruncationString(), currentFont).width; >+ >+ if (effectiveSize.width < dotsWidth) { >+ effectiveSize.width = dotsWidth; >+ } >+ >+ int subStringLength = getTextUtilities().getLargestSubstringConfinedTo( >+ text, currentFont, effectiveSize.width - dotsWidth); >+ subStringText = new String(text.substring(0, subStringLength) >+ + getTruncationString()); >+ return subStringText; >+ } >+ >+ protected void paintFigure(Graphics graphics) { >+ // Draws the text >+ graphics.pushState(); >+ /* >+ * Point[] uboxs = getUnalignedBounds(); PointList pls = new >+ * PointList(); for (int i = 0; i < uboxs.length; i++) >+ * pls.addPoint(uboxs[i]); graphics.drawPolygon(pls); >+ */ >+ graphics.translate(getUnalignedBounds()[0]); >+ if (angle < -90.0 || angle > 90.0) { >+ graphics.rotate((float) angle + 180); >+ } else { >+ graphics.rotate((float) angle); >+ } >+ >+ if (isOpaque()) { >+ Point[] ubox = getUnalignedBounds(); >+ PointList pl = new PointList(); >+ for (int i = 0; i < ubox.length; i++) >+ pl.addPoint(ubox[i]); >+ graphics.fillPolygon(pl); >+ } >+ if (getBorder() instanceof AbstractBackground) { >+ ((AbstractBackground) getBorder()).paintBackground(this, graphics, >+ NO_INSETS); >+ } >+ if (getIcon() != null) { >+ graphics.drawImage(getIcon(), getIconLocation()); >+ } >+ if (!isEnabled()) { >+ graphics.translate(1, 1); >+ graphics.setForegroundColor(ColorConstants.buttonLightest); >+ graphics.drawText(getSubStringText(), new Point()); >+ graphics.translate(-1, -1); >+ graphics.setForegroundColor(ColorConstants.buttonDarker); >+ } >+ graphics.drawText(getSubStringText(), getTextLocation()); >+ graphics.popState(); >+ } >+ >+ public boolean containsPoint(int x, int y) { >+ boolean contains = super.containsPoint(x, y); >+ >+ if (contains) { >+ // check if point is within unaligned box >+ Point[] ubox = getUnalignedBounds(); >+ PointList pl = new PointList(); >+ for (int i = 0; i < ubox.length; i++) >+ pl.addPoint(ubox[i]); >+ pl.addPoint(ubox[0]); >+ contains = pl.polygonContainsPoint(x, y); >+ } >+ return contains; >+ } >+ >+ public void invalidate() { >+ subStringText = null; >+ super.invalidate(); >+ } >+ >+ public void setLocation(Point p) { >+ location.setLocation(p); >+ segmentBase = null; >+ unalignedBounds = null; >+ bounds = null; >+ invalidate(); >+ } >+ >+ public void setReferencePoint(Point ref) { >+ Point pt = Point.SINGLETON; >+ refPoint.setLocation(ref); >+ pt.setLocation(ref); >+ pt.negate().translate(location); >+ this.angle = Math.toDegrees(Math.atan2(pt.y, pt.x)); >+ segmentBase = null; >+ unalignedBounds = null; >+ bounds = null; >+ invalidate(); >+ } >+ >+ public void setCurveDepth(int depth) { >+ this.curveDepth = depth; >+ segmentBase = null; >+ unalignedBounds = null; >+ bounds = null; >+ invalidate(); >+ } >+ >+ public void setTrimText(boolean trimText) { >+ this.trimText = trimText; >+ segmentBase = null; >+ unalignedBounds = null; >+ bounds = null; >+ invalidate(); >+ } >+ >+ public void setTextPosition(int textPosition) { >+ this.textPosition = textPosition; >+ segmentBase = null; >+ unalignedBounds = null; >+ bounds = null; >+ invalidate(); >+ } >+ >+ /** >+ * Translate a point using polar coordinate. >+ */ >+ private static final void translate(Point pointToTranslate, int radius, >+ double radians) { >+ pointToTranslate.translate((int) (radius * Math.cos(radians)), >+ (int) (radius * Math.sin(radians))); >+ } >+ >+ private static final int length(long w, long h) { >+ return (int) Math.sqrt(w * w + h * h); >+ } >+ >+} >diff --git a/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/PolylineLabelLocator.java b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/PolylineLabelLocator.java >new file mode 100644 >index 0000000..4c1885b >--- /dev/null >+++ b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/PolylineLabelLocator.java >@@ -0,0 +1,55 @@ >+package org.eclipse.zest.core.widgets; >+ >+import org.eclipse.draw2d.Connection; >+import org.eclipse.draw2d.IFigure; >+import org.eclipse.draw2d.Locator; >+import org.eclipse.draw2d.geometry.PointList; >+import org.eclipse.zest.core.widgets.internal.PolylineArcConnection; >+ >+/** >+ * Locator used to place a {@link PolylineLabelDecoration} on a >+ * {@link Connection}. >+ * >+ * @since 3.5 >+ */ >+public class PolylineLabelLocator implements Locator { >+ >+ private Connection connection; >+ >+ /** >+ * Constructs a LabelLocator associated with passed connection. >+ * >+ * @param connection >+ * The connection associated with the locator >+ */ >+ public PolylineLabelLocator(Connection connection) { >+ this.connection = connection; >+ } >+ >+ /** >+ * Relocates the passed in figure (which must be a >+ * {@link PolylineLabelDecoration}) at the start of the connection. >+ * >+ * @param target >+ * The PolylineLabelDecoration to relocate >+ */ >+ public void relocate(IFigure target) { >+ >+ PointList points = connection.getPoints(); >+ PolylineLabelDecoration dec = (PolylineLabelDecoration) target; >+ >+ dec.setLocation(points.getFirstPoint()); >+ dec.setReferencePoint(points.getLastPoint()); >+ if (connection instanceof PolylineArcConnection) >+ dec.setCurveDepth(((PolylineArcConnection) connection).getDepth()); >+ >+ /* >+ * int l = points.size(); if (l % 2 == 0) { >+ * dec.setLocation(points.getPoint(l / 2 - 1)); >+ * dec.setReferencePoint(points.getPoint(l / 2)); } else { >+ * dec.setLocation(points.getPoint(l / 2 - 1)); >+ * dec.setReferencePoint(points.getPoint(l / 2 + 1)); } >+ */ >+ >+ } >+} >diff --git a/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/internal/PolylineArcConnection.java b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/internal/PolylineArcConnection.java >index 1ffa57e..5231f07 100644 >--- a/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/internal/PolylineArcConnection.java >+++ b/org.eclipse.zest.core/src/org/eclipse/zest/core/widgets/internal/PolylineArcConnection.java >@@ -49,6 +49,10 @@ > updateArc(points); > } > >+ public int getDepth() { >+ return depth; >+ } >+ > /** > * This method is not supported by this kind of connection. Points are > * calculated based on the arc definition.
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 281246
:
139889
|
159447
| 227462