프로젝트

일반

사용자정보

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

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

이력 | 보기 | 이력해설 | 다운로드 (42.2 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
                GroupID = item.GroupID;
64
            }
65
        }
66

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
140

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

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

    
147

    
148
        #endregion
149
        #region PropertyChanged Method
150

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

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

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

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

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

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

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

    
213

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

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

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

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

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

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

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

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

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

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

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

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

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

    
555
            this.ApplyTemplate();
556

    
557
            Generate();
558

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

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

    
638

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

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

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

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

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

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

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

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

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

    
711
            return 0;
712
        }
713

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

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

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

    
743
            var length = 0D;
744

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

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

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

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

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

    
778
                }
779

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

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

    
801
            double delta = 2 * radius * overlap;
802

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

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

    
815

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

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

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

    
824
                    var length = 0D;
825

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

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

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

    
844

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

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

    
859

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

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

    
866
                        }
867

    
868
                        length += delta;
869
                    }
870

    
871
                }
872
            }
873

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

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

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

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

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

    
926
            }
927

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

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

    
949
                    int count = this.PointSet.Count;
950

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

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

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

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

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

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

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

    
1038
            Point tmp = pt;
1039

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

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

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

    
1052
                //this.ApplyOverViewData();
1053

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

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

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

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

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

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

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

    
1150
                ctrl.ZIndex = this.ZIndex;
1151
                ctrl.GroupID = this.GroupID;
1152

    
1153
                return "|DZ|" + JsonSerializerHelper.CompressString((ctrl.JsonSerialize()));
1154
            }
1155
        }
1156

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

    
1182
                    StartPoint = s.StartPoint,
1183
                    EndPoint = s.EndPoint,
1184
                    Memo = s.Memo,
1185
                    ZIndex = s.ZIndex,
1186
                    GroupID = s.GroupID
1187

    
1188
                    //Fill = s.CloudFill,
1189
                };
1190
            }
1191

    
1192
            return instance;
1193
        }
1194

    
1195
        #region Method
1196
        public override void ApplyOverViewData()
1197
        {
1198
            this.OverViewPathData = this.PathData;
1199
        }
1200
        #endregion
1201
    }
1202

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