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 192882 Details for
Bug 218170
Extension of the snap to shape feature: Snap to distance
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch adopted to GEF 3.7
218170.txt (text/plain), 51.25 KB, created by
Alexander Nyßen
on 2011-04-08 17:46:20 EDT
(
hide
)
Description:
Patch adopted to GEF 3.7
Filename:
MIME Type:
Creator:
Alexander Nyßen
Created:
2011-04-08 17:46:20 EDT
Size:
51.25 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.gef >Index: src/org/eclipse/gef/SnapToDistance.java >=================================================================== >RCS file: src/org/eclipse/gef/SnapToDistance.java >diff -N src/org/eclipse/gef/SnapToDistance.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ src/org/eclipse/gef/SnapToDistance.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,818 @@ >+/******************************************************************************* >+ * Copyright (c) 2003, 2007 IBM Corporation 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: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.gef; >+ >+import java.util.ArrayList; >+import java.util.Collections; >+import java.util.Iterator; >+import java.util.List; >+import java.util.Map; >+ >+import org.eclipse.draw2d.IFigure; >+import org.eclipse.draw2d.geometry.PrecisionRectangle; >+import org.eclipse.draw2d.geometry.Rectangle; >+ >+import org.eclipse.gef.handles.HandleBounds; >+import org.eclipse.gef.requests.GroupRequest; >+ >+/** >+ * A temporary helper used to perform snapping to existing elements. This helper >+ * can be used in conjunction with the >+ * {@link org.eclipse.gef.tools.DragEditPartsTracker DragEditPartsTracker} when >+ * dragging editparts within a graphical viewer. Snapping is based on the >+ * existing children of a <I>container</I>. >+ * <P> >+ * If the snap request is being made during a Move, Reparent or Resize, then the >+ * figures of the participants of that request will not be used for snapping. If >+ * the request is a Clone, then the figures for the parts being cloned will be >+ * used as possible snap locations. >+ * <P> >+ * This helper does not keep up with changes made to the container editpart. >+ * Clients should instantiate a new helper each time one is requested and not >+ * hold on to instances of the helper. * * >+ * >+ * @since 3.7 >+ * @author Sven Koschnicke >+ * @author Florian Schatz >+ */ >+public class SnapToDistance extends SnapToHelper { >+ >+ /** >+ * A property indicating whether this helper should be used. The value >+ * should be an instance of Boolean. Currently, this class does not check to >+ * see if the viewer property is set to <code>true</code>. * * >+ * >+ * @see EditPartViewer#setProperty(String, Object) >+ */ >+ public static final String PROPERTY_SNAP_ENABLED = "SnapToDistance.isEnabled"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the North anchor point in the extended data of a >+ * request. The north anchor may be set to an {@link Integer} value >+ * indicating where the snapping is occurring. This is used for feedback >+ * purposes. >+ */ >+ public static final String KEY_NORTH_ANCHOR = "SnapToDistance.NorthAnchor"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the South anchor point in the extended data of a >+ * request. The south anchor may be set to an {@link Integer} value >+ * indicating where the snapping is occurring. This is used for feedback >+ * purposes. >+ */ >+ public static final String KEY_SOUTH_ANCHOR = "SnapToDistance.SouthAnchor"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the West anchor point in the extended data of a >+ * request. The west anchor may be set to an {@link Integer} value >+ * indicating where the snapping is occurring. This is used for feedback >+ * purposes. >+ */ >+ public static final String KEY_WEST_ANCHOR = "SnapToDistance.WestAnchor"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the East anchor point in the extended data of a >+ * request. The east anchor may be set to an {@link Integer} value >+ * indicating where the snapping is occurring. This is used for feedback >+ * purposes. >+ */ >+ public static final String KEY_EAST_ANCHOR = "SnapToDistance.EastAnchor"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the moved object bounds in the extended data of >+ * a request. This is used for feedback purposes. >+ */ >+ public static final String KEY_MOVED_OBJECT_BOUNDS = "SnapToDistance.MovedObjectBounds"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the first object bounds in the extended data of >+ * a request. This is used for feedback purposes. >+ */ >+ public static final String KEY_VERTICAL_FIRST_OBJECT_BOUNDS = "SnapToDistance.VerticalFirstObjectBounds"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the first object bounds in the extended data of >+ * a request. This is used for feedback purposes. >+ */ >+ public static final String KEY_HORIZONTAL_FIRST_OBJECT_BOUNDS = "SnapToDistance.HorizontalFirstObjectBounds"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the seconds object bounds in the extended data >+ * of a request. This is used for feedback purposes. >+ */ >+ public static final String KEY_VERTICAL_SECOND_OBJECT_BOUNDS = "SnapToDistance.VerticalSecondObjectBounds"; //$NON-NLS-1$ >+ >+ /** >+ * The key used to identify the seconds object bounds in the extended data >+ * of a request. This is used for feedback purposes. >+ */ >+ public static final String KEY_HORIZONTAL_SECOND_OBJECT_BOUNDS = "SnapToDistance.HorizontalSecondObjectBounds"; //$NON-NLS-1$ >+ >+ /** >+ * A vertical or horizontal snapping point. since 3.0 >+ */ >+ protected static class Entry { >+ /** >+ * type of the entry. >+ */ >+ final int type; >+ /** >+ * location of the entry. >+ */ >+ final int location; >+ /** >+ * bounds of moved Object. >+ */ >+ final Rectangle movedObjectBounds; >+ /** >+ * bounds of first Object. >+ */ >+ final Rectangle firstObjectBounds; >+ /** >+ * bounds of seconds Object. >+ */ >+ final Rectangle secondObjectBounds; >+ >+ /** >+ * Constructs a new entry of the given type and location. * * >+ * >+ * @param type2 >+ * an integer between -1 and 1 inclusively >+ * @param location2 >+ * the location >+ * @param movedObjectBounds2 >+ * the Bounds of the moved object >+ * @param firstObjectBounds2 >+ * the Bounds of the first object >+ * @param secondObjectBounds2 >+ * the Bounds of the second object >+ */ >+ protected Entry(int type2, int location2, Rectangle movedObjectBounds2, >+ Rectangle firstObjectBounds2, Rectangle secondObjectBounds2) { >+ if (type2 < -1 || type2 > 1) { >+ throw new IllegalArgumentException("Unrecognized snap type"); //$NON-NLS-1$ >+ } >+ this.type = type2; >+ this.location = location2; >+ this.movedObjectBounds = movedObjectBounds2; >+ this.firstObjectBounds = firstObjectBounds2; >+ this.secondObjectBounds = secondObjectBounds2; >+ } >+ >+ /** >+ * Returns the location of the snap entry. * * >+ * >+ * @return the location >+ * @since 3.2 >+ */ >+ public int getLocation() { >+ return location; >+ } >+ >+ /** >+ * Returns the snap type. The following values may be returned. >+ * <UL> >+ * <LI>-1 indicates left/top >+ * <LI>0 indicates middle/center >+ * <LI>1 indicates right/bottom >+ * </UL> >+ * * * >+ * >+ * @return the snap type >+ * @since 3.2 >+ */ >+ public int getType() { >+ return type; >+ } >+ >+ } >+ >+ /** >+ * The sensitivity of the snapping. Corrections greater than this value will >+ * not occur. >+ */ >+ protected static final double THRESHOLD = 5.0001; >+ >+ /** >+ * The threshhold for snapping. >+ */ >+ private double threshold = THRESHOLD; >+ >+ /** >+ * cache cloned. >+ */ >+ boolean cachedCloneBool; >+ >+ /** >+ * The horizontal rows being snapped to. >+ */ >+ protected Entry[] rows; >+ >+ /** >+ * The vertical columnd being snapped to. >+ */ >+ protected Entry[] cols; >+ >+ /** >+ * The container editpart providing the coordinates and the children to >+ * which snapping occurs. >+ */ >+ protected GraphicalEditPart container; >+ >+ /** >+ * Constructs a helper that will use the given part as its basis for >+ * snapping. The part's contents pane will provide the coordinate system and >+ * its children determine the existing elements. * * >+ * >+ * @since 3.0 >+ * @param container2 >+ * the container editpart >+ */ >+ public SnapToDistance(GraphicalEditPart container2) { >+ this.container = container2; >+ } >+ >+ /** >+ * Get the sensitivity of the snapping. Corrections greater than this value >+ * will not occur. * * >+ * >+ * @return the snapping threshold >+ * @since 3.4 >+ */ >+ protected double getThreshold() { >+ return this.threshold; >+ } >+ >+ /** >+ * Set the sensitivity of the snapping. * * >+ * >+ * @see #getThreshold() >+ * @param newThreshold >+ * the new snapping threshold >+ * @since 3.4 >+ */ >+ protected void setThreshold(double newThreshold) { >+ this.threshold = newThreshold; >+ } >+ >+ /** >+ * Generates a list of parts which should be snapped to. The list is the >+ * original children, minus the given exclusions, minus and children whose >+ * figures are not visible. * * >+ * >+ * @since 3.0 >+ * @param exclusions >+ * the children to exclude >+ * @return a list of parts which should be snapped to >+ */ >+ protected List generateSnapPartsList(List exclusions) { >+ // Don't snap to any figure that is being dragged >+ List children = new ArrayList(container.getChildren()); >+ children.removeAll(exclusions); >+ >+ // Don't snap to hidden figures >+ List hiddenChildren = new ArrayList(); >+ for (Iterator iter = children.iterator(); iter.hasNext();) { >+ GraphicalEditPart child = (GraphicalEditPart) iter.next(); >+ if (!child.getFigure().isVisible()) { >+ hiddenChildren.add(child); >+ } >+ } >+ children.removeAll(hiddenChildren); >+ >+ return children; >+ } >+ >+ /** >+ * Returns the correction value for the given entries and sides. During a >+ * move, the left, right, or center is free to snap to a location. * * >+ * >+ * @param entries >+ * the entries >+ * @param extendedData >+ * the requests extended data >+ * @param vert >+ * <code>true</code> if the correction is vertical >+ * @param near >+ * the left/top side of the rectangle >+ * @param far2 >+ * the right/bottom side of the rectangle >+ * @param bounds >+ * the bounds >+ * @return the correction amount or #getThreshold () if no correction was >+ * made >+ */ >+ protected double getCorrectionFor(Entry[] entries, Map extendedData, >+ boolean vert, double near, double far, Rectangle bounds) { >+ far -= 1.0; >+ double total = near + far; >+ >+ // If the width is even (i.e., odd right now because we have >+ // reduced one >+ // pixel from >+ // far) there is no middle pixel so favor the >+ // left-most/top-most pixel >+ // (which is what >+ // populateRowsAndCols() does by using int precision). >+ if ((int) (near - far) % 2 != 0) { >+ total -= 1.0; >+ } >+ double result = getCorrectionFor(entries, extendedData, vert, >+ total / 2, 0, bounds); >+ >+ // trie to snap again (snapping on, if result != thresh.) >+ if (result == getThreshold()) { >+ result = getCorrectionFor(entries, extendedData, vert, near, -1, >+ bounds); >+ } >+ >+ // trie to snap again (snapping on, if result != thresh.) >+ if (result == getThreshold()) { >+ result = getCorrectionFor(entries, extendedData, vert, far, 1, >+ bounds); >+ } >+ return result; >+ } >+ >+ /** >+ * Returns the correction value between ± {@link #getThreshold()}, or the >+ * #getThreshold () if no corrections were found. * * >+ * >+ * @param entries >+ * the entries >+ * @param extendedData >+ * the map for setting values >+ * @param vert >+ * <code>true</code> if vertical >+ * @param value >+ * the value being corrected >+ * @param side >+ * which sides should be considered >+ * @param bounds >+ * the bounds >+ * @return the correction or #getThreshold () if no correction was made >+ */ >+ protected double getCorrectionFor(Entry[] entries, Map extendedData, >+ boolean vert, double value, int side, Rectangle bounds) { >+ double resultMag = getThreshold(); >+ double result = getThreshold(); >+ >+ String property; >+ if (side == -1) { >+ property = vert ? KEY_WEST_ANCHOR : KEY_NORTH_ANCHOR; >+ >+ } else { >+ property = vert ? KEY_EAST_ANCHOR : KEY_SOUTH_ANCHOR; >+ >+ } >+ >+ // get correction for all entries >+ for (int i = 0; i < entries.length; i++) { >+ if (entries[i] != null) { >+ Entry entry = entries[i]; >+ double magnitude; >+ >+ if (entry.type == -1 && side == 1) { >+ magnitude = Math.abs(value - entry.location); >+ if (magnitude < resultMag) { >+ // only if object >+ // within >+ // distance >+ resultMag = magnitude; >+ result = entry.location - value; // set >+ // correction >+ extendedData.put(property, new Integer(entry.location)); >+ // neu >+ if (vert) { >+ extendedData.put(KEY_MOVED_OBJECT_BOUNDS, bounds); >+ extendedData.put(KEY_VERTICAL_FIRST_OBJECT_BOUNDS, >+ entry.firstObjectBounds); >+ extendedData.put(KEY_VERTICAL_SECOND_OBJECT_BOUNDS, >+ entry.secondObjectBounds); >+ } else { >+ extendedData.put(KEY_MOVED_OBJECT_BOUNDS, bounds); >+ extendedData.put( >+ KEY_HORIZONTAL_FIRST_OBJECT_BOUNDS, >+ entry.firstObjectBounds); >+ extendedData.put( >+ KEY_HORIZONTAL_SECOND_OBJECT_BOUNDS, >+ entry.secondObjectBounds); >+ } >+ } >+ >+ } else if (entry.type == 0 && side == 0) { >+ magnitude = Math.abs(value - entry.location); >+ if (magnitude < resultMag) { // only if object >+ // within >+ // distance >+ resultMag = magnitude; >+ result = entry.location - value; // set >+ // correction >+ extendedData.put(property, new Integer(entry.location)); >+ // neu >+ if (vert) { >+ extendedData.put(KEY_MOVED_OBJECT_BOUNDS, bounds); >+ extendedData.put(KEY_VERTICAL_FIRST_OBJECT_BOUNDS, >+ entry.firstObjectBounds); >+ extendedData.put(KEY_VERTICAL_SECOND_OBJECT_BOUNDS, >+ entry.secondObjectBounds); >+ } else { >+ extendedData.put(KEY_MOVED_OBJECT_BOUNDS, bounds); >+ extendedData.put( >+ KEY_HORIZONTAL_FIRST_OBJECT_BOUNDS, >+ entry.firstObjectBounds); >+ extendedData.put( >+ KEY_HORIZONTAL_SECOND_OBJECT_BOUNDS, >+ entry.secondObjectBounds); >+ } >+ >+ } >+ >+ } else if (entry.type == 1 && side == -1) { >+ magnitude = Math.abs(value - entry.location); >+ if (magnitude < resultMag) { // only if object >+ // within >+ // distance >+ resultMag = magnitude; >+ result = entry.location - value; // set >+ // correction >+ extendedData.put(property, new Integer(entry.location)); >+ >+ // neu >+ if (vert) { >+ extendedData.put(KEY_MOVED_OBJECT_BOUNDS, bounds); >+ extendedData.put(KEY_VERTICAL_FIRST_OBJECT_BOUNDS, >+ entry.firstObjectBounds); >+ extendedData.put(KEY_VERTICAL_SECOND_OBJECT_BOUNDS, >+ entry.secondObjectBounds); >+ } else { >+ extendedData.put(KEY_MOVED_OBJECT_BOUNDS, bounds); >+ extendedData.put( >+ KEY_HORIZONTAL_FIRST_OBJECT_BOUNDS, >+ entry.firstObjectBounds); >+ extendedData.put( >+ KEY_HORIZONTAL_SECOND_OBJECT_BOUNDS, >+ entry.secondObjectBounds); >+ } >+ } >+ >+ } >+ /* >+ * extendedData.put(KEY_MOVED_OBJECT_BOUNDS, bounds); >+ * extendedData.put(KEY_FIRST_OBJECT_BOUNDS, >+ * entry.firstObjectBounds); >+ * extendedData.put(KEY_SECOND_OBJECT_BOUNDS, >+ * entry.secondObjectBounds); >+ */ >+ } >+ } >+ return result; >+ } >+ >+ /** >+ * Returns the rectangular contribution for the given editpart. This is the >+ * rectangle with which snapping is performed. * * >+ * >+ * @since 3.0 >+ * @param part >+ * the child >+ * @return the rectangular guide for that part >+ */ >+ protected Rectangle getFigureBounds(GraphicalEditPart part) { >+ IFigure fig = part.getFigure(); >+ if (fig instanceof HandleBounds) { >+ return ((HandleBounds) fig).getHandleBounds(); >+ } >+ return fig.getBounds(); >+ } >+ >+ /** >+ * Updates the cached row and column Entries using the provided parts. * * >+ * >+ * @since 3.0 >+ * @param parts >+ * a List of EditParts >+ */ >+ protected void populateRowsAndCols(List parts) { >+ >+ int pairs = (parts.size() * (parts.size() - 1)) / 2; >+ >+ rows = new Entry[pairs * 3]; >+ cols = new Entry[pairs * 3]; >+ >+ int countrows = 0; >+ int countcols = 0; >+ >+ for (int i = 0; i < parts.size(); i++) { >+ GraphicalEditPart child = (GraphicalEditPart) parts.get(i); >+ Rectangle bounds = getFigureBounds(child); >+ >+ for (int j = i; j < parts.size(); j++) { >+ if (i != j) { >+ GraphicalEditPart child2 = (GraphicalEditPart) parts.get(j); >+ Rectangle bounds2 = getFigureBounds(child2); >+ >+ int snaptox; >+ int snaptoy; >+ >+ // vertical snaplines >+ >+ // calculate distance between rightmost point of >+ // first and >+ // leftmost of second >+ int firstdistance = Math.abs(bounds2.x >+ - bounds.getRight().x); >+ // calculate distance between leftmost point of >+ // first and >+ // rightmost of second >+ int seconddistance = Math.abs(bounds.x >+ - bounds2.getRight().x); >+ >+ int shortestdistance = (firstdistance < seconddistance) ? firstdistance >+ : seconddistance; >+ >+ if (bounds.x < bounds2.x) { >+ // second is right >+ >+ if (!(bounds2.getRight().x - bounds.x < bounds.width >+ + bounds2.width)) { // not overlap >+ >+ // add left snapline >+ snaptox = bounds.x - shortestdistance; >+ cols[countcols++] = new Entry(-1, snaptox, >+ new Rectangle(snaptox, 0, snaptox + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ >+ // add right snapline >+ snaptox = bounds2.x + bounds2.width >+ + shortestdistance; >+ cols[countcols++] = new Entry(1, snaptox, >+ new Rectangle(snaptox, 0, snaptox + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ >+ // add center snapline >+ snaptox = bounds.x + bounds.width >+ + (shortestdistance / 2); >+ cols[countcols++] = new Entry(0, snaptox, >+ new Rectangle(snaptox, 0, snaptox + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ } >+ } else { >+ // first is right >+ >+ if (!(bounds.getRight().x - bounds2.x < bounds.width >+ + bounds2.width)) { // not overlap >+ >+ // add left snapline >+ snaptox = bounds2.x - shortestdistance; >+ cols[countcols++] = new Entry(-1, snaptox, >+ new Rectangle(snaptox, 0, snaptox + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ >+ // add right snapline >+ snaptox = bounds.x + bounds.width >+ + shortestdistance; >+ cols[countcols++] = new Entry(1, snaptox, >+ new Rectangle(snaptox, 0, snaptox + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ >+ // add center snapline >+ snaptox = bounds2.x + bounds2.width >+ + (shortestdistance / 2); >+ cols[countcols++] = new Entry(0, snaptox, >+ new Rectangle(snaptox, 0, snaptox + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ } >+ } >+ >+ // horizontal snaplines >+ >+ // calculate distance between top point of first >+ // and bottom >+ // of second >+ firstdistance = Math.abs(bounds2.y - bounds.getBottom().y); >+ // calculate distance between bottom point of >+ // first and top >+ // of second >+ seconddistance = Math.abs(bounds.y - bounds2.getBottom().y); >+ >+ shortestdistance = firstdistance > seconddistance ? seconddistance >+ : firstdistance; >+ >+ if (bounds.y < bounds2.y) { >+ // second is bottom >+ >+ if (!(bounds2.getBottom().y - bounds.y < bounds.height >+ + bounds2.height)) { // not overlap >+ // add top snapline >+ snaptoy = bounds.y - shortestdistance; >+ rows[countrows++] = new Entry(-1, snaptoy, >+ new Rectangle(snaptoy, 0, snaptoy + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ >+ // add bottom snapline >+ snaptoy = bounds2.y + bounds2.height >+ + shortestdistance; >+ rows[countrows++] = new Entry(1, snaptoy, >+ new Rectangle(snaptoy, 0, snaptoy + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ >+ // add center snapline >+ snaptoy = bounds.y + bounds.height >+ + (shortestdistance / 2); >+ rows[countrows++] = new Entry(0, snaptoy, >+ new Rectangle(snaptoy, 0, snaptoy + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ } >+ } else { >+ // first is bottom >+ >+ if (!(bounds.getBottom().y - bounds2.y < bounds.height >+ + bounds2.height)) { >+ // add top snapline >+ snaptoy = bounds2.y - shortestdistance; >+ rows[countrows++] = new Entry(-1, snaptoy, >+ new Rectangle(snaptoy, 0, snaptoy + 1, 1), >+ bounds, bounds2); >+ >+ // add bottom snapline >+ snaptoy = bounds.y + bounds.height >+ + shortestdistance; >+ rows[countrows++] = new Entry(1, snaptoy, >+ new Rectangle(snaptoy, 0, snaptoy + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ >+ // add center snapline >+ snaptoy = bounds2.y + bounds2.height >+ + (shortestdistance / 2); >+ rows[countrows++] = new Entry(0, snaptoy, >+ new Rectangle(snaptoy, 0, snaptoy + 1, 1), >+ new Rectangle(bounds), new Rectangle( >+ bounds2)); >+ } >+ } >+ } >+ } >+ } >+ >+ for (int i = countcols; i < cols.length; i++) { >+ cols[i] = null; >+ } >+ for (int i = countrows; i < rows.length; i++) { >+ rows[i] = null; >+ } >+ >+ } >+ >+ /** >+ * @see SnapToHelper#snapRectangle(Request, int, PrecisionRectangle, >+ * PrecisionRectangle) >+ * @param request >+ * the snap request >+ * @param snapOrientation2 >+ * the orientation to be snapped to >+ * @param baseRect >+ * the moved Rectangle >+ * @param result >+ * the result >+ * @return the correction for snapping >+ */ >+ public int snapRectangle(Request request, int snapOrientation, >+ PrecisionRectangle baseRect, PrecisionRectangle result) { >+ >+ baseRect = baseRect.getPreciseCopy(); >+ makeRelative(container.getContentPane(), baseRect); >+ >+ PrecisionRectangle correction = new PrecisionRectangle(); >+ makeRelative(container.getContentPane(), correction); >+ >+ // not if cloning object >+ boolean isClone = request.getType().equals(RequestConstants.REQ_CLONE); >+ >+ // Recalculate snapping locations if needed >+ if (rows == null || cols == null || isClone != cachedCloneBool) { >+ // snapping lines have to be calculated >+ cachedCloneBool = isClone; >+ >+ List exclusionSet = Collections.EMPTY_LIST; >+ if (!isClone && request instanceof GroupRequest) { >+ exclusionSet = ((GroupRequest) request).getEditParts(); >+ } >+ // calculate snapping rows and cols >+ populateRowsAndCols(generateSnapPartsList(exclusionSet)); >+ } >+ >+ if ((snapOrientation & HORIZONTAL) != 0) { >+ >+ double xcorrect = getThreshold(); >+ >+ xcorrect = getCorrectionFor(cols, request.getExtendedData(), true, >+ baseRect.preciseX(), baseRect.preciseRight(), baseRect); >+ >+ if (xcorrect != getThreshold()) { >+ snapOrientation &= ~HORIZONTAL; >+ correction.setPreciseX(correction.preciseX() + xcorrect); >+ } >+ } >+ >+ if ((snapOrientation & VERTICAL) != 0) { >+ >+ double ycorrect = getThreshold(); >+ >+ ycorrect = getCorrectionFor(rows, request.getExtendedData(), false, >+ baseRect.preciseY(), baseRect.preciseBottom(), baseRect); >+ >+ if (ycorrect != getThreshold()) { >+ >+ snapOrientation &= ~VERTICAL; >+ correction.setPreciseY(correction.preciseY() + ycorrect); >+ } >+ } >+ >+ if ((snapOrientation & EAST) != 0) { >+ >+ double rightCorrection = getCorrectionFor(cols, >+ request.getExtendedData(), true, >+ baseRect.preciseRight() - 1, 1, baseRect); >+ >+ if (rightCorrection != getThreshold()) { >+ >+ snapOrientation &= ~EAST; >+ correction.setPreciseWidth(correction.preciseWidth() >+ + rightCorrection); >+ } >+ } >+ >+ if ((snapOrientation & WEST) != 0) { >+ >+ double leftCorrection = getCorrectionFor(cols, >+ request.getExtendedData(), true, baseRect.preciseX(), -1, >+ baseRect); >+ >+ if (leftCorrection != getThreshold()) { >+ >+ snapOrientation &= ~WEST; >+ correction.setPreciseWidth(correction.preciseWidth() >+ - leftCorrection); >+ correction.setPreciseX(correction.preciseX() + leftCorrection); >+ } >+ } >+ >+ if ((snapOrientation & SOUTH) != 0) { >+ >+ double bottom = getCorrectionFor(rows, request.getExtendedData(), >+ false, baseRect.preciseBottom() - 1, 1, baseRect); >+ >+ if (bottom != getThreshold()) { >+ >+ snapOrientation &= ~SOUTH; >+ correction >+ .setPreciseHeight(correction.preciseHeight() + bottom); >+ } >+ } >+ >+ if ((snapOrientation & NORTH) != 0) { >+ double topCorrection = getCorrectionFor(rows, >+ request.getExtendedData(), false, baseRect.preciseY(), -1, >+ baseRect); >+ >+ if (topCorrection != getThreshold()) { >+ >+ snapOrientation &= ~NORTH; >+ correction.setPreciseHeight(correction.preciseHeight() >+ - topCorrection); >+ correction.setPreciseY(correction.preciseY() + topCorrection); >+ } >+ } >+ >+ makeAbsolute(container.getContentPane(), correction); >+ >+ result.setPreciseX(result.preciseX() + correction.preciseX()); >+ result.setPreciseY(result.preciseY() + correction.preciseY()); >+ result.setPreciseWidth(result.preciseWidth() >+ + correction.preciseWidth()); >+ result.setPreciseHeight(result.preciseHeight() >+ + correction.preciseHeight()); >+ >+ return snapOrientation; >+ } >+ >+} >Index: src/org/eclipse/gef/editpolicies/SnapFeedbackPolicy.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/plugins/org.eclipse.gef/src/org/eclipse/gef/editpolicies/SnapFeedbackPolicy.java,v >retrieving revision 1.23 >diff -u -r1.23 SnapFeedbackPolicy.java >--- src/org/eclipse/gef/editpolicies/SnapFeedbackPolicy.java 6 Sep 2010 17:58:57 -0000 1.23 >+++ src/org/eclipse/gef/editpolicies/SnapFeedbackPolicy.java 8 Apr 2011 21:40:01 -0000 >@@ -1,5 +1,5 @@ > /******************************************************************************* >- * Copyright (c) 2003, 2010 IBM Corporation and others. >+ * Copyright (c) 2003, 2005 IBM Corporation 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 >@@ -10,22 +10,38 @@ > *******************************************************************************/ > package org.eclipse.gef.editpolicies; > >+import java.util.ArrayList; >+import java.util.Collections; >+import java.util.List; >+ > import org.eclipse.swt.graphics.Color; >+import org.eclipse.swt.graphics.Font; > import org.eclipse.swt.graphics.Image; > import org.eclipse.swt.graphics.ImageData; > import org.eclipse.swt.graphics.PaletteData; > import org.eclipse.swt.widgets.Display; > > import org.eclipse.draw2d.ColorConstants; >+import org.eclipse.draw2d.Connection; > import org.eclipse.draw2d.Figure; > import org.eclipse.draw2d.FigureUtilities; > import org.eclipse.draw2d.Graphics; > import org.eclipse.draw2d.IFigure; >+import org.eclipse.draw2d.Label; >+import org.eclipse.draw2d.MidpointLocator; >+import org.eclipse.draw2d.PolylineConnection; >+import org.eclipse.draw2d.PolylineDecoration; >+import org.eclipse.draw2d.PositionConstants; >+import org.eclipse.draw2d.RectangleFigure; >+import org.eclipse.draw2d.XYAnchor; >+import org.eclipse.draw2d.geometry.Point; >+import org.eclipse.draw2d.geometry.PointList; > import org.eclipse.draw2d.geometry.PrecisionPoint; > import org.eclipse.draw2d.geometry.Rectangle; > > import org.eclipse.gef.GraphicalEditPart; > import org.eclipse.gef.Request; >+import org.eclipse.gef.SnapToDistance; > import org.eclipse.gef.SnapToGeometry; > import org.eclipse.gef.SnapToGuides; > >@@ -39,8 +55,8 @@ > */ > public class SnapFeedbackPolicy extends GraphicalEditPolicy { > >- IFigure guide[] = new IFigure[6]; >- Integer location[] = new Integer[6]; >+ IFigure guide[] = new IFigure[20]; >+ Integer location[] = new Integer[20]; > > /** > * @see org.eclipse.gef.EditPolicy#eraseTargetFeedback(org.eclipse.gef.Request) >@@ -65,9 +81,12 @@ > super.setOpaque(true); > } > >- private Color createMixedColor() { >+ /** >+ * @see org.eclipse.draw2d.IFigure#getLocalBackgroundColor() >+ */ >+ public Color getLocalBackgroundColor() { > return FigureUtilities >- .mixColors(getLocalBackgroundColor(), getParent() >+ .mixColors(super.getLocalBackgroundColor(), getParent() > .getBackgroundColor(), (double) opacity / FRAMES); > } > >@@ -84,10 +103,8 @@ > if (opacity != FRAMES - 1) { > Display display = Display.getCurrent(); > PaletteData pData = new PaletteData(0xFF, 0xFF00, 0xFF0000); >- Color localBackgroundColor = createMixedColor(); >- int fillColor = pData.getPixel(localBackgroundColor >+ int fillColor = pData.getPixel(getLocalBackgroundColor() > .getRGB()); >- localBackgroundColor.dispose(); > ImageData iData = new ImageData(1, 1, 24, pData); > iData.setPixel(0, 0, fillColor); > iData.setAlpha(0, 0, 255 * opacity / FRAMES); >@@ -102,10 +119,10 @@ > }); > } > Rectangle r = getBounds(); >- if (image != null) >+ if (image != null) { > graphics.drawImage(image, 0, 0, 1, 1, r.x, r.y, r.width, > r.height); >- else >+ } else > super.paintFigure(graphics); > } > >@@ -121,62 +138,581 @@ > } > } > >- // Even offset indicates a vertical feedback line; odd, horizontal. >+ // Even offset indicates a vertical feedback line; odd, >+ // horizontal. > void highlightGuide(Integer pos, Color color, int offset) { >- if (pos == null) { >- if (guide[offset] != null) { >- removeFeedback(guide[offset]); >- guide[offset] = null; >- } >- location[offset] = pos; >- return; >- } >- >- // pos is an integer relative to target's client area. >- // translate pos to absolute, and then make it relative to fig. >- int position = pos.intValue(); >- PrecisionPoint loc = new PrecisionPoint(position, position); >- IFigure contentPane = ((GraphicalEditPart) getHost()).getContentPane(); >- contentPane.translateToParent(loc); >- contentPane.translateToAbsolute(loc); >- >- if (location[offset] == null || !location[offset].equals(pos)) { >- location[offset] = pos; >- if (guide[offset] != null) { >- removeFeedback(guide[offset]); >- guide[offset] = null; >- } >- >- IFigure fig = new FadeIn(color); >- guide[offset] = fig; >- addFeedback(fig); >- fig.translateToRelative(loc); >- position = offset % 2 == 0 ? (int) Math.round(loc.preciseX()) >- : (int) Math.round(loc.preciseY()); >- Rectangle figBounds = getFeedbackLayer().getBounds().getCopy(); >- if ((offset % 2) == 1) { >- figBounds.height = 1; >- figBounds.y = position; >+ >+ try { >+ >+ if (pos == null) { >+ if (guide[offset] != null) { >+ removeFeedback(guide[offset]); >+ guide[offset] = null; >+ } >+ location[offset] = pos; >+ return; >+ } >+ >+ // pos is an integer relative to target's client area. >+ // translate pos to absolute, and then make it relative to >+ // fig. >+ int position = pos.intValue(); >+ PrecisionPoint loc = new PrecisionPoint(position, position); >+ IFigure contentPane = ((GraphicalEditPart) getHost()) >+ .getContentPane(); >+ contentPane.translateToParent(loc); >+ contentPane.translateToAbsolute(loc); >+ >+ if (location[offset] == null || !location[offset].equals(pos)) { >+ location[offset] = pos; >+ if (guide[offset] != null) { >+ removeFeedback(guide[offset]); >+ guide[offset] = null; >+ } >+ >+ IFigure fig = new FadeIn(color); >+ guide[offset] = fig; >+ addFeedback(fig); >+ fig.translateToRelative(loc); >+ position = offset % 2 == 0 ? (int) Math.round(loc.preciseX()) >+ : (int) Math.round(loc.preciseY()); >+ Rectangle figBounds = getFeedbackLayer().getBounds().getCopy(); >+ if ((offset % 2) == 1) { >+ figBounds.height = 1; >+ figBounds.y = position; >+ } else { >+ figBounds.x = position; >+ figBounds.width = 1; >+ } >+ fig.setBounds(figBounds); >+ } else { >+ // The feedback layer could have grown (if >+ // auto-scrolling), so resize the fade-in >+ // line. >+ IFigure fig = guide[offset]; >+ Rectangle figBounds = fig.getBounds().getCopy(); >+ Rectangle feedbackBounds = getFeedbackLayer().getBounds(); >+ if ((offset % 2) == 1) { >+ figBounds.x = feedbackBounds.x; >+ figBounds.width = feedbackBounds.width; >+ } else { >+ figBounds.y = feedbackBounds.y; >+ figBounds.height = feedbackBounds.height; >+ } >+ fig.setBounds(figBounds); >+ } >+ >+ } catch (Exception e) { >+ System.err.println(e); >+ System.err.println(e.getStackTrace().toString()); >+ } >+ } >+ >+ static class ComplexFadeIn extends Figure { >+ int opacity = 0; >+ static final int FRAMES = 6; >+ Image image; >+ static int count; >+ RectangleFigure firstBoundsLine; >+ RectangleFigure secondBoundsLine; >+ Label text; >+ XYAnchor sourceAnchor = new XYAnchor(new Point(0, 0)); >+ XYAnchor targetAnchor = new XYAnchor(new Point(0, 0)); >+ MidpointLocator captionLocator; >+ PolylineDecoration decoration, decoration2; >+ final int TEXTGUIDEOVERHANG = 20; >+ >+ Connection arrow; >+ PolylineConnection c1; >+ >+ int orientation; >+ int firstStart; >+ int secondStart; >+ >+ // orientation: 0 = horizontal, 1 = vertical >+ ComplexFadeIn(Color bg, int orientation, int size) { >+ >+ firstBoundsLine = new RectangleFigure(); >+ firstBoundsLine.setBackgroundColor(bg); >+ secondBoundsLine = new RectangleFigure(); >+ secondBoundsLine.setBackgroundColor(bg); >+ firstBoundsLine.setForegroundColor(ColorConstants.darkGreen); >+ secondBoundsLine.setForegroundColor(ColorConstants.darkGreen); >+ >+ text = new Label("px"); >+ text.setForegroundColor(ColorConstants.darkGreen); >+ text.setBackgroundColor(ColorConstants.white); >+ text.setOpaque(true); >+ text.setVisible(true); >+ text.setLabelAlignment(PositionConstants.CENTER); >+ >+ text.setFont(new Font(Display.getCurrent(), "Serif", 8, 0)); >+ >+ c1 = new PolylineConnection(); >+ >+ c1.setForegroundColor(ColorConstants.darkGreen); >+ >+ c1.setSourceAnchor(sourceAnchor); >+ c1.setTargetAnchor(targetAnchor); >+ >+ decoration = new PolylineDecoration(); >+ PointList decorationPointList = new PointList(); >+ decorationPointList.addPoint(-1, 1); >+ decorationPointList.addPoint(0, 0); >+ decorationPointList.addPoint(-1, -1); >+ decoration.setTemplate(decorationPointList); >+ >+ c1.setSourceDecoration(decoration); >+ >+ decoration2 = new PolylineDecoration(); >+ PointList decorationPointList2 = new PointList(); >+ decorationPointList2.addPoint(-1, 1); >+ decorationPointList2.addPoint(0, 0); >+ decorationPointList2.addPoint(-1, -1); >+ decoration2.setTemplate(decorationPointList2); >+ c1.setTargetDecoration(decoration2); >+ >+ captionLocator = new MidpointLocator(c1, 0); >+ >+ c1.add(text, captionLocator); >+ >+ this.add(c1); >+ this.add(firstBoundsLine); >+ this.add(secondBoundsLine); >+ this.orientation = orientation; >+ >+ if (orientation == 1) { >+ // horizontal guide >+ firstBoundsLine.setSize(this.getBounds().width, 1); >+ secondBoundsLine.setSize(this.getBounds().width, 1); >+ >+ firstBoundsLine.setLocation(new Point(0, 0)); >+ secondBoundsLine.setLocation(new Point(0, >+ this.getBounds().height - 1)); > } else { >- figBounds.x = position; >- figBounds.width = 1; >+ // vertical guide >+ firstBoundsLine.setSize(1, this.getBounds().height); >+ secondBoundsLine.setSize(1, this.getBounds().height); >+ firstBoundsLine.setLocation(new Point(0, 0)); >+ secondBoundsLine.setLocation(new Point( >+ this.getBounds().width - 1, 0)); >+ } >+ setBackgroundColor(ColorConstants.green); >+ super.setOpaque(true); >+ >+ this.setBounds(getBounds()); >+ } >+ >+ /** >+ * @see org.eclipse.draw2d.IFigure#getLocalBackgroundColor() >+ */ >+ public Color getLocalBackgroundColor() { >+ return FigureUtilities >+ .mixColors(super.getLocalBackgroundColor(), getParent() >+ .getBackgroundColor(), (double) opacity / FRAMES); >+ } >+ >+ /** >+ * @see org.eclipse.draw2d.Figure#paintFigure(org.eclipse.draw2d.Graphics) >+ */ >+ protected void paintFigure(Graphics graphics) { >+ >+ if (opacity != FRAMES) { >+ if (image != null) { >+ image.dispose(); >+ count--; >+ image = null; >+ } >+ if (opacity != FRAMES - 1) { >+ Display display = Display.getCurrent(); >+ PaletteData pData = new PaletteData(0xFF, 0xFF00, 0xFF0000); >+ int fillColor = pData.getPixel(getLocalBackgroundColor() >+ .getRGB()); >+ ImageData iData = new ImageData(1, 1, 24, pData); >+ iData.setPixel(0, 0, fillColor); >+ iData.setAlpha(0, 0, 255 * opacity / FRAMES); >+ image = new Image(display, iData); >+ count++; >+ } >+ >+ } >+ Rectangle r = getBounds(); >+ >+ if (image != null) { >+ graphics.drawImage(image, 0, 0, 1, 1, r.x, r.y, r.width, >+ r.height); >+ } else >+ super.paintFigure(graphics); >+ } >+ >+ /** >+ * @see org.eclipse.draw2d.Figure#removeNotify() >+ */ >+ public void removeNotify() { >+ if (image != null) { >+ image.dispose(); >+ count--; >+ image = null; >+ } >+ } >+ >+ public void setLineBounds(int firstStart, int secondStart) { >+ this.firstStart = firstStart; >+ this.secondStart = secondStart; >+ } >+ >+ public void setBounds(Rectangle b) { >+ if (!(b.height < 0 || b.width < 0 || b.x < 0 || b.y < 0)) { >+ Point offset = this.getLocation(); >+ >+ super.setBounds(b); >+ >+ int delta = 0; >+ >+ if (orientation == 1) { >+ // horizontal snapline >+ firstBoundsLine.setSize(this.getBounds().getRight().x >+ - firstStart, 1); >+ secondBoundsLine.setSize(this.getBounds().getRight().x >+ - secondStart, 1); >+ firstBoundsLine >+ .setLocation(new Point(firstStart, offset.y)); >+ secondBoundsLine.setLocation(new Point(secondStart, >+ offset.y + this.getBounds().height - 1)); >+ text.setText(Math.abs(this.firstBoundsLine.getBounds().x >+ - this.secondBoundsLine.getBounds().x) >+ + "px"); >+ >+ delta = Math.abs(this.firstBoundsLine.getBounds().y >+ - this.secondBoundsLine.getBounds().y); >+ >+ sourceAnchor.setLocation(new Point(firstBoundsLine >+ .getBounds().getRight().x - TEXTGUIDEOVERHANG / 2, >+ firstBoundsLine.getBounds().y)); >+ >+ targetAnchor.setLocation(new Point(secondBoundsLine >+ .getBounds().getRight().x - TEXTGUIDEOVERHANG / 2, >+ secondBoundsLine.getBounds().y)); >+ >+ } else { >+ firstBoundsLine.setSize(1, this.getBounds().getBottom().y >+ - firstStart); >+ secondBoundsLine.setSize(1, this.getBounds().getBottom().y >+ - secondStart); >+ firstBoundsLine >+ .setLocation(new Point(offset.x, firstStart)); >+ secondBoundsLine.setLocation(new Point(offset.x >+ + this.getBounds().width - 1, secondStart)); >+ text.setText(Math.abs(this.firstBoundsLine.getBounds().y >+ - this.secondBoundsLine.getBounds().y) >+ + "px"); >+ >+ delta = Math.abs(this.firstBoundsLine.getBounds().x >+ - this.secondBoundsLine.getBounds().x); >+ >+ sourceAnchor.setLocation(new Point(firstBoundsLine >+ .getBounds().x, firstBoundsLine.getBounds() >+ .getBottom().y - TEXTGUIDEOVERHANG / 2)); >+ targetAnchor.setLocation(new Point(secondBoundsLine >+ .getBounds().x, secondBoundsLine.getBounds() >+ .getBottom().y - TEXTGUIDEOVERHANG / 2)); >+ >+ } >+ >+ text.setText(delta + "px"); >+ text.setSize(text.getPreferredSize()); >+ >+ if ((orientation == 1 && delta < 2 * text.getPreferredSize().height) >+ || (orientation == 0 && delta < 2 * text >+ .getPreferredSize().width)) { >+ text.setText(""); >+ c1.setSourceDecoration(null); >+ c1.setTargetDecoration(null); >+ } else { >+ text.setText(delta + "px"); >+ c1.setSourceDecoration(decoration); >+ c1.setTargetDecoration(decoration2); >+ >+ } >+ >+ text.setSize(text.getPreferredSize()); >+ >+ this.repaint(); >+ } >+ } >+ } >+ >+ // Even offset indicates a vertical feedback line; odd, >+ // horizontal. >+ void complexHighlightGuide(Integer pos, Color color, int offset, >+ Rectangle movedObject, Rectangle first, Rectangle second) { >+ >+ try { >+ >+ if (pos == null) { >+ if (guide[offset] != null) { >+ removeFeedback(guide[offset]); >+ guide[offset] = null; >+ } >+ if (guide[offset + 10] != null) { >+ removeFeedback(guide[offset + 10]); >+ guide[offset + 10] = null; >+ } >+ location[offset] = pos; >+ >+ return; >+ } >+ >+ // pos is an integer relative to target's client area. >+ // translate pos to absolute, and then make it relative to >+ // fig. >+ int position = pos.intValue(); >+ PrecisionPoint loc = new PrecisionPoint(position, position); >+ IFigure contentPane = ((GraphicalEditPart) getHost()) >+ .getContentPane(); >+ contentPane.translateToParent(loc); >+ contentPane.translateToAbsolute(loc); >+ >+ if (location[offset] == null || !location[offset].equals(pos)) { >+ location[offset] = pos; >+ if (guide[offset] != null) { >+ removeFeedback(guide[offset]); >+ removeFeedback(guide[offset + 10]); >+ guide[offset] = null; >+ guide[offset + 10] = null; >+ } >+ >+ IFigure fig = new ComplexFadeIn(color, offset % 2, 50); >+ guide[offset] = fig; >+ IFigure fig2 = new ComplexFadeIn(color, offset % 2, 50); >+ guide[offset + 10] = fig2; >+ >+ addFeedback(fig); >+ addFeedback(fig2); >+ >+ fig.translateToRelative(loc); >+ fig2.translateToRelative(loc); >+ >+ position = offset % 2 == 0 ? (int) Math.round(loc.preciseX()) >+ : (int) Math.round(loc.preciseY()); >+ > } >- fig.setBounds(figBounds); >- } else { >- // The feedback layer could have grown (if auto-scrolling), so >- // resize the fade-in >- // line. >- IFigure fig = guide[offset]; >- Rectangle figBounds = fig.getBounds().getCopy(); >- Rectangle feedbackBounds = getFeedbackLayer().getBounds(); >+ >+ // relative to movedObject >+ Rectangle nearObject; >+ Rectangle farObject; >+ >+ Rectangle feedbackBoxNear = guide[offset].getBounds().getCopy(); >+ Rectangle feedbackBoxFar = guide[offset + 10].getBounds().getCopy(); >+ ComplexFadeIn feedbackGuideNear = (ComplexFadeIn) guide[offset]; >+ ComplexFadeIn feedbackGuideFar = (ComplexFadeIn) guide[offset + 10]; >+ > if ((offset % 2) == 1) { >- figBounds.x = feedbackBounds.x; >- figBounds.width = feedbackBounds.width; >+ // horizontal line >+ >+ // calculate which object is near and which is far >+ int distanceFirstToMoved = Math.abs(first.y - movedObject.y); >+ int distanceSecondToMoved = Math.abs(second.y - movedObject.y); >+ >+ if (distanceFirstToMoved < distanceSecondToMoved) { >+ nearObject = first; >+ farObject = second; >+ } else { >+ nearObject = second; >+ farObject = first; >+ } >+ >+ int upmostBorder; >+ int lowestBorder; >+ >+ List list = new ArrayList(); >+ >+ list.add(new Integer(movedObject.getRight().x)); >+ list.add(new Integer(nearObject.getRight().x)); >+ list.add(new Integer(farObject.getRight().x)); >+ >+ upmostBorder = ((Integer) Collections.min(list)).intValue(); >+ lowestBorder = ((Integer) Collections.max(list)).intValue(); >+ >+ feedbackBoxNear.width = feedbackBoxFar.width = lowestBorder >+ - upmostBorder + 20; >+ feedbackBoxNear.x = feedbackBoxFar.x = upmostBorder; >+ >+ if (nearObject.y < movedObject.y && farObject.y < movedObject.y) { >+ // moved is below of both objects >+ >+ feedbackBoxNear.height = pos.intValue() >+ - nearObject.getBottom().y; >+ feedbackBoxFar.height = feedbackBoxNear.height; >+ >+ feedbackBoxNear.y = nearObject.getBottom().y; >+ feedbackBoxFar.y = farObject.getBottom().y; >+ >+ feedbackGuideNear.setLineBounds(nearObject.getRight().x, >+ movedObject.getRight().x); >+ feedbackGuideFar.setLineBounds(farObject.getRight().x, >+ nearObject.getRight().x); >+ >+ } else if (nearObject.y > movedObject.y >+ && farObject.y > movedObject.y) { >+ // moved is above of both objects >+ >+ feedbackBoxNear.height = nearObject.y - (pos.intValue()); >+ feedbackBoxFar.height = feedbackBoxNear.height; >+ >+ feedbackBoxNear.y = pos.intValue(); >+ feedbackBoxFar.y = nearObject.y + nearObject.height; >+ >+ feedbackGuideNear.setLineBounds(movedObject.getRight().x, >+ nearObject.getRight().x); >+ feedbackGuideFar.setLineBounds(nearObject.x >+ + nearObject.width, farObject.getRight().x); >+ >+ } else { >+ >+ if (nearObject.y < movedObject.y) { >+ feedbackBoxNear.height = (pos.intValue() - movedObject.height / 2) >+ - nearObject.getBottom().y; >+ >+ feedbackBoxFar.height = feedbackBoxNear.height; >+ >+ // near is left box >+ feedbackBoxNear.y = nearObject.getBottom().y; >+ feedbackBoxFar.y = pos.intValue() + movedObject.height >+ / 2; >+ feedbackGuideNear.setLineBounds( >+ nearObject.getRight().x, >+ movedObject.getRight().x); >+ feedbackGuideFar.setLineBounds( >+ movedObject.getRight().x, >+ farObject.getRight().x); >+ >+ } else { >+ >+ feedbackBoxNear.height = (pos.intValue() - movedObject.height / 2) >+ - farObject.getBottom().y; >+ >+ feedbackBoxFar.height = feedbackBoxNear.height; >+ >+ feedbackBoxNear.y = pos.intValue() + movedObject.height >+ / 2; >+ feedbackBoxFar.y = farObject.getBottom().y; >+ feedbackGuideFar.setLineBounds(farObject.getRight().x, >+ movedObject.getRight().x); >+ feedbackGuideNear.setLineBounds( >+ movedObject.getRight().x, >+ nearObject.getRight().x); >+ >+ } >+ >+ } >+ > } else { >- figBounds.y = feedbackBounds.y; >- figBounds.height = feedbackBounds.height; >+ // vertical line >+ >+ // calculate which object is near and which is far >+ int distanceFirstToMoved = Math.abs(first.x - movedObject.x); >+ int distanceSecondToMoved = Math.abs(second.x - movedObject.x); >+ >+ if (distanceFirstToMoved < distanceSecondToMoved) { >+ nearObject = first; >+ farObject = second; >+ } else { >+ nearObject = second; >+ farObject = first; >+ } >+ >+ int upmostBorder; >+ int lowestBorder; >+ >+ List list = new ArrayList(); >+ >+ list.add(new Integer(movedObject.getBottom().y)); >+ list.add(new Integer(nearObject.getBottom().y)); >+ list.add(new Integer(farObject.getBottom().y)); >+ >+ upmostBorder = ((Integer) Collections.min(list)).intValue(); >+ lowestBorder = ((Integer) Collections.max(list)).intValue(); >+ >+ feedbackBoxNear.height = feedbackBoxFar.height = lowestBorder >+ - upmostBorder + 20; >+ feedbackBoxNear.y = feedbackBoxFar.y = upmostBorder; >+ >+ if (nearObject.x < movedObject.x && farObject.x < movedObject.x) { >+ // moved is right of both objects >+ >+ feedbackBoxNear.width = pos.intValue() >+ - nearObject.getRight().x; >+ feedbackBoxFar.width = feedbackBoxNear.width; >+ >+ feedbackBoxNear.x = nearObject.getRight().x; >+ feedbackBoxFar.x = farObject.getRight().x; >+ >+ feedbackGuideNear.setLineBounds(nearObject.getBottom().y, >+ movedObject.getBottom().y); >+ feedbackGuideFar.setLineBounds(farObject.getBottom().y, >+ nearObject.getBottom().y); >+ >+ } else if (nearObject.x > movedObject.x >+ && farObject.x > movedObject.x) { >+ // moved is left of both objects >+ >+ feedbackBoxNear.width = nearObject.x - (pos.intValue()); >+ feedbackBoxFar.width = feedbackBoxNear.width; >+ >+ feedbackBoxNear.x = pos.intValue(); >+ feedbackBoxFar.x = nearObject.x + nearObject.width; >+ >+ feedbackGuideNear.setLineBounds(movedObject.getBottom().y, >+ nearObject.getBottom().y); >+ feedbackGuideFar.setLineBounds(nearObject.y >+ + nearObject.height, farObject.getBottom().y); >+ >+ } else { >+ >+ if (nearObject.x < movedObject.x) { >+ feedbackBoxNear.width = (pos.intValue() - movedObject.width / 2) >+ - nearObject.getRight().x; >+ >+ feedbackBoxFar.width = feedbackBoxNear.width; >+ >+ // near is left box >+ feedbackBoxNear.x = nearObject.getRight().x; >+ feedbackBoxFar.x = pos.intValue() + movedObject.width >+ / 2; >+ feedbackGuideNear.setLineBounds( >+ nearObject.getBottom().y, >+ movedObject.getBottom().y); >+ feedbackGuideFar.setLineBounds( >+ movedObject.getBottom().y, >+ farObject.getBottom().y); >+ >+ } else { >+ >+ feedbackBoxNear.width = (pos.intValue() - movedObject.width / 2) >+ - farObject.getRight().x; >+ >+ feedbackBoxFar.width = feedbackBoxNear.width; >+ >+ feedbackBoxNear.x = pos.intValue() + movedObject.width >+ / 2; >+ feedbackBoxFar.x = farObject.getRight().x; >+ feedbackGuideFar.setLineBounds(farObject.getBottom().y, >+ movedObject.getBottom().y); >+ feedbackGuideNear.setLineBounds( >+ movedObject.getBottom().y, >+ nearObject.getBottom().y); >+ >+ } >+ >+ } >+ > } >- fig.setBounds(figBounds); >+ guide[offset].setBounds(feedbackBoxNear); >+ guide[offset + 10].setBounds(feedbackBoxFar); >+ >+ } catch (Exception e) { >+ System.err.println(e); > } > } > >@@ -213,7 +749,41 @@ > value = (Integer) req.getExtendedData().get( > SnapToGuides.KEY_HORIZONTAL_GUIDE); > highlightGuide(value, ColorConstants.red, 5); >+ >+ Rectangle firstvertical = (Rectangle) req.getExtendedData().get( >+ SnapToDistance.KEY_VERTICAL_FIRST_OBJECT_BOUNDS); >+ Rectangle secondvertical = (Rectangle) req.getExtendedData().get( >+ SnapToDistance.KEY_VERTICAL_SECOND_OBJECT_BOUNDS); >+ Rectangle firsthorizontal = (Rectangle) req.getExtendedData().get( >+ SnapToDistance.KEY_HORIZONTAL_FIRST_OBJECT_BOUNDS); >+ Rectangle secondhorizontal = (Rectangle) req.getExtendedData().get( >+ SnapToDistance.KEY_HORIZONTAL_SECOND_OBJECT_BOUNDS); >+ >+ Rectangle moved = (Rectangle) req.getExtendedData().get( >+ SnapToDistance.KEY_MOVED_OBJECT_BOUNDS); >+ >+ // new for Snap to Distance >+ value = (Integer) req.getExtendedData().get( >+ SnapToDistance.KEY_WEST_ANCHOR); >+ complexHighlightGuide(value, ColorConstants.green, 6, moved, >+ firstvertical, secondvertical); >+ >+ value = (Integer) req.getExtendedData().get( >+ SnapToDistance.KEY_NORTH_ANCHOR); >+ complexHighlightGuide(value, ColorConstants.green, 7, moved, >+ firsthorizontal, secondhorizontal); >+ >+ value = (Integer) req.getExtendedData().get( >+ SnapToDistance.KEY_EAST_ANCHOR); >+ complexHighlightGuide(value, ColorConstants.green, 8, moved, >+ firstvertical, secondvertical); >+ >+ value = (Integer) req.getExtendedData().get( >+ SnapToDistance.KEY_SOUTH_ANCHOR); >+ complexHighlightGuide(value, ColorConstants.green, 9, moved, >+ firsthorizontal, secondhorizontal); >+ > } > } > >-} >\ No newline at end of file >+} >#P org.eclipse.gef.examples.logic >Index: src/org/eclipse/gef/examples/logicdesigner/edit/LogicDiagramEditPart.java >=================================================================== >RCS file: /cvsroot/tools/org.eclipse.gef/examples/org.eclipse.gef.examples.logic/src/org/eclipse/gef/examples/logicdesigner/edit/LogicDiagramEditPart.java,v >retrieving revision 1.31 >diff -u -r1.31 LogicDiagramEditPart.java >--- src/org/eclipse/gef/examples/logicdesigner/edit/LogicDiagramEditPart.java 19 May 2010 20:27:48 -0000 1.31 >+++ src/org/eclipse/gef/examples/logicdesigner/edit/LogicDiagramEditPart.java 8 Apr 2011 21:40:04 -0000 >@@ -39,6 +39,7 @@ > import org.eclipse.gef.EditPolicy; > import org.eclipse.gef.LayerConstants; > import org.eclipse.gef.Request; >+import org.eclipse.gef.SnapToDistance; > import org.eclipse.gef.SnapToGeometry; > import org.eclipse.gef.SnapToGrid; > import org.eclipse.gef.SnapToGuides; >@@ -111,8 +112,10 @@ > snapStrategies.add(new SnapToGuides(this)); > val = (Boolean) getViewer().getProperty( > SnapToGeometry.PROPERTY_SNAP_ENABLED); >- if (val != null && val.booleanValue()) >+ if (val != null && val.booleanValue()) { > snapStrategies.add(new SnapToGeometry(this)); >+ snapStrategies.add(new SnapToDistance(this)); >+ } > val = (Boolean) getViewer().getProperty( > SnapToGrid.PROPERTY_GRID_ENABLED); > if (val != null && val.booleanValue())
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 218170
:
89133
|
89136
| 192882