프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

markus / MarkupToPDF / Controls / Polygon / CloudControl.cs @ 666bb823

이력 | 보기 | 이력해설 | 다운로드 (42 KB)

1
using System;
2
using System.Net;
3
using System.Windows;
4
using System.Windows.Controls;
5
using System.Windows.Documents;
6
using System.Windows.Ink;
7
using System.Windows.Input;
8
using System.Windows.Media;
9
using System.Windows.Media.Animation;
10
using System.Windows.Shapes;
11
using System.Collections.Generic;
12
using System.ComponentModel;
13
using MarkupToPDF.Controls.Common;
14
using MarkupToPDF.Common;
15
using MarkupToPDF.Serialize.Core;
16
using MarkupToPDF.Serialize.S_Control;
17
using System.Linq;
18

    
19
namespace MarkupToPDF.Controls.Polygon
20
{
21
    public class CloudControl : CommentUserInfo, IDisposable, INotifyPropertyChanged, IShapeControl, ICloudControl, IDashControl
22
    {
23
        private const string PART_CloudPath = "PART_CloudPath";
24
        private const string PART_CloudSubPath = "PART_CloudSubPath";
25

    
26
        public Path Base_CloudPath = null;
27
        public Path Base_CloudSubPath = null;
28

    
29
        private const double _CloudArcDepth =0.8;  /// 2018.05.14 added by humkyung
30

    
31
        static CloudControl()
32
        {
33
            DefaultStyleKeyProperty.OverrideMetadata(typeof(CloudControl), new FrameworkPropertyMetadata(typeof(CloudControl)));
34
            //Application.Current.Resources.MergedDictionaries.Add(Application.LoadComponent(new Uri("/MarkupToPDF;Component/Themes/generic.xaml")) as ResourceDictionary);
35
            //ResourceDictionary dictionary = new ResourceDictionary();
36
            //dictionary.Source = new Uri("/MarkupToPDF;component/themes/generic.xaml", UriKind.RelativeOrAbsolute);
37
            //Application.Current.Resources.MergedDictionaries.Add(dictionary);
38
        }
39
        public CloudControl()
40
        {
41
            //this.DefaultStyleKey = typeof(CloudControl);
42
        }
43

    
44
        public override void Copy(CommentUserInfo lhs)
45
        {
46
            if (lhs is CloudControl item)
47
            {
48
                this.LineSize = item.LineSize;
49
                this.Toler = item.Toler;
50
                this.PointSet = item.PointSet.ConvertAll(x => new Point(x.X, x.Y));
51
                this.ArcLength = item.ArcLength;
52
                this.Paint = item.Paint;
53
                this.Opacity = item.Opacity;
54
                this.StrokeColor = item.StrokeColor;
55
                this.isTransOn = item.isTransOn;
56
                this.isChain = item.isChain;
57
                this.DashSize = item.DashSize;
58
                this.UserID = item.UserID;
59
                this.StartPoint = new Point(item.StartPoint.X, item.StartPoint.Y);
60
                this.EndPoint = new Point(item.EndPoint.X, item.EndPoint.Y);
61
                this.Memo = item.Memo;
62
            }
63
        }
64

    
65
        public override CommentUserInfo Clone()
66
        {
67
            var clone = new CloudControl();
68
            clone.Copy(this);
69
            return clone;
70
        }
71

    
72
        #region Dependency Properties
73
        public static readonly DependencyProperty UserIDProperty = DependencyProperty.Register(
74
                "UserID", typeof(string), typeof(CloudControl), new PropertyMetadata(null));
75
        public static readonly DependencyProperty LineSizeProperty = DependencyProperty.Register(
76
                "LineSize", typeof(double), typeof(CloudControl), new PropertyMetadata((Double)3));
77
        //강인구 추가
78
        public static readonly DependencyProperty DashSizeProperty = DependencyProperty.Register(
79
                 "DashSize", typeof(DoubleCollection), typeof(CloudControl), new PropertyMetadata(new DoubleCollection { 99999999 }, PointValueChanged));
80
        public static readonly DependencyProperty FillColorProperty = DependencyProperty.Register(
81
                "FillColor", typeof(SolidColorBrush), typeof(CloudControl), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
82

    
83
        public static readonly DependencyProperty IsCompletedProperty = DependencyProperty.Register(
84
                "IsCompleted", typeof(bool), typeof(CloudControl), null);
85
        //강인구
86
        public static readonly DependencyProperty PaintProperty = DependencyProperty.Register(
87
                "Paint", typeof(PaintSet), typeof(CloudControl), new PropertyMetadata(PaintSet.None, PointValueChanged));
88

    
89
        public static readonly DependencyProperty StrokeColorProperty = DependencyProperty.Register(
90
                "StrokeColor", typeof(SolidColorBrush), typeof(CloudControl), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
91

    
92
        public static readonly DependencyProperty ArcLengthProperty = DependencyProperty.Register(
93
                "ArcLength", typeof(double), typeof(CloudControl), new PropertyMetadata((Double)10, PointValueChanged));
94

    
95
        public static readonly DependencyProperty PathDataProperty = DependencyProperty.Register(
96
                "PathData", typeof(Geometry), typeof(CloudControl), null);
97

    
98
        public static readonly DependencyProperty PathSubDataProperty = DependencyProperty.Register(
99
                "PathSubData", typeof(Geometry), typeof(CloudControl), null);
100

    
101
        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register(
102
                "EndPoint", typeof(Point), typeof(CloudControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
103

    
104
        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register(
105
                "StartPoint", typeof(Point), typeof(CloudControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
106

    
107
        public static readonly DependencyProperty PointSetProperty = DependencyProperty.Register(
108
                "PointSet", typeof(List<Point>), typeof(CloudControl), new PropertyMetadata(new List<Point>(), PointValueChanged));
109
        public static readonly DependencyProperty isTransOnProperty = DependencyProperty.Register(
110
                "isTransOn", typeof(bool), typeof(CloudControl), new PropertyMetadata(false));
111
        public static readonly DependencyProperty isChainProperty = DependencyProperty.Register(
112
                "isChain", typeof(bool), typeof(CloudControl), new PropertyMetadata(false));
113
       
114
        /// <summary>
115
        /// StylusPointSet을 List<Point>로 대체하면 PointValueChanged가 작동안한다.
116
        /// </summary>
117
        public static readonly DependencyProperty StylusPointSetProperty = DependencyProperty.Register(
118
               "PointC", typeof(StylusPointSet), typeof(CloudControl), new PropertyMetadata(new StylusPointSet(), PointValueChanged));
119

    
120
        public static readonly DependencyProperty AngleProperty = DependencyProperty.Register("AngleValue", typeof(double), typeof(CloudControl),
121
            new PropertyMetadata((double)0.0, new PropertyChangedCallback(AngleValueChanged)));
122

    
123
        public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register("CenterX", typeof(double), typeof(CloudControl),
124
            new PropertyMetadata((double)0, OnCenterXYChanged));
125

    
126
        public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register("CenterY", typeof(double), typeof(CloudControl),
127
            new PropertyMetadata((double)0, OnCenterXYChanged));
128

    
129
        public static readonly DependencyProperty IsSelectedProperty =
130
    DependencyProperty.Register("IsSelected", typeof(bool), typeof(CloudControl), new FrameworkPropertyMetadata(false, IsSelectedChanged));
131

    
132
        public static readonly DependencyProperty ControlTypeProperty =
133
            DependencyProperty.Register("ControlType", typeof(ControlType), typeof(CloudControl), new FrameworkPropertyMetadata(ControlType.PolygonCloud));
134

    
135
        public static readonly DependencyProperty OverViewPathDataProperty = DependencyProperty.Register(
136
        "OverViewPathData", typeof(Geometry), typeof(ControlType), null);
137

    
138

    
139
        public static readonly DependencyProperty CanvasXProperty = DependencyProperty.Register(
140
                "CanvasX", typeof(double), typeof(CloudControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
141

    
142
        public static readonly DependencyProperty CanvasYProperty = DependencyProperty.Register(
143
                "CanvasY", typeof(double), typeof(CloudControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
144

    
145

    
146
        #endregion
147
        #region PropertyChanged Method
148

    
149
        public static void OnSetCansvasChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
150
        {
151
            var instance = (CloudControl)sender;
152

    
153
            if (e.OldValue != e.NewValue && instance != null)
154
            {
155
                instance.SetValue(e.Property, e.NewValue);
156
            }
157
        }
158

    
159
        public static void PointValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
160
        {
161
            var instance = (CloudControl)sender;
162
            if (e.OldValue != e.NewValue && instance.Base_CloudPath != null)
163
            {
164
                instance.SetValue(e.Property, e.NewValue);
165
                //강인구 추가
166
                instance.SetCloud();
167
                //주석처리
168
            }
169
        }
170
        public static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
171
        {
172
            //var instance = (CloudControl)sender;
173

    
174
            //if (e.OldValue != e.NewValue && instance.Base_CloudPath != null)
175
            //{
176

    
177
            //    instance.SetValue(e.Property, e.NewValue);
178

    
179
            //    if (instance.IsSelected)
180
            //    {
181
            //        instance.Base_CloudPath.Stroke = new SolidColorBrush(Colors.Blue);
182
            //    }
183
            //    else
184
            //    {
185
            //        instance.Base_CloudPath.Stroke = new SolidColorBrush(Colors.Red);
186
            //    }
187
            //}
188
        }
189

    
190
        public static void OnCenterXYChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
191
        {
192
            var instance = (CloudControl)sender;
193
            if (e.OldValue != e.NewValue && instance.Base_CloudPath != null)
194
            {
195
                instance.SetValue(e.Property, e.NewValue);
196
                instance.DrawingCloud();
197
            }
198
        }
199
        public static void AngleValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
200
        {
201
            var instance = (CloudControl)sender;
202
            if (e.OldValue != e.NewValue && instance.Base_CloudPath != null)
203
            {
204
                instance.SetValue(e.Property, e.NewValue);
205
                instance.DrawingCloud();
206
            }
207
        }
208
        #endregion
209
        #region Properties
210

    
211

    
212
        public bool IsCompleted
213
        {
214
            get { return (bool)GetValue(IsCompletedProperty); }
215
            set
216
            {
217
                SetValue(IsCompletedProperty, value);
218
            }
219
        }
220

    
221
        public Geometry OverViewPathData
222
        {
223
            get { return (Geometry)GetValue(OverViewPathDataProperty); }
224
            set
225
            {
226
                SetValue(OverViewPathDataProperty, value);
227
                OnPropertyChanged("OverViewPathData");
228
            }
229
        }
230

    
231
        public double CanvasX
232
        {
233
            get { return (double)GetValue(CanvasXProperty); }
234
            set
235
            {
236
                if (this.CanvasX != value)
237
                {
238
                    SetValue(CanvasXProperty, value);
239
                }
240
            }
241
        }
242

    
243
        public double CanvasY
244
        {
245
            get { return (double)GetValue(CanvasYProperty); }
246
            set
247
            {
248
                if (this.CanvasY != value)
249
                {
250
                    SetValue(CanvasYProperty, value);
251
                }
252
            }
253
        }
254

    
255
        public override bool IsSelected
256
        {
257
            get
258
            {
259
                return (bool)GetValue(IsSelectedProperty);
260
            }
261
            set
262
            {
263
                SetValue(IsSelectedProperty, value);
264
            }
265
        }
266

    
267
        public override ControlType ControlType
268
        {
269
            set
270
            {
271
                SetValue(ControlTypeProperty, value);
272
            }
273
            get
274
            {
275
                return (ControlType)GetValue(ControlTypeProperty);
276
            }
277
        }
278

    
279
        public Double LineSize
280
        {
281
            get { return (Double)GetValue(LineSizeProperty); }
282
            set
283
            {
284
                if (this.LineSize != value)
285
                {
286
                    SetValue(LineSizeProperty, value);
287
                }
288
            }
289
        }
290
        public bool isChain
291
        {
292
            get { return (bool)GetValue(isChainProperty); }
293
            set
294
            {
295
                SetValue(isChainProperty, value);
296
                OnPropertyChanged("isChain");
297
            }
298
        }
299
        public bool isTransOn
300
        {
301
            get { return (bool)GetValue(isTransOnProperty); }
302
            set
303
            {
304
                SetValue(isTransOnProperty, value);
305
                OnPropertyChanged("isTransOn");
306
            }
307
        }
308
        public DoubleCollection DashSize
309
        {
310
            get { return (DoubleCollection)GetValue(DashSizeProperty); }
311
            set
312
            {
313
                if (this.DashSize != value)
314
                {
315
                    SetValue(DashSizeProperty, value);
316
                    OnPropertyChanged("DashSize");
317
                }
318
            }
319
        }
320
        public string UserID
321
        {
322
            get { return (string)GetValue(UserIDProperty); }
323
            set
324
            {
325
                if (this.UserID != value)
326
                {
327
                    SetValue(UserIDProperty, value);
328
                    OnPropertyChanged("UserID");
329
                }
330
            }
331
        }
332
        public PaintSet Paint
333
        {
334
            get { return (PaintSet)GetValue(PaintProperty); }
335
            set
336
            {
337
                if (this.Paint != value)
338
                {
339
                    SetValue(PaintProperty, value);
340
                    OnPropertyChanged("Paint");
341
                }
342
            }
343
        }
344

    
345
        public SolidColorBrush FillColor
346
        {
347
            get { return (SolidColorBrush)GetValue(FillColorProperty); }
348
            set
349
            {
350
                if (this.FillColor != value)
351
                {
352
                    SetValue(FillColorProperty, value);
353
                    OnPropertyChanged("FillColor");
354
                }
355
            }
356
        }
357
        public override SolidColorBrush StrokeColor
358
        {
359
            get { return (SolidColorBrush)GetValue(StrokeColorProperty); }
360
            set
361
            {
362
                if (this.StrokeColor != value)
363
                {
364
                    SetValue(StrokeColorProperty, value);
365
                    OnPropertyChanged("StrokeColor");
366
                }
367
            }
368
        }
369
        public Geometry PathData
370
        {
371
            get 
372
            {
373
                return (Geometry)GetValue(PathDataProperty); 
374
            }
375
            set 
376
            {
377
                SetValue(PathDataProperty, value);
378
                OnPropertyChanged("PathData");
379
            }
380
        }
381
        public Geometry PathSubData
382
        {
383
            get 
384
            {
385
                return (Geometry)GetValue(PathSubDataProperty); 
386
            }
387
            set
388
            {
389
                SetValue(PathSubDataProperty, value);
390
                OnPropertyChanged("PathSubData");
391
            }
392
        }
393
        public Point EndPoint
394
        {
395
            get 
396
            {
397
                return (Point)GetValue(EndPointProperty); 
398
            }
399
            set
400
            {
401
                SetValue(EndPointProperty, value);
402
                OnPropertyChanged("EndPoint");
403
            }
404
        }
405
        public Point StartPoint
406
        {
407
            get 
408
            {
409
                return (Point)GetValue(StartPointProperty); 
410
            }
411
            set
412
            {
413
                SetValue(StartPointProperty, value);
414
                OnPropertyChanged("StartPoint");
415
            }
416
        }
417
        public List<Point> _pointSet;
418

    
419
        public List<Point> PointSet
420
        {
421
            get 
422
            {
423
                return (List<Point>)GetValue(PointSetProperty);
424
            }
425
            set 
426
            {
427
                SetValue(PointSetProperty, value);
428
                OnPropertyChanged("PointSet");
429
            }
430
        }
431

    
432
        public List<Point> pointSet
433
        {
434
            get
435
            {
436
                return _pointSet;
437
            }
438
            set
439
            {
440
                _pointSet = value;
441
                OnPropertyChanged("pointSet");
442
            }
443
        }
444

    
445
        public Double ArcLength
446
        {
447
            get { return (Double)GetValue(ArcLengthProperty); }
448
            set
449
            {
450
                if (this.ArcLength != value)
451
                {
452
                    SetValue(ArcLengthProperty, value);
453
                    OnPropertyChanged("ArcLength");
454
                }
455
            }
456
        }
457

    
458
        private double _toler = 1;
459
        public double Toler
460
        {
461
            get { return _toler; }
462
            set { _toler = value; }
463
        }
464
        //강인구 수정 클라우드 사이즈
465
        //private double _arcLength;
466
        ////private double _arcLength = 30;
467
        //public double ArcLength
468
        //{
469
        //    get { return _arcLength; }
470
        //    set { _arcLength = value; }
471
        //}
472
        private bool _fill = false;
473
        public bool Fill
474
        {
475
            get { return _fill; }
476
            set { _fill = value; }
477
        }
478
        //public double Angle
479
        //{
480
        //    get { return (double)GetValue(AngleProperty); }
481
        //    set
482
        //    {
483
        //        if (this.Angle != value)
484
        //        {
485
        //            SetValue(AngleProperty, value);
486
        //            OnPropertyChanged("Angle");
487
        //        }
488
        //    }
489
        //}
490
        public StylusPointSet PointC
491
        {
492
            get { return (StylusPointSet)GetValue(StylusPointSetProperty); }
493
            set
494
            {
495
                SetValue(StylusPointSetProperty, value);
496
                OnPropertyChanged("PointC");
497
            }
498
        }
499
        public double CenterX
500
        {
501
            get
502
            {
503
                return (double)GetValue(CenterXProperty); 
504
            }
505
            set
506
            {
507
                SetValue(CenterXProperty, value);
508
                OnPropertyChanged("CenterX");
509
            }
510
        }
511
        public double CenterY
512
        {
513
            get
514
            { 
515
                return (double)GetValue(CenterYProperty); 
516
            }
517
            set
518
            {
519
                SetValue(CenterYProperty, value);
520
                OnPropertyChanged("CenterY");
521
            }
522
        }
523
        public double AngleValue
524
        {
525
            get 
526
            {
527
                return (double)GetValue(AngleProperty); 
528
            }
529
            set
530
            {
531
                SetValue(AngleProperty, value);
532
                OnPropertyChanged("AngleValue");
533
            }
534
        }
535
        #endregion
536
        #region Data
537
        private PathGeometry _pathGeometry = new PathGeometry();
538
        private PathGeometry _pathSubGeometry = new PathGeometry();
539
        #endregion
540

    
541
        public override void OnApplyTemplate()
542
        {
543
            base.OnApplyTemplate();
544
            Base_CloudPath = GetTemplateChild(PART_CloudPath) as Path;
545
            Base_CloudSubPath = GetTemplateChild(PART_CloudSubPath) as Path;
546
            SetCloud();
547
        }
548
        public void SetCloud()
549
        {
550
            //this.Width = this.Base_CloudPath.Width;
551
            //this.Height = this.Base_CloudPath.Height;
552

    
553
            this.ApplyTemplate();
554

    
555
            Generate();
556

    
557
            if (!isChain)
558
            {
559
                //ClosePath();
560
            }
561
        }
562
        public int Generate()
563
        {
564
            this._pathGeometry = null;
565
            this._pathSubGeometry = null;
566
            switch (this.Paint)
567
            {
568
                case PaintSet.None:
569
                    this.FillColor = null;
570
                    if (Base_CloudSubPath != null)
571
                    {
572
                        Base_CloudPath.Fill = null;
573
                        Base_CloudSubPath.Fill = null;
574
                        Base_CloudSubPath.Stroke = new SolidColorBrush(Colors.Transparent);
575
                        //Base_CloudSubPath.StrokeThickness = 3;
576
                    }                    
577
                    break;
578
                case PaintSet.Fill:
579
                    this.FillColor = this.StrokeColor;
580
                    if (Base_CloudSubPath != null)
581
                    {
582
                        if (isChain)
583
                        {
584
                            Base_CloudPath.Fill = null;
585
                            Base_CloudSubPath.Fill = null;
586
                            Base_CloudSubPath.Stroke = new SolidColorBrush(Colors.Transparent);
587
                            //Base_CloudSubPath.StrokeThickness = 3;
588
                        }
589
                        else
590
                        {
591
                            Base_CloudSubPath.Stroke = this.StrokeColor;
592
                            //Base_CloudSubPath.Stroke = new SolidColorBrush(Colors.Transparent);
593
                            Base_CloudSubPath.StrokeThickness = 0.5;
594
                            Base_CloudPath.Stroke = this.StrokeColor;
595
                            //Base_CloudPath.StrokeThickness = 3;
596
                            Base_CloudPath.Fill = this.FillColor;
597
                            Base_CloudSubPath.Fill = this.FillColor;
598
                        }
599
                    }                   
600
                    break;
601
                case PaintSet.Hatch:
602
                    if (Base_CloudSubPath != null && !isChain)
603
                    {
604
                        if (isChain)
605
                        {
606
                            Base_CloudPath.Fill = null;
607
                            Base_CloudSubPath.Fill = null;
608
                            Base_CloudSubPath.Stroke = new SolidColorBrush(Colors.Transparent);
609
                            //Base_CloudSubPath.StrokeThickness = 3;
610
                        }
611
                        else
612
                        {
613
                            var size = this.LineSize > 5 ? 5 : this.LineSize;
614
                            Base_CloudPath.Fill = HatchMake.CreateHatchBrush(this.StrokeColor, size * 0.1);
615
                            Base_CloudSubPath.Fill = HatchMake.CreateHatchBrush(this.StrokeColor, size * 0.1);
616
                            Base_CloudSubPath.Stroke = new SolidColorBrush(Colors.Transparent);
617
                        }
618
                    }
619
                    break;
620
                default:
621
                    break;
622
            }
623

    
624
            //강인구 추가
625
            if (Base_CloudPath != null)
626
            {
627
                Base_CloudPath.StrokeDashArray.Clear();
628
                Base_CloudSubPath.StrokeDashArray.Clear();
629
                foreach (var item in this.DashSize)
630
                {
631
                    Base_CloudPath.StrokeDashArray.Add(item);
632
                    Base_CloudSubPath.StrokeDashArray.Add(item);
633
                }
634
            }
635

    
636

    
637
            /// set reverse if area is greater 0 - 2012.07.04 added by humkyung
638
            double area = MathSet.AreaOf(this.PointSet);
639
            bool reverse = (area > 0);
640
            /// up to here
641

    
642
            this._pathGeometry = new PathGeometry { FillRule = FillRule.Nonzero};
643
            this._pathSubGeometry = new PathGeometry { FillRule = FillRule.Nonzero };
644

    
645
            if (isTransOn) // true라면 클라우드 컨트롤
646
            {
647
                //PathFigure pathFigure = CloudControl.GeneratePolyWithCloud(this.PointSet, this.ArcLength, reverse);
648
                //_pathGeometry.Figures.Add(pathFigure);
649

    
650
                for (int i = 0; i < this.PointSet.Count - 1; i++)
651
                {
652
                    var stPoint = this.PointSet[i];
653

    
654
                    Point edPoint = this.PointSet[i + 1];
655

    
656
                    //if (i < this.PointSet.Count() - 1)
657
                    //{
658
                    //    edPoint = this.PointSet[i + 1];
659
                    //}
660
                    //else
661
                    //{
662
                    //    edPoint = this.PointSet[0];
663
                    //}
664

    
665
                    PathFigure pathFigure = CloudControl.GenerateLineWithCloud(stPoint, edPoint, this.ArcLength, reverse);
666
                    _pathGeometry.Figures.Add(pathFigure);
667
                }
668
            }
669
            else
670
            {
671
                PathFigure fm = new PathFigure();
672
                fm.StartPoint = this.PointSet[0];
673
                for (int i = 0; i < this.PointSet.Count() - 2; i++)
674
                {
675
                    fm.Segments.Add(new LineSegment { Point = this.PointSet[i] });
676
                }
677
                _pathGeometry.Figures.Add(fm);
678
            }
679

    
680
            if (this.Paint == PaintSet.Fill || this.Paint == PaintSet.Hatch)
681
            {
682
                PointCollection pd = new PointCollection();
683
                foreach (var item in this.PointSet)
684
                {
685
                    pd.Add(item);
686
                }
687
                _pathSubGeometry.Figures.Add(new PathFigure()
688
                {
689
                    Segments = new PathSegmentCollection()
690
                    {
691
                        new PolyLineSegment()
692
                        {
693
                              Points = pd
694
                        },
695
                    },
696
                    StartPoint = this.PointSet[0]
697
                });
698

    
699
                this.PathSubData = _pathSubGeometry;
700
            }
701
            StartPoint = PointSet[0];
702
            this.PathData = this._pathGeometry;
703
        
704
            this.OverViewPathData = PathData;
705
            this.StrokeColor = StrokeColor;
706
            this.LineSize = LineSize;
707
            EndPoint = PointSet[PointSet.Count - 1];
708

    
709
            return 0;
710
        }
711

    
712
        /// <summary>
713
        /// draw arcs between p1 and p2
714
        /// </summary>
715
        /// <author>humkyung</author>
716
        /// <param name="p1"></param>
717
        /// <param name="p2"></param>
718
        /// <param name="reverse"></param>
719
        /// <returns></returns>
720
        public static PathFigure GenerateLineWithCloud(Point p1, Point p2, double arcLength_, bool reverse, double linesize_ = -20)
721
        {
722
            PathFigure pathFigure = new PathFigure();
723
            //if (linesize_ == -20)
724
            //    linesize_ = arcLength_;
725
            var radius = arcLength_;
726
            double overlap =  5.5D / 6D;
727
            double delta = 2 * radius * overlap;           
728
            pathFigure.IsClosed = false;
729
            pathFigure.IsFilled = false;
730
            var curr = p1;
731
            var prev = p2;         
732

    
733
            var dx = curr.X - prev.X;
734
            var dy = curr.Y - prev.Y;
735
             pathFigure.StartPoint =  p1; //new Point(p1.X + (40 * dx), p1.Y + (40 * dy));//
736
            var len = Math.Sqrt(dx * dx + dy * dy);
737

    
738
            dx = dx / len;
739
            dy = dy / len;
740

    
741
            var length = 0D;
742

    
743
            for (int a = 0; a <= Math.Round(len / delta); a++)
744
            {
745
                if (length > len)
746
                {
747
                    length = len;
748
                }
749

    
750
                ArcSegment arcSeg = new ArcSegment();
751

    
752
                var x = prev.X + length * dx;
753
                var y = prev.Y + length * dy;
754

    
755
                if(!double.IsNaN(x) && !double.IsNaN(y))
756
                {
757
                    arcSeg.Point = new Point(x, y); // (x + (40 * dx), y + (40 * dy));
758
                    arcSeg.Size = new Size(radius, radius);
759
                    arcSeg.IsLargeArc = true;
760

    
761
                    if(reverse)
762
                    {
763
                       arcSeg.SweepDirection = SweepDirection.Counterclockwise;
764
                    }
765
                    else
766
                    {
767
                        arcSeg.SweepDirection = SweepDirection.Clockwise;
768
                    }
769

    
770
                    if (length == 0)
771
                    {
772
                        pathFigure.StartPoint = arcSeg.Point;
773
                    }
774
                   
775
                    pathFigure.Segments.Add(arcSeg);
776

    
777
                }
778

    
779
                length += delta;
780
            }
781
            pathFigure.IsFilled = false;
782
            return pathFigure;
783
        }
784
       
785
        /// <summary>
786
        /// draw arcs between p1 and p2
787
        /// </summary>
788
        /// <author>humkyung</author>
789
        /// <param name="p1"></param>
790
        /// <param name="p2"></param>
791
        /// <param name="reverse"></param>
792
        /// <returns></returns>
793
        public static PathFigure GeneratePolyWithCloud(List<Point> points,double arcLength_, bool reverse)
794
        {
795
            PathFigure pathFigure = new PathFigure();
796

    
797
            var radius = arcLength_;
798
            double overlap = 5.5D / 6D;
799

    
800
            double delta = 2 * radius * overlap;
801

    
802
            if(points.Count() > 1)
803
            {
804
                pathFigure.StartPoint = points[0];
805
                pathFigure.IsClosed = false;
806
                pathFigure.IsFilled = false;
807
                Point prevArcPoint = points[0];
808

    
809
                for (int i = 0; i < points.Count -1; i++)
810
                {
811
                    Point curr = points[i];
812
                    Point prev = points[i + 1];
813

    
814

    
815
                    var dx = curr.X - prev.X;
816
                    var dy = curr.Y - prev.Y;
817

    
818
                    var len = Math.Sqrt(dx * dx + dy * dy);
819

    
820
                    dx = dx / len;
821
                    dy = dy / len;
822

    
823
                    var length = 0D;
824

    
825
                    for (int a = 0; a <= Math.Round(len / delta); a++)
826
                    {
827
                        if (length > len)
828
                        {
829
                            length = len;
830
                        }
831

    
832
                        ArcSegment arcSeg = new ArcSegment();
833
                       
834
                        var x = prev.X + length * dx;
835
                        var y = prev.Y + length * dy;
836

    
837
                        if (!double.IsNaN(x) && !double.IsNaN(y))
838
                        {
839
                            arcSeg.Point = new Point(x, y);
840
                            arcSeg.Size = new Size(radius, radius);
841
                            arcSeg.IsLargeArc = true;
842

    
843

    
844
                            if (reverse)
845
                            {
846
                                arcSeg.SweepDirection = SweepDirection.Counterclockwise;
847
                            }
848
                            else
849
                            {
850
                                arcSeg.SweepDirection = SweepDirection.Clockwise;
851
                            }
852

    
853
                            //if (length == 0)
854
                            //{
855
                            //    pathFigure.StartPoint = arcSeg.Point;
856
                            //}
857

    
858

    
859
                       
860
                            pathFigure.Segments.Add(arcSeg);
861

    
862
                            System.Diagnostics.Debug.WriteLine($"{prevArcPoint} { arcSeg.Point}");
863
                            prevArcPoint = arcSeg.Point;
864

    
865
                        }
866

    
867
                        length += delta;
868
                    }
869

    
870
                }
871
            }
872

    
873
            pathFigure.IsFilled = false;
874
            return pathFigure;
875
        }
876

    
877
        /// <summary>
878
        /// draw arcs between p1 and p2
879
        /// </summary>
880
        /// <author>humkyung</author>
881
        /// <param name="p1"></param>
882
        /// <param name="p2"></param>
883
        /// <param name="reverse"></param>
884
        /// <returns></returns>
885
        public static PathFigure GenerateLineWithCloudOld(Point p1, Point p2, double arcLength_, bool reverse)
886
        {
887
            PathFigure pathFigure = new PathFigure();
888
            pathFigure.StartPoint = p1;
889

    
890
            double arcLength = arcLength_;
891
            /// draw arcs which has arcLength between p1 and p2 - 2012.06.21 added by humkyung 
892
            double dx = p2.X - p1.X;
893
            double dy = p2.Y - p1.Y;
894
            double l = MathSet.DistanceTo(p1, p2); /// distance between p1 and p2
895
            double theta = Math.Atan2(Math.Abs(dy), Math.Abs(dx)) * 180 / Math.PI;
896
            Point lastPt = new Point(p1.X, p1.Y);
897
            double count = l / arcLength;
898
            /// normalize
899
            dx /= l;
900
            dy /= l;
901
            Double j = 1;
902
            for (j = 1; j < (count - 1); j++)
903
            {
904
                ArcSegment arcSeg = new ArcSegment();
905
                arcSeg.Size = new Size(arcLength * CloudControl._CloudArcDepth, arcLength * CloudControl._CloudArcDepth);						/// x size and y size of arc
906
                arcSeg.Point = new Point(p1.X + j * dx * arcLength, p1.Y + j * dy * arcLength);	/// end point of arc
907
                lastPt = arcSeg.Point;  /// save last point
908
                //arcSeg.RotationAngle = theta + 90;
909
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
910

    
911
                pathFigure.Segments.Add(arcSeg);
912
            }
913

    
914
            /// draw arc between last point and end point
915
            if ((count > j) || (count > 0))
916
            {
917
                arcLength = MathSet.DistanceTo(lastPt, p2);
918
                ArcSegment arcSeg = new ArcSegment();
919
                arcSeg.Size = new Size(arcLength * CloudControl._CloudArcDepth, arcLength * CloudControl._CloudArcDepth);	/// x size and y size of arc
920
                arcSeg.Point = new Point(p2.X, p2.Y);/// end point of arc
921
                //arcSeg.RotationAngle = theta;
922
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
923
                pathFigure.Segments.Add(arcSeg);
924

    
925
            }
926

    
927
            pathFigure.IsFilled = true;
928
            return pathFigure;
929
        }
930

    
931
        /// <summary>
932
        /// close path if it's open
933
        /// </summary>
934
        /// <author>humkyung</author>
935
        /// <returns></returns>
936
        public int ClosePath()
937
        {
938
            if (this.PointSet.Count > 1)
939
            {
940
                double d = MathSet.DistanceTo(this.PointSet[0], this.PointSet[this.PointSet.Count - 1]);
941
                if (d > _toler)
942
                {
943
                    /// set reverse if area is greater 0 - 2012.07.04 added by humkyung
944
                    double area = MathSet.AreaOf(this.PointSet);
945
                    bool reverse = (area > 0);
946
                    /// up to here
947

    
948
                    int count = this.PointSet.Count;
949

    
950
                    if (isTransOn) // true라면 클라우드 컨트롤
951
                    {
952
                        ArcLength = ArcLength == 0 ? 10 : ArcLength;
953

    
954
                        PathFigure pathFigure = CloudControl.GenerateLineWithCloud(this.PointSet[count - 1], this.PointSet[0], this.ArcLength - 5, reverse);
955
                        
956
                        if (this.Paint == PaintSet.Fill)
957
                        {
958
                            pathFigure.IsClosed = true;
959
                        }
960

    
961
                        _pathGeometry.Figures.Add(pathFigure);                        
962
                    }
963
                    else
964
                    {
965

    
966
                        PathFigure fm = new PathFigure();
967
                        fm.StartPoint = this.PointSet[count - 1];
968
                        
969
                        //for (int i = 0; i < (count - 1); i++)
970
                        //{
971
                            _pathGeometry.Figures[_pathGeometry.Figures.Count - 1].Segments.Add(new LineSegment { Point = this.PointSet[0] });
972
                            _pathGeometry.Figures[_pathGeometry.Figures.Count - 1].Segments.Add(new LineSegment { Point = this.PointSet[1] });
973
                            //fm.Segments.Add(new LineSegment { Point = this.PointSet[0] });
974
                        //}
975
                    }                 
976
                }
977
            }
978

    
979
            return 0;
980
        }
981
        public void DrawingCloud()
982
        {
983
            AnotherSetCloud();
984
            if (!isChain)
985
            {
986
                //ClosePath();
987
            }
988
        }
989
        public void AnotherSetCloud()
990
        {
991
            this.StrokeColor = StrokeColor;
992
            this.LineSize = LineSize;
993
            this.SetCloud();
994
            //Generate();
995
            this.Width = this.Base_CloudPath.Width;
996
            this.Height = this.Base_CloudPath.Height;
997
        }
998
        public void Dispose()
999
        {
1000
            //GC.Collect();
1001
            ////GC.SuppressFinalize(this);
1002
            this.Base_CloudPath = null;
1003
            this.Base_CloudSubPath = null;
1004
        }
1005
        public event PropertyChangedEventHandler PropertyChanged;
1006
        protected void OnPropertyChanged(string propName)
1007
        {
1008
            if (PropertyChanged != null)
1009
                PropertyChanged(this, new PropertyChangedEventArgs(propName));
1010
        }
1011

    
1012
        public override void UpdateControl()
1013
        {
1014
            var lastIndex = this.PointSet.Count - 1;
1015
            //this.StartPoint = this.PointSet[0];
1016
            //this.EndPoint = this.PointSet[lastIndex];
1017
            CenterX = MathSet.getMiddlePoint(this.PointSet[0], this.PointSet[lastIndex]).X;
1018
            CenterY = MathSet.getMiddlePoint(this.PointSet[0], this.PointSet[lastIndex]).Y;
1019
        }
1020
        public void ChangePaint(PaintSet state)
1021
        {
1022
            this.Paint = state;
1023
            this.SetCloud();
1024
            
1025
        }
1026

    
1027
        /// <summary>
1028
        /// call when mouse is moving while drawing control
1029
        /// </summary>
1030
        /// <param name="pt"></param>
1031
        /// <param name="bAxisLocked"></param>
1032
        public override void OnCreatingMouseMove(Point pt, bool bAxisLocked)
1033
        {
1034
            this.isTransOn = true;
1035
            this.PointSet.RemoveAt(this.PointSet.Count - 1);
1036

    
1037
            Point tmp = pt;
1038

    
1039
            if (bAxisLocked)
1040
            {
1041
                CommentAngle = MathSet.returnAngle(this.StartPoint, ref tmp, bAxisLocked);
1042
            }
1043

    
1044
            if (this.PointSet.Count > 2 && StartPoint == tmp)
1045
            {
1046
                this.IsCompleted = true;
1047

    
1048
                //var firstPoint = this.PointSet.First();
1049
                //this.PointSet.Add(firstPoint);
1050

    
1051
                //this.ApplyOverViewData();
1052

    
1053
                this.SetCloud();
1054
            }
1055
            else
1056
            {
1057
                this.PointSet.Add(tmp);
1058

    
1059
                this.SetCloud();
1060
            }
1061
        }
1062

    
1063
        /// <summary>
1064
        /// move control point has same location of given pt along given delta
1065
        /// </summary>
1066
        /// <author>humkyung</author>
1067
        /// <date>2019.06.20</date>
1068
        /// <param name="pt"></param>
1069
        /// <param name="dx"></param>
1070
        /// <param name="dy"></param>
1071
        public override void OnMoveCtrlPoint(Point pt, double dx, double dy, bool bAxisLocked = false)
1072
        {
1073
            Point selected = MathSet.getNearPoint((this as IPath).PointSet, pt);
1074
            selected.X += dx;
1075
            selected.Y += dy;
1076
            for (int i = 0; i < (this as IPath).PointSet.Count; i++)
1077
            {
1078
                if (pt.Equals((this as IPath).PointSet[i]))
1079
                {
1080
                    (this as IPath).PointSet[i] = selected;
1081
                    break;
1082
                }
1083
            }
1084
            this.UpdateControl();
1085
            this.DrawingCloud();
1086
        }
1087

    
1088
        /// <summary>
1089
        /// return Cloud's area
1090
        /// </summary>
1091
        /// <author>humkyung</author>
1092
        /// <date>2019.06.13</date>
1093
        public override Rect ItemRect
1094
        {
1095
            get
1096
            {
1097
                double dMinX = double.MaxValue;
1098
                double dMinY = double.MaxValue;
1099
                double dMaxX = double.MinValue;
1100
                double dMaxY = double.MinValue;
1101
                foreach (Point pt in this.PointSet)
1102
                {
1103
                    dMinX = Math.Min(dMinX, pt.X);
1104
                    dMinY = Math.Min(dMinY, pt.Y);
1105
                    dMaxX = Math.Max(dMaxX, pt.X);
1106
                    dMaxY = Math.Max(dMaxY, pt.Y);
1107
                }
1108

    
1109
                return new Rect(new Point(dMinX, dMinY), new Point(dMaxX, dMaxY));
1110
            }
1111
        }
1112

    
1113
        /// <summary>
1114
        /// Serialize this
1115
        /// </summary>
1116
        /// <param name="sUserId"></param>
1117
        /// <returns></returns>
1118
        public override string Serialize()
1119
        {
1120
            using (S_CloudControl STemp = new S_CloudControl())
1121
            {
1122
                STemp.TransformPoint = "0|0";
1123
                STemp.SizeSet = String.Format("{0}", this.LineSize);
1124
                //STemp.StrokeColor = "#FF000FFF";
1125
                STemp.StrokeColor = this.StrokeColor.Color.ToString();
1126
                STemp.Name = this.GetType().Name.ToString();
1127
                STemp.Toler = this.Toler;
1128
                STemp.PaintState = this.Paint;
1129
                STemp.Opac = this.Opacity;
1130
                STemp.UserID = this.UserID;
1131
                STemp.IsTrans = this.isTransOn;
1132
                STemp.IsChain = this.isChain;
1133
                STemp.PointSet = new List<Point>();
1134
                STemp.DashSize = this.DashSize;
1135
                STemp.StartPoint = this.StartPoint;
1136
                STemp.EndPoint = this.EndPoint;
1137
                STemp.ArcLength = this.ArcLength;
1138
                foreach (var point in this.PointSet)
1139
                {
1140
                    STemp.PointSet.Add(point);
1141
                }
1142

    
1143
                //STemp.CloudFill = this.Fill;
1144
                STemp.ArcLength = this.ArcLength;
1145
                ///강인구 추가(2017.11.02)
1146
                ///Memo 추가
1147
                STemp.Memo = this.Memo;
1148

    
1149
                return "|DZ|" + JsonSerializerHelper.CompressString((STemp.JsonSerialize()));
1150
            }
1151
        }
1152

    
1153
        /// <summary>
1154
        /// create a cloudcontrol from given string
1155
        /// </summary>
1156
        /// <param name="str"></param>
1157
        /// <returns></returns>
1158
        public static CloudControl FromString(string str, SolidColorBrush brush, string sProjectNo)
1159
        {
1160
            CloudControl instance = null;
1161
            using (S_CloudControl s = JsonSerializerHelper.JsonDeserialize<S_CloudControl>(str))
1162
            {
1163
                string[] data2 = s.SizeSet.Split(delimiterChars2, StringSplitOptions.RemoveEmptyEntries);
1164
                instance = new CloudControl
1165
                {
1166
                    LineSize = Convert.ToDouble(data2.First()),
1167
                    Toler = s.Toler,
1168
                    PointSet = s.PointSet,
1169
                    ArcLength = s.ArcLength,
1170
                    Paint = s.PaintState,
1171
                    Opacity = s.Opac,
1172
                    StrokeColor = brush,
1173
                    isTransOn = s.IsTrans,
1174
                    isChain = s.IsChain,
1175
                    DashSize = s.DashSize,
1176
                    UserID = s.UserID,
1177

    
1178
                    StartPoint = s.StartPoint,
1179
                    EndPoint = s.EndPoint,
1180
                    Memo = s.Memo
1181

    
1182
                    //Fill = s.CloudFill,
1183
                };
1184
            }
1185

    
1186
            return instance;
1187
        }
1188

    
1189
        #region Method
1190
        public override void ApplyOverViewData()
1191
        {
1192
            this.OverViewPathData = this.PathData;
1193
        }
1194
        #endregion
1195
    }
1196

    
1197
}
클립보드 이미지 추가 (최대 크기: 500 MB)