프로젝트

일반

사용자정보

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

markus / MarkupToPDF / Controls / Text / ArrowTextControl.cs @ fb827eb4

이력 | 보기 | 이력해설 | 다운로드 (85.9 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
using System.Runtime.CompilerServices;
18
using System.Windows.Controls.Primitives;
19

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

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

    
37
        private const double _CloudArcDepth = 0.8;  /// 2018.05.14 added by humkyung
38
        private const int _BendingLineLength = 50;
39

    
40
        #region Object & Variable
41
        GeometryGroup instanceGroup { get; } = new GeometryGroup();
42
        LineGeometry connectorSMGeometry { get; } = new LineGeometry();
43
        LineGeometry connectorMEGeometry { get; } = new LineGeometry();
44

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

    
47
        #endregion
48

    
49
        static ArrowTextControl()
50
        {
51
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ArrowTextControl), new FrameworkPropertyMetadata(typeof(ArrowTextControl)));
52
        }
53

    
54
        public ArrowTextControl() : base()
55
        {
56
        }
57

    
58
        public override void Copy(CommentUserInfo lhs)
59
        {
60
            if (lhs is ArrowTextControl item)
61
            {
62
                this.PageAngle = item.PageAngle;
63
                this.LineSize = item.LineSize;
64
                this.PointSet = item.PointSet.ConvertAll(x => new Point(x.X, x.Y));
65
                this.StartPoint = new Point(item.StartPoint.X, item.StartPoint.Y);
66
                this.EndPoint = new Point(item.EndPoint.X, item.EndPoint.Y);
67
                this.StrokeColor = item.StrokeColor;
68
                this.ArcLength = item.ArcLength;
69
                this.ArrowTextStyle = item.ArrowTextStyle;
70
                this.isHighLight = item.isHighLight;
71
                this.ArrowText = item.ArrowText;
72
                this.Opacity = item.Opacity;
73
                this.BorderSize = item.BorderSize;
74
                this.BoxWidth = item.BoxWidth;
75
                this.BoxHeight = item.BoxHeight;
76
                this.isFixed = item.isFixed;
77
                this.ControlType = item.ControlType;
78
                this.UserID = item.UserID;
79
                this.isTrans = item.isTrans;
80
                this.MidPoint = item.MidPoint;
81
                this.Memo = item.Memo;
82
                this.TextFamily = item.TextFamily;
83
                this.TextStyle = item.TextStyle;
84
                this.TextWeight = item.TextWeight;
85
                this.TextSize = item.TextSize;
86
                this.UnderLine = item.UnderLine;
87
                this.GroupID = item.GroupID;
88
            }
89
        }
90

    
91
        public override CommentUserInfo Clone()
92
        {
93
            var clone = new ArrowTextControl();
94
            clone.Copy(this);
95
            return clone;
96
        }
97

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

    
116
                this.Base_TextBox.ApplyTemplate();
117
                this.Base_TextBox.Text = this.ArrowText;
118

    
119
                MoveCustomCaret();
120

    
121
                Base_TextBox.SizeChanged += new SizeChangedEventHandler(Base_TextBox_SizeChanged);
122
                Base_TextBox.GotFocus += new RoutedEventHandler(Base_TextBox_GotFocus);
123
                Base_TextBox.LostFocus += new RoutedEventHandler(Base_TextBox_LostFocus);
124
                Base_TextBox.SelectionChanged += (sender, e) => MoveCustomCaret();
125
                this.KeyDown += ArrowTextControl_KeyDown;
126

    
127
                SetArrowTextPath(true);
128

    
129
                Base_TextBox.IsTabStop = true;
130
            }
131
        }
132

    
133
        private void ArrowTextControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
134
        {
135
           if(e.Key == System.Windows.Input.Key.Escape)
136
            {
137
                if(string.IsNullOrEmpty(Base_TextBox.Text))
138
                {
139
                    this.Visibility = Visibility.Collapsed;
140
                }
141

    
142
                EditEnd();
143
            }
144
        }
145

    
146
        public void SetFontFamily(FontFamily fontFamily)
147
        {
148
            if (this.Base_TextBlock != null)
149
            {
150
                this.Base_TextBlock.FontFamily = fontFamily;
151
            }
152

    
153
            if (this.Base_TextBox != null)
154
            {
155
                this.Base_TextBox.FontFamily = fontFamily;
156
            }
157
            this.FontFamily = fontFamily;
158
            this.TextFamily = fontFamily;
159
        }
160

    
161
        /// <summary>
162
        /// Moves the custom caret on the canvas.
163
        /// </summary>
164
        public void MoveCustomCaret()
165
        {
166
            var caretLocation = this.Base_TextBox.GetRectFromCharacterIndex(this.Base_TextBox.CaretIndex).Location;
167

    
168
            var angle = Math.Abs(this.PageAngle);
169
            //angle = 0;
170
            System.Diagnostics.Debug.WriteLine("Page Angle : " +  this.PageAngle);
171

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

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

    
218
        void Base_TextBox_LostFocus(object sender, RoutedEventArgs e)
219
        {
220
            EditEnd();
221
        }
222

    
223
        private void EditEnd()
224
        { 
225
            this.ArrowText = Base_TextBox.Text;
226
            Base_TextBox.Focusable = false;
227
            this.BaseTextbox_Caret.Visibility = Visibility.Collapsed;
228
            this.IsEditingMode = false;
229
            ApplyOverViewData();
230

    
231
            if(EditEnded != null)
232
            {
233
                EditEnded(this, new EventArgs());
234
            }
235
        }
236

    
237
        void Base_TextBox_GotFocus(object sender, RoutedEventArgs e)
238
        {
239
            this.BaseTextbox_Caret.Visibility = Visibility.Visible;
240
            MoveCustomCaret();
241
            Base_TextBox.Focus();
242
            this.IsEditingMode = true;
243
        }
244

    
245
        void Base_TextBox_SizeChanged(object sender, SizeChangedEventArgs e)
246
        {
247
            if(this.IsEditingMode)
248
            {
249
                if (Base_TextBox.Text.Contains("|OR||DZ|"))
250
                {
251
                    Base_TextBox.Text = this.ArrowText;
252
                }
253

    
254
                this.ArrowText = Base_TextBox.Text;
255
                
256
            }
257
            BoxWidth = e.NewSize.Width;
258
            BoxHeight = e.NewSize.Height;
259
            SetArrowTextPath();
260
        }
261

    
262
        #region Properties
263
        private bool _IsEditingMode;
264
        public bool IsEditingMode
265
        {
266
            get
267
            {
268
                return _IsEditingMode;
269
            }
270
            set
271
            {
272
                _IsEditingMode = value;
273
                OnPropertyChanged("IsEditingMode");
274
            }
275
        }
276

    
277

    
278
        #endregion
279

    
280
        #region dp Properties
281
        //강인구 주석 풀기
282
        public Visibility TextBoxVisibility
283
        {
284
            get { return (Visibility)GetValue(TextBoxVisibilityProperty); }
285
            set
286
            {
287
                if (this.TextBoxVisibility != value)
288
                {
289
                    SetValue(TextBoxVisibilityProperty, value);
290
                    OnPropertyChanged("TextBoxVisibility");
291
                }
292
            }
293
        }
294

    
295
        //강인구 주석 풀기
296
        public Visibility TextBlockVisibility
297
        {
298
            get { return (Visibility)GetValue(TextBlockVisibilityProperty); }
299
            set
300
            {
301
                if (this.TextBlockVisibility != value)
302
                {
303
                    SetValue(TextBlockVisibilityProperty, value);
304
                    OnPropertyChanged("TextBlockVisibility");
305
                }
306
            }
307
        }
308

    
309

    
310
        public override SolidColorBrush StrokeColor
311
        {
312
            get { return (SolidColorBrush)GetValue(StrokeColorProperty); }
313
            set
314
            {
315
                if (this.StrokeColor != value)
316
                {
317
                    SetValue(StrokeColorProperty, value);
318
                }
319
            }
320
        }
321

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

    
335
        public PathGeometry SubPathData
336
        {
337
            get { return (PathGeometry)GetValue(SubPathDataProperty); }
338
            set
339
            {
340
                if (this.SubPathData != value)
341
                {
342
                    SetValue(SubPathDataProperty, value);
343
                }
344
            }
345
        }
346

    
347
        public string UserID
348
        {
349
            get { return (string)GetValue(UserIDProperty); }
350
            set
351
            {
352
                if (this.UserID != value)
353
                {
354
                    SetValue(UserIDProperty, value);
355
                    OnPropertyChanged("UserID");
356
                }
357
            }
358
        }
359

    
360
        public List<Point> PointSet
361
        {
362
            get { return (List<Point>)GetValue(PointSetProperty); }
363
            set { SetValue(PointSetProperty, value); }
364
        }
365

    
366
        public override bool IsSelected
367
        {
368
            get
369
            {
370
                return (bool)GetValue(IsSelectedProperty);
371
            }
372
            set
373
            {
374
                SetValue(IsSelectedProperty, value);
375
                OnPropertyChanged("IsSelected");
376
            }
377
        }
378

    
379
        public override ControlType ControlType
380
        {
381
            set
382
            {
383
                SetValue(ControlTypeProperty, value);
384
                OnPropertyChanged("ControlType");
385
            }
386
            get
387
            {
388
                return (ControlType)GetValue(ControlTypeProperty);
389
            }
390
        }
391

    
392
        public Point StartPoint
393
        {
394
            get { return (Point)GetValue(StartPointProperty); }
395
            set { SetValue(StartPointProperty, value); }
396
        }
397

    
398
        public Point EndPoint
399
        {
400
            get { return (Point)GetValue(EndPointProperty); }
401
            set { SetValue(EndPointProperty, value); }
402
        }
403

    
404
        public Point OverViewStartPoint
405
        {
406
            get { return (Point)GetValue(OverViewStartPointProperty); }
407
            set { SetValue(OverViewStartPointProperty, value); }
408
        }
409

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

    
416

    
417
        //public double Angle
418
        //{
419
        //    get { return (double)GetValue(AngleProperty); }
420
        //    set { SetValue(AngleProperty, value); }
421
        //}
422

    
423
        public Thickness BorderSize
424
        {
425
            get { return (Thickness)GetValue(BorderSizeProperty); }
426
            set
427
            {
428
                if (this.BorderSize != value)
429
                {
430
                    SetValue(BorderSizeProperty, value);
431
                }
432
            }
433
        }
434

    
435

    
436
        public Point MidPoint
437
        {
438
            get { return (Point)GetValue(MidPointProperty); }
439
            set { SetValue(MidPointProperty, value); }
440
        }
441

    
442
        public bool isFixed
443
        {
444
            get { return (bool)GetValue(IsFixedProperty); }
445
            set { SetValue(IsFixedProperty, value); }
446
        }
447

    
448
        public bool isTrans
449
        {
450
            get { return (bool)GetValue(TransformerProperty); }
451
            set { SetValue(TransformerProperty, value); }
452
        }
453

    
454
        public bool isHighLight
455
        {
456
            get { return (bool)GetValue(isHighlightProperty); }
457
            set
458
            {
459
                if (this.isHighLight != value)
460
                {
461
                    SetValue(isHighlightProperty, value);
462
                    OnPropertyChanged("isHighLight");
463
                }
464
            }
465
        }
466

    
467
        public FontWeight TextWeight
468
        {
469
            get { return (FontWeight)GetValue(TextWeightProperty); }
470
            set
471
            {
472
                if (this.TextWeight != value)
473
                {
474
                    SetValue(TextWeightProperty, value);
475
                    OnPropertyChanged("TextWeight");
476
                }
477
            }
478
        }
479

    
480
        public Double LineSize
481
        {
482
            get { return (Double)GetValue(LineSizeProperty); }
483
            set
484
            {
485
                if (this.LineSize != value)
486
                {
487
                    SetValue(LineSizeProperty, value);
488
                }
489
            }
490
        }
491

    
492
        public Double BoxWidth
493
        {
494
            get { return (Double)GetValue(BoxWidthProperty); }
495
            set
496
            {
497
                if (this.BoxWidth != value)
498
                {
499
                    SetValue(BoxWidthProperty, value);
500
                }
501
            }
502
        }
503

    
504
        public Double BoxHeight
505
        {
506
            get { return (Double)GetValue(BoxHeightProperty); }
507
            set
508
            {
509
                if (this.BoxHeight != value)
510
                {
511
                    SetValue(BoxHeightProperty, value);
512
                }
513
            }
514
        }
515

    
516
        public ArrowTextStyleSet ArrowTextStyle
517
        {
518
            get { return (ArrowTextStyleSet)GetValue(ArrowTextStyleProperty); }
519
            set
520
            {
521
                if (this.ArrowTextStyle != value)
522
                {
523
                    SetValue(ArrowTextStyleProperty, value);
524
                }
525
            }
526
        }
527

    
528
        public Geometry PathData
529
        {
530
            get { return (Geometry)GetValue(PathDataProperty); }
531
            set { SetValue(PathDataProperty, value);
532

    
533
                OnPropertyChanged("PathData");
534
            }
535
        }
536

    
537
        public SolidColorBrush BackInnerColor
538
        {
539
            get { return (SolidColorBrush)GetValue(BackInnerColorProperty); }
540
            set
541
            {
542
                if (this.BackInnerColor != value)
543
                {
544
                    SetValue(BackInnerColorProperty, value);
545
                    OnPropertyChanged("BackInnerColor");
546
                }
547
            }
548
        }
549

    
550
        public Geometry PathDataInner
551
        {
552
            get { return (Geometry)GetValue(PathDataInnerProperty); }
553
            set
554
            {
555
                SetValue(PathDataInnerProperty, value);
556
                OnPropertyChanged("PathDataInner");
557
            }
558
        }
559

    
560
        public Geometry OverViewPathData
561
        {
562
            get { return (Geometry)GetValue(OverViewPathDataProperty); }
563
            set { SetValue(OverViewPathDataProperty, value);
564

    
565
                OnPropertyChanged("OverViewPathData");
566

    
567
            }
568
        }
569

    
570
        public FontFamily TextFamily
571
        {
572
            get { return (FontFamily)GetValue(TextFamilyProperty); }
573
            set
574
            {
575
                if (this.TextFamily != value)
576
                {
577
                    SetValue(TextFamilyProperty, value);
578
                    OnPropertyChanged("TextFamily");
579
                }
580
            }
581
        }
582

    
583
        public string ArrowText
584
        {
585
            get { return (string)GetValue(ArrowTextProperty); }
586
            set
587
            {
588
                if (this.ArrowText != value)
589
                {
590
                    SetValue(ArrowTextProperty, value);
591
                    OnPropertyChanged("ArrowText");
592
                }
593
            }
594
        }
595

    
596
        public string OverViewArrowText
597
        {
598

    
599
            get { return (string)GetValue(OverViewArrowTextProperty);
600
            }
601
            set
602
            {
603
                if (this.OverViewArrowText != value)
604
                {
605
                    SetValue(OverViewArrowTextProperty, value);
606
                    OnPropertyChanged("OverViewArrowText");
607
                }
608
            }
609
        }
610

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

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

    
637
        //강인구 추가
638
        public TextDecorationCollection UnderLine
639
        {
640
            get
641
            {
642
                return (TextDecorationCollection)GetValue(UnderLineProperty);
643
            }
644
            set
645
            {
646
                if (this.UnderLine != value)
647
                {
648
                    SetValue(UnderLineProperty, value);
649
                    OnPropertyChanged("UnderLine");
650
                }
651
            }
652
        }
653

    
654
        public double CanvasX
655
        {
656
            get { return (double)GetValue(CanvasXProperty); }
657
            set
658
            {
659
                if (this.CanvasX != value)
660
                {
661
                    SetValue(CanvasXProperty, value);
662
                    OnPropertyChanged("CanvasX");
663
                }
664
            }
665
        }
666

    
667
        public double CanvasY
668
        {
669
            get { return (double)GetValue(CanvasYProperty); }
670
            set
671
            {
672
                if (this.CanvasY != value)
673
                {
674
                    SetValue(CanvasYProperty, value);
675
                    OnPropertyChanged("CanvasY");
676
                }
677
            }
678
        } 
679

    
680
        public double CenterX
681
        {
682
            get { return (double)GetValue(CenterXProperty); }
683
            set { SetValue(CenterXProperty, value);
684
            OnPropertyChanged("CenterX");
685
            
686
            }
687
        }
688

    
689
        public double CenterY
690
        {
691
            get { return (double)GetValue(CenterYProperty); }
692
            set { SetValue(CenterYProperty, value);
693
            OnPropertyChanged("CenterY");
694
            }
695
        }
696

    
697
        public Brush SubPathFill
698
        {
699
            get { return (Brush)GetValue(SubPathFillProperty); }
700
            set
701
            {
702
                SetValue(SubPathFillProperty, value);
703
                OnPropertyChanged("SubPathFill");
704
            }
705
        }
706

    
707
        public Brush TextBoxBackground
708
        {
709
            get { return (Brush)GetValue(TextBoxBackgroundProperty); }
710
            set
711
            {
712
                SetValue(TextBoxBackgroundProperty, value);
713
                OnPropertyChanged("TextBoxBackground");
714
            }
715
        }
716

    
717

    
718
        //강인구 추가 주석풀기
719
       
720

    
721
        public bool EnableEditing
722
        {
723
            get { return (bool)GetValue(EnableEditingProperty); }
724
            set
725
            {
726
                if (this.EnableEditing != value)
727
                {
728
                    SetValue(EnableEditingProperty, value);
729
                    OnPropertyChanged("EnableEditing");
730
                }
731
            }
732
        }
733

    
734
        #endregion
735

    
736
        #region Dependency Properties
737

    
738
        public static readonly DependencyProperty BoxWidthProperty = DependencyProperty.Register(
739
                "BoxWidth", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
740

    
741
        public static readonly DependencyProperty BoxHeightProperty = DependencyProperty.Register(
742
                "BoxHeight", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
743

    
744
        public static readonly DependencyProperty UserIDProperty = DependencyProperty.Register(
745
                "UserID", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
746

    
747
        public static readonly DependencyProperty ArrowTextStyleProperty = DependencyProperty.Register(
748
               "ArrowTextStyle", typeof(ArrowTextStyleSet), typeof(ArrowTextControl), new PropertyMetadata(ArrowTextStyleSet.Normal));
749

    
750
        public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register(
751
                "CenterX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
752

    
753
        public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register(
754
                "CenterY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
755

    
756
        public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
757
                "Angle", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0.0, new PropertyChangedCallback(PointValueChanged)));
758
        
759
        public static readonly DependencyProperty CanvasXProperty = DependencyProperty.Register(
760
                "CanvasX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
761

    
762
        public static readonly DependencyProperty CanvasYProperty = DependencyProperty.Register(
763
                "CanvasY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
764

    
765
        public static readonly DependencyProperty PointSetProperty = DependencyProperty.Register(
766
                "PointSet", typeof(List<Point>), typeof(ArrowTextControl), new PropertyMetadata(new List<Point>(), PointValueChanged));
767

    
768
        public static readonly DependencyProperty TextFamilyProperty = DependencyProperty.Register(
769
                "TextFamily", typeof(FontFamily), typeof(ArrowTextControl), new PropertyMetadata(new FontFamily("Arial"), TextChanged));
770

    
771
        public static readonly DependencyProperty PathDataProperty = DependencyProperty.Register(
772
                "PathData", typeof(Geometry), typeof(ArrowTextControl), null);
773

    
774
        //강인구 추가
775
        public static readonly DependencyProperty UnderLineProperty = DependencyProperty.Register(
776
    "UnderLine", typeof(TextDecorationCollection), typeof(ArrowTextControl), new PropertyMetadata(null, PointValueChanged));
777

    
778
        public static readonly DependencyProperty LineSizeProperty = DependencyProperty.Register(
779
               "LineSize", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)3, PointValueChanged));
780

    
781
        public static readonly DependencyProperty TextStyleProperty = DependencyProperty.Register(
782
                "TextStyle", typeof(FontStyle), typeof(ArrowTextControl), new PropertyMetadata(FontStyles.Normal));
783

    
784
        public static readonly DependencyProperty TextSizeProperty = DependencyProperty.Register(
785
                "TextSize", typeof(Double), typeof(ArrowTextControl), new PropertyMetadata((Double)30, PointValueChanged));
786

    
787
        public static readonly DependencyProperty TextWeightProperty = DependencyProperty.Register(
788
                "TextWeight", typeof(FontWeight), typeof(ArrowTextControl), new PropertyMetadata(FontWeights.Normal));
789

    
790
        public static readonly DependencyProperty IsFixedProperty = DependencyProperty.Register(
791
                "isFixed", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
792

    
793
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
794
                "IsSelected", typeof(bool), typeof(ArrowTextControl), new FrameworkPropertyMetadata(false, IsSelectedChanged));
795

    
796
        public static readonly DependencyProperty StrokeColorProperty = DependencyProperty.Register(
797
                "StrokeColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
798

    
799
        public static readonly DependencyProperty ArcLengthProperty = DependencyProperty.Register(
800
            "ArcLength", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)10, PointValueChanged));
801

    
802
        public static readonly DependencyProperty ControlTypeProperty = DependencyProperty.Register(
803
                "ControlType", typeof(ControlType), typeof(ArrowTextControl), new FrameworkPropertyMetadata(ControlType.ArrowTextControl));
804

    
805
        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register(
806
                "StartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
807

    
808
        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register(
809
                "EndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
810

    
811
        public static readonly DependencyProperty BackInnerColorProperty = DependencyProperty.Register(
812
            "BackInnerColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.White)));
813

    
814
        public static readonly DependencyProperty PathDataInnerProperty = DependencyProperty.Register(
815
    "PathDataInner", typeof(Geometry), typeof(ArrowTextControl), null);
816

    
817
        public static readonly DependencyProperty isHighlightProperty = DependencyProperty.Register(
818
                "isHighlight", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
819

    
820
        public static readonly DependencyProperty MidPointProperty = DependencyProperty.Register(
821
                "MidPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
822

    
823
        public static readonly DependencyProperty TransformerProperty = DependencyProperty.Register(
824
                "isTrans", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
825

    
826
        public static readonly DependencyProperty BorderSizeProperty = DependencyProperty.Register(
827
                "BorderSize", typeof(Thickness), typeof(ArrowTextControl), new PropertyMetadata(new Thickness(0), PointValueChanged));
828
    
829
        public static readonly DependencyProperty ArrowTextProperty = DependencyProperty.Register(
830
              "ArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
831

    
832

    
833

    
834
        //, new PropertyChangedCallback(TextChanged)
835

    
836

    
837
        #region 추가 사항
838
        public static readonly DependencyProperty SubPathDataProperty = DependencyProperty.Register(
839
                "SubPathData", typeof(Geometry), typeof(ArrowTextControl), null);
840

    
841

    
842
        public static readonly DependencyProperty SubPathFillProperty = DependencyProperty.Register(
843
                "SubPathFill", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(null));
844

    
845
        public static readonly DependencyProperty TextBoxBackgroundProperty = DependencyProperty.Register(
846
                "TextBoxBackground", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(Brushes.White));
847

    
848
        public static readonly DependencyProperty OverViewArrowTextProperty = DependencyProperty.Register(
849
                "OverViewArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null, new PropertyChangedCallback(TextChanged)));
850

    
851
        public static readonly DependencyProperty OverViewPathDataProperty = DependencyProperty.Register(
852
                "OverViewPathData", typeof(Geometry), typeof(ArrowTextControl), null);
853

    
854
        public static readonly DependencyProperty OverViewStartPointProperty = DependencyProperty.Register(
855
                "OverViewStartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
856

    
857
        public static readonly DependencyProperty OverViewEndPointProperty = DependencyProperty.Register(
858
                "OverViewEndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
859

    
860
        public static readonly DependencyProperty TextBoxVisibilityProperty = DependencyProperty.Register(
861
            "TextBoxVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Visible), OnTextBoxVisibilityChanged));
862

    
863
        //강인구 추가(주석풀기)
864
        public static readonly DependencyProperty TextBlockVisibilityProperty = DependencyProperty.Register(
865
            "TextBlockVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Collapsed), OnTextBlockVisibilityChanged));
866

    
867
        public static readonly DependencyProperty EnableEditingProperty = DependencyProperty.Register(
868
           "EnableEditing", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata((true), new PropertyChangedCallback(OnIsEditingChanged)));
869

    
870
        #endregion
871

    
872
        #endregion
873

    
874
        #region CallBack Method
875

    
876
        //강인구 추가(주석풀기)
877
        public static void OnIsEditingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
878
        {
879
            var instance = (ArrowTextControl)sender;
880

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

    
885
                if (instance.EnableEditing)
886
                {
887
                    instance.EditingMode();
888
                }
889
                else
890
                {
891
                    instance.UnEditingMode();
892
                }
893
            }
894
        }
895

    
896
        public static void OnTextBoxVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
897
        {
898
            var instance = (ArrowTextControl)sender;
899

    
900
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
901
            {
902
                instance.SetValue(e.Property, e.NewValue);
903
            }
904
        }
905

    
906
        public static void OnTextBlockVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
907
        {
908
            var instance = (ArrowTextControl)sender;
909

    
910
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
911
            {
912
                instance.SetValue(e.Property, e.NewValue);
913
            }
914
        }
915

    
916
        public static void PointValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
917
        {
918
            var instance = (ArrowTextControl)sender;
919

    
920
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
921
            {
922
                if (e.Property.Name == "StartPoint" || e.Property.Name == "EndPoint")
923
                {
924
                    var connections = instance.GetConnectionPointList();
925
                    var near = MathSet.getNearPoint(connections, instance.StartPoint);
926
                    if (!near.Equals(instance.connectorMEGeometry.EndPoint))
927
                    {
928
                        var BendingPoint = instance.GetBendingPoint(connections, instance.StartPoint, null);
929
                        if (BendingPoint.HasValue) instance.MidPoint = BendingPoint.Value;
930
                    }
931

    
932
                    instance.SetArrowTextPath();
933
                }
934
                else if(e.Property.Name == "MidPoint")
935
                {
936
                    instance.SetArrowTextPath();
937
                }
938
            }
939
        }
940

    
941

    
942
        public static void TextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
943
        {
944
            var instance = (ArrowTextControl)sender;
945
            
946
            if (e.OldValue != e.NewValue)
947
            {
948
                instance.SetValue(e.Property, e.NewValue);
949
                //instance.BoxWidth = instance.Base_TextBox.ActualWidth;
950
                //instance.BoxHeight = instance.Base_TextBox.ActualHeight;
951
            }
952
        }
953

    
954
        public static void OnCenterXYChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
955
        {
956
            var instance = (ArrowTextControl)sender;
957
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
958
            {
959
                instance.SetValue(e.Property, e.NewValue);
960
                instance.SetArrowTextPath();
961
            }
962
        }
963

    
964
        public static void OnSetCansvasChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
965
        {
966
            var instance = (ArrowTextControl)sender;
967

    
968
            if (e.OldValue != e.NewValue && instance != null)
969
            {
970
                instance.SetValue(e.Property, e.NewValue);
971
                //Canvas.SetLeft(instance, instance.CanvasX);
972
                //Canvas.SetTop(instance, instance.CanvasY);
973
            }
974
        }
975

    
976
        public static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
977
        {
978
            //var instance = (ArrowTextControl)sender;
979

    
980
            //if (e.OldValue != e.NewValue)
981
            //{
982
            //    instance.SetValue(e.Property, e.NewValue);
983

    
984
            //    if (instance.IsSelected && instance.Base_TextBox != null)
985
            //    {
986
            //        instance.BorderSize = new Thickness(1);
987
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Blue);
988
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Blue);
989
            //    }
990
            //    else
991
            //    {
992
            //        instance.BorderSize = new Thickness(0);
993
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Transparent);
994
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Transparent);
995
            //    }
996
            //}
997
        }
998
        #endregion
999

    
1000
        #region Internal Method
1001

    
1002
        //강인구 주석 풀기
1003
        public void EditingMode()
1004
        {
1005
            TextBoxVisibility = Visibility.Visible;
1006
            TextBlockVisibility = Visibility.Collapsed;
1007

    
1008

    
1009
            //강인구 언더라인 추가
1010
            if (UnderLine != null)
1011
                Base_TextBlock.TextDecorations = UnderLine;
1012
        }
1013
        //강인구 주석 풀기
1014
        public void UnEditingMode()
1015
        {
1016
            TextBoxVisibility = Visibility.Collapsed;
1017
            TextBlockVisibility = Visibility.Visible;
1018

    
1019
            if (Base_TextBlock != null)
1020
            {
1021
                if (UnderLine != null)
1022
                    Base_TextBlock.TextDecorations = UnderLine;
1023

    
1024
                Base_TextBlock.Margin =
1025
                     new Thickness(Base_TextBox.Margin.Left + 4, Base_TextBox.Margin.Top + 4,
1026
                         Base_TextBox.Margin.Right + 4, Base_TextBox.Margin.Bottom + 4);
1027
            }
1028

    
1029
            this.BaseTextbox_Caret.Visibility = Visibility.Collapsed;
1030
        }
1031

    
1032
        /// <summary>
1033
        /// 연결점 리스트를 리턴한다.
1034
        /// </summary>
1035
        /// <returns></returns>
1036
        private List<Point> GetConnectionPointList()
1037
        {
1038
            List<Point> res = new List<Point>();
1039
            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox))); //상단
1040
            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox) + this.BoxHeight)); // 하단
1041
            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2)); //좌단
1042
            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth, Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2));  //우단
1043

    
1044
            if (isTrans)
1045
            {
1046
                switch (Math.Abs(this.PageAngle).ToString())
1047
                {
1048
                    case "90":
1049
                        {
1050
                            res.Clear();
1051

    
1052
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1053
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1054
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1055

    
1056
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1057
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1058

    
1059
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); //중간 하단
1060
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 하단
1061

    
1062
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간
1063
                        }
1064
                        break;
1065
                    case "270":
1066
                        {
1067
                            res.Clear();
1068

    
1069
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1070
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1071
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1072

    
1073
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1074
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1075

    
1076
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1077
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1078

    
1079
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간
1080
                        }
1081
                        break;
1082
                    default:
1083
                        break;
1084
                }
1085
            }
1086
            else
1087
            {
1088
                switch (Math.Abs(this.PageAngle).ToString())
1089
                {
1090
                    case "90":
1091
                        {
1092
                            res.Clear();
1093

    
1094
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1095
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1096
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1097

    
1098
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1099
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1100

    
1101
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); //중간 하단
1102
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 하단
1103
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간 
1104
                        }
1105
                        break;
1106
                    case "270":
1107
                        {
1108
                            res.Clear();
1109

    
1110
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1111
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1112
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1113

    
1114
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1115
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1116

    
1117
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1118
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1119

    
1120
                            res.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간 
1121
                        }
1122
                        break;
1123
                    default:
1124
                        break;
1125
                }
1126
            }
1127

    
1128
            return res;
1129
        }
1130

    
1131
        /// <summary>
1132
        /// connection을 이용하여 꺽인점의 위치를 구한다.
1133
        /// </summary>
1134
        /// <returns></returns>
1135
        private Point? GetBendingPoint(List<Point> ConnectionPointList, Point pt, Point? MidPoint)
1136
        {
1137
            Point? BendingPoint = null;
1138

    
1139
            var connection = MathSet.getNearPoint(ConnectionPointList, pt);
1140
            if (isTrans)
1141
            {
1142
                ///if (!pt.Equals(this.MidPoint) && Point.Subtract(this.connectorMEGeometry.EndPoint, connection).Length == 0) return MidPoint; 
1143

    
1144
                //20180910 LJY 각도에 따라.
1145
                Vector offset = MidPoint.HasValue ? Point.Subtract(MidPoint.Value, connection) : new Vector(0, 0);
1146
                switch (Math.Abs(this.PageAngle).ToString())
1147
                {
1148
                    case "90":
1149
                        if (isFixed)
1150
                        {
1151
                            if (ConnectionPointList[0] == connection) //상단
1152
                            {
1153
                                Vector dir = new Vector(0, 1);
1154
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1155
                                BendingPoint = connection + dir * BendingLength;
1156
                            }
1157
                            else if (ConnectionPointList[1] == connection) //하단
1158
                            {
1159
                                Vector dir = new Vector(0, -1);
1160
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1161
                                BendingPoint = connection + dir * BendingLength;
1162
                            }
1163
                            else if (ConnectionPointList[2] == connection) //좌단
1164
                            {
1165
                                Vector dir = new Vector(-1, 0);
1166
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1167
                                BendingPoint = connection + dir * BendingLength;
1168
                            }
1169
                            else if (ConnectionPointList[3] == connection) //우단
1170
                            {
1171
                                Vector dir = new Vector(1, 0);
1172
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1173
                                BendingPoint = connection + dir * BendingLength;
1174
                            }
1175
                        }
1176
                        else
1177
                        {
1178
                            BendingPoint = connection;
1179
                        }
1180
                        break;
1181
                    case "270":
1182
                        if (isFixed)
1183
                        {
1184
                            if (ConnectionPointList[0] == connection) //상단
1185
                            {
1186
                                Vector dir = new Vector(0, -1);
1187
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1188
                                BendingPoint = connection + dir * BendingLength;
1189
                            }
1190
                            else if (ConnectionPointList[1] == connection) //하단
1191
                            {
1192
                                Vector dir = new Vector(0, 1);
1193
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1194
                                BendingPoint = connection + dir * BendingLength;
1195
                            }
1196
                            else if (ConnectionPointList[2] == connection) //좌단
1197
                            {
1198
                                Vector dir = new Vector(1, 0);
1199
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1200
                                BendingPoint = connection + dir * BendingLength;
1201
                            }
1202
                            else if (ConnectionPointList[3] == connection) //우단
1203
                            {
1204
                                Vector dir = new Vector(-1, 0);
1205
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1206
                                BendingPoint = connection + dir * BendingLength;
1207
                            }
1208
                        }
1209
                        else
1210
                        {
1211
                            BendingPoint = connection;
1212
                        }
1213
                        break;
1214
                    default:
1215
                        if (isFixed)
1216
                        {
1217
                            if (ConnectionPointList[0] == connection) //상단
1218
                            {
1219
                                Vector dir = new Vector(0, -1);
1220
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1221
                                BendingPoint = connection + dir * BendingLength;
1222
                            }
1223
                            else if (ConnectionPointList[1] == connection) //하단
1224
                            {
1225
                                Vector dir = new Vector(0, 1);
1226
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1227
                                BendingPoint = connection + dir * BendingLength;
1228
                            }
1229
                            else if (ConnectionPointList[2] == connection) //좌단
1230
                            {
1231
                                Vector dir = new Vector(-1, 0);
1232
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1233
                                BendingPoint = connection + dir * BendingLength;
1234
                            }
1235
                            else if (ConnectionPointList[3] == connection) //우단
1236
                            {
1237
                                Vector dir = new Vector(1, 0);
1238
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1239
                                BendingPoint = connection + dir * BendingLength;
1240
                            }
1241
                        }
1242
                        else
1243
                        {
1244
                            BendingPoint = connection;
1245
                        }
1246
                        break;
1247
                }
1248
            }
1249
            else
1250
            {
1251
                //20180910 LJY 각도에 따라.
1252
                Vector offset = MidPoint.HasValue ? Point.Subtract(MidPoint.Value, connection) : new Vector(0, 0);
1253
                switch (Math.Abs(this.PageAngle).ToString())
1254
                {
1255
                    case "90":
1256
                        if (isFixed)
1257
                        {
1258
                            if (ConnectionPointList[0] == connection) //상단
1259
                            {
1260
                                Vector dir = new Vector(-1, 0);
1261
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1262
                                BendingPoint = connection + dir * BendingLength;
1263
                            }
1264
                            else if (ConnectionPointList[1] == connection) //하단
1265
                            {
1266
                                Vector dir = new Vector(1, 0);
1267
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1268
                                BendingPoint = connection + dir * BendingLength;
1269
                            }
1270
                            else if (ConnectionPointList[2] == connection) //좌단
1271
                            {
1272
                                Vector dir = new Vector(-1, 0);
1273
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1274
                                BendingPoint = connection + dir * BendingLength;
1275
                            }
1276
                            else if (ConnectionPointList[3] == connection) //우단
1277
                            {
1278
                                Vector dir = new Vector(1, 0);
1279
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1280
                                BendingPoint = connection + dir * BendingLength;
1281
                            }
1282
                        }
1283
                        else
1284
                        {
1285
                            BendingPoint = connection;
1286
                        }
1287
                        break;
1288
                    case "270":
1289
                        if (isFixed)
1290
                        {
1291
                            if (ConnectionPointList[0] == connection) //상단
1292
                            {
1293
                                Vector dir = new Vector(1, 0);
1294
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1295
                                BendingPoint = connection + dir * BendingLength;
1296
                            }
1297
                            else if (ConnectionPointList[1] == connection) //하단
1298
                            {
1299
                                Vector dir = new Vector(-1, 0);
1300
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1301
                                BendingPoint = connection + dir * BendingLength;
1302
                            }
1303
                            else if (ConnectionPointList[2] == connection) //좌단
1304
                            {
1305
                                Vector dir = new Vector(1, 0);
1306
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1307
                                BendingPoint = connection + dir * BendingLength;
1308
                            }
1309
                            else if (ConnectionPointList[3] == connection) //우단
1310
                            {
1311
                                Vector dir = new Vector(1, 0);
1312
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1313
                                BendingPoint = connection + dir * BendingLength;
1314
                            }
1315
                        }
1316
                        else
1317
                        {
1318
                            BendingPoint = connection;
1319
                        }
1320
                        break;
1321
                    default:
1322
                        if (isFixed)
1323
                        {
1324
                            if (ConnectionPointList[0] == connection) //상단
1325
                            {
1326
                                Vector dir = new Vector(0, -1);
1327
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1328
                                BendingPoint = connection + dir * BendingLength;
1329
                            }
1330
                            else if (ConnectionPointList[1] == connection) //하단
1331
                            {
1332
                                Vector dir = new Vector(0, 1);
1333
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1334
                                BendingPoint = connection + dir * BendingLength;
1335
                            }
1336
                            else if (ConnectionPointList[2] == connection) //좌단
1337
                            {
1338
                                Vector dir = new Vector(-1, 0);
1339
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1340
                                BendingPoint = connection + dir * BendingLength;
1341
                            }
1342
                            else if (ConnectionPointList[3] == connection) //우단
1343
                            {
1344
                                Vector dir = new Vector(1, 0);
1345
                                double BendingLength = offset.Length == 0 ? _BendingLineLength : Math.Abs(dir.Dot(offset));
1346
                                BendingPoint = connection + dir * BendingLength;
1347
                            }
1348
                        }
1349
                        else
1350
                        {
1351
                            BendingPoint = connection;
1352
                        }
1353
                        break;
1354
                }
1355
            }
1356

    
1357
            return BendingPoint;
1358
        }
1359
        
1360
        /// <summary>
1361
        /// 형상을 생성한다.
1362
        /// </summary>
1363
        /// <param name="IsInit"></param>
1364
        private void SetArrowTextPath(bool IsInit = false)
1365
        {
1366
            instanceGroup.Children.Clear();
1367

    
1368
            if (Math.Abs(PageAngle).ToString() == "90")
1369
            {
1370
                VisualPageAngle = 270;
1371
            }
1372
            else if (Math.Abs(PageAngle).ToString() == "270")
1373
            {
1374
                VisualPageAngle = 90;
1375
            }
1376
            else
1377
            {
1378
                VisualPageAngle = PageAngle;
1379
            }
1380

    
1381
            connectorSMGeometry.StartPoint = this.StartPoint;
1382
            connectorSMGeometry.EndPoint = this.MidPoint;
1383
            connectorMEGeometry.StartPoint = this.MidPoint; //핵심
1384

    
1385
            /// 텍스트박스의 좌표 설정
1386
            Canvas.SetLeft(Base_TextBox, this.EndPoint.X);
1387
            Canvas.SetTop(Base_TextBox, this.EndPoint.Y);
1388

    
1389
            List<Point> ps = GetConnectionPointList();
1390
            if (isTrans)
1391
            {
1392
                var ConnectionPoint = MathSet.getNearPoint(ps, this.MidPoint);
1393
                Point? BendingPoint = GetBendingPoint(ps, this.MidPoint, this.MidPoint);
1394
                if (BendingPoint.HasValue)
1395
                {
1396
                    connectorSMGeometry.EndPoint = BendingPoint.Value;
1397
                    connectorMEGeometry.StartPoint = BendingPoint.Value;
1398
                    connectorMEGeometry.EndPoint = ConnectionPoint;
1399

    
1400
                    //20180910 LJY 각도에 따라.
1401
                    this.MidPoint = BendingPoint.Value;
1402
                }
1403
                instanceGroup.Children.Add(DrawSet.DrawArrow(BendingPoint.Value, this.StartPoint, this.LineSize));
1404
                instanceGroup.FillRule = FillRule.Nonzero;
1405
                this.Base_ArrowPath.Fill = this.StrokeColor;
1406
                this.Base_ArrowSubPath.Fill = this.StrokeColor;
1407
            }
1408
            else
1409
            {
1410
                var ConnectionPoint = MathSet.getNearPoint(ps, this.MidPoint);
1411
                #region 보정치
1412
                Point? BendingPoint = GetBendingPoint(ps, this.MidPoint, this.MidPoint);
1413
                if (BendingPoint.HasValue)
1414
                {
1415
                    connectorSMGeometry.EndPoint = BendingPoint.Value;
1416
                    connectorMEGeometry.StartPoint = BendingPoint.Value;
1417
                    connectorMEGeometry.EndPoint = ConnectionPoint;
1418

    
1419
                    instanceGroup.Children.Add(DrawSet.DrawArrow(BendingPoint.Value, this.StartPoint, this.LineSize));
1420
                    instanceGroup.FillRule = FillRule.Nonzero;
1421
                    this.Base_ArrowPath.Fill = this.StrokeColor;
1422
                    this.Base_ArrowSubPath.Fill = this.StrokeColor;
1423
                }
1424
                #endregion
1425
            }
1426

    
1427
            switch (this.ArrowTextStyle)
1428
            {
1429
                case ArrowTextStyleSet.Normal:
1430
                    this.BorderSize = new Thickness(0);
1431
                    DrawingRect();
1432
                    break;
1433
                case ArrowTextStyleSet.Cloud:
1434
                    this.BorderSize = new Thickness(0);
1435
                    DrawingCloud();
1436
                    break;
1437
                default:
1438
                    {
1439
                        this.BorderSize = new Thickness(LineSize);
1440
                        DrawingRect();
1441
                    }
1442

    
1443
                    break;
1444
            }
1445

    
1446
            if (isHighLight)
1447
            {
1448
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1449
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1450

    
1451
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1452
            }
1453
            else
1454
            {
1455
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1456
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1457
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.1), Colors.White.R, Colors.White.G, Colors.White.B));
1458
            }
1459

    
1460
            instanceGroup.Children.Add(connectorSMGeometry);
1461
            instanceGroup.Children.Add(connectorMEGeometry);
1462

    
1463
            this.PathData = instanceGroup;
1464
            OverViewPathData = PathData;
1465
            OverViewArrowText = ArrowText;
1466
            OverViewEndPoint = connectorMEGeometry.EndPoint;
1467
            OverViewStartPoint = connectorSMGeometry.StartPoint;
1468

    
1469
            var tempAngle = Math.Abs(this.VisualPageAngle);
1470

    
1471
            if (tempAngle == Convert.ToDouble(90) || tempAngle == Convert.ToDouble(270))
1472
            {
1473
                this.RenderTransformOrigin = new Point(0.5, 0.5);
1474
                this.Base_ArrowPath.RenderTransformOrigin = new Point(0, 0);
1475
                this.Base_ArrowSubPath.RenderTransformOrigin = new Point(0, 0);
1476

    
1477
                Base_TextBox.RenderTransformOrigin = new Point(0, 0);
1478
                BaseTextbox_Caret.RenderTransformOrigin = new Point(0, 0);
1479
            }
1480

    
1481
            Base_TextBox.RenderTransform = new RotateTransform
1482
            {
1483
                Angle = this.VisualPageAngle,
1484
                CenterX = this.CenterX,
1485
                CenterY = this.CenterY,
1486
            };
1487

    
1488
            Base_ArrowSubPath.RenderTransform = new RotateTransform
1489
            {
1490
                Angle = this.VisualPageAngle,
1491
                CenterX = this.EndPoint.X,
1492
                CenterY = this.EndPoint.Y,
1493
            };
1494

    
1495
            if (BaseTextbox_Caret.Visibility == Visibility.Visible)
1496
            {
1497
                BaseTextbox_Caret.RenderTransform = new RotateTransform
1498
                {
1499
                    Angle = this.VisualPageAngle,
1500
                    CenterX = this.CenterX,
1501
                    CenterY = this.CenterY,
1502
                };
1503

    
1504
                MoveCustomCaret();
1505
            }
1506
        }
1507

    
1508
        private void DrawingCloud()
1509
        {
1510
            //20180906 LJY Textbox guide
1511
            string angle = Math.Abs(this.PageAngle).ToString();
1512
            //방지
1513
            if (this.ArcLength == 0) this.ArcLength = 10;
1514
            if (angle == "180")
1515
            {
1516
                List<Point> pCloud = new List<Point>()
1517
                {
1518
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1519
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxHeight), //왼쪽 아래
1520
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox) - BoxHeight),
1521
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox)),
1522
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1523
                };
1524
                SubPathData = Generate(pCloud, this.ArcLength);
1525
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1526
            
1527
            }//20180906 LJY Textbox guide
1528
            else
1529
            {
1530
                var boxWidth = BoxWidth;
1531
                System.Diagnostics.Debug.WriteLine("disp Width : " + BoxWidth);
1532
                //boxWidth = boxWidth + Base_TextBox.Margin.Left + Base_TextBox.Margin.Right + Base_TextBox.Padding.Left + Base_TextBox.Padding.Right;
1533

    
1534
                List<Point> pCloud = new List<Point>()
1535
                {
1536
    #if SILVERLIGHT
1537
		            new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1538
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1539
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1540
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1541
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1542

    
1543
    #else
1544
                    new Point(Canvas.GetLeft(Base_TextBox)-(this.LineSize ), Canvas.GetTop(Base_TextBox) -(this.LineSize)), //위
1545
                    new Point(Canvas.GetLeft(Base_TextBox)-(this.LineSize ), Canvas.GetTop(Base_TextBox)+ BoxHeight+(this.LineSize)), //왼쪽 아래
1546
                    new Point(Canvas.GetLeft(Base_TextBox)+ boxWidth+(this.LineSize ), Canvas.GetTop(Base_TextBox) + BoxHeight+(this.LineSize)),
1547
                    new Point(Canvas.GetLeft(Base_TextBox) + boxWidth+(this.LineSize ), Canvas.GetTop(Base_TextBox)-(this.LineSize)),
1548
                    new Point(Canvas.GetLeft(Base_TextBox)-(this.LineSize), Canvas.GetTop(Base_TextBox)-(this.LineSize)), //위  
1549

    
1550
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1551
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1552
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1553
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1554
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1555
    #endif
1556
                };
1557
                //instanceGroup.Children.Add(Generate(pCloud));
1558
                SubPathData = Generate(pCloud, this.ArcLength);
1559
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1560
                //   }
1561
            }
1562

    
1563
        }
1564

    
1565
        private void DrawingRect()
1566
        {
1567
            //20180906 LJY Textbox guide
1568
            if(this.ArrowTextStyle == ArrowTextStyleSet.Normal)
1569
            {
1570
                this.Base_TextBox.BorderBrush = Brushes.Transparent;
1571
            }
1572
            
1573
            if (Math.Abs(this.PageAngle).ToString() == "90")
1574
            {
1575
                List<Point> pCloud = new List<Point>()
1576
                {
1577
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1578
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxWidth), //왼쪽 아래
1579
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox) - BoxWidth),
1580
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox)),
1581
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1582
                };
1583
                PathDataInner = (GenerateInner(pCloud));
1584
            }
1585
            else if(Math.Abs(this.PageAngle).ToString() == "270")
1586
            {
1587
                List<Point> pCloud = new List<Point>()
1588
                {
1589
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1590
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + BoxWidth), //왼쪽 아래
1591
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox) + BoxWidth),
1592
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox)),
1593
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1594
                };
1595
                PathDataInner = (GenerateInner(pCloud));
1596
            }//20180906 LJY Textbox guide
1597
            else
1598
            { 
1599
                List<Point> pCloud = new List<Point>()
1600
                {
1601
    #if SILVERLIGHT
1602
		            new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1603
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1604
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1605
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1606
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1607

    
1608
    #else
1609
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1610
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1611
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1612
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1613
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1614

    
1615
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1616
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1617
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1618
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1619
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1620
    #endif
1621
                };
1622
                //instanceGroup.Children.Add(Generate(pCloud));
1623
                PathDataInner = (GenerateInner(pCloud));
1624
            }
1625
        }
1626

    
1627
        public override void UpdateControl()
1628
        {
1629
            if(!this.StartPoint.Equals(this.PointSet[0])) 
1630
                this.StartPoint = new Point(this.PointSet[0].X, this.PointSet[0].Y);
1631
            if (!this.MidPoint.Equals(this.PointSet[1]))
1632
                this.MidPoint = new Point(this.PointSet[1].X, this.PointSet[1].Y);
1633
            if (!this.EndPoint.Equals(this.PointSet[2]))
1634
                this.EndPoint = new Point(this.PointSet[2].X, this.PointSet[2].Y);
1635
        }
1636

    
1637
        public override void ApplyOverViewData()
1638
        {
1639
            this.OverViewPathData = this.PathData;
1640
            if (ArrowText == "")
1641
            {
1642
                this.OverViewArrowText = "";
1643
                this.ArrowText = this.OverViewArrowText;
1644
            }
1645
            else
1646
                this.OverViewArrowText = this.ArrowText;
1647
            this.OverViewStartPoint = this.StartPoint;
1648
            this.OverViewEndPoint = this.EndPoint;
1649
        }
1650

    
1651
        #endregion
1652

    
1653
        public static PathFigure GenerateLineWithCloud(Point p1, Point p2, double arcLength_, bool reverse)
1654
        {
1655
            PathFigure pathFigure = new PathFigure();
1656
            pathFigure.StartPoint = p1;
1657

    
1658
            double arcLength = arcLength_;
1659
            /// draw arcs which has arcLength between p1 and p2 - 2012.06.21 added by humkyung 
1660
            double dx = p2.X - p1.X;
1661
            double dy = p2.Y - p1.Y;
1662
            double l = MathSet.DistanceTo(p1, p2); /// distance between p1 and p2
1663
            double theta = Math.Atan2(Math.Abs(dy), Math.Abs(dx)) * 180 / Math.PI;
1664
            Point lastPt = new Point(p1.X, p1.Y);
1665
            double count = l / arcLength;
1666
            /// normalize
1667
            dx /= l;
1668
            dy /= l;
1669
            Double j = 1;
1670
            for (j = 1; j < (count - 1); j++) 
1671
            {
1672
                ArcSegment arcSeg = new ArcSegment();
1673
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);						/// x size and y size of arc
1674
                arcSeg.Point = new Point(p1.X + j * dx * arcLength, p1.Y + j * dy * arcLength);	/// end point of arc
1675
                lastPt = arcSeg.Point;  /// save last point
1676
                arcSeg.RotationAngle = theta + 90;
1677
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1678
                pathFigure.Segments.Add(arcSeg);
1679
            }
1680

    
1681
            /// draw arc between last point and end point
1682
            if ((count > j) || (count > 0))
1683
            {
1684
                arcLength = MathSet.DistanceTo(lastPt, p2);
1685
                ArcSegment arcSeg = new ArcSegment();
1686
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);	/// x size and y size of arc
1687
                arcSeg.Point = new Point(p2.X, p2.Y);						/// end point of arc
1688
                arcSeg.RotationAngle = theta;
1689
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1690
                pathFigure.Segments.Add(arcSeg);
1691
            }
1692
            /// up to here
1693

    
1694
            return pathFigure;
1695
        }
1696

    
1697
        public static PathGeometry Generate(List<Point> pData, double _ArcLength)
1698
        {
1699
            var _pathGeometry = new PathGeometry();
1700
            
1701
            double area = MathSet.AreaOf(pData);
1702
            bool reverse = (area > 0);
1703
            int count = pData.Count;
1704
            for (int i = 0; i < (count - 1); i++)
1705
            {
1706
                PathFigure pathFigure = Polygon.CloudControl.GenerateLineWithCloud(pData[i], pData[i + 1], _ArcLength, reverse);
1707
                pathFigure.IsClosed = false;
1708
                pathFigure.IsFilled = false;
1709
                _pathGeometry.Figures.Add(pathFigure);
1710
            }
1711
            
1712
            return _pathGeometry;
1713
        }
1714

    
1715
        
1716
        public static PathGeometry GenerateInner(List<Point> pData)
1717
        {
1718
            var _pathGeometry = new PathGeometry();
1719
            double area = MathSet.AreaOf(pData);
1720
            bool reverse = (area > 0);
1721
            int count = pData.Count;
1722

    
1723
            PathFigure pathFigur2 = new PathFigure();
1724
            pathFigur2.StartPoint = pData[0];
1725

    
1726
            LineSegment lineSegment0 = new LineSegment();
1727
            lineSegment0.Point = pData[0];
1728
            pathFigur2.Segments.Add(lineSegment0);
1729

    
1730
            LineSegment lineSegment1 = new LineSegment();
1731
            lineSegment1.Point = pData[1];
1732
            pathFigur2.Segments.Add(lineSegment1);
1733

    
1734
            LineSegment lineSegment2 = new LineSegment();
1735
            lineSegment2.Point = pData[2];
1736
            pathFigur2.Segments.Add(lineSegment2);
1737

    
1738
            LineSegment lineSegment3 = new LineSegment();
1739
            lineSegment3.Point = pData[3];
1740
            pathFigur2.Segments.Add(lineSegment3);
1741

    
1742

    
1743
            pathFigur2.IsClosed = true;
1744
            pathFigur2.IsFilled = true;
1745
            _pathGeometry.Figures.Add(pathFigur2);           
1746

    
1747
            return _pathGeometry;
1748
        }
1749

    
1750
        //20180910 LJY Cloud rotation 추가
1751
        public static PathGeometry GenerateInnerCloud(List<Point> pData, string angle)
1752
        {
1753
            var _pathGeometry = new PathGeometry();
1754
            double area = MathSet.AreaOf(pData);
1755
            bool reverse = (area > 0);
1756
            int count = pData.Count;
1757

    
1758
            PathFigure pathFigur2 = new PathFigure();
1759
            pathFigur2.StartPoint = pData[0];
1760

    
1761
            LineSegment lineSegment0 = new LineSegment();
1762
            lineSegment0.Point = pData[0];
1763
            pathFigur2.Segments.Add(lineSegment0);
1764

    
1765
            LineSegment lineSegment1 = new LineSegment();
1766
            lineSegment1.Point = pData[1];
1767
            pathFigur2.Segments.Add(lineSegment1);
1768

    
1769
            LineSegment lineSegment2 = new LineSegment();
1770
            lineSegment2.Point = pData[2];
1771
            pathFigur2.Segments.Add(lineSegment2);
1772

    
1773
            LineSegment lineSegment3 = new LineSegment();
1774
            lineSegment3.Point = pData[3];
1775
            pathFigur2.Segments.Add(lineSegment3);
1776
            
1777
            RotateTransform transform = new RotateTransform();
1778
            switch (angle)
1779
            {
1780
                case "90":
1781
                    transform.Angle = -90;
1782
                    break;
1783
                case "180":
1784
                    transform.Angle = -180;
1785
                    break;
1786
                case "270":
1787
                    transform.Angle = -270;
1788
                    break;
1789
            }
1790
            transform.CenterX = pData[0].X;
1791
            transform.CenterY = pData[0].Y;
1792
            _pathGeometry.Transform = transform;
1793

    
1794
            pathFigur2.IsClosed = true;
1795
            pathFigur2.IsFilled = true;
1796
            _pathGeometry.Figures.Add(pathFigur2);
1797

    
1798
            return _pathGeometry;
1799
        }
1800

    
1801
        /// <summary>
1802
        /// call when mouse is moving while drawing control
1803
        /// </summary>
1804
        /// <author>humkyung</author>
1805
        /// <param name="pt"></param>
1806
        /// <param name="bAxisLocked"></param>
1807
        public override void OnCreatingMouseMove(Point pt, bool bAxisLocked)
1808
        {
1809
            this.EndPoint = pt;
1810

    
1811
            Point tempPoint = this.EndPoint;
1812
            CommentAngle = MathSet.returnAngle(this.StartPoint, ref tempPoint, bAxisLocked);
1813

    
1814
            if (bAxisLocked)
1815
            {
1816
                this.EndPoint = tempPoint;
1817
            }
1818

    
1819
            this.MidPoint = MathSet.getMiddlePoint(this.StartPoint, this.EndPoint);
1820
            this.isFixed = (this.ControlType == ControlType.ArrowTransTextControl) ||
1821
                (this.ControlType == ControlType.ArrowTransTextBorderControl) || (this.ControlType == ControlType.ArrowTransTextCloudControl);
1822

    
1823
            this.PointSet = new List<Point>
1824
            {
1825
                this.StartPoint,
1826
                this.MidPoint,
1827
                this.EndPoint,
1828
            };
1829
        }
1830

    
1831
        /// <summary>
1832
        /// move control point has same location of given pt along given delta
1833
        /// </summary>
1834
        /// <author>humkyung</author>
1835
        /// <date>2019.06.20</date>
1836
        /// <param name="pt"></param>
1837
        /// <param name="dx"></param>
1838
        /// <param name="dy"></param>
1839
        public override void OnMoveCtrlPoint(Point pt, double dx, double dy, bool bAxisLocked = false)
1840
        {
1841
            IPath path = (this as IPath);
1842

    
1843
            Point selected = MathSet.getNearPoint(path.PointSet, pt);
1844
            selected.X += dx;
1845
            selected.Y += dy;
1846

    
1847
            int i = 0;
1848
            for (i = 0; i < (this as IPath).PointSet.Count; i++)
1849
            {
1850
                if (pt.Equals((this as IPath).PointSet[i])) break;
1851
            }
1852

    
1853
            #region 끝점을 이동할때
1854
            if (i == 0)
1855
            {
1856
                #region 끝점을 기준으로 중간점을 계산한다.
1857
                var connections = GetConnectionPointList();
1858
                var connection = MathSet.getNearPoint(connections, selected);
1859
                #region 연결점이 바뀌지 않으면 중간점을 그대로 그렇지 않으면 중간점을 재계산한다.
1860
                Point? bending = null;
1861
                if (connectorMEGeometry.EndPoint.Equals(connection))
1862
                {
1863
                    bending = GetBendingPoint(connections, selected, this.MidPoint);
1864
                }
1865
                else
1866
                {
1867
                    bending = GetBendingPoint(connections, selected, null);
1868
                }
1869
                #endregion
1870
                if (bending.HasValue) path.PointSet[1] = bending.Value;
1871
                #endregion
1872
            }
1873
            #endregion
1874
            #region 중간점을 이동할때
1875
            else if (i == 1)
1876
            {
1877
                path.PointSet[1] = selected;
1878
            }
1879
            #endregion
1880
            #region 텍스트 박스를 이동할때
1881
            else
1882
            {
1883
                var connections = GetConnectionPointList();
1884
                var connection = MathSet.getNearPoint(connections, this.StartPoint);
1885
                if (!connectorMEGeometry.EndPoint.Equals(connection))
1886
                {
1887
                    var bending = GetBendingPoint(connections, this.StartPoint, null);
1888
                    if (bending.HasValue) path.PointSet[1] = bending.Value;
1889
                }
1890
                else
1891
                {
1892
                    var bending = GetBendingPoint(connections, this.StartPoint, this.MidPoint);
1893
                    if (bending.HasValue) path.PointSet[1] = bending.Value;
1894
                }
1895
            }
1896
            #endregion
1897

    
1898
            if (path.PointSet.Count > i) {
1899
                path.PointSet[i] = selected;
1900
            }
1901

    
1902
            this.UpdateControl();
1903
        }
1904

    
1905
        /// <summary>
1906
        /// return ArrowTextControl's area
1907
        /// </summary>
1908
        /// <author>humkyung</author>
1909
        /// <date>2019.06.13</date>
1910
        public override Rect ItemRect
1911
        {
1912
            get
1913
            {
1914
                double dMinX = Math.Min(this.StartPoint.X, this.EndPoint.X);
1915
                double dMinY = Math.Min(this.StartPoint.Y, this.EndPoint.Y);
1916
                double dMaxX = Math.Max(this.StartPoint.X, this.EndPoint.X);
1917
                double dMaxY = Math.Max(this.StartPoint.Y, this.EndPoint.Y);
1918

    
1919
                return new Rect(new Point(dMinX, dMinY), new Point(dMaxX, dMaxY));
1920
            }
1921
        }
1922

    
1923
        /// <summary>
1924
        /// Serialize this
1925
        /// </summary>
1926
        /// <param name="sUserId"></param>
1927
        /// <returns></returns>
1928
        public override string Serialize()
1929
        {
1930
            using (S_ArrowTextControl ctrl = new S_ArrowTextControl())
1931
            {
1932
                ctrl.TransformPoint = "0|0";
1933
                ctrl.PointSet = this.PointSet;
1934
                ctrl.SizeSet = String.Format("{0}", this.LineSize);
1935
                ctrl.StrokeColor = this.StrokeColor.Color.ToString();
1936
                ctrl.StartPoint = this.StartPoint;
1937
                ctrl.ArrowStyle = this.ArrowTextStyle;
1938
                ctrl.UserID = this.UserID;
1939
                ctrl.ArrowText = this.Base_TextBox.Text;
1940
                ctrl.BorderSize = this.BorderSize;
1941
                ctrl.isHighLight = this.isHighLight;
1942
                ctrl.BoxHeight = this.BoxHeight;
1943
                ctrl.BoxWidth = this.BoxWidth;
1944
                ctrl.Opac = this.Opacity;
1945
                ctrl.EndPoint = this.EndPoint;
1946
                ctrl.isFixed = this.isFixed;
1947
                ctrl.ControlType = this.ControlType;
1948
                ctrl.Name = this.GetType().Name.ToString();
1949
                ctrl.isTrans = this.isTrans;
1950
                ctrl.MidPoint = this.MidPoint;
1951
                ctrl.Angle = this.PageAngle;
1952
                ctrl.fontConfig = new List<string>()
1953
                {
1954
                    this.TextFamily.FontName(),
1955
                    this.TextStyle.ToString(),
1956
                    this.TextWeight.ToString(),
1957
                    this.TextSize.ToString(),
1958
                };
1959

    
1960
                if (this.UnderLine != null)
1961
                {
1962
                    ctrl.fontConfig.Add("true");
1963
                }
1964

    
1965
                ctrl.Memo = this.Memo;
1966
                ctrl.BorderSize = this.BorderSize;
1967
                ctrl.ArcLength = this.ArcLength;
1968
                ctrl.Index = this.Index;
1969
                ctrl.ZIndex = this.ZIndex;
1970
                ctrl.GroupID = this.GroupID;
1971

    
1972
                return "|DZ|" + JsonSerializerHelper.CompressString((ctrl.JsonSerialize()));
1973
            };
1974
        }
1975

    
1976
        /// <summary>
1977
        /// create a arrowtextcontrol from given string
1978
        /// </summary>
1979
        /// <param name="str"></param>
1980
        /// <returns></returns>
1981
        public static ArrowTextControl FromString(string str, SolidColorBrush brush, string sProjectNo,double PageAngle)
1982
        {
1983
            ArrowTextControl instance = null;
1984
            using (S_ArrowTextControl s = JsonSerializerHelper.JsonDeserialize<S_ArrowTextControl>(str))
1985
            {
1986
                string[] data2 = s.SizeSet.Split(delimiterChars2, StringSplitOptions.RemoveEmptyEntries);
1987
                instance = new ArrowTextControl();
1988
                instance.PageAngle = s.Angle;
1989
                instance.LineSize = Convert.ToDouble(data2.First());
1990
                instance.PointSet = s.PointSet;
1991
                instance.StartPoint = s.StartPoint;
1992
                instance.EndPoint = s.EndPoint;
1993
                instance.StrokeColor = brush;
1994
                instance.ArrowTextStyle = s.ArrowStyle;
1995
                instance.isHighLight = s.isHighLight;
1996
                instance.ArrowText = s.ArrowText;
1997
                instance.Opacity = s.Opac;
1998
                instance.BorderSize = s.BorderSize;
1999
                instance.BoxWidth = s.BoxWidth;
2000
                instance.BoxHeight = s.BoxHeight;
2001
                instance.isFixed = s.isFixed;
2002
                instance.ControlType = s.ControlType;
2003
                instance.UserID = s.UserID;
2004
                instance.isTrans = s.isTrans;
2005
                instance.MidPoint = s.MidPoint;
2006
                instance.Memo = s.Memo;
2007
                instance.Index = s.Index;
2008
                instance.ZIndex = s.ZIndex;
2009
                instance.GroupID = s.GroupID;
2010
                if (s.fontConfig == null || s.fontConfig.ToList().Count == 0)
2011
                {
2012
                    s.fontConfig = new List<string>();
2013

    
2014
                    s.fontConfig.Add("Arial");
2015
                    s.fontConfig.Add("Normal");
2016
                    s.fontConfig.Add("Normal");
2017
                    s.fontConfig.Add("30");
2018
                }
2019
                instance.TextFamily = Markus.Fonts.FontHelper.GetFontFamily(s.fontConfig[0]);
2020
                //인구 추가(2018.04.17)
2021
                instance.TextStyle = StringToFont.ConFontStyle(s.fontConfig[1]);
2022
                instance.TextWeight = StringToFont.ConFontWeight(s.fontConfig[2]);
2023
                instance.TextSize = Convert.ToDouble(s.fontConfig[3]);
2024
                instance.ArcLength = s.ArcLength;
2025
                if (s.fontConfig.Count == 5)
2026
                {
2027
                    instance.UnderLine = TextDecorations.Underline;
2028
                }
2029
            }
2030

    
2031
            return instance;
2032
        }
2033

    
2034
        #region Dispose
2035
        public void Dispose()
2036
        {
2037
            //GC.Collect();
2038
            ////GC.SuppressFinalize(this);
2039
            this.BaseTextbox_Caret = null;
2040
            this.Base_ArrowPath = null;
2041
            this.Base_ArrowSubPath = null;
2042
            this.Base_TextBlock = null;
2043
            this.Base_TextBox = null;
2044
        } 
2045
        #endregion
2046

    
2047
        #region INotifyPropertyChanged
2048
        private void OnPropertyChanged(string name)
2049
        {
2050
            if (PropertyChanged != null)
2051
            {
2052
                PropertyChanged(this, new PropertyChangedEventArgs(name));
2053
            }
2054
        }
2055

    
2056
        public Rect GetCommentRect()
2057
        {
2058
            Rect rect = new Rect();
2059

    
2060
            rect.Location = new Point();
2061
            rect.Size = new Size();
2062

    
2063
            List<Point> points = new List<Point>();
2064

    
2065
            points.AddRange(this.PointSet);
2066

    
2067
            var boxTopleft = new Point(Canvas.GetTop(Base_TextBox), Canvas.GetLeft(Base_TextBox));
2068
            points.Add(boxTopleft);
2069

    
2070
            var boxBottomRight =new Point(boxTopleft.X + Base_TextBox.ActualWidth, boxTopleft.Y + Base_TextBox.ActualHeight);
2071
            points.Add(boxBottomRight);
2072

    
2073
            rect = CommentMath.CalculateBoundingRect(points);
2074

    
2075
            return rect;
2076
        }
2077

    
2078
        public event PropertyChangedEventHandler PropertyChanged; 
2079
        #endregion
2080
    }
2081

    
2082
    public static class Extension
2083
    {
2084
        public static double Dot(this Vector lhs,  Vector rhs)
2085
        {
2086
            return lhs.X * rhs.X + lhs.Y * rhs.Y;
2087
        }
2088
    }
2089
}
클립보드 이미지 추가 (최대 크기: 500 MB)