프로젝트

일반

사용자정보

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

markus / MarkupToPDF / Controls / Polygon / CloudControl.cs @ 2a2e72c2

이력 | 보기 | 이력해설 | 다운로드 (41.8 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)
721
        {
722
            PathFigure pathFigure = new PathFigure();
723

    
724
            var radius = arcLength_;
725
            double overlap = 5.5D / 6D;
726

    
727
            double delta = 2 * radius * overlap;
728

    
729
            pathFigure.StartPoint = p1;
730
            pathFigure.IsClosed = false;
731
            pathFigure.IsFilled = false;
732
            var prev = p2;
733

    
734
            var curr = p1;
735

    
736
            var dx = curr.X - prev.X;
737
            var dy = curr.Y - prev.Y;
738

    
739
            var len = Math.Sqrt(dx * dx + dy * dy);
740

    
741
            dx = dx / len;
742
            dy = dy / len;
743

    
744
            var length = 0D;
745

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

    
753
                ArcSegment arcSeg = new ArcSegment();
754

    
755
                var x = prev.X + length * dx;
756
                var y = prev.Y + length * dy;
757

    
758
                if(!double.IsNaN(x) && !double.IsNaN(y))
759
                {
760
                    arcSeg.Point = new Point(x, y);
761
                    arcSeg.Size = new Size(radius, radius);
762
                    arcSeg.IsLargeArc = true;
763

    
764
                    if(reverse)
765
                    {
766
                       arcSeg.SweepDirection = SweepDirection.Counterclockwise;
767
                    }
768
                    else
769
                    {
770
                        arcSeg.SweepDirection = SweepDirection.Clockwise;
771
                    }
772

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

    
779
                }
780

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

    
799
            var radius = arcLength_;
800
            double overlap = 5.5D / 6D;
801

    
802
            double delta = 2 * radius * overlap;
803

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

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

    
816

    
817
                    var dx = curr.X - prev.X;
818
                    var dy = curr.Y - prev.Y;
819

    
820
                    var len = Math.Sqrt(dx * dx + dy * dy);
821

    
822
                    dx = dx / len;
823
                    dy = dy / len;
824

    
825
                    var length = 0D;
826

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

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

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

    
845

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

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

    
860

    
861
                       
862
                            pathFigure.Segments.Add(arcSeg);
863

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

    
867
                        }
868

    
869
                        length += delta;
870
                    }
871

    
872
                }
873
            }
874

    
875
            pathFigure.IsFilled = false;
876
            return pathFigure;
877
        }
878

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

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

    
913
                pathFigure.Segments.Add(arcSeg);
914
            }
915

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

    
927
            }
928

    
929
            pathFigure.IsFilled = true;
930
            return pathFigure;
931
        }
932

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

    
950
                    int count = this.PointSet.Count;
951

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

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

    
963
                        _pathGeometry.Figures.Add(pathFigure);                        
964
                    }
965
                    else
966
                    {
967

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

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

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

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

    
1039
            Point tmp = pt;
1040

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

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

    
1050
                //var firstPoint = this.PointSet.First();
1051
                //this.PointSet.Add(firstPoint);
1052

    
1053
                //this.ApplyOverViewData();
1054

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

    
1061
                this.SetCloud();
1062
            }
1063
        }
1064

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

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

    
1111
                return new Rect(new Point(dMinX, dMinY), new Point(dMaxX, dMaxY));
1112
            }
1113
        }
1114

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

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

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

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

    
1180
                    StartPoint = s.StartPoint,
1181
                    EndPoint = s.EndPoint,
1182
                    Memo = s.Memo
1183

    
1184
                    //Fill = s.CloudFill,
1185
                };
1186
            }
1187

    
1188
            return instance;
1189
        }
1190

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

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