Changeset 8385


Ignore:
Timestamp:
Sep 25, 2019, 11:05:05 PM (2 years ago)
Author:
Sven Rech
Message:

WorkspaceManager: Improved adjustment of manually modified connection lines. Moving several connected plugins at once no moves the overall line construct (if possible).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/CrypPlugins/WorkspaceManager/View/VisualComponents/CryptoLineView/CryptoLineView.xaml.cs

    r8365 r8385  
    871871        /// Adjusts only start and end points of an already existing path which was modified manually.
    872872        /// </summary>
    873         /// <param name="points">The points of the old line.</param>
     873        /// <param name="segments">The segments of the old line.</param>
    874874        /// <param name="newStartPoint">The new start point to adjust to.</param>
    875875        /// <param name="newEndPoint">The new end point to adjust to.</param>
    876876        /// <returns>Whether adjustment was possible.</returns>
    877         private static bool AdjustManuallyModifiedLine(IEnumerable<FromTo> points, Point newStartPoint, Point newEndPoint)
    878         {
    879             //Zip point lists to create adjacent points:
    880             var adjacentPoints = points.Zip(points.Skip(1), (a, b) => (First: a, Second: b));
    881             //Get start point and its neighbor:
    882             var (startPoint, startPointNeighbor) = adjacentPoints.SingleOrDefault(
     877        private static bool AdjustManuallyModifiedLine(IEnumerable<FromTo> segments, Point newStartPoint, Point newEndPoint)
     878        {
     879            //Zip segment lists to create adjacent segments:
     880            var adjacentSegments = segments.Zip(segments.Skip(1), (a, b) => (First: a, Second: b));
     881            //Get start segment and its neighbor:
     882            var (startSeg, startSegNeighbor) = adjacentSegments.SingleOrDefault(
    883883                pair => pair.First.MetaData == FromToMeta.HasStartPoint || pair.First.MetaData == FromToMeta.HasEndStartPoint);
    884             //Get end point and its neighbor:
    885             var (endPointNeighbor, endPoint) = adjacentPoints.SingleOrDefault(
     884            //Get end segment and its neighbor:
     885            var (endSegNeighbor, endSeg) = adjacentSegments.SingleOrDefault(
    886886                pair => pair.Second.MetaData == FromToMeta.HasEndpoint || pair.Second.MetaData == FromToMeta.HasEndStartPoint);
    887887
    888             if (startPoint == null || startPointNeighbor == null || endPoint == null || endPointNeighbor == null)
     888            if (startSeg == null || startSegNeighbor == null || endSeg == null || endSegNeighbor == null)
    889889            {
    890890                return false;
    891891            }
    892892
    893             if (startPoint.IsXDir == startPointNeighbor.IsXDir || endPoint.IsXDir == endPointNeighbor.IsXDir)
    894             {
    895                 //start and end points need to have different directions in relation to their neighbors for the adjustment to work.
     893            if (startSeg.IsXDir == startSegNeighbor.IsXDir || endSeg.IsXDir == endSegNeighbor.IsXDir)
     894            {
     895                //start and end segments need to have different directions in relation to their neighbors for the adjustment to work.
    896896                return false;
    897897            }
    898898
    899             //Adjust start point (and neighbor):
    900             if (newStartPoint != startPoint.From)
    901             {
    902                 var startDiff = Point.Subtract(newStartPoint, startPoint.From);
    903                 var startAdj = startPoint.IsXDir ? new Vector(0, startDiff.Y) : new Vector(startDiff.X, 0);
    904                 startPoint.From = newStartPoint;
    905                 startPoint.To = Point.Add(startPoint.To, startAdj);
    906                 startPointNeighbor.From = startPoint.To;
    907             }
    908 
    909             //Adjust end point (and neighbor):
    910             if (newEndPoint != endPoint.To)
    911             {
    912                 var endDiff = Point.Subtract(newEndPoint, endPoint.To);
    913                 var endAdj = endPoint.IsXDir ? new Vector(0, endDiff.Y) : new Vector(endDiff.X, 0);
    914                 endPoint.To = newEndPoint;
    915                 endPoint.From = Point.Add(endPoint.From, endAdj);
    916                 endPointNeighbor.To = endPoint.From;
     899            var initialStartDir = startSeg.DirSort;
     900            var initialEndDir = endSeg.DirSort;
     901
     902            //If both start segment and end segment are new, try to translate overall line construct accordingly:
     903            if ((newStartPoint != startSeg.From) && (newEndPoint != endSeg.To))
     904            {
     905                var startDiff = Point.Subtract(newStartPoint, startSeg.From);
     906                var endDiff = Point.Subtract(newEndPoint, endSeg.To);
     907
     908                double getNearerToZero(double val1, double val2) => Math.Abs(val1) < Math.Abs(val2) ? val1 : val2;
     909                bool hasSameSign(double val1, double val2) => Math.Sign(val1) * Math.Sign(val2) >= 0;
     910                double getTotalTransVal(double val1, double val2) => hasSameSign(val1, val2) ? getNearerToZero(val1, val2) : 0;
     911                Vector getTotalTransVector(Vector v1, Vector v2) => new Vector(getTotalTransVal(v1.X, v2.X), getTotalTransVal(v1.Y, v2.Y));
     912
     913                var totalTrans = getTotalTransVector(startDiff, endDiff);
     914                foreach (var seg in segments)
     915                {
     916                    seg.From = Point.Add(seg.From, totalTrans);
     917                    seg.To = Point.Add(seg.To, totalTrans);
     918                }
     919            }
     920
     921            //Adjust start segment (and neighbor):
     922            if (newStartPoint != startSeg.From)
     923            {
     924                var startDiff = Point.Subtract(newStartPoint, startSeg.From);
     925                var startAdj = startSeg.IsXDir ? new Vector(0, startDiff.Y) : new Vector(startDiff.X, 0);
     926                startSeg.From = newStartPoint;
     927                startSeg.To = Point.Add(startSeg.To, startAdj);
     928                startSegNeighbor.From = startSeg.To;
     929            }
     930
     931            //Adjust end segment (and neighbor):
     932            if (newEndPoint != endSeg.To)
     933            {
     934                var endDiff = Point.Subtract(newEndPoint, endSeg.To);
     935                var endAdj = endSeg.IsXDir ? new Vector(0, endDiff.Y) : new Vector(endDiff.X, 0);
     936                endSeg.To = newEndPoint;
     937                endSeg.From = Point.Add(endSeg.From, endAdj);
     938                endSegNeighbor.To = endSeg.From;
     939            }
     940
     941            if (initialStartDir != startSeg.DirSort || initialEndDir != endSeg.DirSort)
     942            {
     943                //If initial directions of start or end segments differ from directions after adjustment,
     944                //the adjustment is potentially more confusing than helpful.
     945                //Therefore, do not use it:
     946                return false;
    917947            }
    918948
Note: See TracChangeset for help on using the changeset viewer.