프로젝트

일반

사용자정보

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

markus / MarkupToPDF / Controls / Polygon / CloudControl.cs @ b2d0f316

이력 | 보기 | 이력해설 | 다운로드 (42.1 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
                this.ZIndex = item.ZIndex;
63
            }
64
        }
65

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
139

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

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

    
146

    
147
        #endregion
148
        #region PropertyChanged Method
149

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

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

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

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

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

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

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

    
212

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

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

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

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

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

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

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

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

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

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

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

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

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

    
554
            this.ApplyTemplate();
555

    
556
            Generate();
557

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

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

    
637

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

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

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

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

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

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

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

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

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

    
710
            return 0;
711
        }
712

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

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

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

    
742
            var length = 0D;
743

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

    
751
                ArcSegment arcSeg = new ArcSegment();
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 ctrl = new S_CloudControl())
1121
            {
1122
                ctrl.TransformPoint = "0|0";
1123
                ctrl.SizeSet = String.Format("{0}", this.LineSize);
1124
                //ctrl.StrokeColor = "#FF000FFF";
1125
                ctrl.StrokeColor = this.StrokeColor.Color.ToString();
1126
                ctrl.Name = this.GetType().Name.ToString();
1127
                ctrl.Toler = this.Toler;
1128
                ctrl.PaintState = this.Paint;
1129
                ctrl.Opac = this.Opacity;
1130
                ctrl.UserID = this.UserID;
1131
                ctrl.IsTrans = this.isTransOn;
1132
                ctrl.IsChain = this.isChain;
1133
                ctrl.PointSet = new List<Point>();
1134
                ctrl.DashSize = this.DashSize;
1135
                ctrl.StartPoint = this.StartPoint;
1136
                ctrl.EndPoint = this.EndPoint;
1137
                ctrl.ArcLength = this.ArcLength;
1138
                foreach (var point in this.PointSet)
1139
                {
1140
                    ctrl.PointSet.Add(point);
1141
                }
1142

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

    
1149
                ctrl.ZIndex = this.ZIndex;
1150

    
1151
                return "|DZ|" + JsonSerializerHelper.CompressString((ctrl.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
                    ZIndex = s.ZIndex
1184

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

    
1189
            return instance;
1190
        }
1191

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

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