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

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

-Intersected lines now drawn correctly

File size: 11.0 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;
15
16namespace WorkspaceManager.View.VisualComponents
17{
18        public sealed class CryptoLineView : Shape, IConnection, IUpdateableView
19    {
20        #region Variables
21
22        private IntersectPoint intersectPoint;
23        private List<FromTo> pointList = new List<FromTo>();
24        public HashSet<CryptoLineView> UpdateList = new HashSet<CryptoLineView>();
25
26        private ConnectionModel model;
27        public ConnectionModel Model
28        {
29            get { return model; }
30            private set { model = value; }
31        }
32        private static double offset = 7.5;
33
34        #endregion
35
36        #region Dependency Properties
37
38        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register("StartPoint", typeof(Point), typeof(CryptoLineView), new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
39        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register("EndPoint", typeof(Point), typeof(CryptoLineView), new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
40
41                #endregion
42
43                #region CLR Properties
44
45        public Point StartPoint
46        {
47            get { return (Point)GetValue(StartPointProperty); }
48            set 
49            {
50                SetValue(StartPointProperty, value);
51            }
52        }
53
54        public Point EndPoint
55        {
56            get { return (Point)GetValue(EndPointProperty); }
57            set 
58            {
59                SetValue(EndPointProperty, value);
60            }
61        }
62
63                #endregion
64
65        public CryptoLineView()
66        {
67            Stroke = Brushes.Black;
68            StrokeThickness = 2;
69        }
70
71        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
72        {
73            base.OnPropertyChanged(e);
74            foreach (CryptoLineView line in UpdateList)
75            {
76                line.InvalidateVisual();
77            }
78        }
79
80        public CryptoLineView(ConnectionModel connectionModel) : this()
81        {
82            this.Model = connectionModel;
83            Color color = ColorHelper.GetColor(connectionModel.ConnectionType);
84            Stroke = new SolidColorBrush(color);
85            StrokeThickness = 2;
86        }
87
88                #region Overrides
89
90                protected override Geometry DefiningGeometry
91                {
92                        get
93                        {
94                                StreamGeometry geometry = new StreamGeometry();
95                                geometry.FillRule = FillRule.EvenOdd;
96
97                                using (StreamGeometryContext context = geometry.Open())
98                                {
99                    internalGeometryDraw(context);
100                                }
101
102                                geometry.Freeze();
103                                return geometry;
104                        }
105                }               
106
107                #endregion
108
109                #region Privates
110        private bool isBetween(double min, double max, double between)
111        {
112            return min <= between && between <= max;
113        }
114
115        private bool findIntersection(Point StartPoint, Point EndPoint, Point StartPointSec, Point EndPointSec)
116        {
117            if (StartPoint.X != EndPoint.X &&
118                StartPoint.Y != EndPoint.Y)
119            {
120                return false;
121            }
122            if (StartPointSec.X != EndPointSec.X &&
123                StartPointSec.Y != EndPointSec.Y)
124            {
125                return false;
126            }
127
128            // parallel
129            if (StartPoint.X == EndPoint.X && StartPointSec.X == EndPointSec.X ||
130                StartPoint.Y == EndPoint.Y && StartPointSec.Y == EndPointSec.Y)
131            {
132                return false;
133            }
134            else
135            {
136                // orthonogal
137                Point up, down, left, right;
138                if (StartPoint.X == EndPoint.X)
139                {
140                    up = StartPoint;
141                    down = EndPoint;
142                    left = StartPointSec;
143                    right = EndPointSec;
144                }
145                else
146                {
147                    up = StartPointSec;
148                    down = EndPointSec;
149                    left = StartPoint;
150                    right = EndPoint;
151                }
152
153                if (up.Y < down.Y)
154                {
155                    double swap = up.Y;
156                    up.Y = down.Y;
157                    down.Y = swap;
158                }
159
160                if (left.X > right.X)
161                {
162                    double swap = left.X;
163                    left.X = right.X;
164                    right.X = swap;
165                }
166                   
167                if(isBetween(down.Y, up.Y, left.Y) && isBetween(left.X, right.X, up.X))
168                {
169                    if (StartPoint.Y == StartPointSec.Y && StartPoint.X > StartPointSec.X)
170                    {
171                        intersectPoint = new IntersectPoint(new Point(up.X, left.Y));
172                        //intersectPoint.Mode = IntersectPointMode.InnerIntersect;
173                    }
174                    else
175                    {
176                        intersectPoint = new IntersectPoint(new Point(up.X, left.Y));
177                    }
178                    return true;
179                }
180                return false;
181            }
182        }
183
184                private void internalGeometryDraw(StreamGeometryContext context)
185                {
186            makeOrthogonalPoints();
187            foreach (var element in (Parent as Panel).Children)
188            {
189                if (element is CryptoLineView && !element.Equals(this))
190                {
191                    CryptoLineView result = element as CryptoLineView;
192                    foreach (FromTo fromTo in pointList)
193                    {
194                        foreach (FromTo resultFromTo in result.pointList)
195                        {
196                            if (findIntersection(fromTo.From, fromTo.To, resultFromTo.From, resultFromTo.To))
197                            {
198                                fromTo.Intersection.Add(intersectPoint);
199
200                                if (fromTo.DirSort == DirSort.Y_ASC || fromTo.DirSort == DirSort.Y_DESC)
201                                    this.UpdateList.Add(result);
202                            }
203                        }
204                    }
205                }
206            }
207
208            context.BeginFigure(StartPoint, true, false);
209
210            foreach (FromTo fromTo in pointList)
211            {
212                if (fromTo.Intersection.Count > 0)
213                {
214                    foreach (IntersectPoint interPoint in fromTo.Intersection)
215                    {
216                        if (intersectPoint.Mode == IntersectPointMode.NormalIntersect)
217                        {
218                            switch (fromTo.DirSort)
219                            {
220                                case DirSort.X_ASC:
221                                    context.LineTo(new Point(interPoint.Point.X - offset, interPoint.Point.Y), true, true);
222                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - offset), new Point(interPoint.Point.X + offset, interPoint.Point.Y), true, true);
223                                    break;
224                                case DirSort.X_DESC:
225                                    context.LineTo(new Point(interPoint.Point.X + offset, interPoint.Point.Y), true, true);
226                                    context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - offset), new Point(interPoint.Point.X - offset, interPoint.Point.Y), true, true);
227                                    break;
228                                //case DirSort.Y_ASC:
229                                //    context.LineTo(new Point(interPoint.X, interPoint.Y - offset), true, true);
230                                //    context.QuadraticBezierTo(new Point(interPoint.X + offset, interPoint.Y), new Point(interPoint.X, interPoint.Y + offset), true, true);
231                                //    break;
232                                //case DirSort.Y_DESC:
233                                //    context.LineTo(new Point(interPoint.X, interPoint.Y + offset), true, true);
234                                //    context.QuadraticBezierTo(new Point(interPoint.X + offset, interPoint.Y), new Point(interPoint.X, interPoint.Y - offset), true, true);
235                                //    break;
236                            }
237                        }
238                        else if (intersectPoint.Mode == IntersectPointMode.InnerIntersect)
239                        {
240                            context.LineTo(new Point(interPoint.Point.X - offset, interPoint.Point.Y), true, true);
241                            context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - offset), new Point(interPoint.Point.X + offset, interPoint.Point.Y), true, true);
242                            context.QuadraticBezierTo(new Point(interPoint.Point.X, interPoint.Point.Y - offset), new Point(interPoint.Point.X - offset, interPoint.Point.Y), true, true);
243                        }
244                    }
245                    context.LineTo(fromTo.To, true, true);
246                }
247                else
248                {
249                    context.LineTo(fromTo.To, true, true);
250                }
251            }
252        }
253
254        private void makeOrthogonalPoints()
255        {
256            if (StartPoint.X < EndPoint.X)
257            {
258                pointList.Clear();
259                pointList.Add(new FromTo(StartPoint, new Point((EndPoint.X + StartPoint.X) / 2, StartPoint.Y)));
260                pointList.Add(new FromTo(new Point((EndPoint.X + StartPoint.X) / 2, StartPoint.Y), new Point((EndPoint.X + StartPoint.X) / 2, EndPoint.Y)));
261                pointList.Add(new FromTo(new Point((EndPoint.X + StartPoint.X) / 2, EndPoint.Y), EndPoint));
262            }
263            else
264            {
265                if (StartPoint.X > EndPoint.X)
266                {
267                    pointList.Clear();
268                    pointList.Add(new FromTo(StartPoint, new Point((StartPoint.X + EndPoint.X) / 2, StartPoint.Y)));
269                    pointList.Add(new FromTo(new Point((StartPoint.X + EndPoint.X) / 2, StartPoint.Y), new Point((StartPoint.X + EndPoint.X) / 2, EndPoint.Y)));
270                    pointList.Add(new FromTo(new Point((StartPoint.X + EndPoint.X) / 2, EndPoint.Y), EndPoint));
271                }
272            }
273        }
274               
275                #endregion
276
277        #region IUpdateableView Members
278
279        public void update()
280        {
281            Stroke = Brushes.Green;
282        }
283
284        #endregion
285    }
286}
Note: See TracBrowser for help on using the repository browser.