프로젝트

일반

사용자정보

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

markus / MarkupToPDF / Controls / Text / ArrowTextControl.cs @ 4f017ed3

이력 | 보기 | 이력해설 | 다운로드 (78.4 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
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

    
35
        private const double _CloudArcDepth = 0.8;  /// 2018.05.14 added by humkyung
36

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

    
44
        public enum ArrowTextStyleSet { Normal, Cloud, Rect };
45

    
46
        #endregion
47

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

    
57
        public ArrowTextControl()
58
        {
59
            //this.DefaultStyleKey = typeof(ArrowTextControl);
60
        }
61

    
62
        public override void OnApplyTemplate()
63
        {
64
            base.OnApplyTemplate();
65
            Base_ArrowPath = GetTemplateChild(PART_ArrowPath) as Path;
66
            Base_ArrowSubPath = GetTemplateChild(PART_ArrowSubPath) as Path;
67
            Base_TextBox = GetTemplateChild(PART_TextBox) as TextBox;
68
            BaseTextbox_Caret = GetTemplateChild(PART_BaseTextbox_Caret) as Border;
69
            Base_TextBox.Text = this.ArrowText;
70
           
71
            this.Base_TextBox.CaretIndex = this.Base_TextBox.Text.Length;
72
            this.Base_TextBox.CaretBrush = new SolidColorBrush(Colors.Transparent);
73
            this.Base_TextBox.ApplyTemplate();
74
            MoveCustomCaret();
75

    
76
            Base_TextBox.SizeChanged += new SizeChangedEventHandler(Base_TextBox_SizeChanged);
77
            Base_TextBox.GotFocus += new RoutedEventHandler(Base_TextBox_GotFocus);
78
            Base_TextBox.LostFocus += new RoutedEventHandler(Base_TextBox_LostFocus);
79
            Base_TextBox.SelectionChanged += (sender, e) => MoveCustomCaret();
80
            this.KeyDown += ArrowTextControl_KeyDown;
81

    
82
            SetArrowTextPath(true);
83

    
84
            Base_TextBox.IsTabStop = true;
85
        }
86

    
87
        private void ArrowTextControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
88
        {
89
           if(e.Key == System.Windows.Input.Key.Escape)
90
            {
91
                if(string.IsNullOrEmpty(Base_TextBox.Text))
92
                {
93
                    this.Visibility = Visibility.Collapsed;
94
                }
95

    
96
                EditEnd();
97
            }
98
        }
99

    
100
        public void SetFontFamily(FontFamily fontFamily)
101
        {
102
            this.FontFamily = fontFamily;
103
            this.TextFamily = fontFamily;
104
        }
105

    
106
        /// <summary>
107
        /// Moves the custom caret on the canvas.
108
        /// </summary>
109
        public void MoveCustomCaret()
110
        {
111
            var caretLocation = this.Base_TextBox.GetRectFromCharacterIndex(this.Base_TextBox.CaretIndex).Location;
112

    
113
            var angle = Math.Abs(this.PageAngle);
114
            //angle = 0;
115
            System.Diagnostics.Debug.WriteLine("Page Angle : " +  this.PageAngle);
116

    
117
            if (!double.IsInfinity(caretLocation.X))
118
            {
119
                if (angle == 90)
120
                {
121
                    Canvas.SetLeft(this.BaseTextbox_Caret, this.EndPoint.X + caretLocation.Y);
122
                }
123
                else if (angle == 180)
124
                {
125
                    
126
                    Canvas.SetLeft(this.BaseTextbox_Caret, (this.EndPoint.X+ this.Base_TextBox.ActualWidth) - caretLocation.X) ;
127
                    System.Diagnostics.Debug.WriteLine("Caret X : " + ((this.EndPoint.X + this.Base_TextBox.ActualWidth) - caretLocation.X));
128
                } 
129
                else if (angle == 270)
130
                {
131
                    Canvas.SetLeft(this.BaseTextbox_Caret, (this.EndPoint.X) - caretLocation.Y);
132
                }
133
                else
134
                {
135
                    System.Diagnostics.Debug.WriteLine("Caret X : " + (this.EndPoint.X - caretLocation.X));
136
                    Canvas.SetLeft(this.BaseTextbox_Caret, this.EndPoint.X + caretLocation.X);
137
                } 
138
            }
139

    
140
            if (!double.IsInfinity(caretLocation.Y))
141
            {
142
                if (angle == 90)
143
                {
144
                    Canvas.SetTop(this.BaseTextbox_Caret, this.EndPoint.Y - caretLocation.X);
145
                }
146
                else if (angle == 180)
147
                {//보정치40
148
                    Canvas.SetTop(this.BaseTextbox_Caret, ((this.EndPoint.Y -40) + this.Base_TextBox.ActualHeight)- caretLocation.Y );
149
                    System.Diagnostics.Debug.WriteLine("Caret Y : " + (((this.EndPoint.Y - 40) + this.Base_TextBox.ActualHeight) - caretLocation.Y));
150
                }
151
                else if (angle == 270)
152
                {
153
                    Canvas.SetTop(this.BaseTextbox_Caret, (this.EndPoint.Y) + caretLocation.X);
154
                }
155
                else
156
                {
157
                    Canvas.SetTop(this.BaseTextbox_Caret, this.EndPoint.Y  + caretLocation.Y);
158
                    System.Diagnostics.Debug.WriteLine("Caret Y : " + (this.EndPoint.Y + caretLocation.Y - BaseTextbox_Caret.ActualHeight));
159
                }
160
            }
161
        }
162

    
163
        public void MoveCustomCaret(Point point)
164
        {
165

    
166
            var caretLocation = this.Base_TextBox.GetRectFromCharacterIndex(this.Base_TextBox.CaretIndex).Location;
167

    
168
            if (!double.IsInfinity(caretLocation.X))
169
            {
170
                if (Math.Abs(this.PageAngle) == 90)
171
                {
172
                    Canvas.SetLeft(this.BaseTextbox_Caret, point.X + caretLocation.Y);
173
                }
174
                else if (Math.Abs(this.PageAngle) == 180)
175
                {
176

    
177
                    Canvas.SetLeft(this.BaseTextbox_Caret, (point.X + this.Base_TextBox.ActualWidth) - caretLocation.X);
178
                }
179
                else if (Math.Abs(this.PageAngle) == 270)
180
                {
181
                    Canvas.SetLeft(this.BaseTextbox_Caret, (point.X) - caretLocation.Y);
182
                }
183
                else
184
                {
185
                    Canvas.SetLeft(this.BaseTextbox_Caret, point.X + caretLocation.X);
186
                }
187
            }
188

    
189
            if (!double.IsInfinity(caretLocation.Y))
190
            {
191
                if (Math.Abs(this.PageAngle) == 90)
192
                {
193
                    Canvas.SetTop(this.BaseTextbox_Caret, point.Y - caretLocation.X);
194
                }
195
                else if (Math.Abs(this.PageAngle) == 180)
196
                {
197
                    Canvas.SetTop(this.BaseTextbox_Caret, (point.Y + this.Base_TextBox.ActualHeight) - caretLocation.Y);
198
                }
199
                else if (Math.Abs(this.CommentAngle) == 270)
200
                {
201
                    Canvas.SetTop(this.BaseTextbox_Caret, (point.Y) + caretLocation.X);
202
                }
203
                else
204
                {
205
                    Canvas.SetTop(this.BaseTextbox_Caret, point.Y + caretLocation.Y);
206
                }
207
            }
208
        }
209

    
210

    
211
        void Base_TextBox_LostFocus(object sender, RoutedEventArgs e)
212
        {
213
            EditEnd();
214
        }
215

    
216
        private void EditEnd()
217
        { 
218
            this.ArrowText = Base_TextBox.Text;
219
            Base_TextBox.Focusable = false;
220
            this.BaseTextbox_Caret.Visibility = Visibility.Collapsed;
221
            this.IsEditingMode = false;
222
            ApplyOverViewData();
223
        }
224

    
225
        void Base_TextBox_GotFocus(object sender, RoutedEventArgs e)
226
        {
227
            this.BaseTextbox_Caret.Visibility = Visibility.Visible;
228
            MoveCustomCaret();
229
            this.IsEditingMode = true;
230
        }
231

    
232
        void Base_TextBox_SizeChanged(object sender, SizeChangedEventArgs e)
233
        {
234
            if(this.IsEditingMode)
235
            {
236
                if (Base_TextBox.Text.Contains("|OR||DZ|"))
237
                {
238
                    Base_TextBox.Text = this.ArrowText;
239
                }
240

    
241
                this.ArrowText = Base_TextBox.Text;
242
                
243
            }
244
            BoxWidth = e.NewSize.Width;
245
            BoxHeight = e.NewSize.Height;
246
            SetArrowTextPath();
247
        }
248

    
249
        #region Properties
250
        private bool _IsEditingMode;
251
        public bool IsEditingMode
252
        {
253
            get
254
            {
255
                return _IsEditingMode;
256
            }
257
            set
258
            {
259
                _IsEditingMode = value;
260
                OnPropertyChanged("IsEditingMode");
261
            }
262
        }
263

    
264

    
265
        #endregion
266

    
267
        #region dp Properties
268
        //강인구 주석 풀기
269
        public Visibility TextBoxVisibility
270
        {
271
            get { return (Visibility)GetValue(TextBoxVisibilityProperty); }
272
            set
273
            {
274
                if (this.TextBoxVisibility != value)
275
                {
276
                    SetValue(TextBoxVisibilityProperty, value);
277
                    OnPropertyChanged("TextBoxVisibility");
278
                }
279
            }
280
        }
281

    
282
        //강인구 주석 풀기
283
        public Visibility TextBlockVisibility
284
        {
285
            get { return (Visibility)GetValue(TextBlockVisibilityProperty); }
286
            set
287
            {
288
                if (this.TextBlockVisibility != value)
289
                {
290
                    SetValue(TextBlockVisibilityProperty, value);
291
                    OnPropertyChanged("TextBlockVisibility");
292
                }
293
            }
294
        }
295

    
296

    
297
        public override SolidColorBrush StrokeColor
298
        {
299
            get { return (SolidColorBrush)GetValue(StrokeColorProperty); }
300
            set
301
            {
302
                if (this.StrokeColor != value)
303
                {
304
                    SetValue(StrokeColorProperty, value);
305
                }
306
            }
307
        }
308

    
309
        public PathGeometry SubPathData
310
        {
311
            get { return (PathGeometry)GetValue(SubPathDataProperty); }
312
            set
313
            {
314
                if (this.SubPathData != value)
315
                {
316
                    SetValue(SubPathDataProperty, value);
317
                }
318
            }
319
        }
320

    
321
        public string UserID
322
        {
323
            get { return (string)GetValue(UserIDProperty); }
324
            set
325
            {
326
                if (this.UserID != value)
327
                {
328
                    SetValue(UserIDProperty, value);
329
                    OnPropertyChanged("UserID");
330
                }
331
            }
332
        }
333

    
334
        public List<Point> PointSet
335
        {
336
            get { return (List<Point>)GetValue(PointSetProperty); }
337
            set { SetValue(PointSetProperty, value); }
338
        }
339

    
340
        public override bool IsSelected
341
        {
342
            get
343
            {
344
                return (bool)GetValue(IsSelectedProperty);
345
            }
346
            set
347
            {
348
                SetValue(IsSelectedProperty, value);
349
                OnPropertyChanged("IsSelected");
350
            }
351
        }
352

    
353
        public override ControlType ControlType
354
        {
355
            set
356
            {
357
                SetValue(ControlTypeProperty, value);
358
                OnPropertyChanged("ControlType");
359
            }
360
            get
361
            {
362
                return (ControlType)GetValue(ControlTypeProperty);
363
            }
364
        }
365

    
366
        public Point StartPoint
367
        {
368
            get { return (Point)GetValue(StartPointProperty); }
369
            set { SetValue(StartPointProperty, value); }
370
        }
371

    
372
        public Point EndPoint
373
        {
374
            get { return (Point)GetValue(EndPointProperty); }
375
            set { SetValue(EndPointProperty, value); }
376
        }
377

    
378
        public Point OverViewStartPoint
379
        {
380
            get { return (Point)GetValue(OverViewStartPointProperty); }
381
            set { SetValue(OverViewStartPointProperty, value); }
382
        }
383

    
384
        public Point OverViewEndPoint
385
        {
386
            get { return (Point)GetValue(OverViewEndPointProperty); }
387
            set { SetValue(OverViewEndPointProperty, value); }
388
        }
389

    
390

    
391
        //public double Angle
392
        //{
393
        //    get { return (double)GetValue(AngleProperty); }
394
        //    set { SetValue(AngleProperty, value); }
395
        //}
396

    
397
        public Thickness BorderSize
398
        {
399
            get { return (Thickness)GetValue(BorderSizeProperty); }
400
            set
401
            {
402
                if (this.BorderSize != value)
403
                {
404
                    SetValue(BorderSizeProperty, value);
405
                }
406
            }
407
        }
408

    
409

    
410
        public Point MidPoint
411
        {
412
            get { return (Point)GetValue(MidPointProperty); }
413
            set { SetValue(MidPointProperty, value); }
414
        }
415

    
416
        public bool isFixed
417
        {
418
            get { return (bool)GetValue(IsFixedProperty); }
419
            set { SetValue(IsFixedProperty, value); }
420
        }
421

    
422
        public bool isTrans
423
        {
424
            get { return (bool)GetValue(TransformerProperty); }
425
            set { SetValue(TransformerProperty, value); }
426
        }
427

    
428
        public bool isHighLight
429
        {
430
            get { return (bool)GetValue(isHighlightProperty); }
431
            set
432
            {
433
                if (this.isHighLight != value)
434
                {
435
                    SetValue(isHighlightProperty, value);
436
                    OnPropertyChanged("isHighLight");
437
                }
438
            }
439
        }
440

    
441
        public FontWeight TextWeight
442
        {
443
            get { return (FontWeight)GetValue(TextWeightProperty); }
444
            set
445
            {
446
                if (this.TextWeight != value)
447
                {
448
                    SetValue(TextWeightProperty, value);
449
                    OnPropertyChanged("TextWeight");
450
                }
451
            }
452
        }
453

    
454
        public Double LineSize
455
        {
456
            get { return (Double)GetValue(LineSizeProperty); }
457
            set
458
            {
459
                if (this.LineSize != value)
460
                {
461
                    SetValue(LineSizeProperty, value);
462
                }
463
            }
464
        }
465

    
466
        public Double BoxWidth
467
        {
468
            get { return (Double)GetValue(BoxWidthProperty); }
469
            set
470
            {
471
                if (this.BoxWidth != value)
472
                {
473
                    SetValue(BoxWidthProperty, value);
474
                }
475
            }
476
        }
477

    
478
        public Double BoxHeight
479
        {
480
            get { return (Double)GetValue(BoxHeightProperty); }
481
            set
482
            {
483
                if (this.BoxHeight != value)
484
                {
485
                    SetValue(BoxHeightProperty, value);
486
                }
487
            }
488
        }
489

    
490
        public ArrowTextStyleSet ArrowTextStyle
491
        {
492
            get { return (ArrowTextStyleSet)GetValue(ArrowTextStyleProperty); }
493
            set
494
            {
495
                if (this.ArrowTextStyle != value)
496
                {
497
                    SetValue(ArrowTextStyleProperty, value);
498
                }
499
            }
500
        }
501

    
502
        public Geometry PathData
503
        {
504
            get { return (Geometry)GetValue(PathDataProperty); }
505
            set { SetValue(PathDataProperty, value);
506

    
507
                OnPropertyChanged("PathData");
508
            }
509
        }
510

    
511
        public SolidColorBrush BackInnerColor
512
        {
513
            get { return (SolidColorBrush)GetValue(BackInnerColorProperty); }
514
            set
515
            {
516
                if (this.BackInnerColor != value)
517
                {
518
                    SetValue(BackInnerColorProperty, value);
519
                    OnPropertyChanged("BackInnerColor");
520
                }
521
            }
522
        }
523

    
524
        public Geometry PathDataInner
525
        {
526
            get { return (Geometry)GetValue(PathDataInnerProperty); }
527
            set
528
            {
529
                SetValue(PathDataInnerProperty, value);
530
                OnPropertyChanged("PathDataInner");
531
            }
532
        }
533

    
534
        public Geometry OverViewPathData
535
        {
536
            get { return (Geometry)GetValue(OverViewPathDataProperty); }
537
            set { SetValue(OverViewPathDataProperty, value);
538

    
539
                OnPropertyChanged("OverViewPathData");
540

    
541
            }
542
        }
543

    
544
        public FontFamily TextFamily
545
        {
546
            get { return (FontFamily)GetValue(TextFamilyProperty); }
547
            set
548
            {
549
                if (this.TextFamily != value)
550
                {
551
                    SetValue(TextFamilyProperty, value);
552
                    OnPropertyChanged("TextFamily");
553
                }
554
            }
555
        }
556

    
557
        public string ArrowText
558
        {
559
            get { return (string)GetValue(ArrowTextProperty); }
560
            set
561
            {
562
                if (this.ArrowText != value)
563
                {
564
                    SetValue(ArrowTextProperty, value);
565
                    OnPropertyChanged("ArrowText");
566
                }
567
            }
568
        }
569

    
570
        public string OverViewArrowText
571
        {
572

    
573
            get { return (string)GetValue(OverViewArrowTextProperty);
574
            }
575
            set
576
            {
577
                if (this.OverViewArrowText != value)
578
                {
579
                    SetValue(OverViewArrowTextProperty, value);
580
                    OnPropertyChanged("OverViewArrowText");
581
                }
582
            }
583
        }
584

    
585
        public Double TextSize
586
        {
587
            get { return (Double)GetValue(TextSizeProperty); }
588
            set
589
            {
590
                if (this.TextSize != value)
591
                {
592
                    SetValue(TextSizeProperty, value);
593
                    OnPropertyChanged("TextSize");
594
                }
595
            }
596
        }
597

    
598
        public FontStyle TextStyle
599
        {
600
            get { return (FontStyle)GetValue(TextStyleProperty); }
601
            set
602
            {
603
                if (this.TextStyle != value)
604
                {
605
                    SetValue(TextStyleProperty, value);
606
                    OnPropertyChanged("TextStyle");
607
                }
608
            }
609
        }
610

    
611
        //강인구 추가
612
        public TextDecorationCollection UnderLine
613
        {
614
            get
615
            {
616
                return (TextDecorationCollection)GetValue(UnderLineProperty);
617
            }
618
            set
619
            {
620
                if (this.UnderLine != value)
621
                {
622
                    SetValue(UnderLineProperty, value);
623
                    OnPropertyChanged("UnderLine");
624
                }
625
            }
626
        }
627

    
628
        public double CanvasX
629
        {
630
            get { return (double)GetValue(CanvasXProperty); }
631
            set
632
            {
633
                if (this.CanvasX != value)
634
                {
635
                    SetValue(CanvasXProperty, value);
636
                    OnPropertyChanged("CanvasX");
637
                }
638
            }
639
        }
640

    
641
        public double CanvasY
642
        {
643
            get { return (double)GetValue(CanvasYProperty); }
644
            set
645
            {
646
                if (this.CanvasY != value)
647
                {
648
                    SetValue(CanvasYProperty, value);
649
                    OnPropertyChanged("CanvasY");
650
                }
651
            }
652
        } 
653

    
654
        public double CenterX
655
        {
656
            get { return (double)GetValue(CenterXProperty); }
657
            set { SetValue(CenterXProperty, value);
658
            OnPropertyChanged("CenterX");
659
            
660
            }
661
        }
662

    
663
        public double CenterY
664
        {
665
            get { return (double)GetValue(CenterYProperty); }
666
            set { SetValue(CenterYProperty, value);
667
            OnPropertyChanged("CenterY");
668
            }
669
        }
670

    
671
        public Brush SubPathFill
672
        {
673
            get { return (Brush)GetValue(SubPathFillProperty); }
674
            set
675
            {
676
                SetValue(SubPathFillProperty, value);
677
                OnPropertyChanged("SubPathFill");
678
            }
679
        }
680

    
681
        public Brush TextBoxBackground
682
        {
683
            get { return (Brush)GetValue(TextBoxBackgroundProperty); }
684
            set
685
            {
686
                SetValue(TextBoxBackgroundProperty, value);
687
                OnPropertyChanged("TextBoxBackground");
688
            }
689
        }
690

    
691

    
692
        //강인구 추가 주석풀기
693
       
694

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

    
708
        #endregion
709

    
710
        #region Dependency Properties
711

    
712
        public static readonly DependencyProperty BoxWidthProperty = DependencyProperty.Register(
713
                "BoxWidth", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
714

    
715
        public static readonly DependencyProperty BoxHeightProperty = DependencyProperty.Register(
716
                "BoxHeight", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
717

    
718
        public static readonly DependencyProperty UserIDProperty = DependencyProperty.Register(
719
                "UserID", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
720

    
721
        public static readonly DependencyProperty ArrowTextStyleProperty = DependencyProperty.Register(
722
               "ArrowTextStyle", typeof(ArrowTextStyleSet), typeof(ArrowTextControl), new PropertyMetadata(ArrowTextStyleSet.Normal));
723

    
724
        public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register(
725
                "CenterX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
726

    
727
        public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register(
728
                "CenterY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
729

    
730
        public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
731
                "Angle", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0.0, new PropertyChangedCallback(PointValueChanged)));
732
        
733
        public static readonly DependencyProperty CanvasXProperty = DependencyProperty.Register(
734
                "CanvasX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
735

    
736
        public static readonly DependencyProperty CanvasYProperty = DependencyProperty.Register(
737
                "CanvasY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
738

    
739
        public static readonly DependencyProperty PointSetProperty = DependencyProperty.Register(
740
                "PointSet", typeof(List<Point>), typeof(ArrowTextControl), new PropertyMetadata(new List<Point>(), PointValueChanged));
741

    
742
        public static readonly DependencyProperty TextFamilyProperty = DependencyProperty.Register(
743
                "TextFamily", typeof(FontFamily), typeof(ArrowTextControl), new PropertyMetadata(new FontFamily("Arial"), TextChanged));
744

    
745
        public static readonly DependencyProperty PathDataProperty = DependencyProperty.Register(
746
                "PathData", typeof(Geometry), typeof(ArrowTextControl), null);
747

    
748
        //강인구 추가
749
        public static readonly DependencyProperty UnderLineProperty = DependencyProperty.Register(
750
    "UnderLine", typeof(TextDecorationCollection), typeof(ArrowTextControl), new PropertyMetadata(null, PointValueChanged));
751

    
752
        public static readonly DependencyProperty LineSizeProperty = DependencyProperty.Register(
753
               "LineSize", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)3, PointValueChanged));
754

    
755
        public static readonly DependencyProperty TextStyleProperty = DependencyProperty.Register(
756
                "TextStyle", typeof(FontStyle), typeof(ArrowTextControl), new PropertyMetadata(FontStyles.Normal));
757

    
758
        public static readonly DependencyProperty TextSizeProperty = DependencyProperty.Register(
759
                "TextSize", typeof(Double), typeof(ArrowTextControl), new PropertyMetadata((Double)30, PointValueChanged));
760

    
761
        public static readonly DependencyProperty TextWeightProperty = DependencyProperty.Register(
762
                "TextWeight", typeof(FontWeight), typeof(ArrowTextControl), new PropertyMetadata(FontWeights.Normal));
763

    
764
        public static readonly DependencyProperty IsFixedProperty = DependencyProperty.Register(
765
                "isFixed", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
766

    
767
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
768
                "IsSelected", typeof(bool), typeof(ArrowTextControl), new FrameworkPropertyMetadata(false, IsSelectedChanged));
769

    
770
        public static readonly DependencyProperty StrokeColorProperty = DependencyProperty.Register(
771
                "StrokeColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
772

    
773
        public static readonly DependencyProperty ControlTypeProperty = DependencyProperty.Register(
774
                "ControlType", typeof(ControlType), typeof(ArrowTextControl), new FrameworkPropertyMetadata(ControlType.ArrowTextControl));
775

    
776
        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register(
777
                "StartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
778

    
779
        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register(
780
                "EndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
781

    
782
        public static readonly DependencyProperty BackInnerColorProperty = DependencyProperty.Register(
783
            "BackInnerColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.White)));
784

    
785
        public static readonly DependencyProperty PathDataInnerProperty = DependencyProperty.Register(
786
    "PathDataInner", typeof(Geometry), typeof(ArrowTextControl), null);
787

    
788
        public static readonly DependencyProperty isHighlightProperty = DependencyProperty.Register(
789
                "isHighlight", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
790

    
791
        public static readonly DependencyProperty MidPointProperty = DependencyProperty.Register(
792
                "MidPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
793

    
794
        public static readonly DependencyProperty TransformerProperty = DependencyProperty.Register(
795
                "isTrans", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
796

    
797
        public static readonly DependencyProperty BorderSizeProperty = DependencyProperty.Register(
798
                "BorderSize", typeof(Thickness), typeof(ArrowTextControl), new PropertyMetadata(new Thickness(0), PointValueChanged));
799
    
800
        public static readonly DependencyProperty ArrowTextProperty = DependencyProperty.Register(
801
              "ArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
802

    
803

    
804

    
805
        //, new PropertyChangedCallback(TextChanged)
806

    
807

    
808
        #region 추가 사항
809
        public static readonly DependencyProperty SubPathDataProperty = DependencyProperty.Register(
810
                "SubPathData", typeof(Geometry), typeof(ArrowTextControl), null);
811

    
812

    
813
        public static readonly DependencyProperty SubPathFillProperty = DependencyProperty.Register(
814
                "SubPathFill", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(null));
815

    
816
        public static readonly DependencyProperty TextBoxBackgroundProperty = DependencyProperty.Register(
817
                "TextBoxBackground", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(Brushes.White));
818

    
819
        public static readonly DependencyProperty OverViewArrowTextProperty = DependencyProperty.Register(
820
                "OverViewArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null, new PropertyChangedCallback(TextChanged)));
821

    
822
        public static readonly DependencyProperty OverViewPathDataProperty = DependencyProperty.Register(
823
                "OverViewPathData", typeof(Geometry), typeof(ArrowTextControl), null);
824

    
825
        public static readonly DependencyProperty OverViewStartPointProperty = DependencyProperty.Register(
826
                "OverViewStartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
827

    
828
        public static readonly DependencyProperty OverViewEndPointProperty = DependencyProperty.Register(
829
                "OverViewEndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
830

    
831
        public static readonly DependencyProperty TextBoxVisibilityProperty = DependencyProperty.Register(
832
            "TextBoxVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Visible), OnTextBoxVisibilityChanged));
833

    
834
        //강인구 추가(주석풀기)
835
        public static readonly DependencyProperty TextBlockVisibilityProperty = DependencyProperty.Register(
836
            "TextBlockVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Collapsed), OnTextBlockVisibilityChanged));
837

    
838
        public static readonly DependencyProperty EnableEditingProperty = DependencyProperty.Register(
839
           "EnableEditing", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata((true), new PropertyChangedCallback(OnIsEditingChanged)));
840

    
841
        #endregion
842

    
843
        #endregion
844

    
845
        #region CallBack Method
846

    
847
        //강인구 추가(주석풀기)
848
        public static void OnIsEditingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
849
        {
850
            var instance = (ArrowTextControl)sender;
851

    
852
            if (e.OldValue != e.NewValue && instance.Base_TextBlock != null)
853
            {
854
                instance.SetValue(e.Property, e.NewValue);
855

    
856
                if (instance.EnableEditing)
857
                {
858
                    instance.EditingMode();
859
                }
860
                else
861
                {
862
                    instance.UnEditingMode();
863
                }
864
            }
865
        }
866

    
867
        public static void OnTextBoxVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
868
        {
869
            var instance = (ArrowTextControl)sender;
870

    
871
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
872
            {
873
                instance.SetValue(e.Property, e.NewValue);
874
            }
875
        }
876

    
877
        public static void OnTextBlockVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
878
        {
879
            var instance = (ArrowTextControl)sender;
880

    
881
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
882
            {
883
                instance.SetValue(e.Property, e.NewValue);
884
            }
885
        }
886

    
887
        public static void PointValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
888
        {
889
            var instance = (ArrowTextControl)sender;
890

    
891
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
892
            {
893
                instance.SetArrowTextPath();
894
            }
895
        }
896

    
897

    
898

    
899
        public static void TextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
900
        {
901
            var instance = (ArrowTextControl)sender;
902
            
903
            if (e.OldValue != e.NewValue)
904
            {
905
                instance.SetValue(e.Property, e.NewValue);
906
                //instance.BoxWidth = instance.Base_TextBox.ActualWidth;
907
                //instance.BoxHeight = instance.Base_TextBox.ActualHeight;
908
            }
909
        }
910

    
911
        public static void OnCenterXYChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
912
        {
913
            var instance = (ArrowTextControl)sender;
914
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
915
            {
916
                instance.SetValue(e.Property, e.NewValue);
917
                instance.SetArrowTextPath();
918
            }
919
        }
920

    
921
        public static void OnSetCansvasChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
922
        {
923
            var instance = (ArrowTextControl)sender;
924

    
925
            if (e.OldValue != e.NewValue && instance != null)
926
            {
927
                instance.SetValue(e.Property, e.NewValue);
928
                //Canvas.SetLeft(instance, instance.CanvasX);
929
                //Canvas.SetTop(instance, instance.CanvasY);
930
            }
931
        }
932

    
933
        public static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
934
        {
935
            //var instance = (ArrowTextControl)sender;
936

    
937
            //if (e.OldValue != e.NewValue)
938
            //{
939
            //    instance.SetValue(e.Property, e.NewValue);
940

    
941
            //    if (instance.IsSelected && instance.Base_TextBox != null)
942
            //    {
943
            //        instance.BorderSize = new Thickness(1);
944
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Blue);
945
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Blue);
946
            //    }
947
            //    else
948
            //    {
949
            //        instance.BorderSize = new Thickness(0);
950
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Transparent);
951
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Transparent);
952
            //    }
953
            //}
954
        }
955
        #endregion
956

    
957
        #region Internal Method
958

    
959
        //강인구 주석 풀기
960
        public void EditingMode()
961
        {
962
            TextBoxVisibility = Visibility.Visible;
963
            TextBlockVisibility = Visibility.Collapsed;
964

    
965

    
966
            //강인구 언더라인 추가
967
            if (UnderLine != null)
968
                Base_TextBlock.TextDecorations = UnderLine;
969
        }
970
        //강인구 주석 풀기
971
        public void UnEditingMode()
972
        {
973

    
974
            TextBoxVisibility = Visibility.Collapsed;
975
            TextBlockVisibility = Visibility.Visible;
976

    
977
            if (UnderLine != null)
978
                Base_TextBlock.TextDecorations = UnderLine;
979

    
980
            Base_TextBlock.Margin =
981
                 new Thickness(Base_TextBox.Margin.Left + 4, Base_TextBox.Margin.Top + 4,
982
                     Base_TextBox.Margin.Right + 4, Base_TextBox.Margin.Bottom + 4);
983
        }
984

    
985
        private void SetArrowTextPath(bool IsInit = false)
986
        {
987
            instanceGroup.Children.Clear();
988

    
989
            //VisualPageAngle = 0;
990

    
991
            if (Math.Abs(PageAngle).ToString() == "90")
992
            {
993
                VisualPageAngle = 270;
994
            }
995
            else if (Math.Abs(PageAngle).ToString() == "270")
996
            {
997
                VisualPageAngle = 90;
998
            }
999
            else
1000
            {
1001
                VisualPageAngle = PageAngle;
1002
            }
1003

    
1004
            connectorSMGeometry.StartPoint = this.StartPoint;
1005
            connectorSMGeometry.EndPoint = this.MidPoint;
1006
            connectorMEGeometry.StartPoint = this.MidPoint; //핵심
1007

    
1008
            /// 텍스트박스의 좌표 설정
1009
            Canvas.SetLeft(Base_TextBox, this.EndPoint.X);
1010
            Canvas.SetTop(Base_TextBox, this.EndPoint.Y);
1011
            //System.Diagnostics.Debug.WriteLine($"TextBox Set {this.EndPoint.X},{this.EndPoint.Y}");
1012
            
1013

    
1014
            List<Point> ps = new List<Point>();
1015
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox))); //상단
1016
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox) + this.BoxHeight)); // 하단
1017
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2)); //좌단
1018
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth, Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2));  //우단
1019

    
1020
            if (isTrans)
1021
            {
1022
                switch (Math.Abs(this.PageAngle).ToString())
1023
                {
1024
                    case "90":
1025
                        {
1026
                            ps.Clear();
1027
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1028
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1029
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1030

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

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

    
1037
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간
1038
                        }
1039
                        break;
1040
                    case "270":
1041
                        {
1042
                            ps.Clear();
1043
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1044
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1045
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1046

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

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

    
1053
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간
1054
                        }
1055
                        break;
1056
                    default:
1057
                        break;
1058
                }
1059
                
1060
                var endP = MathSet.getNearPoint(ps, this.MidPoint);
1061

    
1062
                //20180911 LJY 꺾이는 부분 수정
1063
                Point testP = endP;                
1064
                switch (Math.Abs(this.PageAngle).ToString())
1065
                {
1066
                    case "90":
1067
                        testP = new Point(endP.X + 50, endP.Y);
1068
                        break;
1069
                    case "270":
1070
                        testP = new Point(endP.X - 50, endP.Y);
1071
                        break;
1072
                }                
1073

    
1074
                //20180910 LJY 각도에 따라.
1075
                switch (Math.Abs(this.PageAngle).ToString())
1076
                {
1077
                    case "90":
1078
                        if (isFixed)
1079
                        {
1080
                            if (ps[0] == endP) //상단
1081
                            {
1082
                                testP = new Point(endP.X , endP.Y + 50);
1083
                                //System.Diagnostics.Debug.WriteLine("상단"+ testP);
1084
                            }
1085
                            else if (ps[1] == endP) //하단
1086
                            {
1087
                                testP = new Point(endP.X , endP.Y - 50);
1088
                                //System.Diagnostics.Debug.WriteLine("하단"+ testP);
1089
                            }
1090
                            else if (ps[2] == endP) //좌단
1091
                            {
1092
                                testP = new Point(endP.X - 50, endP.Y);
1093
                                //System.Diagnostics.Debug.WriteLine("좌단"+ testP);
1094
                            }
1095
                            else if (ps[3] == endP) //우단
1096
                            {
1097
                                testP = new Point(endP.X + 50, endP.Y);
1098
                                //System.Diagnostics.Debug.WriteLine("우단"+ testP);
1099
                            }
1100
                        }
1101
                        break;
1102
                    case "270":
1103
                        if (isFixed)
1104
                        {
1105
                            if (ps[0] == endP) //상단
1106
                            {
1107
                                testP = new Point(endP.X , endP.Y - 50);
1108
                                //System.Diagnostics.Debug.WriteLine("상단" + testP);
1109
                            }
1110
                            else if (ps[1] == endP) //하단
1111
                            {
1112
                                testP = new Point(endP.X, endP.Y + 50);
1113
                                //System.Diagnostics.Debug.WriteLine("하단" + testP);
1114
                            }
1115
                            else if (ps[2] == endP) //좌단
1116
                            {
1117
                                testP = new Point(endP.X + 50, endP.Y);
1118
                                //System.Diagnostics.Debug.WriteLine("좌단" + testP);
1119
                            }
1120
                            else if (ps[3] == endP) //우단
1121
                            {
1122
                                testP = new Point(endP.X - 50, endP.Y);
1123
                                //System.Diagnostics.Debug.WriteLine("우단" + testP);
1124
                            }
1125
                        }
1126
                        break;
1127
                    default:
1128
                        if (isFixed)
1129
                        {
1130
                            if (ps[0] == endP) //상단
1131
                            {
1132
                                testP = new Point(endP.X, endP.Y - 50);
1133
                                //System.Diagnostics.Debug.WriteLine("상단");
1134
                            }
1135
                            else if (ps[1] == endP) //하단
1136
                            {
1137
                                testP = new Point(endP.X, endP.Y + 50);
1138
                                //System.Diagnostics.Debug.WriteLine("하단");
1139
                            }
1140
                            else if (ps[2] == endP) //좌단
1141
                            {
1142
                                testP = new Point(endP.X - 50, endP.Y);
1143
                                //System.Diagnostics.Debug.WriteLine("좌단");
1144
                            }
1145
                            else if (ps[3] == endP) //우단
1146
                            {
1147
                                testP = new Point(endP.X + 50, endP.Y);
1148
                                //System.Diagnostics.Debug.WriteLine("우단");
1149
                            }
1150
                        }
1151
                        break;
1152
                }
1153
                connectorMEGeometry.EndPoint = endP;
1154
                connectorSMGeometry.EndPoint = testP;
1155
                connectorMEGeometry.StartPoint = testP;
1156
                
1157
                //20180910 LJY 각도에 따라.
1158
                this.MidPoint = testP;
1159
                instanceGroup.Children.Add(DrawSet.DrawArrow(testP, this.StartPoint, this.LineSize));
1160
                instanceGroup.FillRule = FillRule.Nonzero;
1161
                this.Base_ArrowPath.Fill = this.StrokeColor;
1162
                this.Base_ArrowSubPath.Fill = this.StrokeColor;
1163
            }
1164
            else
1165
            {
1166
                switch (Math.Abs(this.PageAngle).ToString())
1167
                {
1168
                    case "90":
1169
                        {
1170
                            ps.Clear();
1171

    
1172
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1173
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1174
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1175

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

    
1179
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); //중간 하단
1180
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 하단
1181
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간 
1182
                        }
1183
                        break;
1184
                    case "270":
1185
                        {
1186
                            ps.Clear();
1187
                            
1188
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1189
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1190
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1191

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

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

    
1198
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간 
1199
                        }
1200
                        break;
1201
                    //case "180":
1202
                    //    {
1203
                    //        ps.Clear();
1204

    
1205
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1206
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1207
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1208

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

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

    
1215
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간 
1216
                    //    }
1217
                    //    break;
1218
                    default:
1219
                        break;
1220
                }
1221

    
1222

    
1223
                var endP = MathSet.getNearPoint(ps, this.MidPoint);
1224
                connectorMEGeometry.EndPoint = endP; //최상단
1225
                                                     //connectorMEGeometry.EndPoint = this.EndPoint; //핵심
1226
                                                     //this.MidPoint= MathSet.getMiddlePoint(this.StartPoint, endP);
1227
                #region 보정치
1228
                Point testP = endP;
1229

    
1230
                //20180910 LJY 각도에 따라.
1231
                switch (Math.Abs(this.PageAngle).ToString())
1232
                {
1233
                    case "90":
1234
                        if (isFixed)
1235
                        {
1236
                            if (ps[0] == endP) //상단
1237
                            {
1238
                                testP = new Point(endP.X - 50, endP.Y);
1239
                                //System.Diagnostics.Debug.WriteLine("상단"+ testP);
1240
                            }
1241
                            else if (ps[1] == endP) //하단
1242
                            {
1243
                                testP = new Point(endP.X + 50, endP.Y);
1244
                                //System.Diagnostics.Debug.WriteLine("하단"+ testP);
1245
                            }
1246
                            else if (ps[2] == endP) //좌단
1247
                            {
1248
                                testP = new Point(endP.X - 50, endP.Y);
1249
                                //System.Diagnostics.Debug.WriteLine("좌단"+ testP);
1250
                            }
1251
                            else if (ps[3] == endP) //우단
1252
                            {
1253
                                testP = new Point(endP.X + 50 , endP.Y);
1254
                                //System.Diagnostics.Debug.WriteLine("우단"+ testP);
1255
                            }
1256
                        }
1257
                        break;
1258
                    case "270":
1259
                        if (isFixed)
1260
                        {
1261
                            if (ps[0] == endP) //상단
1262
                            {
1263
                                testP = new Point(endP.X + 50, endP.Y);
1264
                                //System.Diagnostics.Debug.WriteLine("상단" + testP);
1265
                            }
1266
                            else if (ps[1] == endP) //하단
1267
                            {
1268
                                testP = new Point(endP.X - 50, endP.Y);
1269
                                //System.Diagnostics.Debug.WriteLine("하단" + testP);
1270
                            }
1271
                            else if (ps[2] == endP) //좌단
1272
                            {
1273
                                testP = new Point(endP.X + 50, endP.Y);
1274
                                //System.Diagnostics.Debug.WriteLine("좌단" + testP);
1275
                            }
1276
                            else if (ps[3] == endP) //우단
1277
                            {
1278
                                testP = new Point(endP.X + 50, endP.Y );
1279
                                //System.Diagnostics.Debug.WriteLine("우단" + testP);
1280
                            }
1281
                        }
1282
                        break;
1283
                    default:
1284
                        if (isFixed)
1285
                        {
1286
                            if (ps[0] == endP) //상단
1287
                            {
1288
                                testP = new Point(endP.X, endP.Y - 50);
1289
                                //System.Diagnostics.Debug.WriteLine("상단");
1290
                            }
1291
                            else if (ps[1] == endP) //하단
1292
                            {
1293
                                testP = new Point(endP.X, endP.Y + 50);
1294
                                //System.Diagnostics.Debug.WriteLine("하단");
1295
                            }
1296
                            else if (ps[2] == endP) //좌단
1297
                            {
1298
                                testP = new Point(endP.X - 50, endP.Y);
1299
                                //System.Diagnostics.Debug.WriteLine("좌단");
1300
                            }
1301
                            else if (ps[3] == endP) //우단
1302
                            {
1303
                                testP = new Point(endP.X + 50, endP.Y);
1304
                                //System.Diagnostics.Debug.WriteLine("우단");
1305
                            }
1306
                        }
1307
                        break;
1308
                }
1309
                  
1310

    
1311
                connectorSMGeometry.EndPoint = testP;
1312
                connectorMEGeometry.StartPoint = testP;
1313
                instanceGroup.Children.Add(DrawSet.DrawArrow(testP, this.StartPoint, this.LineSize));
1314
                instanceGroup.FillRule = FillRule.Nonzero;
1315
                this.Base_ArrowPath.Fill = this.StrokeColor;
1316
                this.Base_ArrowSubPath.Fill = this.StrokeColor;
1317
                #endregion
1318
            }
1319

    
1320
            switch (this.ArrowTextStyle)
1321
            {
1322
                case ArrowTextStyleSet.Normal:
1323
                    this.BorderSize = new Thickness(0);
1324
                    DrawingRect();
1325
                    break;
1326
                case ArrowTextStyleSet.Cloud:
1327
                    this.BorderSize = new Thickness(0);
1328
                    DrawingCloud();
1329
                    break;
1330
                default:
1331
                    {
1332
                        this.BorderSize = new Thickness(LineSize); //올라
1333
                        DrawingRect();
1334
                    }
1335

    
1336
                    break;
1337
            }
1338

    
1339
            if (isHighLight)
1340
            {
1341
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1342
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1343

    
1344
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1345
            }
1346
            else
1347
            {
1348
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1349
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1350
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.1), Colors.White.R, Colors.White.G, Colors.White.B));
1351
            }
1352

    
1353
            instanceGroup.Children.Add(connectorSMGeometry);
1354
            instanceGroup.Children.Add(connectorMEGeometry);
1355

    
1356
            this.PathData = instanceGroup;
1357
            OverViewPathData = PathData;
1358
            OverViewArrowText = ArrowText;
1359
            OverViewEndPoint = connectorMEGeometry.EndPoint;
1360
            OverViewStartPoint = connectorSMGeometry.StartPoint;
1361

    
1362
            var tempAngle = Math.Abs(this.VisualPageAngle);
1363

    
1364
            if (tempAngle == Convert.ToDouble(90) || tempAngle == Convert.ToDouble(270))
1365
            {
1366
                this.RenderTransformOrigin = new Point(0.5, 0.5);
1367
                this.Base_ArrowPath.RenderTransformOrigin = new Point(0, 0);
1368
                this.Base_ArrowSubPath.RenderTransformOrigin = new Point(0, 0);
1369

    
1370
                Base_TextBox.RenderTransformOrigin = new Point(0, 0);
1371
                BaseTextbox_Caret.RenderTransformOrigin = new Point(0, 0);
1372
            }
1373

    
1374
            Base_TextBox.RenderTransform = new RotateTransform
1375
            {
1376
                Angle = this.VisualPageAngle,
1377
                CenterX = this.CenterX,
1378
                CenterY = this.CenterY,
1379
            };
1380

    
1381
            System.Diagnostics.Debug.WriteLine($"base TextBox center X : {this.CenterX} Y : {this.CenterY} ");
1382

    
1383
            
1384

    
1385
            Base_ArrowSubPath.RenderTransform = new RotateTransform
1386
            {
1387
                Angle = this.VisualPageAngle,
1388
                CenterX = this.EndPoint.X,
1389
                CenterY = this.EndPoint.Y,
1390
            };
1391

    
1392
            if (BaseTextbox_Caret.Visibility == Visibility.Visible)
1393
            {
1394
                BaseTextbox_Caret.RenderTransform = new RotateTransform
1395
                {
1396
                    Angle = this.VisualPageAngle,
1397
                    CenterX = this.CenterX,
1398
                    CenterY = this.CenterY,
1399
                };
1400

    
1401
                MoveCustomCaret();
1402
            }
1403
        }
1404

    
1405
        private void DrawingCloud()
1406
        {
1407
            //20180906 LJY Textbox guide
1408
            string angle = Math.Abs(this.PageAngle).ToString();
1409
            if (angle == "180")
1410
            {
1411
                List<Point> pCloud = new List<Point>()
1412
                {
1413
                     new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1414
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxHeight), //왼쪽 아래
1415
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox) - BoxHeight),
1416
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox)),
1417
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1418
                };
1419
                SubPathData = (Generate(pCloud));
1420
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1421
            
1422
            }//20180906 LJY Textbox guide
1423
            else
1424
            {            
1425
                List<Point> pCloud = new List<Point>()
1426
                {
1427
    #if SILVERLIGHT
1428
		            new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1429
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1430
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1431
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1432
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1433

    
1434
    #else
1435
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1436
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1437
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1438
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1439
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1440

    
1441
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1442
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1443
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1444
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1445
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1446
    #endif
1447
                };
1448
                //instanceGroup.Children.Add(Generate(pCloud));
1449
                SubPathData = (Generate(pCloud));
1450
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1451
                //   }
1452
            }
1453

    
1454
        }
1455

    
1456
        private void DrawingRect()
1457
        {
1458
            //20180906 LJY Textbox guide
1459
            if(this.ArrowTextStyle == ArrowTextStyleSet.Normal)
1460
            {
1461
                this.Base_TextBox.BorderBrush = Brushes.Transparent;
1462
            }
1463

    
1464
            if (Math.Abs(this.PageAngle).ToString() == "90")
1465
            {
1466
                List<Point> pCloud = new List<Point>()
1467
                {
1468
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1469
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxWidth), //왼쪽 아래
1470
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox) - BoxWidth),
1471
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox)),
1472
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1473
                };
1474
                PathDataInner = (GenerateInner(pCloud));
1475
            }
1476
            else if(Math.Abs(this.PageAngle).ToString() == "270")
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) + BoxWidth), //왼쪽 아래
1482
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox) + BoxWidth),
1483
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox)),
1484
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1485
                };
1486
                PathDataInner = (GenerateInner(pCloud));
1487
            }//20180906 LJY Textbox guide
1488
            else
1489
            { 
1490
                List<Point> pCloud = new List<Point>()
1491
                {
1492
    #if SILVERLIGHT
1493
		            new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1494
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1495
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1496
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1497
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1498

    
1499
    #else
1500
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1501
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1502
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1503
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1504
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1505

    
1506
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1507
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1508
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1509
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1510
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1511
    #endif
1512
                };
1513
                //instanceGroup.Children.Add(Generate(pCloud));
1514
                PathDataInner = (GenerateInner(pCloud));
1515
            }
1516
        }
1517

    
1518
        public override void UpdateControl()
1519
        {
1520
            this.StartPoint = new Point(this.PointSet[0].X, this.PointSet[0].Y);
1521
            this.MidPoint = new Point(this.PointSet[1].X, this.PointSet[1].Y);
1522
            this.EndPoint = new Point(this.PointSet[2].X, this.PointSet[2].Y);
1523
        }
1524

    
1525
        public override void ApplyOverViewData()
1526
        {
1527
            this.OverViewPathData = this.PathData;
1528
            if (ArrowText == "")
1529
                this.ArrowText = this.OverViewArrowText;
1530
            else
1531
                this.OverViewArrowText = this.ArrowText;
1532
            this.OverViewStartPoint = this.StartPoint;
1533
            this.OverViewEndPoint = this.EndPoint;
1534
        }
1535

    
1536
        #endregion
1537

    
1538
        public static PathFigure GenerateLineWithCloud(Point p1, Point p2, double arcLength_, bool reverse)
1539
        {
1540
            PathFigure pathFigure = new PathFigure();
1541
            pathFigure.StartPoint = p1;
1542

    
1543
            double arcLength = arcLength_;
1544
            /// draw arcs which has arcLength between p1 and p2 - 2012.06.21 added by humkyung 
1545
            double dx = p2.X - p1.X;
1546
            double dy = p2.Y - p1.Y;
1547
            double l = MathSet.DistanceTo(p1, p2); /// distance between p1 and p2
1548
            double theta = Math.Atan2(Math.Abs(dy), Math.Abs(dx)) * 180 / Math.PI;
1549
            Point lastPt = new Point(p1.X, p1.Y);
1550
            double count = l / arcLength;
1551
            /// normalize
1552
            dx /= l;
1553
            dy /= l;
1554
            Double j = 1;
1555
            for (j = 1; j < (count - 1); j++) 
1556
            {
1557
                ArcSegment arcSeg = new ArcSegment();
1558
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);						/// x size and y size of arc
1559
                arcSeg.Point = new Point(p1.X + j * dx * arcLength, p1.Y + j * dy * arcLength);	/// end point of arc
1560
                lastPt = arcSeg.Point;  /// save last point
1561
                arcSeg.RotationAngle = theta + 90;
1562
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1563
                pathFigure.Segments.Add(arcSeg);
1564
            }
1565

    
1566
            /// draw arc between last point and end point
1567
            if ((count > j) || (count > 0))
1568
            {
1569
                arcLength = MathSet.DistanceTo(lastPt, p2);
1570
                ArcSegment arcSeg = new ArcSegment();
1571
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);	/// x size and y size of arc
1572
                arcSeg.Point = new Point(p2.X, p2.Y);						/// end point of arc
1573
                arcSeg.RotationAngle = theta;
1574
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1575
                pathFigure.Segments.Add(arcSeg);
1576
            }
1577
            /// up to here
1578

    
1579
            return pathFigure;
1580
        }
1581

    
1582
        public static PathGeometry Generate(List<Point> pData)
1583
        {
1584
            var _pathGeometry = new PathGeometry();
1585
            
1586
            double area = MathSet.AreaOf(pData);
1587
            bool reverse = (area > 0);
1588
            int count = pData.Count;
1589
            for (int i = 0; i < (count - 1); i++)
1590
            {
1591
                PathFigure pathFigure = GenerateLineWithCloud(pData[i], pData[i + 1], 20, reverse);
1592
                pathFigure.IsClosed = false;
1593
                pathFigure.IsFilled = true;
1594
                _pathGeometry.Figures.Add(pathFigure);
1595
            }
1596
            
1597
            return _pathGeometry;
1598
        }
1599

    
1600
        
1601
        public static PathGeometry GenerateInner(List<Point> pData)
1602
        {
1603
            var _pathGeometry = new PathGeometry();
1604
            double area = MathSet.AreaOf(pData);
1605
            bool reverse = (area > 0);
1606
            int count = pData.Count;
1607

    
1608
            PathFigure pathFigur2 = new PathFigure();
1609
            pathFigur2.StartPoint = pData[0];
1610

    
1611
            LineSegment lineSegment0 = new LineSegment();
1612
            lineSegment0.Point = pData[0];
1613
            pathFigur2.Segments.Add(lineSegment0);
1614

    
1615
            LineSegment lineSegment1 = new LineSegment();
1616
            lineSegment1.Point = pData[1];
1617
            pathFigur2.Segments.Add(lineSegment1);
1618

    
1619
            LineSegment lineSegment2 = new LineSegment();
1620
            lineSegment2.Point = pData[2];
1621
            pathFigur2.Segments.Add(lineSegment2);
1622

    
1623
            LineSegment lineSegment3 = new LineSegment();
1624
            lineSegment3.Point = pData[3];
1625
            pathFigur2.Segments.Add(lineSegment3);
1626

    
1627

    
1628
            pathFigur2.IsClosed = true;
1629
            pathFigur2.IsFilled = true;
1630
            _pathGeometry.Figures.Add(pathFigur2);           
1631

    
1632
            return _pathGeometry;
1633
        }
1634

    
1635
        //20180910 LJY Cloud rotation 추가
1636
        public static PathGeometry GenerateInnerCloud(List<Point> pData, string angle)
1637
        {
1638
            var _pathGeometry = new PathGeometry();
1639
            double area = MathSet.AreaOf(pData);
1640
            bool reverse = (area > 0);
1641
            int count = pData.Count;
1642

    
1643
            PathFigure pathFigur2 = new PathFigure();
1644
            pathFigur2.StartPoint = pData[0];
1645

    
1646
            LineSegment lineSegment0 = new LineSegment();
1647
            lineSegment0.Point = pData[0];
1648
            pathFigur2.Segments.Add(lineSegment0);
1649

    
1650
            LineSegment lineSegment1 = new LineSegment();
1651
            lineSegment1.Point = pData[1];
1652
            pathFigur2.Segments.Add(lineSegment1);
1653

    
1654
            LineSegment lineSegment2 = new LineSegment();
1655
            lineSegment2.Point = pData[2];
1656
            pathFigur2.Segments.Add(lineSegment2);
1657

    
1658
            LineSegment lineSegment3 = new LineSegment();
1659
            lineSegment3.Point = pData[3];
1660
            pathFigur2.Segments.Add(lineSegment3);
1661
            
1662
            RotateTransform transform = new RotateTransform();
1663
            switch (angle)
1664
            {
1665
                case "90":
1666
                    transform.Angle = -90;
1667
                    break;
1668
                case "180":
1669
                    transform.Angle = -180;
1670
                    break;
1671
                case "270":
1672
                    transform.Angle = -270;
1673
                    break;
1674
            }
1675
            transform.CenterX = pData[0].X;
1676
            transform.CenterY = pData[0].Y;
1677
            _pathGeometry.Transform = transform;
1678

    
1679
            pathFigur2.IsClosed = true;
1680
            pathFigur2.IsFilled = true;
1681
            _pathGeometry.Figures.Add(pathFigur2);
1682

    
1683
            return _pathGeometry;
1684
        }
1685

    
1686
        /// <summary>
1687
        /// call when mouse is moving while drawing control
1688
        /// </summary>
1689
        /// <author>humkyung</author>
1690
        /// <param name="pt"></param>
1691
        /// <param name="bAxisLocked"></param>
1692
        public override void OnCreatingMouseMove(Point pt, bool bAxisLocked)
1693
        {
1694
            this.EndPoint = pt;
1695

    
1696
            Point tempPoint = this.EndPoint;
1697
            CommentAngle = MathSet.returnAngle(this.StartPoint, ref tempPoint, bAxisLocked);
1698

    
1699
            if (bAxisLocked)
1700
            {
1701
                this.EndPoint = tempPoint;
1702
            }
1703

    
1704
            this.MidPoint = MathSet.getMiddlePoint(this.StartPoint, this.EndPoint);
1705
            this.isFixed = (this.ControlType == ControlType.ArrowTransTextControl) || 
1706
                (this.ControlType == ControlType.ArrowTransTextBorderControl) || (this.ControlType == ControlType.ArrowTransTextCloudControl);
1707

    
1708
            this.PointSet = new List<Point>
1709
            {
1710
                this.StartPoint,
1711
                this.MidPoint,
1712
                this.EndPoint,
1713
            };
1714
        }
1715

    
1716
        /// <summary>
1717
        /// move control point has same location of given pt along given delta
1718
        /// </summary>
1719
        /// <author>humkyung</author>
1720
        /// <date>2019.06.20</date>
1721
        /// <param name="pt"></param>
1722
        /// <param name="dx"></param>
1723
        /// <param name="dy"></param>
1724
        public override void OnMoveCtrlPoint(Point pt, double dx, double dy, bool bAxisLocked = false)
1725
        {
1726
            IPath path = (this as IPath);
1727

    
1728
            //System.Diagnostics.Debug.WriteLine($"OnMoveCtrlPoint : {path.PointSet[1].X},{path.PointSet[1].Y}");
1729

    
1730
            Point selected = MathSet.getNearPoint(path.PointSet, pt);
1731

    
1732
            //StartPoint에 표시된 Thumb는 dx,dy가 +로 더해줘야한다.
1733
            if (path.PointSet.IndexOf(selected) != 0)
1734
            {
1735
                double radian = this.CommentAngle * Math.PI / 180;
1736
                double cos = Math.Cos(radian);
1737
                double sin = Math.Sin(radian);
1738

    
1739
                double _dx = dx * cos - dy * sin;
1740
                double _dy = dx * sin + dy * cos;
1741

    
1742
                selected.X += _dx;
1743
                selected.Y += _dy;
1744
            }
1745
            else
1746
            {
1747
                selected.X += dx;
1748
                selected.Y += dy;
1749
            }
1750

    
1751
            int i = 0;
1752
            for (i = 0; i < (this as IPath).PointSet.Count; i++)
1753
            {
1754
                if (pt.Equals((this as IPath).PointSet[i])) break;
1755
            }
1756

    
1757
            List<Point> pts = path.PointSet;
1758
            if ((pts[0].X > pts[1].X && dx > 0) || (pts[0].X < pts[1].X && dx < 0))
1759
            {
1760
                pts[1] = new Point(pts[1].X + dx, pts[1].Y);
1761
            }
1762
            if ((pts[0].Y > pts[1].Y && dy > 0) || (pts[0].Y < pts[1].Y && dy < 0))
1763
            {
1764
                pts[1] = new Point(pts[1].X, pts[1].Y + dy);
1765
            }
1766

    
1767
            path.PointSet[1] = pts[1];
1768

    
1769
            if (path.PointSet.Count > i) {
1770
                path.PointSet[i] = selected;
1771
            }
1772
            //System.Diagnostics.Debug.WriteLine($"OnMoveCtrlPoint end : {path.PointSet[1].X},{path.PointSet[1].Y}");
1773
            this.UpdateControl();
1774
        }
1775

    
1776
        /// <summary>
1777
        /// return ArrowTextControl's area
1778
        /// </summary>
1779
        /// <author>humkyung</author>
1780
        /// <date>2019.06.13</date>
1781
        public override Rect ItemRect
1782
        {
1783
            get
1784
            {
1785
                double dMinX = Math.Min(this.StartPoint.X, this.EndPoint.X);
1786
                double dMinY = Math.Min(this.StartPoint.Y, this.EndPoint.Y);
1787
                double dMaxX = Math.Max(this.StartPoint.X, this.EndPoint.X);
1788
                double dMaxY = Math.Max(this.StartPoint.Y, this.EndPoint.Y);
1789

    
1790
                return new Rect(new Point(dMinX, dMinY), new Point(dMaxX, dMaxY));
1791
            }
1792
        }
1793

    
1794
        /// <summary>
1795
        /// Serialize this
1796
        /// </summary>
1797
        /// <param name="sUserId"></param>
1798
        /// <returns></returns>
1799
        public override string Serialize()
1800
        {
1801
            using (S_ArrowTextControl STemp = new S_ArrowTextControl())
1802
            {
1803
                STemp.TransformPoint = "0|0";
1804
                STemp.PointSet = this.PointSet;
1805
                STemp.SizeSet = String.Format("{0}", this.LineSize);
1806
                STemp.StrokeColor = this.StrokeColor.Color.ToString();
1807
                STemp.StartPoint = this.StartPoint;
1808
                STemp.ArrowStyle = this.ArrowTextStyle;
1809
                //STemp.StrokeColor = "#FF00FF00";
1810
                STemp.UserID = this.UserID;
1811
                STemp.ArrowText = this.Base_TextBox.Text;
1812
                STemp.BorderSize = this.BorderSize;
1813
                STemp.isHighLight = this.isHighLight;
1814
                STemp.BoxHeight = this.BoxHeight;
1815
                STemp.BoxWidth = this.BoxWidth;
1816
                STemp.Opac = this.Opacity;
1817
                STemp.EndPoint = this.EndPoint;
1818
                STemp.isFixed = this.isFixed;
1819
                //STemp.DashSize = this.DashSize;
1820
                STemp.Name = this.GetType().Name.ToString();
1821
                STemp.isTrans = this.isTrans;
1822
                STemp.MidPoint = this.MidPoint;
1823
                STemp.Angle = this.PageAngle;
1824
                STemp.fontConfig = new List<string>()
1825
                            {
1826
                                this.TextFamily.FontName(),
1827
                                this.TextStyle.ToString(),
1828
                                this.TextWeight.ToString(),
1829
                                this.TextSize.ToString(),
1830
                            };
1831

    
1832
                if (this.UnderLine != null)
1833
                {
1834
                    STemp.fontConfig.Add("true");
1835
                }
1836

    
1837
                ///강인구 추가(2017.11.02)
1838
                ///Memo 추가
1839
                STemp.Memo = this.Memo;
1840
                STemp.BorderSize = this.BorderSize;
1841
                return "|DZ|" + JsonSerializerHelper.CompressString((STemp.JsonSerialize()));
1842
            };
1843
        }
1844

    
1845
        /// <summary>
1846
        /// create a arrowtextcontrol from given string
1847
        /// </summary>
1848
        /// <param name="str"></param>
1849
        /// <returns></returns>
1850
        public static ArrowTextControl FromString(string str, SolidColorBrush brush, string sProjectNo,double PageAngle)
1851
        {
1852
            ArrowTextControl instance = null;
1853
            using (S_ArrowTextControl s = JsonSerializerHelper.JsonDeserialize<S_ArrowTextControl>(str))
1854
            {
1855
                string[] data2 = s.SizeSet.Split(delimiterChars2, StringSplitOptions.RemoveEmptyEntries);
1856
                instance = new ArrowTextControl();
1857
                instance.PageAngle = s.Angle;
1858
                instance.LineSize = Convert.ToDouble(data2.First());
1859
                instance.PointSet = s.PointSet;
1860
                instance.StartPoint = s.StartPoint;
1861
                instance.EndPoint = s.EndPoint;
1862
                instance.StrokeColor = brush;
1863
                //instance.DashSize = s.DashSize;
1864
                instance.ArrowTextStyle = s.ArrowStyle;
1865
                instance.isHighLight = s.isHighLight;
1866
                instance.ArrowText = s.ArrowText;
1867
                instance.Opacity = s.Opac;
1868
                instance.BorderSize = s.BorderSize;
1869
                instance.BoxWidth = s.BoxWidth;
1870
                instance.BoxHeight = s.BoxHeight;
1871
                instance.isFixed = s.isFixed;
1872
                //instance.VisualPageAngle = s.Angle;
1873
                instance.UserID = s.UserID;
1874
                instance.isTrans = s.isTrans;
1875
                instance.MidPoint = s.MidPoint;
1876
                instance.Memo = s.Memo;
1877
                if (s.fontConfig == null || s.fontConfig.ToList().Count == 0)
1878
                {
1879
                    s.fontConfig = new List<string>();
1880

    
1881
                    s.fontConfig.Add("Arial");
1882
                    s.fontConfig.Add("Normal");
1883
                    s.fontConfig.Add("Normal");
1884
                    s.fontConfig.Add("30");
1885
                }
1886
                instance.TextFamily = Markus.Fonts.FontHelper.GetFontFamily(s.fontConfig[0]);
1887
                //인구 추가(2018.04.17)
1888
                instance.TextStyle = StringToFont.ConFontStyle(s.fontConfig[1]);
1889
                instance.TextWeight = StringToFont.ConFontWeight(s.fontConfig[2]);
1890
                instance.TextSize = Convert.ToDouble(s.fontConfig[3]);
1891

    
1892
                if (s.fontConfig.Count() == 5)
1893
                {
1894
                    instance.UnderLine = TextDecorations.Underline;
1895
                }
1896
            }
1897

    
1898
            return instance;
1899
        }
1900

    
1901
        #region Dispose
1902
        public void Dispose()
1903
        {
1904
            //GC.Collect();
1905
            ////GC.SuppressFinalize(this);
1906
            this.BaseTextbox_Caret = null;
1907
            this.Base_ArrowPath = null;
1908
            this.Base_ArrowSubPath = null;
1909
            this.Base_TextBlock = null;
1910
            this.Base_TextBox = null;
1911
        } 
1912
        #endregion
1913

    
1914
        #region INotifyPropertyChanged
1915
        private void OnPropertyChanged(string name)
1916
        {
1917
            if (PropertyChanged != null)
1918
            {
1919
                PropertyChanged(this, new PropertyChangedEventArgs(name));
1920
            }
1921
        }
1922

    
1923
        public event PropertyChangedEventHandler PropertyChanged; 
1924
        #endregion
1925
    }
1926
}
클립보드 이미지 추가 (최대 크기: 500 MB)