프로젝트

일반

사용자정보

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

markus / MarkupToPDF / Controls / Text / ArrowTextControl.cs @ 873011c4

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

1
using MarkupToPDF.Controls.Common;
2
using System;
3
using System.Collections.Generic;
4
using System.ComponentModel;
5
using System.Linq;
6
using System.Text;
7
using System.Threading.Tasks;
8
using System.Windows;
9
using System.Windows.Controls;
10
using System.Windows.Media;
11
using System.Windows.Shapes;
12
using MarkupToPDF.Controls.Custom;
13
using MarkupToPDF.Common;
14
using MarkupToPDF.Serialize.Core;
15
using MarkupToPDF.Serialize.S_Control;
16
using Markus.Fonts;
17

    
18
namespace MarkupToPDF.Controls.Text
19
{
20
    public class ArrowTextControl : CommentUserInfo, IDisposable, INotifyPropertyChanged, IPath, ITextControl, IMarkupControlData,ICommentRect
21
    {
22
        private const string PART_ArrowPath = "PART_ArrowPath";
23
        private const string PART_TextBox = "PART_ArrowTextBox";
24
        //private const string PART_TextBlock = "PART_ArrowTextBlock";
25
        private const string PART_ArrowSubPath = "PART_ArrowSubPath";
26
        private const string PART_Border = "PART_Border";
27
        private const string PART_BaseTextbox_Caret = "Caret";
28

    
29
        public Path Base_ArrowPath = null;
30
        public Path Base_ArrowSubPath = null;
31
        public TextBox Base_TextBox = null;
32
        public TextBlock Base_TextBlock = null;
33
        public Border BaseTextbox_Caret = null;
34
        public event EventHandler<EventArgs> EditEnded;
35

    
36

    
37
        private const double _CloudArcDepth = 0.8;  /// 2018.05.14 added by humkyung
38

    
39
        #region Object & Variable
40
        GeometryGroup instanceGroup = new GeometryGroup();
41
        
42
        Path Cemy = new Path();
43
        LineGeometry connectorSMGeometry = new LineGeometry();
44
        LineGeometry connectorMEGeometry = new LineGeometry();
45

    
46
        public enum ArrowTextStyleSet { Normal, Cloud, Rect };
47

    
48
        #endregion
49

    
50
        static ArrowTextControl()
51
        {
52
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ArrowTextControl), new FrameworkPropertyMetadata(typeof(ArrowTextControl)));
53
            //ResourceDictionary dictionary = new ResourceDictionary();
54
            //dictionary.Source = new Uri("/MarkupToPDF;component/themes/generic.xaml", UriKind.RelativeOrAbsolute);
55
            //if(!Application.Current.Resources.MergedDictionaries.Any(x=>x.Source == dictionary.Source))
56
            //    Application.Current.Resources.MergedDictionaries.Add(dictionary);
57
        }
58

    
59
        public ArrowTextControl() :base()
60
        {
61
            //this.DefaultStyleKey = typeof(ArrowTextControl);
62
        }
63

    
64
        public override void Copy(CommentUserInfo lhs)
65
        {
66
            if (lhs is ArrowTextControl ArrowTextCtrl)
67
            {
68
                this.PageAngle = ArrowTextCtrl.PageAngle;
69
                this.LineSize = ArrowTextCtrl.LineSize;
70
                this.PointSet = ArrowTextCtrl.PointSet;
71
                this.StartPoint = ArrowTextCtrl.StartPoint;
72
                this.EndPoint = ArrowTextCtrl.EndPoint;
73
                this.StrokeColor = ArrowTextCtrl.StrokeColor;
74
                //this.DashSize = s.DashSize; 
75
                this.ArrowTextStyle = ArrowTextCtrl.ArrowTextStyle;
76
                this.isHighLight = ArrowTextCtrl.isHighLight;
77
                this.ArrowText = ArrowTextCtrl.ArrowText;
78
                this.Opacity = ArrowTextCtrl.Opacity;
79
                this.BorderSize = ArrowTextCtrl.BorderSize;
80
                this.BoxWidth = ArrowTextCtrl.BoxWidth;
81
                this.BoxHeight = ArrowTextCtrl.BoxHeight;
82
                this.isFixed = ArrowTextCtrl.isFixed;
83
                //this.VisualPageAngle = s.Angle;
84
                this.UserID = ArrowTextCtrl.UserID;
85
                this.isTrans = ArrowTextCtrl.isTrans;
86
                this.MidPoint = ArrowTextCtrl.MidPoint;
87
                this.Memo = ArrowTextCtrl.Memo;
88
                this.TextFamily = ArrowTextCtrl.TextFamily;
89
                this.TextStyle = ArrowTextCtrl.TextStyle;
90
                this.TextWeight = ArrowTextCtrl.TextWeight;
91
                this.TextSize = ArrowTextCtrl.TextSize;
92
                this.UnderLine = ArrowTextCtrl.UnderLine;
93
            }
94
        }
95

    
96
        public override CommentUserInfo Clone()
97
        {
98
            var clone = new ArrowTextControl();
99
            clone.Copy(this);
100
            return clone;
101
        }
102

    
103
        public override void OnApplyTemplate()
104
        {
105
            base.OnApplyTemplate();
106
            Base_ArrowPath = GetTemplateChild(PART_ArrowPath) as Path;
107
            Base_ArrowSubPath = GetTemplateChild(PART_ArrowSubPath) as Path;
108
            Base_TextBox = GetTemplateChild(PART_TextBox) as TextBox;
109
            BaseTextbox_Caret = GetTemplateChild(PART_BaseTextbox_Caret) as Border;
110
            Base_TextBox.FontFamily = this.TextFamily;
111
            if (Base_TextBox != null)
112
            {
113
                this.Base_TextBox.CaretIndex = this.Base_TextBox.Text.Length;
114
                this.Base_TextBox.CaretBrush = new SolidColorBrush(Colors.Transparent);
115
                
116
                if (this.ArrowTextStyle == ArrowTextStyleSet.Cloud)
117
                {
118
                    
119
                }
120

    
121
                this.Base_TextBox.ApplyTemplate();
122
                this.Base_TextBox.Text = this.ArrowText;
123

    
124
                MoveCustomCaret();
125

    
126
                Base_TextBox.SizeChanged += new SizeChangedEventHandler(Base_TextBox_SizeChanged);
127
                Base_TextBox.GotFocus += new RoutedEventHandler(Base_TextBox_GotFocus);
128
                Base_TextBox.LostFocus += new RoutedEventHandler(Base_TextBox_LostFocus);
129
                Base_TextBox.SelectionChanged += (sender, e) => MoveCustomCaret();
130
                this.KeyDown += ArrowTextControl_KeyDown;
131

    
132
                SetArrowTextPath(true);
133

    
134
                Base_TextBox.IsTabStop = true;
135
            }
136
        }
137

    
138
        private void ArrowTextControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
139
        {
140
           if(e.Key == System.Windows.Input.Key.Escape)
141
            {
142
                if(string.IsNullOrEmpty(Base_TextBox.Text))
143
                {
144
                    this.Visibility = Visibility.Collapsed;
145
                }
146

    
147
                EditEnd();
148
            }
149
        }
150

    
151
        public void SetFontFamily(FontFamily fontFamily)
152
        {
153
            if (this.Base_TextBlock != null)
154
            {
155
                this.Base_TextBlock.FontFamily = fontFamily;
156
            }
157

    
158
            if (this.Base_TextBox != null)
159
            {
160
                this.Base_TextBox.FontFamily = fontFamily;
161
            }
162
            this.FontFamily = fontFamily;
163
            this.TextFamily = fontFamily;
164
        }
165

    
166
        /// <summary>
167
        /// Moves the custom caret on the canvas.
168
        /// </summary>
169
        public void MoveCustomCaret()
170
        {
171
            var caretLocation = this.Base_TextBox.GetRectFromCharacterIndex(this.Base_TextBox.CaretIndex).Location;
172

    
173
            var angle = Math.Abs(this.PageAngle);
174
            //angle = 0;
175
            System.Diagnostics.Debug.WriteLine("Page Angle : " +  this.PageAngle);
176

    
177
            if (!double.IsInfinity(caretLocation.X))
178
            {
179
                if (angle == 90)
180
                {
181
                    Canvas.SetLeft(this.BaseTextbox_Caret, this.EndPoint.X + caretLocation.Y);
182
                }
183
                else if (angle == 180)
184
                {
185
                    
186
                    Canvas.SetLeft(this.BaseTextbox_Caret, (this.EndPoint.X+ this.Base_TextBox.ActualWidth) - caretLocation.X) ;
187
                    System.Diagnostics.Debug.WriteLine("Caret X : " + ((this.EndPoint.X + this.Base_TextBox.ActualWidth) - caretLocation.X));
188
                } 
189
                else if (angle == 270)
190
                {
191
                    Canvas.SetLeft(this.BaseTextbox_Caret, (this.EndPoint.X) - caretLocation.Y);
192
                }
193
                else
194
                {
195
                    System.Diagnostics.Debug.WriteLine("Caret X : " + (this.EndPoint.X - caretLocation.X));
196
                    Canvas.SetLeft(this.BaseTextbox_Caret, this.EndPoint.X + caretLocation.X);
197
                } 
198
            }
199

    
200
            if (!double.IsInfinity(caretLocation.Y))
201
            {
202
                if (angle == 90)
203
                {
204
                    Canvas.SetTop(this.BaseTextbox_Caret, this.EndPoint.Y - caretLocation.X);
205
                }
206
                else if (angle == 180)
207
                {//보정치40
208
                    Canvas.SetTop(this.BaseTextbox_Caret, ((this.EndPoint.Y -40) + this.Base_TextBox.ActualHeight)- caretLocation.Y );
209
                    System.Diagnostics.Debug.WriteLine("Caret Y : " + (((this.EndPoint.Y - 40) + this.Base_TextBox.ActualHeight) - caretLocation.Y));
210
                }
211
                else if (angle == 270)
212
                {
213
                    Canvas.SetTop(this.BaseTextbox_Caret, (this.EndPoint.Y) + caretLocation.X);
214
                }
215
                else
216
                {
217
                    Canvas.SetTop(this.BaseTextbox_Caret, this.EndPoint.Y  + caretLocation.Y);
218
                    System.Diagnostics.Debug.WriteLine("Caret Y : " + (this.EndPoint.Y + caretLocation.Y - BaseTextbox_Caret.ActualHeight));
219
                }
220
            }
221
        }
222

    
223
        public void MoveCustomCaret(Point point)
224
        {
225

    
226
            var caretLocation = this.Base_TextBox.GetRectFromCharacterIndex(this.Base_TextBox.CaretIndex).Location;
227

    
228
            if (!double.IsInfinity(caretLocation.X))
229
            {
230
                if (Math.Abs(this.PageAngle) == 90)
231
                {
232
                    Canvas.SetLeft(this.BaseTextbox_Caret, point.X + caretLocation.Y);
233
                }
234
                else if (Math.Abs(this.PageAngle) == 180)
235
                {
236

    
237
                    Canvas.SetLeft(this.BaseTextbox_Caret, (point.X + this.Base_TextBox.ActualWidth) - caretLocation.X);
238
                }
239
                else if (Math.Abs(this.PageAngle) == 270)
240
                {
241
                    Canvas.SetLeft(this.BaseTextbox_Caret, (point.X) - caretLocation.Y);
242
                }
243
                else
244
                {
245
                    Canvas.SetLeft(this.BaseTextbox_Caret, point.X + caretLocation.X);
246
                }
247
            }
248

    
249
            if (!double.IsInfinity(caretLocation.Y))
250
            {
251
                if (Math.Abs(this.PageAngle) == 90)
252
                {
253
                    Canvas.SetTop(this.BaseTextbox_Caret, point.Y - caretLocation.X);
254
                }
255
                else if (Math.Abs(this.PageAngle) == 180)
256
                {
257
                    Canvas.SetTop(this.BaseTextbox_Caret, (point.Y + this.Base_TextBox.ActualHeight) - caretLocation.Y);
258
                }
259
                else if (Math.Abs(this.CommentAngle) == 270)
260
                {
261
                    Canvas.SetTop(this.BaseTextbox_Caret, (point.Y) + caretLocation.X);
262
                }
263
                else
264
                {
265
                    Canvas.SetTop(this.BaseTextbox_Caret, point.Y + caretLocation.Y);
266
                }
267
            }
268
        }
269

    
270

    
271
        void Base_TextBox_LostFocus(object sender, RoutedEventArgs e)
272
        {
273
            EditEnd();
274
        }
275

    
276
        private void EditEnd()
277
        { 
278
            this.ArrowText = Base_TextBox.Text;
279
            Base_TextBox.Focusable = false;
280
            this.BaseTextbox_Caret.Visibility = Visibility.Collapsed;
281
            this.IsEditingMode = false;
282
            ApplyOverViewData();
283

    
284
            if(EditEnded != null)
285
            {
286
                EditEnded(this, new EventArgs());
287
            }
288

    
289
        }
290

    
291
        void Base_TextBox_GotFocus(object sender, RoutedEventArgs e)
292
        {
293
            this.BaseTextbox_Caret.Visibility = Visibility.Visible;
294
            MoveCustomCaret();
295
            Base_TextBox.Focus();
296
            this.IsEditingMode = true;
297
        }
298

    
299
        void Base_TextBox_SizeChanged(object sender, SizeChangedEventArgs e)
300
        {
301
            if(this.IsEditingMode)
302
            {
303
                if (Base_TextBox.Text.Contains("|OR||DZ|"))
304
                {
305
                    Base_TextBox.Text = this.ArrowText;
306
                }
307

    
308
                this.ArrowText = Base_TextBox.Text;
309
                
310
            }
311
            BoxWidth = e.NewSize.Width;
312
            BoxHeight = e.NewSize.Height;
313
            SetArrowTextPath();
314
        }
315

    
316
        #region Properties
317
        private bool _IsEditingMode;
318
        public bool IsEditingMode
319
        {
320
            get
321
            {
322
                return _IsEditingMode;
323
            }
324
            set
325
            {
326
                _IsEditingMode = value;
327
                OnPropertyChanged("IsEditingMode");
328
            }
329
        }
330

    
331

    
332
        #endregion
333

    
334
        #region dp Properties
335
        //강인구 주석 풀기
336
        public Visibility TextBoxVisibility
337
        {
338
            get { return (Visibility)GetValue(TextBoxVisibilityProperty); }
339
            set
340
            {
341
                if (this.TextBoxVisibility != value)
342
                {
343
                    SetValue(TextBoxVisibilityProperty, value);
344
                    OnPropertyChanged("TextBoxVisibility");
345
                }
346
            }
347
        }
348

    
349
        //강인구 주석 풀기
350
        public Visibility TextBlockVisibility
351
        {
352
            get { return (Visibility)GetValue(TextBlockVisibilityProperty); }
353
            set
354
            {
355
                if (this.TextBlockVisibility != value)
356
                {
357
                    SetValue(TextBlockVisibilityProperty, value);
358
                    OnPropertyChanged("TextBlockVisibility");
359
                }
360
            }
361
        }
362

    
363

    
364
        public override SolidColorBrush StrokeColor
365
        {
366
            get { return (SolidColorBrush)GetValue(StrokeColorProperty); }
367
            set
368
            {
369
                if (this.StrokeColor != value)
370
                {
371
                    SetValue(StrokeColorProperty, value);
372
                }
373
            }
374
        }
375

    
376
        public PathGeometry SubPathData
377
        {
378
            get { return (PathGeometry)GetValue(SubPathDataProperty); }
379
            set
380
            {
381
                if (this.SubPathData != value)
382
                {
383
                    SetValue(SubPathDataProperty, value);
384
                }
385
            }
386
        }
387

    
388
        public string UserID
389
        {
390
            get { return (string)GetValue(UserIDProperty); }
391
            set
392
            {
393
                if (this.UserID != value)
394
                {
395
                    SetValue(UserIDProperty, value);
396
                    OnPropertyChanged("UserID");
397
                }
398
            }
399
        }
400

    
401
        public List<Point> PointSet
402
        {
403
            get { return (List<Point>)GetValue(PointSetProperty); }
404
            set { SetValue(PointSetProperty, value); }
405
        }
406

    
407
        public override bool IsSelected
408
        {
409
            get
410
            {
411
                return (bool)GetValue(IsSelectedProperty);
412
            }
413
            set
414
            {
415
                SetValue(IsSelectedProperty, value);
416
                OnPropertyChanged("IsSelected");
417
            }
418
        }
419

    
420
        public override ControlType ControlType
421
        {
422
            set
423
            {
424
                SetValue(ControlTypeProperty, value);
425
                OnPropertyChanged("ControlType");
426
            }
427
            get
428
            {
429
                return (ControlType)GetValue(ControlTypeProperty);
430
            }
431
        }
432

    
433
        public Point StartPoint
434
        {
435
            get { return (Point)GetValue(StartPointProperty); }
436
            set { SetValue(StartPointProperty, value); }
437
        }
438

    
439
        public Point EndPoint
440
        {
441
            get { return (Point)GetValue(EndPointProperty); }
442
            set { SetValue(EndPointProperty, value); }
443
        }
444

    
445
        public Point OverViewStartPoint
446
        {
447
            get { return (Point)GetValue(OverViewStartPointProperty); }
448
            set { SetValue(OverViewStartPointProperty, value); }
449
        }
450

    
451
        public Point OverViewEndPoint
452
        {
453
            get { return (Point)GetValue(OverViewEndPointProperty); }
454
            set { SetValue(OverViewEndPointProperty, value); }
455
        }
456

    
457

    
458
        //public double Angle
459
        //{
460
        //    get { return (double)GetValue(AngleProperty); }
461
        //    set { SetValue(AngleProperty, value); }
462
        //}
463

    
464
        public Thickness BorderSize
465
        {
466
            get { return (Thickness)GetValue(BorderSizeProperty); }
467
            set
468
            {
469
                if (this.BorderSize != value)
470
                {
471
                    SetValue(BorderSizeProperty, value);
472
                }
473
            }
474
        }
475

    
476

    
477
        public Point MidPoint
478
        {
479
            get { return (Point)GetValue(MidPointProperty); }
480
            set { SetValue(MidPointProperty, value); }
481
        }
482

    
483
        public bool isFixed
484
        {
485
            get { return (bool)GetValue(IsFixedProperty); }
486
            set { SetValue(IsFixedProperty, value); }
487
        }
488

    
489
        public bool isTrans
490
        {
491
            get { return (bool)GetValue(TransformerProperty); }
492
            set { SetValue(TransformerProperty, value); }
493
        }
494

    
495
        public bool isHighLight
496
        {
497
            get { return (bool)GetValue(isHighlightProperty); }
498
            set
499
            {
500
                if (this.isHighLight != value)
501
                {
502
                    SetValue(isHighlightProperty, value);
503
                    OnPropertyChanged("isHighLight");
504
                }
505
            }
506
        }
507

    
508
        public FontWeight TextWeight
509
        {
510
            get { return (FontWeight)GetValue(TextWeightProperty); }
511
            set
512
            {
513
                if (this.TextWeight != value)
514
                {
515
                    SetValue(TextWeightProperty, value);
516
                    OnPropertyChanged("TextWeight");
517
                }
518
            }
519
        }
520

    
521
        public Double LineSize
522
        {
523
            get { return (Double)GetValue(LineSizeProperty); }
524
            set
525
            {
526
                if (this.LineSize != value)
527
                {
528
                    SetValue(LineSizeProperty, value);
529
                }
530
            }
531
        }
532

    
533
        public Double BoxWidth
534
        {
535
            get { return (Double)GetValue(BoxWidthProperty); }
536
            set
537
            {
538
                if (this.BoxWidth != value)
539
                {
540
                    SetValue(BoxWidthProperty, value);
541
                }
542
            }
543
        }
544

    
545
        public Double BoxHeight
546
        {
547
            get { return (Double)GetValue(BoxHeightProperty); }
548
            set
549
            {
550
                if (this.BoxHeight != value)
551
                {
552
                    SetValue(BoxHeightProperty, value);
553
                }
554
            }
555
        }
556

    
557
        public ArrowTextStyleSet ArrowTextStyle
558
        {
559
            get { return (ArrowTextStyleSet)GetValue(ArrowTextStyleProperty); }
560
            set
561
            {
562
                if (this.ArrowTextStyle != value)
563
                {
564
                    SetValue(ArrowTextStyleProperty, value);
565
                }
566
            }
567
        }
568

    
569
        public Geometry PathData
570
        {
571
            get { return (Geometry)GetValue(PathDataProperty); }
572
            set { SetValue(PathDataProperty, value);
573

    
574
                OnPropertyChanged("PathData");
575
            }
576
        }
577

    
578
        public SolidColorBrush BackInnerColor
579
        {
580
            get { return (SolidColorBrush)GetValue(BackInnerColorProperty); }
581
            set
582
            {
583
                if (this.BackInnerColor != value)
584
                {
585
                    SetValue(BackInnerColorProperty, value);
586
                    OnPropertyChanged("BackInnerColor");
587
                }
588
            }
589
        }
590

    
591
        public Geometry PathDataInner
592
        {
593
            get { return (Geometry)GetValue(PathDataInnerProperty); }
594
            set
595
            {
596
                SetValue(PathDataInnerProperty, value);
597
                OnPropertyChanged("PathDataInner");
598
            }
599
        }
600

    
601
        public Geometry OverViewPathData
602
        {
603
            get { return (Geometry)GetValue(OverViewPathDataProperty); }
604
            set { SetValue(OverViewPathDataProperty, value);
605

    
606
                OnPropertyChanged("OverViewPathData");
607

    
608
            }
609
        }
610

    
611
        public FontFamily TextFamily
612
        {
613
            get { return (FontFamily)GetValue(TextFamilyProperty); }
614
            set
615
            {
616
                if (this.TextFamily != value)
617
                {
618
                    SetValue(TextFamilyProperty, value);
619
                    OnPropertyChanged("TextFamily");
620
                }
621
            }
622
        }
623

    
624
        public string ArrowText
625
        {
626
            get { return (string)GetValue(ArrowTextProperty); }
627
            set
628
            {
629
                if (this.ArrowText != value)
630
                {
631
                    SetValue(ArrowTextProperty, value);
632
                    OnPropertyChanged("ArrowText");
633
                }
634
            }
635
        }
636

    
637
        public string OverViewArrowText
638
        {
639

    
640
            get { return (string)GetValue(OverViewArrowTextProperty);
641
            }
642
            set
643
            {
644
                if (this.OverViewArrowText != value)
645
                {
646
                    SetValue(OverViewArrowTextProperty, value);
647
                    OnPropertyChanged("OverViewArrowText");
648
                }
649
            }
650
        }
651

    
652
        public Double TextSize
653
        {
654
            get { return (Double)GetValue(TextSizeProperty); }
655
            set
656
            {
657
                if (this.TextSize != value)
658
                {
659
                    SetValue(TextSizeProperty, value);
660
                    OnPropertyChanged("TextSize");
661
                }
662
            }
663
        }
664

    
665
        public FontStyle TextStyle
666
        {
667
            get { return (FontStyle)GetValue(TextStyleProperty); }
668
            set
669
            {
670
                if (this.TextStyle != value)
671
                {
672
                    SetValue(TextStyleProperty, value);
673
                    OnPropertyChanged("TextStyle");
674
                }
675
            }
676
        }
677

    
678
        //강인구 추가
679
        public TextDecorationCollection UnderLine
680
        {
681
            get
682
            {
683
                return (TextDecorationCollection)GetValue(UnderLineProperty);
684
            }
685
            set
686
            {
687
                if (this.UnderLine != value)
688
                {
689
                    SetValue(UnderLineProperty, value);
690
                    OnPropertyChanged("UnderLine");
691
                }
692
            }
693
        }
694

    
695
        public double CanvasX
696
        {
697
            get { return (double)GetValue(CanvasXProperty); }
698
            set
699
            {
700
                if (this.CanvasX != value)
701
                {
702
                    SetValue(CanvasXProperty, value);
703
                    OnPropertyChanged("CanvasX");
704
                }
705
            }
706
        }
707

    
708
        public double CanvasY
709
        {
710
            get { return (double)GetValue(CanvasYProperty); }
711
            set
712
            {
713
                if (this.CanvasY != value)
714
                {
715
                    SetValue(CanvasYProperty, value);
716
                    OnPropertyChanged("CanvasY");
717
                }
718
            }
719
        } 
720

    
721
        public double CenterX
722
        {
723
            get { return (double)GetValue(CenterXProperty); }
724
            set { SetValue(CenterXProperty, value);
725
            OnPropertyChanged("CenterX");
726
            
727
            }
728
        }
729

    
730
        public double CenterY
731
        {
732
            get { return (double)GetValue(CenterYProperty); }
733
            set { SetValue(CenterYProperty, value);
734
            OnPropertyChanged("CenterY");
735
            }
736
        }
737

    
738
        public Brush SubPathFill
739
        {
740
            get { return (Brush)GetValue(SubPathFillProperty); }
741
            set
742
            {
743
                SetValue(SubPathFillProperty, value);
744
                OnPropertyChanged("SubPathFill");
745
            }
746
        }
747

    
748
        public Brush TextBoxBackground
749
        {
750
            get { return (Brush)GetValue(TextBoxBackgroundProperty); }
751
            set
752
            {
753
                SetValue(TextBoxBackgroundProperty, value);
754
                OnPropertyChanged("TextBoxBackground");
755
            }
756
        }
757

    
758

    
759
        //강인구 추가 주석풀기
760
       
761

    
762
        public bool EnableEditing
763
        {
764
            get { return (bool)GetValue(EnableEditingProperty); }
765
            set
766
            {
767
                if (this.EnableEditing != value)
768
                {
769
                    SetValue(EnableEditingProperty, value);
770
                    OnPropertyChanged("EnableEditing");
771
                }
772
            }
773
        }
774

    
775
        #endregion
776

    
777
        #region Dependency Properties
778

    
779
        public static readonly DependencyProperty BoxWidthProperty = DependencyProperty.Register(
780
                "BoxWidth", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
781

    
782
        public static readonly DependencyProperty BoxHeightProperty = DependencyProperty.Register(
783
                "BoxHeight", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
784

    
785
        public static readonly DependencyProperty UserIDProperty = DependencyProperty.Register(
786
                "UserID", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
787

    
788
        public static readonly DependencyProperty ArrowTextStyleProperty = DependencyProperty.Register(
789
               "ArrowTextStyle", typeof(ArrowTextStyleSet), typeof(ArrowTextControl), new PropertyMetadata(ArrowTextStyleSet.Normal));
790

    
791
        public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register(
792
                "CenterX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
793

    
794
        public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register(
795
                "CenterY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
796

    
797
        public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
798
                "Angle", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0.0, new PropertyChangedCallback(PointValueChanged)));
799
        
800
        public static readonly DependencyProperty CanvasXProperty = DependencyProperty.Register(
801
                "CanvasX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
802

    
803
        public static readonly DependencyProperty CanvasYProperty = DependencyProperty.Register(
804
                "CanvasY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
805

    
806
        public static readonly DependencyProperty PointSetProperty = DependencyProperty.Register(
807
                "PointSet", typeof(List<Point>), typeof(ArrowTextControl), new PropertyMetadata(new List<Point>(), PointValueChanged));
808

    
809
        public static readonly DependencyProperty TextFamilyProperty = DependencyProperty.Register(
810
                "TextFamily", typeof(FontFamily), typeof(ArrowTextControl), new PropertyMetadata(new FontFamily("Arial"), TextChanged));
811

    
812
        public static readonly DependencyProperty PathDataProperty = DependencyProperty.Register(
813
                "PathData", typeof(Geometry), typeof(ArrowTextControl), null);
814

    
815
        //강인구 추가
816
        public static readonly DependencyProperty UnderLineProperty = DependencyProperty.Register(
817
    "UnderLine", typeof(TextDecorationCollection), typeof(ArrowTextControl), new PropertyMetadata(null, PointValueChanged));
818

    
819
        public static readonly DependencyProperty LineSizeProperty = DependencyProperty.Register(
820
               "LineSize", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)3, PointValueChanged));
821

    
822
        public static readonly DependencyProperty TextStyleProperty = DependencyProperty.Register(
823
                "TextStyle", typeof(FontStyle), typeof(ArrowTextControl), new PropertyMetadata(FontStyles.Normal));
824

    
825
        public static readonly DependencyProperty TextSizeProperty = DependencyProperty.Register(
826
                "TextSize", typeof(Double), typeof(ArrowTextControl), new PropertyMetadata((Double)30, PointValueChanged));
827

    
828
        public static readonly DependencyProperty TextWeightProperty = DependencyProperty.Register(
829
                "TextWeight", typeof(FontWeight), typeof(ArrowTextControl), new PropertyMetadata(FontWeights.Normal));
830

    
831
        public static readonly DependencyProperty IsFixedProperty = DependencyProperty.Register(
832
                "isFixed", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
833

    
834
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
835
                "IsSelected", typeof(bool), typeof(ArrowTextControl), new FrameworkPropertyMetadata(false, IsSelectedChanged));
836

    
837
        public static readonly DependencyProperty StrokeColorProperty = DependencyProperty.Register(
838
                "StrokeColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
839

    
840
        public static readonly DependencyProperty ControlTypeProperty = DependencyProperty.Register(
841
                "ControlType", typeof(ControlType), typeof(ArrowTextControl), new FrameworkPropertyMetadata(ControlType.ArrowTextControl));
842

    
843
        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register(
844
                "StartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
845

    
846
        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register(
847
                "EndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
848

    
849
        public static readonly DependencyProperty BackInnerColorProperty = DependencyProperty.Register(
850
            "BackInnerColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.White)));
851

    
852
        public static readonly DependencyProperty PathDataInnerProperty = DependencyProperty.Register(
853
    "PathDataInner", typeof(Geometry), typeof(ArrowTextControl), null);
854

    
855
        public static readonly DependencyProperty isHighlightProperty = DependencyProperty.Register(
856
                "isHighlight", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
857

    
858
        public static readonly DependencyProperty MidPointProperty = DependencyProperty.Register(
859
                "MidPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
860

    
861
        public static readonly DependencyProperty TransformerProperty = DependencyProperty.Register(
862
                "isTrans", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
863

    
864
        public static readonly DependencyProperty BorderSizeProperty = DependencyProperty.Register(
865
                "BorderSize", typeof(Thickness), typeof(ArrowTextControl), new PropertyMetadata(new Thickness(0), PointValueChanged));
866
    
867
        public static readonly DependencyProperty ArrowTextProperty = DependencyProperty.Register(
868
              "ArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
869

    
870

    
871

    
872
        //, new PropertyChangedCallback(TextChanged)
873

    
874

    
875
        #region 추가 사항
876
        public static readonly DependencyProperty SubPathDataProperty = DependencyProperty.Register(
877
                "SubPathData", typeof(Geometry), typeof(ArrowTextControl), null);
878

    
879

    
880
        public static readonly DependencyProperty SubPathFillProperty = DependencyProperty.Register(
881
                "SubPathFill", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(null));
882

    
883
        public static readonly DependencyProperty TextBoxBackgroundProperty = DependencyProperty.Register(
884
                "TextBoxBackground", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(Brushes.White));
885

    
886
        public static readonly DependencyProperty OverViewArrowTextProperty = DependencyProperty.Register(
887
                "OverViewArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null, new PropertyChangedCallback(TextChanged)));
888

    
889
        public static readonly DependencyProperty OverViewPathDataProperty = DependencyProperty.Register(
890
                "OverViewPathData", typeof(Geometry), typeof(ArrowTextControl), null);
891

    
892
        public static readonly DependencyProperty OverViewStartPointProperty = DependencyProperty.Register(
893
                "OverViewStartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
894

    
895
        public static readonly DependencyProperty OverViewEndPointProperty = DependencyProperty.Register(
896
                "OverViewEndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
897

    
898
        public static readonly DependencyProperty TextBoxVisibilityProperty = DependencyProperty.Register(
899
            "TextBoxVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Visible), OnTextBoxVisibilityChanged));
900

    
901
        //강인구 추가(주석풀기)
902
        public static readonly DependencyProperty TextBlockVisibilityProperty = DependencyProperty.Register(
903
            "TextBlockVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Collapsed), OnTextBlockVisibilityChanged));
904

    
905
        public static readonly DependencyProperty EnableEditingProperty = DependencyProperty.Register(
906
           "EnableEditing", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata((true), new PropertyChangedCallback(OnIsEditingChanged)));
907

    
908
        #endregion
909

    
910
        #endregion
911

    
912
        #region CallBack Method
913

    
914
        //강인구 추가(주석풀기)
915
        public static void OnIsEditingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
916
        {
917
            var instance = (ArrowTextControl)sender;
918

    
919
            if (e.OldValue != e.NewValue && instance.Base_TextBlock != null)
920
            {
921
                instance.SetValue(e.Property, e.NewValue);
922

    
923
                if (instance.EnableEditing)
924
                {
925
                    instance.EditingMode();
926
                }
927
                else
928
                {
929
                    instance.UnEditingMode();
930
                }
931
            }
932
        }
933

    
934
        public static void OnTextBoxVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
935
        {
936
            var instance = (ArrowTextControl)sender;
937

    
938
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
939
            {
940
                instance.SetValue(e.Property, e.NewValue);
941
            }
942
        }
943

    
944
        public static void OnTextBlockVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
945
        {
946
            var instance = (ArrowTextControl)sender;
947

    
948
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
949
            {
950
                instance.SetValue(e.Property, e.NewValue);
951
            }
952
        }
953

    
954
        public static void PointValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
955
        {
956
            var instance = (ArrowTextControl)sender;
957

    
958
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
959
            {
960
                instance.SetArrowTextPath();
961
            }
962
        }
963

    
964

    
965

    
966
        public static void TextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
967
        {
968
            var instance = (ArrowTextControl)sender;
969
            
970
            if (e.OldValue != e.NewValue)
971
            {
972
                instance.SetValue(e.Property, e.NewValue);
973
                //instance.BoxWidth = instance.Base_TextBox.ActualWidth;
974
                //instance.BoxHeight = instance.Base_TextBox.ActualHeight;
975
            }
976
        }
977

    
978
        public static void OnCenterXYChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
979
        {
980
            var instance = (ArrowTextControl)sender;
981
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
982
            {
983
                instance.SetValue(e.Property, e.NewValue);
984
                instance.SetArrowTextPath();
985
            }
986
        }
987

    
988
        public static void OnSetCansvasChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
989
        {
990
            var instance = (ArrowTextControl)sender;
991

    
992
            if (e.OldValue != e.NewValue && instance != null)
993
            {
994
                instance.SetValue(e.Property, e.NewValue);
995
                //Canvas.SetLeft(instance, instance.CanvasX);
996
                //Canvas.SetTop(instance, instance.CanvasY);
997
            }
998
        }
999

    
1000
        public static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
1001
        {
1002
            //var instance = (ArrowTextControl)sender;
1003

    
1004
            //if (e.OldValue != e.NewValue)
1005
            //{
1006
            //    instance.SetValue(e.Property, e.NewValue);
1007

    
1008
            //    if (instance.IsSelected && instance.Base_TextBox != null)
1009
            //    {
1010
            //        instance.BorderSize = new Thickness(1);
1011
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Blue);
1012
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Blue);
1013
            //    }
1014
            //    else
1015
            //    {
1016
            //        instance.BorderSize = new Thickness(0);
1017
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Transparent);
1018
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Transparent);
1019
            //    }
1020
            //}
1021
        }
1022
        #endregion
1023

    
1024
        #region Internal Method
1025

    
1026
        //강인구 주석 풀기
1027
        public void EditingMode()
1028
        {
1029
            TextBoxVisibility = Visibility.Visible;
1030
            TextBlockVisibility = Visibility.Collapsed;
1031

    
1032

    
1033
            //강인구 언더라인 추가
1034
            if (UnderLine != null)
1035
                Base_TextBlock.TextDecorations = UnderLine;
1036
        }
1037
        //강인구 주석 풀기
1038
        public void UnEditingMode()
1039
        {
1040
            TextBoxVisibility = Visibility.Collapsed;
1041
            TextBlockVisibility = Visibility.Visible;
1042

    
1043
            if (Base_TextBlock != null)
1044
            {
1045
                if (UnderLine != null)
1046
                    Base_TextBlock.TextDecorations = UnderLine;
1047

    
1048
                Base_TextBlock.Margin =
1049
                     new Thickness(Base_TextBox.Margin.Left + 4, Base_TextBox.Margin.Top + 4,
1050
                         Base_TextBox.Margin.Right + 4, Base_TextBox.Margin.Bottom + 4);
1051
            }
1052

    
1053
            this.BaseTextbox_Caret.Visibility = Visibility.Collapsed;
1054
        }
1055

    
1056
        private void SetArrowTextPath(bool IsInit = false)
1057
        {
1058
            instanceGroup.Children.Clear();
1059

    
1060
            //VisualPageAngle = 0;
1061

    
1062
            if (Math.Abs(PageAngle).ToString() == "90")
1063
            {
1064
                VisualPageAngle = 270;
1065
            }
1066
            else if (Math.Abs(PageAngle).ToString() == "270")
1067
            {
1068
                VisualPageAngle = 90;
1069
            }
1070
            else
1071
            {
1072
                VisualPageAngle = PageAngle;
1073
            }
1074

    
1075
            connectorSMGeometry.StartPoint = this.StartPoint;
1076
            connectorSMGeometry.EndPoint = this.MidPoint;
1077
            connectorMEGeometry.StartPoint = this.MidPoint; //핵심
1078

    
1079
            /// 텍스트박스의 좌표 설정
1080
            Canvas.SetLeft(Base_TextBox, this.EndPoint.X);
1081
            Canvas.SetTop(Base_TextBox, this.EndPoint.Y);
1082
            //System.Diagnostics.Debug.WriteLine($"TextBox Set {this.EndPoint.X},{this.EndPoint.Y}");
1083
            
1084

    
1085
            List<Point> ps = new List<Point>();
1086
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox))); //상단
1087
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox) + this.BoxHeight)); // 하단
1088
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2)); //좌단
1089
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth, Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2));  //우단
1090

    
1091
            if (isTrans)
1092
            {
1093
                switch (Math.Abs(this.PageAngle).ToString())
1094
                {
1095
                    case "90":
1096
                        {
1097
                            ps.Clear();
1098
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1099
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1100
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1101

    
1102
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1103
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1104

    
1105
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); //중간 하단
1106
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 하단
1107

    
1108
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간
1109
                        }
1110
                        break;
1111
                    case "270":
1112
                        {
1113
                            ps.Clear();
1114
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1115
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1116
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1117

    
1118
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1119
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1120

    
1121
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1122
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1123

    
1124
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간
1125
                        }
1126
                        break;
1127
                    default:
1128
                        break;
1129
                }
1130
                
1131
                var endP = MathSet.getNearPoint(ps, this.MidPoint);
1132

    
1133
                //20180911 LJY 꺾이는 부분 수정
1134
                Point testP = endP;                
1135
                switch (Math.Abs(this.PageAngle).ToString())
1136
                {
1137
                    case "90":
1138
                        testP = new Point(endP.X + 50, endP.Y);
1139
                        break;
1140
                    case "270":
1141
                        testP = new Point(endP.X - 50, endP.Y);
1142
                        break;
1143
                }                
1144

    
1145
                //20180910 LJY 각도에 따라.
1146
                switch (Math.Abs(this.PageAngle).ToString())
1147
                {
1148
                    case "90":
1149
                        if (isFixed)
1150
                        {
1151
                            if (ps[0] == endP) //상단
1152
                            {
1153
                                testP = new Point(endP.X , endP.Y + 50);
1154
                                //System.Diagnostics.Debug.WriteLine("상단"+ testP);
1155
                            }
1156
                            else if (ps[1] == endP) //하단
1157
                            {
1158
                                testP = new Point(endP.X , endP.Y - 50);
1159
                                //System.Diagnostics.Debug.WriteLine("하단"+ testP);
1160
                            }
1161
                            else if (ps[2] == endP) //좌단
1162
                            {
1163
                                testP = new Point(endP.X - 50, endP.Y);
1164
                                //System.Diagnostics.Debug.WriteLine("좌단"+ testP);
1165
                            }
1166
                            else if (ps[3] == endP) //우단
1167
                            {
1168
                                testP = new Point(endP.X + 50, endP.Y);
1169
                                //System.Diagnostics.Debug.WriteLine("우단"+ testP);
1170
                            }
1171
                        }
1172
                        break;
1173
                    case "270":
1174
                        if (isFixed)
1175
                        {
1176
                            if (ps[0] == endP) //상단
1177
                            {
1178
                                testP = new Point(endP.X , endP.Y - 50);
1179
                                //System.Diagnostics.Debug.WriteLine("상단" + testP);
1180
                            }
1181
                            else if (ps[1] == endP) //하단
1182
                            {
1183
                                testP = new Point(endP.X, endP.Y + 50);
1184
                                //System.Diagnostics.Debug.WriteLine("하단" + testP);
1185
                            }
1186
                            else if (ps[2] == endP) //좌단
1187
                            {
1188
                                testP = new Point(endP.X + 50, endP.Y);
1189
                                //System.Diagnostics.Debug.WriteLine("좌단" + testP);
1190
                            }
1191
                            else if (ps[3] == endP) //우단
1192
                            {
1193
                                testP = new Point(endP.X - 50, endP.Y);
1194
                                //System.Diagnostics.Debug.WriteLine("우단" + testP);
1195
                            }
1196
                        }
1197
                        break;
1198
                    default:
1199
                        if (isFixed)
1200
                        {
1201
                            if (ps[0] == endP) //상단
1202
                            {
1203
                                testP = new Point(endP.X, endP.Y - 50);
1204
                                //System.Diagnostics.Debug.WriteLine("상단");
1205
                            }
1206
                            else if (ps[1] == endP) //하단
1207
                            {
1208
                                testP = new Point(endP.X, endP.Y + 50);
1209
                                //System.Diagnostics.Debug.WriteLine("하단");
1210
                            }
1211
                            else if (ps[2] == endP) //좌단
1212
                            {
1213
                                testP = new Point(endP.X - 50, endP.Y);
1214
                                //System.Diagnostics.Debug.WriteLine("좌단");
1215
                            }
1216
                            else if (ps[3] == endP) //우단
1217
                            {
1218
                                testP = new Point(endP.X + 50, endP.Y);
1219
                                //System.Diagnostics.Debug.WriteLine("우단");
1220
                            }
1221
                        }
1222
                        break;
1223
                }
1224
                connectorMEGeometry.EndPoint = endP;
1225
                connectorSMGeometry.EndPoint = testP;
1226
                connectorMEGeometry.StartPoint = testP;
1227
                
1228
                //20180910 LJY 각도에 따라.
1229
                this.MidPoint = testP;
1230
                instanceGroup.Children.Add(DrawSet.DrawArrow(testP, this.StartPoint, this.LineSize));
1231
                instanceGroup.FillRule = FillRule.Nonzero;
1232
                this.Base_ArrowPath.Fill = this.StrokeColor;
1233
                this.Base_ArrowSubPath.Fill = this.StrokeColor;
1234
            }
1235
            else
1236
            {
1237
                switch (Math.Abs(this.PageAngle).ToString())
1238
                {
1239
                    case "90":
1240
                        {
1241
                            ps.Clear();
1242

    
1243
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1244
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1245
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1246

    
1247
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1248
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1249

    
1250
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); //중간 하단
1251
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 하단
1252
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간 
1253
                        }
1254
                        break;
1255
                    case "270":
1256
                        {
1257
                            ps.Clear();
1258
                            
1259
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1260
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1261
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1262

    
1263
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1264
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1265

    
1266
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1267
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1268

    
1269
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간 
1270
                        }
1271
                        break;
1272
                    //case "180":
1273
                    //    {
1274
                    //        ps.Clear();
1275

    
1276
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1277
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1278
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1279

    
1280
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1281
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1282

    
1283
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1284
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1285

    
1286
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간 
1287
                    //    }
1288
                    //    break;
1289
                    default:
1290
                        break;
1291
                }
1292

    
1293

    
1294
                var endP = MathSet.getNearPoint(ps, this.MidPoint);
1295
                connectorMEGeometry.EndPoint = endP; //최상단
1296
                                                     //connectorMEGeometry.EndPoint = this.EndPoint; //핵심
1297
                                                     //this.MidPoint= MathSet.getMiddlePoint(this.StartPoint, endP);
1298
                #region 보정치
1299
                Point testP = endP;
1300

    
1301
                //20180910 LJY 각도에 따라.
1302
                switch (Math.Abs(this.PageAngle).ToString())
1303
                {
1304
                    case "90":
1305
                        if (isFixed)
1306
                        {
1307
                            if (ps[0] == endP) //상단
1308
                            {
1309
                                testP = new Point(endP.X - 50, endP.Y);
1310
                                //System.Diagnostics.Debug.WriteLine("상단"+ testP);
1311
                            }
1312
                            else if (ps[1] == endP) //하단
1313
                            {
1314
                                testP = new Point(endP.X + 50, endP.Y);
1315
                                //System.Diagnostics.Debug.WriteLine("하단"+ testP);
1316
                            }
1317
                            else if (ps[2] == endP) //좌단
1318
                            {
1319
                                testP = new Point(endP.X - 50, endP.Y);
1320
                                //System.Diagnostics.Debug.WriteLine("좌단"+ testP);
1321
                            }
1322
                            else if (ps[3] == endP) //우단
1323
                            {
1324
                                testP = new Point(endP.X + 50 , endP.Y);
1325
                                //System.Diagnostics.Debug.WriteLine("우단"+ testP);
1326
                            }
1327
                        }
1328
                        break;
1329
                    case "270":
1330
                        if (isFixed)
1331
                        {
1332
                            if (ps[0] == endP) //상단
1333
                            {
1334
                                testP = new Point(endP.X + 50, endP.Y);
1335
                                //System.Diagnostics.Debug.WriteLine("상단" + testP);
1336
                            }
1337
                            else if (ps[1] == endP) //하단
1338
                            {
1339
                                testP = new Point(endP.X - 50, endP.Y);
1340
                                //System.Diagnostics.Debug.WriteLine("하단" + testP);
1341
                            }
1342
                            else if (ps[2] == endP) //좌단
1343
                            {
1344
                                testP = new Point(endP.X + 50, endP.Y);
1345
                                //System.Diagnostics.Debug.WriteLine("좌단" + testP);
1346
                            }
1347
                            else if (ps[3] == endP) //우단
1348
                            {
1349
                                testP = new Point(endP.X + 50, endP.Y );
1350
                                //System.Diagnostics.Debug.WriteLine("우단" + testP);
1351
                            }
1352
                        }
1353
                        break;
1354
                    default:
1355
                        if (isFixed)
1356
                        {
1357
                            if (ps[0] == endP) //상단
1358
                            {
1359
                                testP = new Point(endP.X, endP.Y - 50);
1360
                                //System.Diagnostics.Debug.WriteLine("상단");
1361
                            }
1362
                            else if (ps[1] == endP) //하단
1363
                            {
1364
                                testP = new Point(endP.X, endP.Y + 50);
1365
                                //System.Diagnostics.Debug.WriteLine("하단");
1366
                            }
1367
                            else if (ps[2] == endP) //좌단
1368
                            {
1369
                                testP = new Point(endP.X - 50, endP.Y);
1370
                                //System.Diagnostics.Debug.WriteLine("좌단");
1371
                            }
1372
                            else if (ps[3] == endP) //우단
1373
                            {
1374
                                testP = new Point(endP.X + 50, endP.Y);
1375
                                //System.Diagnostics.Debug.WriteLine("우단");
1376
                            }
1377
                        }
1378
                        break;
1379
                }
1380
                  
1381

    
1382
                connectorSMGeometry.EndPoint = testP;
1383
                connectorMEGeometry.StartPoint = testP;
1384
                instanceGroup.Children.Add(DrawSet.DrawArrow(testP, this.StartPoint, this.LineSize));
1385
                instanceGroup.FillRule = FillRule.Nonzero;
1386
                this.Base_ArrowPath.Fill = this.StrokeColor;
1387
                this.Base_ArrowSubPath.Fill = this.StrokeColor;
1388
                #endregion
1389
            }
1390

    
1391
            switch (this.ArrowTextStyle)
1392
            {
1393
                case ArrowTextStyleSet.Normal:
1394
                    this.BorderSize = new Thickness(0);
1395
                    DrawingRect();
1396
                    break;
1397
                case ArrowTextStyleSet.Cloud:
1398
                    this.BorderSize = new Thickness(0);
1399
                    DrawingCloud();
1400
                    break;
1401
                default:
1402
                    {
1403
                        this.BorderSize = new Thickness(LineSize);
1404
                        DrawingRect();
1405
                    }
1406

    
1407
                    break;
1408
            }
1409

    
1410
            if (isHighLight)
1411
            {
1412
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1413
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1414

    
1415
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1416
            }
1417
            else
1418
            {
1419
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1420
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1421
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.1), Colors.White.R, Colors.White.G, Colors.White.B));
1422
            }
1423

    
1424
            instanceGroup.Children.Add(connectorSMGeometry);
1425
            instanceGroup.Children.Add(connectorMEGeometry);
1426

    
1427
            this.PathData = instanceGroup;
1428
            OverViewPathData = PathData;
1429
            OverViewArrowText = ArrowText;
1430
            OverViewEndPoint = connectorMEGeometry.EndPoint;
1431
            OverViewStartPoint = connectorSMGeometry.StartPoint;
1432

    
1433
            var tempAngle = Math.Abs(this.VisualPageAngle);
1434

    
1435
            if (tempAngle == Convert.ToDouble(90) || tempAngle == Convert.ToDouble(270))
1436
            {
1437
                this.RenderTransformOrigin = new Point(0.5, 0.5);
1438
                this.Base_ArrowPath.RenderTransformOrigin = new Point(0, 0);
1439
                this.Base_ArrowSubPath.RenderTransformOrigin = new Point(0, 0);
1440

    
1441
                Base_TextBox.RenderTransformOrigin = new Point(0, 0);
1442
                BaseTextbox_Caret.RenderTransformOrigin = new Point(0, 0);
1443
            }
1444

    
1445
            Base_TextBox.RenderTransform = new RotateTransform
1446
            {
1447
                Angle = this.VisualPageAngle,
1448
                CenterX = this.CenterX,
1449
                CenterY = this.CenterY,
1450
            };
1451

    
1452
            Base_ArrowSubPath.RenderTransform = new RotateTransform
1453
            {
1454
                Angle = this.VisualPageAngle,
1455
                CenterX = this.EndPoint.X,
1456
                CenterY = this.EndPoint.Y,
1457
            };
1458

    
1459
            if (BaseTextbox_Caret.Visibility == Visibility.Visible)
1460
            {
1461
                BaseTextbox_Caret.RenderTransform = new RotateTransform
1462
                {
1463
                    Angle = this.VisualPageAngle,
1464
                    CenterX = this.CenterX,
1465
                    CenterY = this.CenterY,
1466
                };
1467

    
1468
                MoveCustomCaret();
1469
            }
1470
        }
1471

    
1472
        private void DrawingCloud()
1473
        {
1474
            //20180906 LJY Textbox guide
1475
            string angle = Math.Abs(this.PageAngle).ToString();
1476
            if (angle == "180")
1477
            {
1478
                List<Point> pCloud = new List<Point>()
1479
                {
1480
                     new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1481
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxHeight), //왼쪽 아래
1482
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox) - BoxHeight),
1483
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox)),
1484
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1485
                };
1486
                SubPathData = (Generate(pCloud));
1487
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1488
            
1489
            }//20180906 LJY Textbox guide
1490
            else
1491
            {
1492
                var boxWidth = BoxWidth;
1493
                System.Diagnostics.Debug.WriteLine("disp Width : " + BoxWidth);
1494
                //boxWidth = boxWidth + Base_TextBox.Margin.Left + Base_TextBox.Margin.Right + Base_TextBox.Padding.Left + Base_TextBox.Padding.Right;
1495

    
1496
                List<Point> pCloud = new List<Point>()
1497
                {
1498
    #if SILVERLIGHT
1499
		            new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1500
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1501
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1502
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1503
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1504

    
1505
    #else
1506
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1507
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1508
                    new Point(Canvas.GetLeft(Base_TextBox)+ boxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1509
                    new Point(Canvas.GetLeft(Base_TextBox) + boxWidth, Canvas.GetTop(Base_TextBox)),
1510
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1511

    
1512
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1513
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1514
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1515
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1516
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1517
    #endif
1518
                };
1519
                //instanceGroup.Children.Add(Generate(pCloud));
1520
                SubPathData = (Generate(pCloud));
1521
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1522
                //   }
1523
            }
1524

    
1525
        }
1526

    
1527
        private void DrawingRect()
1528
        {
1529
            //20180906 LJY Textbox guide
1530
            if(this.ArrowTextStyle == ArrowTextStyleSet.Normal)
1531
            {
1532
                this.Base_TextBox.BorderBrush = Brushes.Transparent;
1533
            }
1534
            
1535
            if (Math.Abs(this.PageAngle).ToString() == "90")
1536
            {
1537
                List<Point> pCloud = new List<Point>()
1538
                {
1539
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1540
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxWidth), //왼쪽 아래
1541
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox) - BoxWidth),
1542
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox)),
1543
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1544
                };
1545
                PathDataInner = (GenerateInner(pCloud));
1546
            }
1547
            else if(Math.Abs(this.PageAngle).ToString() == "270")
1548
            {
1549
                List<Point> pCloud = new List<Point>()
1550
                {
1551
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1552
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + BoxWidth), //왼쪽 아래
1553
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox) + BoxWidth),
1554
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox)),
1555
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1556
                };
1557
                PathDataInner = (GenerateInner(pCloud));
1558
            }//20180906 LJY Textbox guide
1559
            else
1560
            { 
1561
                List<Point> pCloud = new List<Point>()
1562
                {
1563
    #if SILVERLIGHT
1564
		            new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1565
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1566
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1567
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1568
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1569

    
1570
    #else
1571
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1572
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1573
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1574
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1575
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1576

    
1577
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1578
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1579
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1580
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1581
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1582
    #endif
1583
                };
1584
                //instanceGroup.Children.Add(Generate(pCloud));
1585
                PathDataInner = (GenerateInner(pCloud));
1586
            }
1587
        }
1588

    
1589
        public override void UpdateControl()
1590
        {
1591
            this.StartPoint = new Point(this.PointSet[0].X, this.PointSet[0].Y);
1592
            this.MidPoint = new Point(this.PointSet[1].X, this.PointSet[1].Y);
1593
            this.EndPoint = new Point(this.PointSet[2].X, this.PointSet[2].Y);
1594
        }
1595

    
1596
        public override void ApplyOverViewData()
1597
        {
1598
            this.OverViewPathData = this.PathData;
1599
            if (ArrowText == "")
1600
            {
1601
                this.OverViewArrowText = "";
1602
                this.ArrowText = this.OverViewArrowText;
1603
            }
1604
            else
1605
                this.OverViewArrowText = this.ArrowText;
1606
            this.OverViewStartPoint = this.StartPoint;
1607
            this.OverViewEndPoint = this.EndPoint;
1608
        }
1609

    
1610
        #endregion
1611

    
1612
        public static PathFigure GenerateLineWithCloud(Point p1, Point p2, double arcLength_, bool reverse)
1613
        {
1614
            PathFigure pathFigure = new PathFigure();
1615
            pathFigure.StartPoint = p1;
1616

    
1617
            double arcLength = arcLength_;
1618
            /// draw arcs which has arcLength between p1 and p2 - 2012.06.21 added by humkyung 
1619
            double dx = p2.X - p1.X;
1620
            double dy = p2.Y - p1.Y;
1621
            double l = MathSet.DistanceTo(p1, p2); /// distance between p1 and p2
1622
            double theta = Math.Atan2(Math.Abs(dy), Math.Abs(dx)) * 180 / Math.PI;
1623
            Point lastPt = new Point(p1.X, p1.Y);
1624
            double count = l / arcLength;
1625
            /// normalize
1626
            dx /= l;
1627
            dy /= l;
1628
            Double j = 1;
1629
            for (j = 1; j < (count - 1); j++) 
1630
            {
1631
                ArcSegment arcSeg = new ArcSegment();
1632
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);						/// x size and y size of arc
1633
                arcSeg.Point = new Point(p1.X + j * dx * arcLength, p1.Y + j * dy * arcLength);	/// end point of arc
1634
                lastPt = arcSeg.Point;  /// save last point
1635
                arcSeg.RotationAngle = theta + 90;
1636
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1637
                pathFigure.Segments.Add(arcSeg);
1638
            }
1639

    
1640
            /// draw arc between last point and end point
1641
            if ((count > j) || (count > 0))
1642
            {
1643
                arcLength = MathSet.DistanceTo(lastPt, p2);
1644
                ArcSegment arcSeg = new ArcSegment();
1645
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);	/// x size and y size of arc
1646
                arcSeg.Point = new Point(p2.X, p2.Y);						/// end point of arc
1647
                arcSeg.RotationAngle = theta;
1648
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1649
                pathFigure.Segments.Add(arcSeg);
1650
            }
1651
            /// up to here
1652

    
1653
            return pathFigure;
1654
        }
1655

    
1656
        public static PathGeometry Generate(List<Point> pData)
1657
        {
1658
            var _pathGeometry = new PathGeometry();
1659
            
1660
            double area = MathSet.AreaOf(pData);
1661
            bool reverse = (area > 0);
1662
            int count = pData.Count;
1663
            for (int i = 0; i < (count - 1); i++)
1664
            {
1665
                PathFigure pathFigure = Polygon.CloudControl.GenerateLineWithCloud(pData[i], pData[i + 1], 20, reverse);
1666
                pathFigure.IsClosed = false;
1667
                pathFigure.IsFilled = false;
1668
                _pathGeometry.Figures.Add(pathFigure);
1669
            }
1670
            
1671
            return _pathGeometry;
1672
        }
1673

    
1674
        
1675
        public static PathGeometry GenerateInner(List<Point> pData)
1676
        {
1677
            var _pathGeometry = new PathGeometry();
1678
            double area = MathSet.AreaOf(pData);
1679
            bool reverse = (area > 0);
1680
            int count = pData.Count;
1681

    
1682
            PathFigure pathFigur2 = new PathFigure();
1683
            pathFigur2.StartPoint = pData[0];
1684

    
1685
            LineSegment lineSegment0 = new LineSegment();
1686
            lineSegment0.Point = pData[0];
1687
            pathFigur2.Segments.Add(lineSegment0);
1688

    
1689
            LineSegment lineSegment1 = new LineSegment();
1690
            lineSegment1.Point = pData[1];
1691
            pathFigur2.Segments.Add(lineSegment1);
1692

    
1693
            LineSegment lineSegment2 = new LineSegment();
1694
            lineSegment2.Point = pData[2];
1695
            pathFigur2.Segments.Add(lineSegment2);
1696

    
1697
            LineSegment lineSegment3 = new LineSegment();
1698
            lineSegment3.Point = pData[3];
1699
            pathFigur2.Segments.Add(lineSegment3);
1700

    
1701

    
1702
            pathFigur2.IsClosed = true;
1703
            pathFigur2.IsFilled = true;
1704
            _pathGeometry.Figures.Add(pathFigur2);           
1705

    
1706
            return _pathGeometry;
1707
        }
1708

    
1709
        //20180910 LJY Cloud rotation 추가
1710
        public static PathGeometry GenerateInnerCloud(List<Point> pData, string angle)
1711
        {
1712
            var _pathGeometry = new PathGeometry();
1713
            double area = MathSet.AreaOf(pData);
1714
            bool reverse = (area > 0);
1715
            int count = pData.Count;
1716

    
1717
            PathFigure pathFigur2 = new PathFigure();
1718
            pathFigur2.StartPoint = pData[0];
1719

    
1720
            LineSegment lineSegment0 = new LineSegment();
1721
            lineSegment0.Point = pData[0];
1722
            pathFigur2.Segments.Add(lineSegment0);
1723

    
1724
            LineSegment lineSegment1 = new LineSegment();
1725
            lineSegment1.Point = pData[1];
1726
            pathFigur2.Segments.Add(lineSegment1);
1727

    
1728
            LineSegment lineSegment2 = new LineSegment();
1729
            lineSegment2.Point = pData[2];
1730
            pathFigur2.Segments.Add(lineSegment2);
1731

    
1732
            LineSegment lineSegment3 = new LineSegment();
1733
            lineSegment3.Point = pData[3];
1734
            pathFigur2.Segments.Add(lineSegment3);
1735
            
1736
            RotateTransform transform = new RotateTransform();
1737
            switch (angle)
1738
            {
1739
                case "90":
1740
                    transform.Angle = -90;
1741
                    break;
1742
                case "180":
1743
                    transform.Angle = -180;
1744
                    break;
1745
                case "270":
1746
                    transform.Angle = -270;
1747
                    break;
1748
            }
1749
            transform.CenterX = pData[0].X;
1750
            transform.CenterY = pData[0].Y;
1751
            _pathGeometry.Transform = transform;
1752

    
1753
            pathFigur2.IsClosed = true;
1754
            pathFigur2.IsFilled = true;
1755
            _pathGeometry.Figures.Add(pathFigur2);
1756

    
1757
            return _pathGeometry;
1758
        }
1759

    
1760
        /// <summary>
1761
        /// call when mouse is moving while drawing control
1762
        /// </summary>
1763
        /// <author>humkyung</author>
1764
        /// <param name="pt"></param>
1765
        /// <param name="bAxisLocked"></param>
1766
        public override void OnCreatingMouseMove(Point pt, bool bAxisLocked)
1767
        {
1768
            this.EndPoint = pt;
1769

    
1770
            Point tempPoint = this.EndPoint;
1771
            CommentAngle = MathSet.returnAngle(this.StartPoint, ref tempPoint, bAxisLocked);
1772

    
1773
            if (bAxisLocked)
1774
            {
1775
                this.EndPoint = tempPoint;
1776
            }
1777

    
1778
            this.MidPoint = MathSet.getMiddlePoint(this.StartPoint, this.EndPoint);
1779
            this.isFixed = (this.ControlType == ControlType.ArrowTransTextControl) || 
1780
                (this.ControlType == ControlType.ArrowTransTextBorderControl) || (this.ControlType == ControlType.ArrowTransTextCloudControl);
1781

    
1782
            this.PointSet = new List<Point>
1783
            {
1784
                this.StartPoint,
1785
                this.MidPoint,
1786
                this.EndPoint,
1787
            };
1788
        }
1789

    
1790
        /// <summary>
1791
        /// move control point has same location of given pt along given delta
1792
        /// </summary>
1793
        /// <author>humkyung</author>
1794
        /// <date>2019.06.20</date>
1795
        /// <param name="pt"></param>
1796
        /// <param name="dx"></param>
1797
        /// <param name="dy"></param>
1798
        public override void OnMoveCtrlPoint(Point pt, double dx, double dy, bool bAxisLocked = false)
1799
        {
1800
            IPath path = (this as IPath);
1801

    
1802
            Point selected = MathSet.getNearPoint(path.PointSet, pt);
1803

    
1804
            //StartPoint에 표시된 Thumb는 dx,dy가 +로 더해줘야한다.
1805
            if (path.PointSet.IndexOf(selected) != 0)
1806
            {
1807
                double radian = this.CommentAngle * Math.PI / 180;
1808
                double cos = Math.Cos(radian);
1809
                double sin = Math.Sin(radian);
1810

    
1811
                double _dx = dx * cos - dy * sin;
1812
                double _dy = dx * sin + dy * cos;
1813

    
1814
                //var transform = new RotateTransform() { Angle = CommentAngle, CenterX = dx, CenterY = dy };
1815
                //var transformedPoint = transform.Transform(pt);
1816
                //selected = transformedPoint;
1817

    
1818
                selected.X += _dx;
1819
                selected.Y += _dy;
1820
            }
1821
            else
1822
            {
1823
                selected.X += dx;
1824
                selected.Y += dy;
1825
            }
1826

    
1827
    int i = 0;
1828
            for (i = 0; i < (this as IPath).PointSet.Count; i++)
1829
            {
1830
                if (pt.Equals((this as IPath).PointSet[i])) break;
1831
            }
1832

    
1833
            List<Point> pts = path.PointSet;
1834
            if ((pts[0].X > pts[1].X && dx > 0) || (pts[0].X < pts[1].X && dx < 0))
1835
            {
1836
                pts[1] = new Point(pts[1].X + dx, pts[1].Y);
1837
            }
1838
            if ((pts[0].Y > pts[1].Y && dy > 0) || (pts[0].Y < pts[1].Y && dy < 0))
1839
            {
1840
                pts[1] = new Point(pts[1].X, pts[1].Y + dy);
1841
            }
1842

    
1843
            path.PointSet[1] = pts[1];
1844

    
1845
            if (path.PointSet.Count > i) {
1846
                path.PointSet[i] = selected;
1847
            }
1848
            //System.Diagnostics.Debug.WriteLine($"OnMoveCtrlPoint end : {path.PointSet[1].X},{path.PointSet[1].Y}");
1849
            this.UpdateControl();
1850
        }
1851

    
1852
        /// <summary>
1853
        /// return ArrowTextControl's area
1854
        /// </summary>
1855
        /// <author>humkyung</author>
1856
        /// <date>2019.06.13</date>
1857
        public override Rect ItemRect
1858
        {
1859
            get
1860
            {
1861
                double dMinX = Math.Min(this.StartPoint.X, this.EndPoint.X);
1862
                double dMinY = Math.Min(this.StartPoint.Y, this.EndPoint.Y);
1863
                double dMaxX = Math.Max(this.StartPoint.X, this.EndPoint.X);
1864
                double dMaxY = Math.Max(this.StartPoint.Y, this.EndPoint.Y);
1865

    
1866
                return new Rect(new Point(dMinX, dMinY), new Point(dMaxX, dMaxY));
1867
            }
1868
        }
1869

    
1870
        /// <summary>
1871
        /// Serialize this
1872
        /// </summary>
1873
        /// <param name="sUserId"></param>
1874
        /// <returns></returns>
1875
        public override string Serialize()
1876
        {
1877
            using (S_ArrowTextControl STemp = new S_ArrowTextControl())
1878
            {
1879
                STemp.TransformPoint = "0|0";
1880
                STemp.PointSet = this.PointSet;
1881
                STemp.SizeSet = String.Format("{0}", this.LineSize);
1882
                STemp.StrokeColor = this.StrokeColor.Color.ToString();
1883
                STemp.StartPoint = this.StartPoint;
1884
                STemp.ArrowStyle = this.ArrowTextStyle;
1885
                //STemp.StrokeColor = "#FF00FF00";
1886
                STemp.UserID = this.UserID;
1887
                STemp.ArrowText = this.Base_TextBox.Text;
1888
                STemp.BorderSize = this.BorderSize;
1889
                STemp.isHighLight = this.isHighLight;
1890
                STemp.BoxHeight = this.BoxHeight;
1891
                STemp.BoxWidth = this.BoxWidth;
1892
                STemp.Opac = this.Opacity;
1893
                STemp.EndPoint = this.EndPoint;
1894
                STemp.isFixed = this.isFixed;
1895
                //STemp.DashSize = this.DashSize;
1896
                STemp.Name = this.GetType().Name.ToString();
1897
                STemp.isTrans = this.isTrans;
1898
                STemp.MidPoint = this.MidPoint;
1899
                STemp.Angle = this.PageAngle;
1900
                STemp.fontConfig = new List<string>()
1901
                            {
1902
                                this.TextFamily.FontName(),
1903
                                this.TextStyle.ToString(),
1904
                                this.TextWeight.ToString(),
1905
                                this.TextSize.ToString(),
1906
                            };
1907

    
1908
                if (this.UnderLine != null)
1909
                {
1910
                    STemp.fontConfig.Add("true");
1911
                }
1912

    
1913
                ///강인구 추가(2017.11.02)
1914
                ///Memo 추가
1915
                STemp.Memo = this.Memo;
1916
                STemp.BorderSize = this.BorderSize;
1917
                return "|DZ|" + JsonSerializerHelper.CompressString((STemp.JsonSerialize()));
1918
            };
1919
        }
1920

    
1921
        /// <summary>
1922
        /// create a arrowtextcontrol from given string
1923
        /// </summary>
1924
        /// <param name="str"></param>
1925
        /// <returns></returns>
1926
        public static ArrowTextControl FromString(string str, SolidColorBrush brush, string sProjectNo,double PageAngle)
1927
        {
1928
            ArrowTextControl instance = null;
1929
            using (S_ArrowTextControl s = JsonSerializerHelper.JsonDeserialize<S_ArrowTextControl>(str))
1930
            {
1931
                string[] data2 = s.SizeSet.Split(delimiterChars2, StringSplitOptions.RemoveEmptyEntries);
1932
                instance = new ArrowTextControl();
1933
                instance.PageAngle = s.Angle;
1934
                instance.LineSize = Convert.ToDouble(data2.First());
1935
                instance.PointSet = s.PointSet;
1936
                instance.StartPoint = s.StartPoint;
1937
                instance.EndPoint = s.EndPoint;
1938
                instance.StrokeColor = brush;
1939
                //instance.DashSize = s.DashSize; 
1940
                instance.ArrowTextStyle = s.ArrowStyle;
1941
                instance.isHighLight = s.isHighLight;
1942
                instance.ArrowText = s.ArrowText;
1943
                instance.Opacity = s.Opac;
1944
                instance.BorderSize = s.BorderSize;
1945
                instance.BoxWidth = s.BoxWidth;
1946
                instance.BoxHeight = s.BoxHeight;
1947
                instance.isFixed = s.isFixed;
1948
                //instance.VisualPageAngle = s.Angle;
1949
                instance.UserID = s.UserID;
1950
                instance.isTrans = s.isTrans;
1951
                instance.MidPoint = s.MidPoint;
1952
                instance.Memo = s.Memo;
1953
                if (s.fontConfig == null || s.fontConfig.ToList().Count == 0)
1954
                {
1955
                    s.fontConfig = new List<string>();
1956

    
1957
                    s.fontConfig.Add("Arial");
1958
                    s.fontConfig.Add("Normal");
1959
                    s.fontConfig.Add("Normal");
1960
                    s.fontConfig.Add("30");
1961
                }
1962
                instance.TextFamily = Markus.Fonts.FontHelper.GetFontFamily(s.fontConfig[0]);
1963
                //인구 추가(2018.04.17)
1964
                instance.TextStyle = StringToFont.ConFontStyle(s.fontConfig[1]);
1965
                instance.TextWeight = StringToFont.ConFontWeight(s.fontConfig[2]);
1966
                instance.TextSize = Convert.ToDouble(s.fontConfig[3]);
1967

    
1968
                if (s.fontConfig.Count() == 5)
1969
                {
1970
                    instance.UnderLine = TextDecorations.Underline;
1971
                }
1972
            }
1973

    
1974
            return instance;
1975
        }
1976

    
1977
        #region Dispose
1978
        public void Dispose()
1979
        {
1980
            //GC.Collect();
1981
            ////GC.SuppressFinalize(this);
1982
            this.BaseTextbox_Caret = null;
1983
            this.Base_ArrowPath = null;
1984
            this.Base_ArrowSubPath = null;
1985
            this.Base_TextBlock = null;
1986
            this.Base_TextBox = null;
1987
        } 
1988
        #endregion
1989

    
1990
        #region INotifyPropertyChanged
1991
        private void OnPropertyChanged(string name)
1992
        {
1993
            if (PropertyChanged != null)
1994
            {
1995
                PropertyChanged(this, new PropertyChangedEventArgs(name));
1996
            }
1997
        }
1998

    
1999
        public Rect GetCommentRect()
2000
        {
2001
            Rect rect = new Rect();
2002

    
2003
            rect.Location = new Point();
2004
            rect.Size = new Size();
2005

    
2006
            List<Point> points = new List<Point>();
2007

    
2008
            points.AddRange(this.PointSet);
2009

    
2010
            var boxTopleft = new Point(Canvas.GetTop(Base_TextBox), Canvas.GetLeft(Base_TextBox));
2011
            points.Add(boxTopleft);
2012

    
2013
            var boxBottomRight =new Point(boxTopleft.X + Base_TextBox.ActualWidth, boxTopleft.Y + Base_TextBox.ActualHeight);
2014
            points.Add(boxBottomRight);
2015

    
2016
            rect = CommentMath.CalculateBoundingRect(points);
2017

    
2018
            return rect;
2019
        }
2020

    
2021
        public event PropertyChangedEventHandler PropertyChanged; 
2022
        #endregion
2023
    }
2024
}
클립보드 이미지 추가 (최대 크기: 500 MB)