source: trunk/CrypPlugins/WorkspaceManager/View/VisualComponents/CryptoLineView/CryptoLineView.cs @ 2383

Last change on this file since 2383 was 2383, checked in by matkovic, 11 years ago

-fixed a Line issue
-Path finding only at "Mouse-Drop"

File size: 33.2 KB
Line 
1using System;
2using System.ComponentModel;
3using System.Windows;
4using System.Windows.Media;
5using System.Windows.Input;
6using System.Windows.Controls;
7using System.Windows.Shapes;
8using System.Reflection;
9using System.Windows.Threading;
10using WorkspaceManager.View.Interface;
11using WorkspaceManager.Model;
12using System.Windows.Documents;
13using System.Collections.Generic;
14using System.Threading;
15using WorkspaceManager.View.Container;
16using System.Collections;
17using WorkspaceManager.View.VisualComponents.StackFrameDijkstra;
18using System.Windows.Data;
19
20namespace WorkspaceManager.View.VisualComponents
21{
22        public sealed class CryptoLineView : Shape, IConnection, IUpdateableView
23    {
24        #region Variables
25
26        public static readonly DependencyProperty IsDraggingDependencyProperty = DependencyProperty.Register("IsDragging", typeof(bool), typeof(CryptoLineView), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure, new PropertyChangedCallback(OnDraggingPropertyChanged)));
27
28        [TypeConverter(typeof(bool))]
29        public bool IsDragging
30        {
31            get { return (bool)base.GetValue(IsDraggingDependencyProperty); }
32            set
33            {
34                base.SetValue(IsDraggingDependencyProperty, value);
35            }
36        }
37
38        private static void OnDraggingPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
39        {
40            CryptoLineView line = (CryptoLineView)d;
41            Panel p = (line.Parent as Panel);
42            if (p == null)
43                return;
44            foreach (UIElement shape in p.Children)
45            {
46                if (shape is CryptoLineView)
47                    shape.InvalidateVisual();
48            }
49        }
50
51        private IntersectPoint intersectPoint;
52        private List<FromTo> pointList = new List<FromTo>();
53        public HashSet<CryptoLineView> UpdateList = new HashSet<CryptoLineView>();
54
55        private ConnectionModel model;
56        public ConnectionModel Model
57        {
58            get { return model; }
59            private set { model = value; }
60        }
61        private static double offset = 6;
62
63        #endregion
64
65        #region Dependency Properties
66
67        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register("StartPoint", typeof(Point), typeof(CryptoLineView), new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
68        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register("EndPoint", typeof(Point), typeof(CryptoLineView), new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
69        private ConnectionModel connectionModel;
70        //private ConnectorView source;
71        //private ConnectorView target;
72
73                #endregion
74
75                #region CLR Properties
76
77        public Point StartPoint
78        {
79            get { return (Point)GetValue(StartPointProperty); }
80            set 
81            {
82                SetValue(StartPointProperty, value);
83            }
84        }
85
86        public Point EndPoint
87        {
88            get { return (Point)GetValue(EndPointProperty); }
89            set 
90            {
91                SetValue(EndPointProperty, value);
92            }
93        }
94
95                #endregion
96
97        public CryptoLineView()
98        {
99            Stroke = Brushes.Black;
100            StrokeThickness = 2;
101        }
102
103        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
104        {
105            base.OnPropertyChanged(e);
106        }
107
108        protected override void OnMouseDown(MouseButtonEventArgs args)
109        {
110            if (args.RightButton == MouseButtonState.Pressed)
111            {
112                if (this.model != null && !this.model.WorkspaceModel.WorkspaceManagerEditor.isExecuting())
113                {
114                    this.model.WorkspaceModel.deleteConnectionModel(this.model);
115                }
116            }           
117        }
118
119        public CryptoLineView(ConnectionModel connectionModel, ConnectorView source, ConnectorView target)
120        {
121            this.Loaded += new RoutedEventHandler(CryptoLineView_Loaded);
122            this.connectionModel = connectionModel;
123            this.StartPointSource = source;
124            this.EndPointSource = target;
125        }
126
127        void CryptoLineView_Loaded(object sender, RoutedEventArgs e)
128        {
129            Color color = ColorHelper.GetLineColor(connectionModel.ConnectionType);
130            Stroke = new SolidColorBrush(color);
131            StrokeThickness = 2;
132        }
133
134        private void makeBinding(ConnectorView source, ConnectorView target)
135        {
136            MultiBinding multiBinding = new MultiBinding();
137            multiBinding.Converter = new MultiDragValueConverter();
138
139            Binding bind = new Binding();
140            bind.Source = source.Parent;
141            bind.Path = new PropertyPath(PluginContainerView.IsDragStartedDependencyProperty);
142            multiBinding.Bindings.Add(bind);
143
144            bind = new Binding();
145            bind.Source = target.Parent;
146            bind.Path = new PropertyPath(PluginContainerView.IsDragStartedDependencyProperty);
147            multiBinding.Bindings.Add(bind);
148
149            SetBinding(CryptoLineView.IsDraggingDependencyProperty, multiBinding);
150        }
151
152                #region Overrides
153
154                protected override Geometry DefiningGeometry
155                {
156                        get
157                        {
158                                StreamGeometry geometry = new StreamGeometry();
159                                geometry.FillRule = FillRule.EvenOdd;
160
161                                using (StreamGeometryContext context = geometry.Open())
162                                {
163                    internalGeometryDraw(context);
164                                }
165
166                                geometry.Freeze();
167                                return geometry;
168                        }
169                }               
170
171                #endregion
172
173                #region Privates
174        private bool isBetween(double min, double max, double between)
175        {
176            return min <= between && between <= max;
177        }
178
179        private bool findIntersection(Point StartPoint, Point EndPoint, Point StartPointSec, Point EndPointSec)
180        {
181            if (StartPoint.X != EndPoint.X &&
182                StartPoint.Y != EndPoint.Y)
183            {
184                return false;
185            }
186            if (StartPointSec.X != EndPointSec.X &&
187                StartPointSec.Y != EndPointSec.Y)
188            {
189                return false;
190            }
191
192            // parallel, also overlapping case
193            if (StartPoint.X == EndPoint.X && StartPointSec.X == EndPointSec.X ||
194                StartPoint.Y == EndPoint.Y && StartPointSec.Y == EndPointSec.Y)
195            {
196                return false;
197            }
198            else
199            {
200                // orthogonal but maybe not intersected
201                Point up, down, left, right;
202                if (StartPoint.X == EndPoint.X)
203                {
204                    up = StartPoint;
205                    down = EndPoint;
206                    left = StartPointSec;
207                    right = EndPointSec;
208                }
209                else
210                {
211                    up = StartPointSec;
212                    down = EndPointSec;
213                    left = StartPoint;
214                    right = EndPoint;
215                }
216
217                if (up.Y < down.Y)
218                {
219                    double swap = up.Y;
220                    up.Y = down.Y;
221                    down.Y = swap;
222                }
223
224                if (left.X > right.X)
225                {
226                    double swap = left.X;
227                    left.X = right.X;
228                    right.X = swap;
229                }
230                 //check if is intersected at all
231                if(isBetween(down.Y, up.Y, left.Y) && isBetween(left.X, right.X, up.X))
232                {
233                    if (up.Y == left.Y ||
234                        down.Y == left.Y ||
235                        left.X == up.X || right.X == up.X)
236                    {
237                        intersectPoint = new IntersectPoint(new Point(up.X, left.Y), IntersectPointMode.InnerIntersect);
238                    }
239                    else
240                    {
241                        intersectPoint = new IntersectPoint(new Point(up.X, left.Y), IntersectPointMode.NormalIntersect);
242                    }
243                    return true;
244                }
245                return false;
246            }
247        }
248
249                private void internalGeometryDraw(StreamGeometryContext context)
250                {
251            makeOrthogonalPoints();
252            foreach (var element in (Parent as Panel).Children)
253            {
254                if (element is CryptoLineView && !element.Equals(this))
255                {
256                    CryptoLineView result = element as CryptoLineView;
257                    foreach (FromTo fromTo in pointList)
258                    {
259                        foreach (FromTo resultFromTo in result.pointList)
260                        {
261                            if (findIntersection(fromTo.From, fromTo.To, resultFromTo.From, resultFromTo.To))
262                            {
263                                fromTo.Intersection.Add(intersectPoint);
264
265                                if (fromTo.DirSort == DirSort.Y_ASC || fromTo.DirSort == DirSort.Y_DESC)
266                                    this.UpdateList.Add(result);
267                            }
268                        }
269                    }
270                }
271            }
272
273            context.BeginFigure(StartPoint, true, false);
274
275            foreach (FromTo fromTo in pointList)
276            {
277                if (fromTo.Intersection.Count > 0)
278                {
279                    foreach (IntersectPoint interPoint in fromTo.Intersection)
280                    {
281                        switch (fromTo.DirSort)
282                        {
283                            case DirSort.X_ASC:
284                                if (interPoint.Mode == IntersectPointMode.NormalIntersect)
285                                {
286                                    context.LineTo(new Point(interPoint.Point.X - offset, interPoint.Point.Y), true, true);
287                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - offset), new Point(interPoint.Point.X + offset, interPoint.Point.Y), true, true);
288                                }
289                                else if (interPoint.Mode == IntersectPointMode.InnerIntersect)
290                                {
291                                    context.LineTo(new Point(interPoint.Point.X - 2.5, interPoint.Point.Y), true, true);
292                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - 3.5), new Point(interPoint.Point.X + 2.5, interPoint.Point.Y), true, true);
293                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y + 3.5), new Point(interPoint.Point.X - 2.5, interPoint.Point.Y), true, true);
294                                }
295                                break;
296                            case DirSort.X_DESC:
297                                if (interPoint.Mode == IntersectPointMode.NormalIntersect)
298                                {
299                                    context.LineTo(new Point(interPoint.Point.X + offset, interPoint.Point.Y), true, true);
300                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - offset), new Point(interPoint.Point.X - offset, interPoint.Point.Y), true, true);
301                                }
302                                else if (interPoint.Mode == IntersectPointMode.InnerIntersect)
303                                {
304                                    context.LineTo(new Point(interPoint.Point.X + 2.5, interPoint.Point.Y), true, true);
305                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - 3.5), new Point(interPoint.Point.X - 2.5, interPoint.Point.Y), true, true);
306                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y + 3.5), new Point(interPoint.Point.X + 2.5, interPoint.Point.Y), true, true);
307                                }
308                                break;
309                            //case DirSort.Y_ASC:
310                            //    context.LineTo(new Point(interPoint.X, interPoint.Y - offset), true, true);
311                            //    context.QuadraticBezierTo(new Point(interPoint.X + offset, interPoint.Y), new Point(interPoint.X, interPoint.Y + offset), true, true);
312                            //    break;
313                            //case DirSort.Y_DESC:
314                            //    context.LineTo(new Point(interPoint.X, interPoint.Y + offset), true, true);
315                            //    context.QuadraticBezierTo(new Point(interPoint.X + offset, interPoint.Y), new Point(interPoint.X, interPoint.Y - offset), true, true);
316                            //    break;
317                        }
318                    }
319                    context.LineTo(fromTo.To, true, true);
320                }
321                else
322                {
323                    context.LineTo(fromTo.To, true, true);
324                }
325            }
326        }
327
328
329
330        //private bool isConnectionPossible(Point p1, Point p2, QuadTreeLib.QuadTree<FakeNode> quad)
331        //{
332        //    if (p1.X != p2.X && p1.Y != p2.Y)
333        //        throw new ArgumentException("only 90° allowed");
334
335        //    if (p1.Y != p2.Y)
336        //    {
337        //        Point up = p2.Y < p1.Y ? p2 : p1;
338        //        Point down = p2.Y < p1.Y ? p1 : p2;
339
340        //        Panel parent = (Parent as Panel);
341        //        foreach (var element in parent.Children)
342        //        {
343        //            PluginContainerView plug1 = element as PluginContainerView;
344        //            if (plug1 == null)
345        //                continue;
346        //            Point pos = new Point((plug1.RenderTransform as TranslateTransform).X, (plug1.RenderTransform as TranslateTransform).Y);
347
348        //            if (!isBetween(pos.X, pos.X + plug1.ActualWidth, up.X))
349        //                continue;
350
351        //            // case 1: one point is inside the plugin
352        //            if (isBetween(pos.Y, pos.Y + plug1.ActualHeight, up.Y) ||
353        //                isBetween(pos.Y, pos.Y + plug1.ActualHeight, down.Y))
354        //            {
355        //                return false;
356        //            }
357
358        //            // case 2: goes through
359        //            if (pos.Y > up.Y && pos.Y + plug1.ActualHeight < down.Y)
360        //            {
361        //                return false;
362        //            }
363        //        }
364        //    }
365        //    else
366        //    {
367        //        Point left = p2.X < p1.X ? p2 : p1;
368        //        Point right = p2.X < p1.X ? p1 : p2;
369
370        //        Panel parent = (Parent as Panel);
371        //        foreach (var element in parent.Children)
372        //        {
373        //            PluginContainerView plug1 = element as PluginContainerView;
374        //            if (plug1 == null)
375        //                continue;
376        //            Point pos = new Point((plug1.RenderTransform as TranslateTransform).X, (plug1.RenderTransform as TranslateTransform).Y);
377        //            if (!isBetween(pos.Y, pos.Y + plug1.ActualHeight, left.Y))
378        //                continue;
379        //            // case 1: one point is inside the plugin
380        //            if (isBetween(pos.X, pos.X + plug1.ActualWidth, left.X) ||
381        //                isBetween(pos.X, pos.X + plug1.ActualWidth, right.X))
382        //            {
383        //                return false;
384        //            }
385        //            // case 2: goes through
386        //            if (pos.X > left.X && pos.X + plug1.ActualWidth < right.X)
387        //            {
388        //                return false;
389        //            }
390        //        }
391        //    }
392        //    return true;
393        //}
394
395        private bool isConnectionPossible(Point p1, Point p2, QuadTreeLib.QuadTree<FakeNode> quadTree)
396        {
397            if (p1.X != p2.X && p1.Y != p2.Y)
398                throw new ArgumentException("only 90° allowed");
399
400            System.Drawing.RectangleF queryRect;
401            if (p1.Y != p2.Y)
402            {
403                Point up = p2.Y < p1.Y ? p2 : p1;
404                Point down = p2.Y < p1.Y ? p1 : p2;
405
406                queryRect = new System.Drawing.RectangleF((float)up.X, (float)up.Y, 1, (float)(down.Y - up.Y));
407            }
408            else
409            {
410                Point left = p2.X < p1.X ? p2 : p1;
411                Point right = p2.X < p1.X ? p1 : p2;
412
413                queryRect = new System.Drawing.RectangleF((float)left.X, (float)left.Y, (float)(right.X - left.X), 1);
414            }
415            return !quadTree.QueryAny(queryRect);
416        }
417
418        private bool performOrthogonalPointConnection(Node n1, Point p2, Node n3, List<Node> nodeList, QuadTreeLib.QuadTree<FakeNode> quadTreePlugins, QuadTreeLib.QuadTree<FakeNode> quadTreeLines)
419        {
420            //bool isHorizontal;
421            //Point help1, help2;
422            //foreach (FakeNode FKNode in getQueriesFromLine(n1.Point, p2, quadTreeLines, out isHorizontal))
423            //{
424            //    if (isHorizontal)
425            //    {
426            //        if (FKNode.Source != this.source)
427            //            continue;
428
429            //        help1 = new Point(n1.Point.X, 2);
430            //        help2 = new Point(p
431            //    }
432            //    else
433            //    {
434            //        if (FKNode.Source != this.source)
435            //            continue;
436            //    }
437            //}
438
439            //foreach (FakeNode FKNode in getQueriesFromLine(p2, n3.Point, quadTreeLines, out isHorizontal))
440            //{
441            //    if (isHorizontal)
442            //    {
443
444            //    }
445            //    else
446            //    {
447
448            //    }
449            //}
450
451            if (isConnectionPossible(n1.Point, p2, quadTreePlugins) && isConnectionPossible(p2, n3.Point, quadTreePlugins))
452            {
453                Node n2 = new Node() { Point = p2 };
454                n1.Vertices.Add(n2);
455
456                n2.Vertices.Add(n1);
457                n2.Vertices.Add(n3);
458
459                n3.Vertices.Add(n2);
460
461                nodeList.Add(n2);
462                return true;
463            }
464
465            return false;
466        }
467
468        private List<FakeNode> getQueriesFromLine(Point p1,Point p2,QuadTreeLib.QuadTree<FakeNode> quadTreeLines, out bool isHorizontal)
469        {
470            if (p1.X != p2.X && p1.Y != p2.Y)
471                throw new ArgumentException("only 90° allowed");
472
473            System.Drawing.RectangleF queryRect;
474
475            if (p1.Y != p2.Y)
476            {
477                Point up = p2.Y < p1.Y ? p2 : p1;
478                Point down = p2.Y < p1.Y ? p1 : p2;
479                isHorizontal = false;
480
481                queryRect = new System.Drawing.RectangleF((float)up.X, (float)up.Y, 1, (float)(down.Y - up.Y));
482            }
483            else
484            {
485                Point left = p2.X < p1.X ? p2 : p1;
486                Point right = p2.X < p1.X ? p1 : p2;
487                isHorizontal = true;
488
489                queryRect = new System.Drawing.RectangleF((float)left.X, (float)left.Y, (float)(right.X - left.X), 1);
490            }
491
492            return quadTreeLines.Query(queryRect);
493        }
494
495        //private bool isSimpleOrthogonalConnectionPossible(Point p1, Point p2, QuadTreeLib.QuadTree<FakeNode> quadTree)
496        //{
497        //    if (p1.X != p2.X && p1.Y != p2.Y)
498        //        throw new ArgumentException("only 90° allowed");
499
500        //    List<FakeNode> list;
501        //    System.Drawing.RectangleF queryRect;
502        //    if (p1.Y != p2.Y)
503        //    {
504        //        Point up = p2.Y < p1.Y ? p2 : p1;
505        //        Point down = p2.Y < p1.Y ? p1 : p2;
506
507        //        queryRect = new System.Drawing.RectangleF((float)up.X, (float)up.Y, (float)5, (float)(down.Y - up.Y));
508        //    }
509        //    else
510        //    {
511        //        Point left = p2.X < p1.X ? p2 : p1;
512        //        Point right = p2.X < p1.X ? p1 : p2;
513
514        //        queryRect = new System.Drawing.RectangleF((float)left.X, (float)left.Y, (float)(right.X - left.X), (float)5);
515        //    }
516
517        //    list = quadTree.Query(queryRect);
518
519        //    return !quadTree.Query(queryRect);
520        //}
521
522        private void performOrthogonalPointConnection(Node p1, Node p2, QuadTreeLib.QuadTree<FakeNode> quadTree)
523        {
524            if (isConnectionPossible(p1.Point, p2.Point, quadTree))
525            {
526                p1.Vertices.Add(p2);
527                p2.Vertices.Add(p1);
528            }
529        }
530
531        internal class FakeNode : QuadTreeLib.IHasRect
532        {
533            public System.Drawing.RectangleF Rectangle { get; set; }
534            public ConnectorView Source { get; set; }
535            public ConnectorView Target { get; set; }
536        }
537
538        private void makeOrthogonalPoints()
539        {
540            if (StartPointSource != null && EndPointSource != null && IsDragging == false)
541            {
542                List<Node> nodeList = new List<Node>();
543                Panel parent = (Parent as Panel);
544
545                // add start and end. Index will be 0 and 1
546                Node startNode = new Node() { Point = cheat42(StartPoint , StartPointSource, 1)},
547                    endNode = new Node() { Point = cheat42(EndPoint, EndPointSource, -1) };
548                nodeList.Add(startNode);
549                nodeList.Add(endNode);
550
551                float actualWidth = (float)parent.ActualWidth, actualHeight = (float)parent.ActualWidth;
552                //Consider zoom factor
553                QuadTreeLib.QuadTree<FakeNode> quadTreePlugins = new QuadTreeLib.QuadTree<FakeNode>
554                    (new System.Drawing.RectangleF(-actualWidth, -actualHeight, actualWidth * 5, actualHeight * 5));
555
556                QuadTreeLib.QuadTree<FakeNode> quadTreeLines = new QuadTreeLib.QuadTree<FakeNode>
557                    (new System.Drawing.RectangleF(-actualWidth, -actualHeight, actualWidth * 5, actualHeight * 5));
558
559
560
561                //foreach (var element in parent.Children)
562                //{
563                //    if (element is PluginContainerView)
564                //    {
565                //        PluginContainerView p1 = element as PluginContainerView;
566                //        foreach (var routPoint in p1.RoutingPoints)
567                //        {
568                //            nodeList.Add(new Node() { Point = routPoint });
569                //        }
570                //        quadTree.Insert(new FakeNode() { Rectangle = new System.Drawing.RectangleF((float)(p1.RenderTransform as TranslateTransform).X,
571                //                                                                                    (float)(p1.RenderTransform as TranslateTransform).Y,
572                //                                                                                    (float)p1.ActualWidth,
573                //                                                                                    (float)p1.ActualHeight)});
574                //    }
575                //}
576                for (int routPoint = 0; routPoint < 4; ++routPoint)
577                {
578                    foreach (var element in parent.Children)
579                    {
580                        if (element is PluginContainerView)
581                        {
582                            PluginContainerView p1 = element as PluginContainerView;
583                            nodeList.Add(new Node() { Point = p1.GetRoutingPoint(routPoint) });
584                            if (routPoint == 0)
585                            {
586                                quadTreePlugins.Insert(new FakeNode()
587                                {
588                                    Rectangle = new System.Drawing.RectangleF((float)p1.GetPosition().X,
589                                                                               (float)p1.GetPosition().Y + (float)p1.ControlPanel.ActualHeight,
590                                                                               (float)p1.PluginBase.ActualWidth,
591                                                                               (float)p1.PluginBase.ActualHeight - (float)p1.ControlPanel.ActualHeight)
592                                });
593                            }
594                        }
595
596                        if (routPoint != 0)
597                            continue;
598
599                        if (element is CryptoLineView)
600                        {
601                            CryptoLineView l1 = element as CryptoLineView;
602                            foreach (FromTo fromto in l1.pointList)
603                            {
604                                Point p1 = fromto.From, p2 = fromto.To;
605                                if (p1.Y != p2.Y)
606                                {
607                                    Point up = p2.Y < p1.Y ? p2 : p1;
608                                    Point down = p2.Y < p1.Y ? p1 : p2;
609
610                                    quadTreeLines.Insert(new FakeNode()
611                                    {
612                                        Source = l1.StartPointSource,
613                                        Target = l1.EndPointSource,
614                                        Rectangle = new System.Drawing.RectangleF((float)up.X, (float)up.Y, 1, (float)(down.Y - up.Y))
615                                    });
616                                }
617                                else
618                                {
619                                    Point left = p2.X < p1.X ? p2 : p1;
620                                    Point right = p2.X < p1.X ? p1 : p2;
621
622                                    quadTreeLines.Insert(new FakeNode()
623                                    {
624                                        Source = l1.StartPointSource,
625                                        Target = l1.EndPointSource,
626                                        Rectangle = new System.Drawing.RectangleF((float)left.X, (float)left.Y, (float)(right.X - left.X), 1)
627                                    });
628                                }
629                            }
630
631                        }
632                    }
633                }
634
635                // connect points
636                int loopCount = nodeList.Count;
637                const int performanceTradeoffAt = 10;
638
639                LinkedList<Node> path = null;
640
641                for (int i = 0; i < loopCount; ++i)
642                {
643                    if (performanceTradeoffAt != 0 &&
644                           i == performanceTradeoffAt)
645                    {
646                        StackFrameDijkstra.Dijkstra<Node> dijkstra = new StackFrameDijkstra.Dijkstra<Node>();
647                        path = dijkstra.findPath(nodeList, startNode, endNode);
648                        if (path != null)
649                        {
650                            break;
651                        }
652                    }
653
654                    var p1 = nodeList[i];
655                    // TODO: inner loop restriction! n²-n!
656                    // is k=i instead of k=0 correct?
657                    for (int k = i; k < loopCount; ++k)
658                    {
659
660
661                        var p2 = nodeList[k];
662                        if (p1 == p2)
663                            continue;
664                        if (p1.Vertices.Contains(p2))
665                            continue;
666
667                        // no helping point required?
668                        if (p1.Point.X == p2.Point.X ||
669                            p1.Point.Y == p2.Point.Y)
670                        {
671                            performOrthogonalPointConnection(p1, p2, quadTreePlugins);
672                        }
673                        else
674                        {
675                            Point help = new Point(p1.Point.X, p2.Point.Y);
676
677                            if (!performOrthogonalPointConnection(p1, help, p2, nodeList, quadTreePlugins, quadTreeLines))
678                            {
679                                help = new Point(p2.Point.X, p1.Point.Y);
680                                if (!performOrthogonalPointConnection(p1, help, p2, nodeList, quadTreePlugins, quadTreeLines))
681                                {
682                                    // optional todo: double edge helping routes
683                                }
684                            }
685
686                        }
687                    }
688                }
689
690                if (path == null)
691                {
692                    StackFrameDijkstra.Dijkstra<Node> dijkstra = new StackFrameDijkstra.Dijkstra<Node>();
693                    path = dijkstra.findPath(nodeList, startNode, endNode);
694                }
695
696                if (path != null)
697                {
698                    pointList.Clear();
699                    Point prevPoint = StartPoint;
700
701                    foreach (var i in path)
702                    {
703                        Point thisPoint = i.Point;
704                        this.pointList.Add(new FromTo(prevPoint, thisPoint));
705                        prevPoint = thisPoint;
706                    }
707                    this.pointList.Add(new FromTo(prevPoint, EndPoint));
708                    return;
709                }
710            }
711            //Failsafe
712            if (StartPoint.X < EndPoint.X)
713            {
714                pointList.Clear();
715                pointList.Add(new FromTo(StartPoint, new Point((EndPoint.X + StartPoint.X) / 2, StartPoint.Y)));
716                pointList.Add(new FromTo(new Point((EndPoint.X + StartPoint.X) / 2, StartPoint.Y), new Point((EndPoint.X + StartPoint.X) / 2, EndPoint.Y)));
717                pointList.Add(new FromTo(new Point((EndPoint.X + StartPoint.X) / 2, EndPoint.Y), EndPoint));
718            }
719            else
720            {
721                if (StartPoint.X > EndPoint.X)
722                {
723                    pointList.Clear();
724                    pointList.Add(new FromTo(StartPoint, new Point((StartPoint.X + EndPoint.X) / 2, StartPoint.Y)));
725                    pointList.Add(new FromTo(new Point((StartPoint.X + EndPoint.X) / 2, StartPoint.Y), new Point((StartPoint.X + EndPoint.X) / 2, EndPoint.Y)));
726                    pointList.Add(new FromTo(new Point((StartPoint.X + EndPoint.X) / 2, EndPoint.Y), EndPoint));
727                }
728            }
729        }
730
731        private static Point cheat42(Point EndPoint, ConnectorView EndPointSource, int flipper)
732        {
733            double xoffset = 0;
734            double yoffset = 0;
735            double baseoffset = 15;
736            switch (EndPointSource.Orientation)
737            {
738                case ConnectorOrientation.East:
739                    xoffset = baseoffset;
740                    break;
741                case ConnectorOrientation.West:
742                    xoffset = -baseoffset;
743                    break;
744                case ConnectorOrientation.North:
745                    yoffset = -baseoffset;
746                    break;
747                case ConnectorOrientation.South:
748                    yoffset = baseoffset;
749                    break;
750            }
751            //xoffset *= flipper;
752            //yoffset *= flipper;
753            return new Point(EndPoint.X + xoffset, EndPoint.Y + yoffset);
754        }
755               
756                #endregion
757
758        #region IUpdateableView Members
759
760        public void update()
761        {
762            Stroke = Brushes.Green;
763        }
764
765        #endregion
766
767        internal void Reset()
768        {
769            Color color = ColorHelper.GetColor(Model.ConnectionType);
770            Stroke = new SolidColorBrush(color);
771        }
772
773
774        private ConnectorView startPointSource;
775        public ConnectorView StartPointSource
776        { 
777            get { return startPointSource; } 
778            set 
779            {
780                startPointSource = value; 
781                if (endPointSource == null || startPointSource == null)
782                    return;
783                makeBinding(startPointSource, endPointSource); 
784            } 
785        }
786
787        private ConnectorView endPointSource;
788        public ConnectorView EndPointSource
789        { 
790            get { return endPointSource; } 
791            set 
792            { 
793                endPointSource = value;
794                if (endPointSource == null || startPointSource == null)
795                    return;
796                makeBinding(startPointSource, endPointSource); 
797            } 
798        }
799    }
800
801    public class MultiDragValueConverter : IMultiValueConverter
802    {
803        public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
804        {
805            bool a = (bool)values[0], b = (bool)values[1];
806            if (a == true || b == true)
807                return true;
808            else
809                return false;
810        }
811
812        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
813        {
814            throw new NotImplementedException();
815        }
816    }
817
818}
Note: See TracBrowser for help on using the repository browser.