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

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