프로젝트

일반

사용자정보

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
138

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

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

    
145

    
146
        #endregion
147
        #region PropertyChanged Method
148

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

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

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

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

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

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

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

    
211

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

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

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

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

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

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

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

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

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

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

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

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

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

    
553
            this.ApplyTemplate();
554

    
555
            Generate();
556

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

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

    
636

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

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

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

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

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

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

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

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

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

    
709
            return 0;
710
        }
711

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

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

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

    
741
            var length = 0D;
742

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

    
750
                ArcSegment arcSeg = new ArcSegment();
751
                var x = prev.X + length * dx;
752
                var y = prev.Y + length * dy;
753

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

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

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

    
776
                }
777

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

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

    
799
            double delta = 2 * radius * overlap;
800

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

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

    
813

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

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

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

    
822
                    var length = 0D;
823

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

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

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

    
842

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

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

    
857

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

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

    
864
                        }
865

    
866
                        length += delta;
867
                    }
868

    
869
                }
870
            }
871

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

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

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

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

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

    
924
            }
925

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

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

    
947
                    int count = this.PointSet.Count;
948

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

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

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

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

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

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

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

    
1036
            Point tmp = pt;
1037

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

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

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

    
1050
                //this.ApplyOverViewData();
1051

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

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

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

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

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

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

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

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

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

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

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

    
1185
            return instance;
1186
        }
1187

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

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