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

Last change on this file since 2388 was 2388, checked in by kopal, 11 years ago

small bug fix: gui used the "wrong" model

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