프로젝트

일반

사용자정보

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

markus / MarkupToPDF / Controls / Text / ArrowTextControl.cs @ 1c0c336a

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

1 787a4489 KangIngu
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 036650a0 humkyung
using MarkupToPDF.Serialize.Core;
15
using MarkupToPDF.Serialize.S_Control;
16 24c5e56c taeseongkim
using Markus.Fonts;
17 787a4489 KangIngu
18
namespace MarkupToPDF.Controls.Text
19
{
20 b79d6e7f humkyung
    public class ArrowTextControl : CommentUserInfo, IDisposable, INotifyPropertyChanged, ITextControl, IMarkupControlData,ICommentRect
21 787a4489 KangIngu
    {
22
        private const string PART_ArrowPath = "PART_ArrowPath";
23
        private const string PART_TextBox = "PART_ArrowTextBox";
24
        //private const string PART_TextBlock = "PART_ArrowTextBlock";
25
        private const string PART_ArrowSubPath = "PART_ArrowSubPath";
26
        private const string PART_Border = "PART_Border";
27 3074202c 송근호
        private const string PART_BaseTextbox_Caret = "Caret";
28
29 787a4489 KangIngu
        public Path Base_ArrowPath = null;
30
        public Path Base_ArrowSubPath = null;
31
        public TextBox Base_TextBox = null;
32
        public TextBlock Base_TextBlock = null;
33 3074202c 송근호
        public Border BaseTextbox_Caret = null;
34 1b2cf911 taeseongkim
        public event EventHandler<EventArgs> EditEnded;
35
36 787a4489 KangIngu
37 53393bae KangIngu
        private const double _CloudArcDepth = 0.8;  /// 2018.05.14 added by humkyung
38
39 787a4489 KangIngu
        #region Object & Variable
40
        GeometryGroup instanceGroup = new GeometryGroup();
41
        
42
        Path Cemy = new Path();
43
        LineGeometry connectorSMGeometry = new LineGeometry();
44
        LineGeometry connectorMEGeometry = new LineGeometry();
45
46
        public enum ArrowTextStyleSet { Normal, Cloud, Rect };
47
48
        #endregion
49
50
        static ArrowTextControl()
51
        {
52
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ArrowTextControl), new FrameworkPropertyMetadata(typeof(ArrowTextControl)));
53 a6f7f9b6 djkim
            //ResourceDictionary dictionary = new ResourceDictionary();
54
            //dictionary.Source = new Uri("/MarkupToPDF;component/themes/generic.xaml", UriKind.RelativeOrAbsolute);
55
            //if(!Application.Current.Resources.MergedDictionaries.Any(x=>x.Source == dictionary.Source))
56
            //    Application.Current.Resources.MergedDictionaries.Add(dictionary);
57 787a4489 KangIngu
        }
58
59 907a99b3 taeseongkim
        public ArrowTextControl() :base()
60 787a4489 KangIngu
        {
61 a6f7f9b6 djkim
            //this.DefaultStyleKey = typeof(ArrowTextControl);
62 787a4489 KangIngu
        }
63
64 873011c4 humkyung
        public override void Copy(CommentUserInfo lhs)
65
        {
66 30d84e1a humkyung
            if (lhs is ArrowTextControl item)
67 873011c4 humkyung
            {
68 30d84e1a humkyung
                this.PageAngle = item.PageAngle;
69
                this.LineSize = item.LineSize;
70
                this.PointSet = item.PointSet.ConvertAll(x => new Point(x.X, x.Y));
71
                this.StartPoint = new Point(item.StartPoint.X, item.StartPoint.Y);
72
                this.EndPoint = new Point(item.EndPoint.X, item.EndPoint.Y);
73
                this.StrokeColor = item.StrokeColor;
74 b79d6e7f humkyung
                this.ArcLength = item.ArcLength;
75 873011c4 humkyung
                //this.DashSize = s.DashSize; 
76 30d84e1a humkyung
                this.ArrowTextStyle = item.ArrowTextStyle;
77
                this.isHighLight = item.isHighLight;
78
                this.ArrowText = item.ArrowText;
79
                this.Opacity = item.Opacity;
80
                this.BorderSize = item.BorderSize;
81
                this.BoxWidth = item.BoxWidth;
82
                this.BoxHeight = item.BoxHeight;
83
                this.isFixed = item.isFixed;
84 873011c4 humkyung
                //this.VisualPageAngle = s.Angle;
85 30d84e1a humkyung
                this.UserID = item.UserID;
86
                this.isTrans = item.isTrans;
87
                this.MidPoint = item.MidPoint;
88
                this.Memo = item.Memo;
89
                this.TextFamily = item.TextFamily;
90
                this.TextStyle = item.TextStyle;
91
                this.TextWeight = item.TextWeight;
92
                this.TextSize = item.TextSize;
93
                this.UnderLine = item.UnderLine;
94 873011c4 humkyung
            }
95
        }
96
97
        public override CommentUserInfo Clone()
98
        {
99
            var clone = new ArrowTextControl();
100
            clone.Copy(this);
101
            return clone;
102
        }
103
104 787a4489 KangIngu
        public override void OnApplyTemplate()
105
        {
106
            base.OnApplyTemplate();
107
            Base_ArrowPath = GetTemplateChild(PART_ArrowPath) as Path;
108
            Base_ArrowSubPath = GetTemplateChild(PART_ArrowSubPath) as Path;
109
            Base_TextBox = GetTemplateChild(PART_TextBox) as TextBox;
110 3074202c 송근호
            BaseTextbox_Caret = GetTemplateChild(PART_BaseTextbox_Caret) as Border;
111 4fcb686a taeseongkim
            Base_TextBox.FontFamily = this.TextFamily;
112 907a99b3 taeseongkim
            if (Base_TextBox != null)
113
            {
114
                this.Base_TextBox.CaretIndex = this.Base_TextBox.Text.Length;
115
                this.Base_TextBox.CaretBrush = new SolidColorBrush(Colors.Transparent);
116 4fcb686a taeseongkim
                
117
                if (this.ArrowTextStyle == ArrowTextStyleSet.Cloud)
118
                {
119
                    
120
                }
121
122 907a99b3 taeseongkim
                this.Base_TextBox.ApplyTemplate();
123
                this.Base_TextBox.Text = this.ArrowText;
124
125
                MoveCustomCaret();
126
127
                Base_TextBox.SizeChanged += new SizeChangedEventHandler(Base_TextBox_SizeChanged);
128
                Base_TextBox.GotFocus += new RoutedEventHandler(Base_TextBox_GotFocus);
129
                Base_TextBox.LostFocus += new RoutedEventHandler(Base_TextBox_LostFocus);
130
                Base_TextBox.SelectionChanged += (sender, e) => MoveCustomCaret();
131
                this.KeyDown += ArrowTextControl_KeyDown;
132
133
                SetArrowTextPath(true);
134
135
                Base_TextBox.IsTabStop = true;
136
            }
137 787a4489 KangIngu
        }
138
139 fa48eb85 taeseongkim
        private void ArrowTextControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
140
        {
141
           if(e.Key == System.Windows.Input.Key.Escape)
142
            {
143
                if(string.IsNullOrEmpty(Base_TextBox.Text))
144
                {
145
                    this.Visibility = Visibility.Collapsed;
146
                }
147
148
                EditEnd();
149
            }
150
        }
151
152 55d4f382 송근호
        public void SetFontFamily(FontFamily fontFamily)
153
        {
154 4fcb686a taeseongkim
            if (this.Base_TextBlock != null)
155
            {
156
                this.Base_TextBlock.FontFamily = fontFamily;
157
            }
158
159
            if (this.Base_TextBox != null)
160
            {
161
                this.Base_TextBox.FontFamily = fontFamily;
162
            }
163 55d4f382 송근호
            this.FontFamily = fontFamily;
164
            this.TextFamily = fontFamily;
165
        }
166
167 3074202c 송근호
        /// <summary>
168
        /// Moves the custom caret on the canvas.
169
        /// </summary>
170
        public void MoveCustomCaret()
171
        {
172 f011637d 송근호
            var caretLocation = this.Base_TextBox.GetRectFromCharacterIndex(this.Base_TextBox.CaretIndex).Location;
173
174 fa48eb85 taeseongkim
            var angle = Math.Abs(this.PageAngle);
175
            //angle = 0;
176
            System.Diagnostics.Debug.WriteLine("Page Angle : " +  this.PageAngle);
177
178 f011637d 송근호
            if (!double.IsInfinity(caretLocation.X))
179
            {
180 fa48eb85 taeseongkim
                if (angle == 90)
181 f011637d 송근호
                {
182
                    Canvas.SetLeft(this.BaseTextbox_Caret, this.EndPoint.X + caretLocation.Y);
183
                }
184 fa48eb85 taeseongkim
                else if (angle == 180)
185 f011637d 송근호
                {
186
                    
187
                    Canvas.SetLeft(this.BaseTextbox_Caret, (this.EndPoint.X+ this.Base_TextBox.ActualWidth) - caretLocation.X) ;
188 fa48eb85 taeseongkim
                    System.Diagnostics.Debug.WriteLine("Caret X : " + ((this.EndPoint.X + this.Base_TextBox.ActualWidth) - caretLocation.X));
189
                } 
190
                else if (angle == 270)
191 f011637d 송근호
                {
192
                    Canvas.SetLeft(this.BaseTextbox_Caret, (this.EndPoint.X) - caretLocation.Y);
193
                }
194
                else
195
                {
196 fa48eb85 taeseongkim
                    System.Diagnostics.Debug.WriteLine("Caret X : " + (this.EndPoint.X - caretLocation.X));
197 f011637d 송근호
                    Canvas.SetLeft(this.BaseTextbox_Caret, this.EndPoint.X + caretLocation.X);
198 fa48eb85 taeseongkim
                } 
199 f011637d 송근호
            }
200
201
            if (!double.IsInfinity(caretLocation.Y))
202
            {
203 fa48eb85 taeseongkim
                if (angle == 90)
204 f011637d 송근호
                {
205
                    Canvas.SetTop(this.BaseTextbox_Caret, this.EndPoint.Y - caretLocation.X);
206
                }
207 fa48eb85 taeseongkim
                else if (angle == 180)
208 f011637d 송근호
                {//보정치40
209
                    Canvas.SetTop(this.BaseTextbox_Caret, ((this.EndPoint.Y -40) + this.Base_TextBox.ActualHeight)- caretLocation.Y );
210 fa48eb85 taeseongkim
                    System.Diagnostics.Debug.WriteLine("Caret Y : " + (((this.EndPoint.Y - 40) + this.Base_TextBox.ActualHeight) - caretLocation.Y));
211 f011637d 송근호
                }
212 fa48eb85 taeseongkim
                else if (angle == 270)
213 f011637d 송근호
                {
214
                    Canvas.SetTop(this.BaseTextbox_Caret, (this.EndPoint.Y) + caretLocation.X);
215
                }
216
                else
217
                {
218 fa48eb85 taeseongkim
                    Canvas.SetTop(this.BaseTextbox_Caret, this.EndPoint.Y  + caretLocation.Y);
219
                    System.Diagnostics.Debug.WriteLine("Caret Y : " + (this.EndPoint.Y + caretLocation.Y - BaseTextbox_Caret.ActualHeight));
220 f011637d 송근호
                }
221
            }
222
        }
223
224
        public void MoveCustomCaret(Point point)
225
        {
226 3074202c 송근호
227
            var caretLocation = this.Base_TextBox.GetRectFromCharacterIndex(this.Base_TextBox.CaretIndex).Location;
228
229
            if (!double.IsInfinity(caretLocation.X))
230
            {
231 fa48eb85 taeseongkim
                if (Math.Abs(this.PageAngle) == 90)
232 f011637d 송근호
                {
233
                    Canvas.SetLeft(this.BaseTextbox_Caret, point.X + caretLocation.Y);
234
                }
235 fa48eb85 taeseongkim
                else if (Math.Abs(this.PageAngle) == 180)
236 f011637d 송근호
                {
237
238
                    Canvas.SetLeft(this.BaseTextbox_Caret, (point.X + this.Base_TextBox.ActualWidth) - caretLocation.X);
239
                }
240 fa48eb85 taeseongkim
                else if (Math.Abs(this.PageAngle) == 270)
241 f011637d 송근호
                {
242
                    Canvas.SetLeft(this.BaseTextbox_Caret, (point.X) - caretLocation.Y);
243
                }
244
                else
245
                {
246
                    Canvas.SetLeft(this.BaseTextbox_Caret, point.X + caretLocation.X);
247
                }
248 3074202c 송근호
            }
249
250
            if (!double.IsInfinity(caretLocation.Y))
251
            {
252 fa48eb85 taeseongkim
                if (Math.Abs(this.PageAngle) == 90)
253 f011637d 송근호
                {
254
                    Canvas.SetTop(this.BaseTextbox_Caret, point.Y - caretLocation.X);
255
                }
256 fa48eb85 taeseongkim
                else if (Math.Abs(this.PageAngle) == 180)
257 f011637d 송근호
                {
258
                    Canvas.SetTop(this.BaseTextbox_Caret, (point.Y + this.Base_TextBox.ActualHeight) - caretLocation.Y);
259
                }
260 fa48eb85 taeseongkim
                else if (Math.Abs(this.CommentAngle) == 270)
261 f011637d 송근호
                {
262
                    Canvas.SetTop(this.BaseTextbox_Caret, (point.Y) + caretLocation.X);
263
                }
264
                else
265
                {
266
                    Canvas.SetTop(this.BaseTextbox_Caret, point.Y + caretLocation.Y);
267
                }
268 3074202c 송근호
            }
269
        }
270
271
272 787a4489 KangIngu
        void Base_TextBox_LostFocus(object sender, RoutedEventArgs e)
273
        {
274 fa48eb85 taeseongkim
            EditEnd();
275
        }
276
277
        private void EditEnd()
278
        { 
279 787a4489 KangIngu
            this.ArrowText = Base_TextBox.Text;
280 fa48eb85 taeseongkim
            Base_TextBox.Focusable = false;
281 3074202c 송근호
            this.BaseTextbox_Caret.Visibility = Visibility.Collapsed;
282 787a4489 KangIngu
            this.IsEditingMode = false;
283
            ApplyOverViewData();
284 1b2cf911 taeseongkim
285
            if(EditEnded != null)
286
            {
287
                EditEnded(this, new EventArgs());
288
            }
289
290 787a4489 KangIngu
        }
291
292
        void Base_TextBox_GotFocus(object sender, RoutedEventArgs e)
293
        {
294 3074202c 송근호
            this.BaseTextbox_Caret.Visibility = Visibility.Visible;
295 fa48eb85 taeseongkim
            MoveCustomCaret();
296 1305c420 taeseongkim
            Base_TextBox.Focus();
297 787a4489 KangIngu
            this.IsEditingMode = true;
298
        }
299
300
        void Base_TextBox_SizeChanged(object sender, SizeChangedEventArgs e)
301
        {
302 3c71b3a5 taeseongkim
            if(this.IsEditingMode)
303 b0fb3ad7 ljiyeon
            {
304 3c71b3a5 taeseongkim
                if (Base_TextBox.Text.Contains("|OR||DZ|"))
305
                {
306
                    Base_TextBox.Text = this.ArrowText;
307
                }
308
309
                this.ArrowText = Base_TextBox.Text;
310 8898253f djkim
                
311
            }
312
            BoxWidth = e.NewSize.Width;
313
            BoxHeight = e.NewSize.Height;
314
            SetArrowTextPath();
315 787a4489 KangIngu
        }
316
317
        #region Properties
318
        private bool _IsEditingMode;
319
        public bool IsEditingMode
320
        {
321
            get
322
            {
323
                return _IsEditingMode;
324
            }
325
            set
326
            {
327
                _IsEditingMode = value;
328
                OnPropertyChanged("IsEditingMode");
329
            }
330
        }
331
332
333
        #endregion
334
335
        #region dp Properties
336
        //강인구 주석 풀기
337
        public Visibility TextBoxVisibility
338
        {
339
            get { return (Visibility)GetValue(TextBoxVisibilityProperty); }
340
            set
341
            {
342
                if (this.TextBoxVisibility != value)
343
                {
344
                    SetValue(TextBoxVisibilityProperty, value);
345
                    OnPropertyChanged("TextBoxVisibility");
346
                }
347
            }
348
        }
349
350
        //강인구 주석 풀기
351
        public Visibility TextBlockVisibility
352
        {
353
            get { return (Visibility)GetValue(TextBlockVisibilityProperty); }
354
            set
355
            {
356
                if (this.TextBlockVisibility != value)
357
                {
358
                    SetValue(TextBlockVisibilityProperty, value);
359
                    OnPropertyChanged("TextBlockVisibility");
360
                }
361
            }
362
        }
363
364
365 4913851c humkyung
        public override SolidColorBrush StrokeColor
366 787a4489 KangIngu
        {
367
            get { return (SolidColorBrush)GetValue(StrokeColorProperty); }
368
            set
369
            {
370
                if (this.StrokeColor != value)
371
                {
372
                    SetValue(StrokeColorProperty, value);
373
                }
374
            }
375
        }
376
377 b79d6e7f humkyung
        public Double ArcLength
378
        {
379
            get { return (Double)GetValue(ArcLengthProperty); }
380
            set
381
            {
382
                if (this.ArcLength != value)
383
                {
384
                    SetValue(ArcLengthProperty, value);
385
                    OnPropertyChanged("ArcLength");
386
                }
387
            }
388
        }
389
390 787a4489 KangIngu
        public PathGeometry SubPathData
391
        {
392
            get { return (PathGeometry)GetValue(SubPathDataProperty); }
393
            set
394
            {
395
                if (this.SubPathData != value)
396
                {
397
                    SetValue(SubPathDataProperty, value);
398
                }
399
            }
400
        }
401
402
        public string UserID
403
        {
404
            get { return (string)GetValue(UserIDProperty); }
405
            set
406
            {
407
                if (this.UserID != value)
408
                {
409
                    SetValue(UserIDProperty, value);
410
                    OnPropertyChanged("UserID");
411
                }
412
            }
413
        }
414
415
        public List<Point> PointSet
416
        {
417
            get { return (List<Point>)GetValue(PointSetProperty); }
418
            set { SetValue(PointSetProperty, value); }
419
        }
420
421 959b3ef2 humkyung
        public override bool IsSelected
422 787a4489 KangIngu
        {
423
            get
424
            {
425
                return (bool)GetValue(IsSelectedProperty);
426
            }
427
            set
428
            {
429
                SetValue(IsSelectedProperty, value);
430
                OnPropertyChanged("IsSelected");
431
            }
432
        }
433
434 5529d2a2 humkyung
        public override ControlType ControlType
435 787a4489 KangIngu
        {
436
            set
437
            {
438
                SetValue(ControlTypeProperty, value);
439
                OnPropertyChanged("ControlType");
440
            }
441
            get
442
            {
443
                return (ControlType)GetValue(ControlTypeProperty);
444
            }
445
        }
446
447
        public Point StartPoint
448
        {
449
            get { return (Point)GetValue(StartPointProperty); }
450
            set { SetValue(StartPointProperty, value); }
451
        }
452
453
        public Point EndPoint
454
        {
455
            get { return (Point)GetValue(EndPointProperty); }
456
            set { SetValue(EndPointProperty, value); }
457
        }
458
459
        public Point OverViewStartPoint
460
        {
461
            get { return (Point)GetValue(OverViewStartPointProperty); }
462
            set { SetValue(OverViewStartPointProperty, value); }
463
        }
464
465
        public Point OverViewEndPoint
466
        {
467
            get { return (Point)GetValue(OverViewEndPointProperty); }
468
            set { SetValue(OverViewEndPointProperty, value); }
469
        }
470
471
472 168f8027 taeseongkim
        //public double Angle
473
        //{
474
        //    get { return (double)GetValue(AngleProperty); }
475
        //    set { SetValue(AngleProperty, value); }
476
        //}
477 787a4489 KangIngu
478
        public Thickness BorderSize
479
        {
480
            get { return (Thickness)GetValue(BorderSizeProperty); }
481
            set
482
            {
483
                if (this.BorderSize != value)
484
                {
485
                    SetValue(BorderSizeProperty, value);
486
                }
487
            }
488
        }
489
490
491
        public Point MidPoint
492
        {
493
            get { return (Point)GetValue(MidPointProperty); }
494
            set { SetValue(MidPointProperty, value); }
495
        }
496
497
        public bool isFixed
498
        {
499
            get { return (bool)GetValue(IsFixedProperty); }
500
            set { SetValue(IsFixedProperty, value); }
501
        }
502
503
        public bool isTrans
504
        {
505
            get { return (bool)GetValue(TransformerProperty); }
506
            set { SetValue(TransformerProperty, value); }
507
        }
508
509
        public bool isHighLight
510
        {
511
            get { return (bool)GetValue(isHighlightProperty); }
512
            set
513
            {
514
                if (this.isHighLight != value)
515
                {
516
                    SetValue(isHighlightProperty, value);
517
                    OnPropertyChanged("isHighLight");
518
                }
519
            }
520
        }
521
522
        public FontWeight TextWeight
523
        {
524
            get { return (FontWeight)GetValue(TextWeightProperty); }
525
            set
526
            {
527
                if (this.TextWeight != value)
528
                {
529
                    SetValue(TextWeightProperty, value);
530
                    OnPropertyChanged("TextWeight");
531
                }
532
            }
533
        }
534
535
        public Double LineSize
536
        {
537
            get { return (Double)GetValue(LineSizeProperty); }
538
            set
539
            {
540
                if (this.LineSize != value)
541
                {
542
                    SetValue(LineSizeProperty, value);
543
                }
544
            }
545
        }
546
547
        public Double BoxWidth
548
        {
549
            get { return (Double)GetValue(BoxWidthProperty); }
550
            set
551
            {
552
                if (this.BoxWidth != value)
553
                {
554
                    SetValue(BoxWidthProperty, value);
555
                }
556
            }
557
        }
558
559
        public Double BoxHeight
560
        {
561
            get { return (Double)GetValue(BoxHeightProperty); }
562
            set
563
            {
564
                if (this.BoxHeight != value)
565
                {
566
                    SetValue(BoxHeightProperty, value);
567
                }
568
            }
569
        }
570
571
        public ArrowTextStyleSet ArrowTextStyle
572
        {
573
            get { return (ArrowTextStyleSet)GetValue(ArrowTextStyleProperty); }
574
            set
575
            {
576
                if (this.ArrowTextStyle != value)
577
                {
578
                    SetValue(ArrowTextStyleProperty, value);
579
                }
580
            }
581
        }
582
583
        public Geometry PathData
584
        {
585
            get { return (Geometry)GetValue(PathDataProperty); }
586
            set { SetValue(PathDataProperty, value);
587
588
                OnPropertyChanged("PathData");
589
            }
590
        }
591
592
        public SolidColorBrush BackInnerColor
593
        {
594
            get { return (SolidColorBrush)GetValue(BackInnerColorProperty); }
595
            set
596
            {
597
                if (this.BackInnerColor != value)
598
                {
599
                    SetValue(BackInnerColorProperty, value);
600
                    OnPropertyChanged("BackInnerColor");
601
                }
602
            }
603
        }
604
605
        public Geometry PathDataInner
606
        {
607
            get { return (Geometry)GetValue(PathDataInnerProperty); }
608
            set
609
            {
610
                SetValue(PathDataInnerProperty, value);
611
                OnPropertyChanged("PathDataInner");
612
            }
613
        }
614
615
        public Geometry OverViewPathData
616
        {
617
            get { return (Geometry)GetValue(OverViewPathDataProperty); }
618
            set { SetValue(OverViewPathDataProperty, value);
619
620
                OnPropertyChanged("OverViewPathData");
621
622
            }
623
        }
624
625
        public FontFamily TextFamily
626
        {
627
            get { return (FontFamily)GetValue(TextFamilyProperty); }
628
            set
629
            {
630
                if (this.TextFamily != value)
631
                {
632
                    SetValue(TextFamilyProperty, value);
633
                    OnPropertyChanged("TextFamily");
634
                }
635
            }
636
        }
637
638
        public string ArrowText
639
        {
640
            get { return (string)GetValue(ArrowTextProperty); }
641
            set
642
            {
643
                if (this.ArrowText != value)
644
                {
645
                    SetValue(ArrowTextProperty, value);
646
                    OnPropertyChanged("ArrowText");
647
                }
648
            }
649
        }
650
651
        public string OverViewArrowText
652
        {
653
654
            get { return (string)GetValue(OverViewArrowTextProperty);
655
            }
656
            set
657
            {
658
                if (this.OverViewArrowText != value)
659
                {
660
                    SetValue(OverViewArrowTextProperty, value);
661
                    OnPropertyChanged("OverViewArrowText");
662
                }
663
            }
664
        }
665
666
        public Double TextSize
667
        {
668
            get { return (Double)GetValue(TextSizeProperty); }
669
            set
670
            {
671
                if (this.TextSize != value)
672
                {
673
                    SetValue(TextSizeProperty, value);
674
                    OnPropertyChanged("TextSize");
675
                }
676
            }
677
        }
678
679
        public FontStyle TextStyle
680
        {
681
            get { return (FontStyle)GetValue(TextStyleProperty); }
682
            set
683
            {
684
                if (this.TextStyle != value)
685
                {
686
                    SetValue(TextStyleProperty, value);
687
                    OnPropertyChanged("TextStyle");
688
                }
689
            }
690
        }
691
692
        //강인구 추가
693
        public TextDecorationCollection UnderLine
694
        {
695
            get
696
            {
697
                return (TextDecorationCollection)GetValue(UnderLineProperty);
698
            }
699
            set
700
            {
701
                if (this.UnderLine != value)
702
                {
703
                    SetValue(UnderLineProperty, value);
704
                    OnPropertyChanged("UnderLine");
705
                }
706
            }
707
        }
708
709
        public double CanvasX
710
        {
711
            get { return (double)GetValue(CanvasXProperty); }
712
            set
713
            {
714
                if (this.CanvasX != value)
715
                {
716
                    SetValue(CanvasXProperty, value);
717
                    OnPropertyChanged("CanvasX");
718
                }
719
            }
720
        }
721
722
        public double CanvasY
723
        {
724
            get { return (double)GetValue(CanvasYProperty); }
725
            set
726
            {
727
                if (this.CanvasY != value)
728
                {
729
                    SetValue(CanvasYProperty, value);
730
                    OnPropertyChanged("CanvasY");
731
                }
732
            }
733
        } 
734
735
        public double CenterX
736
        {
737
            get { return (double)GetValue(CenterXProperty); }
738
            set { SetValue(CenterXProperty, value);
739
            OnPropertyChanged("CenterX");
740
            
741
            }
742
        }
743
744
        public double CenterY
745
        {
746
            get { return (double)GetValue(CenterYProperty); }
747
            set { SetValue(CenterYProperty, value);
748
            OnPropertyChanged("CenterY");
749
            }
750
        }
751
752
        public Brush SubPathFill
753
        {
754
            get { return (Brush)GetValue(SubPathFillProperty); }
755
            set
756
            {
757
                SetValue(SubPathFillProperty, value);
758
                OnPropertyChanged("SubPathFill");
759
            }
760
        }
761
762
        public Brush TextBoxBackground
763
        {
764
            get { return (Brush)GetValue(TextBoxBackgroundProperty); }
765
            set
766
            {
767
                SetValue(TextBoxBackgroundProperty, value);
768
                OnPropertyChanged("TextBoxBackground");
769
            }
770
        }
771
772
773
        //강인구 추가 주석풀기
774 71d7e0bf 송근호
       
775 787a4489 KangIngu
776
        public bool EnableEditing
777
        {
778
            get { return (bool)GetValue(EnableEditingProperty); }
779
            set
780
            {
781
                if (this.EnableEditing != value)
782
                {
783
                    SetValue(EnableEditingProperty, value);
784
                    OnPropertyChanged("EnableEditing");
785
                }
786
            }
787
        }
788
789
        #endregion
790
791
        #region Dependency Properties
792
793
        public static readonly DependencyProperty BoxWidthProperty = DependencyProperty.Register(
794
                "BoxWidth", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
795
796
        public static readonly DependencyProperty BoxHeightProperty = DependencyProperty.Register(
797
                "BoxHeight", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)20));
798
799
        public static readonly DependencyProperty UserIDProperty = DependencyProperty.Register(
800
                "UserID", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
801
802
        public static readonly DependencyProperty ArrowTextStyleProperty = DependencyProperty.Register(
803
               "ArrowTextStyle", typeof(ArrowTextStyleSet), typeof(ArrowTextControl), new PropertyMetadata(ArrowTextStyleSet.Normal));
804
805
        public static readonly DependencyProperty CenterXProperty = DependencyProperty.Register(
806
                "CenterX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
807
808
        public static readonly DependencyProperty CenterYProperty = DependencyProperty.Register(
809
                "CenterY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnCenterXYChanged));
810
811
        public static readonly DependencyProperty AngleProperty = DependencyProperty.Register(
812
                "Angle", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0.0, new PropertyChangedCallback(PointValueChanged)));
813
        
814
        public static readonly DependencyProperty CanvasXProperty = DependencyProperty.Register(
815
                "CanvasX", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
816
817
        public static readonly DependencyProperty CanvasYProperty = DependencyProperty.Register(
818
                "CanvasY", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((double)0, OnSetCansvasChanged));
819
820
        public static readonly DependencyProperty PointSetProperty = DependencyProperty.Register(
821
                "PointSet", typeof(List<Point>), typeof(ArrowTextControl), new PropertyMetadata(new List<Point>(), PointValueChanged));
822
823
        public static readonly DependencyProperty TextFamilyProperty = DependencyProperty.Register(
824
                "TextFamily", typeof(FontFamily), typeof(ArrowTextControl), new PropertyMetadata(new FontFamily("Arial"), TextChanged));
825
826
        public static readonly DependencyProperty PathDataProperty = DependencyProperty.Register(
827
                "PathData", typeof(Geometry), typeof(ArrowTextControl), null);
828
829
        //강인구 추가
830
        public static readonly DependencyProperty UnderLineProperty = DependencyProperty.Register(
831
    "UnderLine", typeof(TextDecorationCollection), typeof(ArrowTextControl), new PropertyMetadata(null, PointValueChanged));
832
833
        public static readonly DependencyProperty LineSizeProperty = DependencyProperty.Register(
834
               "LineSize", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)3, PointValueChanged));
835
836
        public static readonly DependencyProperty TextStyleProperty = DependencyProperty.Register(
837
                "TextStyle", typeof(FontStyle), typeof(ArrowTextControl), new PropertyMetadata(FontStyles.Normal));
838
839
        public static readonly DependencyProperty TextSizeProperty = DependencyProperty.Register(
840
                "TextSize", typeof(Double), typeof(ArrowTextControl), new PropertyMetadata((Double)30, PointValueChanged));
841
842
        public static readonly DependencyProperty TextWeightProperty = DependencyProperty.Register(
843
                "TextWeight", typeof(FontWeight), typeof(ArrowTextControl), new PropertyMetadata(FontWeights.Normal));
844
845
        public static readonly DependencyProperty IsFixedProperty = DependencyProperty.Register(
846
                "isFixed", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
847
848
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register(
849
                "IsSelected", typeof(bool), typeof(ArrowTextControl), new FrameworkPropertyMetadata(false, IsSelectedChanged));
850
851
        public static readonly DependencyProperty StrokeColorProperty = DependencyProperty.Register(
852
                "StrokeColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.Red)));
853
854 b79d6e7f humkyung
        public static readonly DependencyProperty ArcLengthProperty = DependencyProperty.Register(
855
            "ArcLength", typeof(double), typeof(ArrowTextControl), new PropertyMetadata((Double)10, PointValueChanged));
856
857 787a4489 KangIngu
        public static readonly DependencyProperty ControlTypeProperty = DependencyProperty.Register(
858
                "ControlType", typeof(ControlType), typeof(ArrowTextControl), new FrameworkPropertyMetadata(ControlType.ArrowTextControl));
859
860
        public static readonly DependencyProperty StartPointProperty = DependencyProperty.Register(
861
                "StartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
862
863
        public static readonly DependencyProperty EndPointProperty = DependencyProperty.Register(
864
                "EndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
865
866
        public static readonly DependencyProperty BackInnerColorProperty = DependencyProperty.Register(
867
            "BackInnerColor", typeof(SolidColorBrush), typeof(ArrowTextControl), new PropertyMetadata(new SolidColorBrush(Colors.White)));
868
869
        public static readonly DependencyProperty PathDataInnerProperty = DependencyProperty.Register(
870
    "PathDataInner", typeof(Geometry), typeof(ArrowTextControl), null);
871
872
        public static readonly DependencyProperty isHighlightProperty = DependencyProperty.Register(
873
                "isHighlight", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
874
875
        public static readonly DependencyProperty MidPointProperty = DependencyProperty.Register(
876
                "MidPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(new Point(0, 0), PointValueChanged));
877
878
        public static readonly DependencyProperty TransformerProperty = DependencyProperty.Register(
879
                "isTrans", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata(false, PointValueChanged));
880
881
        public static readonly DependencyProperty BorderSizeProperty = DependencyProperty.Register(
882 f8769f8a ljiyeon
                "BorderSize", typeof(Thickness), typeof(ArrowTextControl), new PropertyMetadata(new Thickness(0), PointValueChanged));
883 787a4489 KangIngu
    
884
        public static readonly DependencyProperty ArrowTextProperty = DependencyProperty.Register(
885
              "ArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null));
886
887
888
889
        //, new PropertyChangedCallback(TextChanged)
890
891
892
        #region 추가 사항
893
        public static readonly DependencyProperty SubPathDataProperty = DependencyProperty.Register(
894
                "SubPathData", typeof(Geometry), typeof(ArrowTextControl), null);
895
896
897
        public static readonly DependencyProperty SubPathFillProperty = DependencyProperty.Register(
898
                "SubPathFill", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(null));
899
900
        public static readonly DependencyProperty TextBoxBackgroundProperty = DependencyProperty.Register(
901
                "TextBoxBackground", typeof(Brush), typeof(ArrowTextControl), new PropertyMetadata(Brushes.White));
902
903
        public static readonly DependencyProperty OverViewArrowTextProperty = DependencyProperty.Register(
904
                "OverViewArrowText", typeof(string), typeof(ArrowTextControl), new PropertyMetadata(null, new PropertyChangedCallback(TextChanged)));
905
906
        public static readonly DependencyProperty OverViewPathDataProperty = DependencyProperty.Register(
907
                "OverViewPathData", typeof(Geometry), typeof(ArrowTextControl), null);
908
909
        public static readonly DependencyProperty OverViewStartPointProperty = DependencyProperty.Register(
910
                "OverViewStartPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
911
912
        public static readonly DependencyProperty OverViewEndPointProperty = DependencyProperty.Register(
913
                "OverViewEndPoint", typeof(Point), typeof(ArrowTextControl), new PropertyMetadata(null));
914
915
        public static readonly DependencyProperty TextBoxVisibilityProperty = DependencyProperty.Register(
916
            "TextBoxVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Visible), OnTextBoxVisibilityChanged));
917
918
        //강인구 추가(주석풀기)
919
        public static readonly DependencyProperty TextBlockVisibilityProperty = DependencyProperty.Register(
920
            "TextBlockVisibility", typeof(Visibility), typeof(ArrowTextControl), new PropertyMetadata((Visibility.Collapsed), OnTextBlockVisibilityChanged));
921
922
        public static readonly DependencyProperty EnableEditingProperty = DependencyProperty.Register(
923 71d7e0bf 송근호
           "EnableEditing", typeof(bool), typeof(ArrowTextControl), new PropertyMetadata((true), new PropertyChangedCallback(OnIsEditingChanged)));
924 787a4489 KangIngu
925
        #endregion
926
927
        #endregion
928
929
        #region CallBack Method
930
931
        //강인구 추가(주석풀기)
932
        public static void OnIsEditingChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
933
        {
934
            var instance = (ArrowTextControl)sender;
935
936
            if (e.OldValue != e.NewValue && instance.Base_TextBlock != null)
937
            {
938
                instance.SetValue(e.Property, e.NewValue);
939
940
                if (instance.EnableEditing)
941
                {
942 71d7e0bf 송근호
                    instance.EditingMode();
943 787a4489 KangIngu
                }
944
                else
945
                {
946
                    instance.UnEditingMode();
947
                }
948
            }
949
        }
950
951
        public static void OnTextBoxVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
952
        {
953
            var instance = (ArrowTextControl)sender;
954
955
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
956
            {
957
                instance.SetValue(e.Property, e.NewValue);
958
            }
959
        }
960
961
        public static void OnTextBlockVisibilityChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
962
        {
963
            var instance = (ArrowTextControl)sender;
964
965
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
966
            {
967
                instance.SetValue(e.Property, e.NewValue);
968
            }
969
        }
970
971
        public static void PointValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
972
        {
973
            var instance = (ArrowTextControl)sender;
974
975
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
976
            {
977
                instance.SetArrowTextPath();
978
            }
979
        }
980
981
982
983
        public static void TextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
984
        {
985
            var instance = (ArrowTextControl)sender;
986
            
987
            if (e.OldValue != e.NewValue)
988
            {
989
                instance.SetValue(e.Property, e.NewValue);
990
                //instance.BoxWidth = instance.Base_TextBox.ActualWidth;
991
                //instance.BoxHeight = instance.Base_TextBox.ActualHeight;
992
            }
993
        }
994
995
        public static void OnCenterXYChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
996
        {
997
            var instance = (ArrowTextControl)sender;
998
            if (e.OldValue != e.NewValue && instance.Base_ArrowPath != null)
999
            {
1000
                instance.SetValue(e.Property, e.NewValue);
1001
                instance.SetArrowTextPath();
1002
            }
1003
        }
1004
1005
        public static void OnSetCansvasChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
1006
        {
1007
            var instance = (ArrowTextControl)sender;
1008
1009
            if (e.OldValue != e.NewValue && instance != null)
1010
            {
1011
                instance.SetValue(e.Property, e.NewValue);
1012
                //Canvas.SetLeft(instance, instance.CanvasX);
1013
                //Canvas.SetTop(instance, instance.CanvasY);
1014
            }
1015
        }
1016
1017
        public static void IsSelectedChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
1018
        {
1019
            //var instance = (ArrowTextControl)sender;
1020
1021
            //if (e.OldValue != e.NewValue)
1022
            //{
1023
            //    instance.SetValue(e.Property, e.NewValue);
1024
1025
            //    if (instance.IsSelected && instance.Base_TextBox != null)
1026
            //    {
1027
            //        instance.BorderSize = new Thickness(1);
1028
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Blue);
1029
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Blue);
1030
            //    }
1031
            //    else
1032
            //    {
1033
            //        instance.BorderSize = new Thickness(0);
1034
            //        //instance.Base_TextBox.BorderBrush = new SolidColorBrush(Colors.Transparent);
1035
            //        //instance.Base_ArrowPath.Stroke = new SolidColorBrush(Colors.Transparent);
1036
            //    }
1037
            //}
1038
        }
1039
        #endregion
1040
1041
        #region Internal Method
1042
1043
        //강인구 주석 풀기
1044
        public void EditingMode()
1045
        {
1046
            TextBoxVisibility = Visibility.Visible;
1047
            TextBlockVisibility = Visibility.Collapsed;
1048
1049
1050
            //강인구 언더라인 추가
1051
            if (UnderLine != null)
1052
                Base_TextBlock.TextDecorations = UnderLine;
1053
        }
1054
        //강인구 주석 풀기
1055
        public void UnEditingMode()
1056
        {
1057
            TextBoxVisibility = Visibility.Collapsed;
1058
            TextBlockVisibility = Visibility.Visible;
1059
1060 38d69491 taeseongkim
            if (Base_TextBlock != null)
1061
            {
1062
                if (UnderLine != null)
1063
                    Base_TextBlock.TextDecorations = UnderLine;
1064 787a4489 KangIngu
1065 38d69491 taeseongkim
                Base_TextBlock.Margin =
1066
                     new Thickness(Base_TextBox.Margin.Left + 4, Base_TextBox.Margin.Top + 4,
1067
                         Base_TextBox.Margin.Right + 4, Base_TextBox.Margin.Bottom + 4);
1068
            }
1069
1070
            this.BaseTextbox_Caret.Visibility = Visibility.Collapsed;
1071 787a4489 KangIngu
        }
1072
1073 4f017ed3 taeseongkim
        private void SetArrowTextPath(bool IsInit = false)
1074 787a4489 KangIngu
        {
1075
            instanceGroup.Children.Clear();
1076
1077 fa48eb85 taeseongkim
            //VisualPageAngle = 0;
1078
1079
            if (Math.Abs(PageAngle).ToString() == "90")
1080
            {
1081
                VisualPageAngle = 270;
1082
            }
1083
            else if (Math.Abs(PageAngle).ToString() == "270")
1084
            {
1085
                VisualPageAngle = 90;
1086
            }
1087
            else
1088
            {
1089
                VisualPageAngle = PageAngle;
1090
            }
1091
1092 787a4489 KangIngu
            connectorSMGeometry.StartPoint = this.StartPoint;
1093
            connectorSMGeometry.EndPoint = this.MidPoint;
1094
            connectorMEGeometry.StartPoint = this.MidPoint; //핵심
1095 ca40e004 ljiyeon
1096 fa48eb85 taeseongkim
            /// 텍스트박스의 좌표 설정
1097 787a4489 KangIngu
            Canvas.SetLeft(Base_TextBox, this.EndPoint.X);
1098
            Canvas.SetTop(Base_TextBox, this.EndPoint.Y);
1099 15bbef90 taeseongkim
            //System.Diagnostics.Debug.WriteLine($"TextBox Set {this.EndPoint.X},{this.EndPoint.Y}");
1100 fa48eb85 taeseongkim
            
1101
1102 787a4489 KangIngu
            List<Point> ps = new List<Point>();
1103
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox))); //상단
1104
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth / 2, Canvas.GetTop(Base_TextBox) + this.BoxHeight)); // 하단
1105
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2)); //좌단
1106
            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxWidth, Canvas.GetTop(Base_TextBox) + this.BoxHeight / 2));  //우단
1107
1108
            if (isTrans)
1109
            {
1110 fa48eb85 taeseongkim
                switch (Math.Abs(this.PageAngle).ToString())
1111 787a4489 KangIngu
                {
1112
                    case "90":
1113
                        {
1114
                            ps.Clear();
1115
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1116
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1117
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1118
1119
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1120
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1121
1122
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); //중간 하단
1123
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 하단
1124
1125
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간
1126
                        }
1127
                        break;
1128
                    case "270":
1129
                        {
1130
                            ps.Clear();
1131
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1132
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1133
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1134
1135
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1136
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1137
1138
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1139
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1140
1141
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간
1142
                        }
1143
                        break;
1144
                    default:
1145
                        break;
1146
                }
1147 ca40e004 ljiyeon
                
1148 787a4489 KangIngu
                var endP = MathSet.getNearPoint(ps, this.MidPoint);
1149
1150 ca40e004 ljiyeon
                //20180911 LJY 꺾이는 부분 수정
1151 6c122a60 ljiyeon
                Point testP = endP;                
1152 fa48eb85 taeseongkim
                switch (Math.Abs(this.PageAngle).ToString())
1153 ca40e004 ljiyeon
                {
1154 6c122a60 ljiyeon
                    case "90":
1155
                        testP = new Point(endP.X + 50, endP.Y);
1156
                        break;
1157
                    case "270":
1158
                        testP = new Point(endP.X - 50, endP.Y);
1159
                        break;
1160
                }                
1161 ca40e004 ljiyeon
1162
                //20180910 LJY 각도에 따라.
1163 fa48eb85 taeseongkim
                switch (Math.Abs(this.PageAngle).ToString())
1164 ca40e004 ljiyeon
                {
1165
                    case "90":
1166
                        if (isFixed)
1167
                        {
1168
                            if (ps[0] == endP) //상단
1169
                            {
1170
                                testP = new Point(endP.X , endP.Y + 50);
1171
                                //System.Diagnostics.Debug.WriteLine("상단"+ testP);
1172
                            }
1173
                            else if (ps[1] == endP) //하단
1174
                            {
1175
                                testP = new Point(endP.X , endP.Y - 50);
1176
                                //System.Diagnostics.Debug.WriteLine("하단"+ testP);
1177
                            }
1178
                            else if (ps[2] == endP) //좌단
1179
                            {
1180
                                testP = new Point(endP.X - 50, endP.Y);
1181
                                //System.Diagnostics.Debug.WriteLine("좌단"+ testP);
1182
                            }
1183
                            else if (ps[3] == endP) //우단
1184
                            {
1185
                                testP = new Point(endP.X + 50, endP.Y);
1186
                                //System.Diagnostics.Debug.WriteLine("우단"+ testP);
1187
                            }
1188
                        }
1189
                        break;
1190
                    case "270":
1191
                        if (isFixed)
1192
                        {
1193
                            if (ps[0] == endP) //상단
1194
                            {
1195
                                testP = new Point(endP.X , endP.Y - 50);
1196
                                //System.Diagnostics.Debug.WriteLine("상단" + testP);
1197
                            }
1198
                            else if (ps[1] == endP) //하단
1199
                            {
1200
                                testP = new Point(endP.X, endP.Y + 50);
1201
                                //System.Diagnostics.Debug.WriteLine("하단" + testP);
1202
                            }
1203
                            else if (ps[2] == endP) //좌단
1204
                            {
1205
                                testP = new Point(endP.X + 50, endP.Y);
1206
                                //System.Diagnostics.Debug.WriteLine("좌단" + testP);
1207
                            }
1208
                            else if (ps[3] == endP) //우단
1209
                            {
1210
                                testP = new Point(endP.X - 50, endP.Y);
1211
                                //System.Diagnostics.Debug.WriteLine("우단" + testP);
1212
                            }
1213
                        }
1214
                        break;
1215
                    default:
1216
                        if (isFixed)
1217
                        {
1218
                            if (ps[0] == endP) //상단
1219
                            {
1220
                                testP = new Point(endP.X, endP.Y - 50);
1221
                                //System.Diagnostics.Debug.WriteLine("상단");
1222
                            }
1223
                            else if (ps[1] == endP) //하단
1224
                            {
1225
                                testP = new Point(endP.X, endP.Y + 50);
1226
                                //System.Diagnostics.Debug.WriteLine("하단");
1227
                            }
1228
                            else if (ps[2] == endP) //좌단
1229
                            {
1230
                                testP = new Point(endP.X - 50, endP.Y);
1231
                                //System.Diagnostics.Debug.WriteLine("좌단");
1232
                            }
1233
                            else if (ps[3] == endP) //우단
1234
                            {
1235
                                testP = new Point(endP.X + 50, endP.Y);
1236
                                //System.Diagnostics.Debug.WriteLine("우단");
1237
                            }
1238
                        }
1239
                        break;
1240
                }
1241 f9d42594 djkim
                connectorMEGeometry.EndPoint = endP;
1242 ca40e004 ljiyeon
                connectorSMGeometry.EndPoint = testP;
1243
                connectorMEGeometry.StartPoint = testP;
1244 f9d42594 djkim
                
1245 ca40e004 ljiyeon
                //20180910 LJY 각도에 따라.
1246 f9d42594 djkim
                this.MidPoint = testP;
1247 d251456f humkyung
                instanceGroup.Children.Add(DrawSet.DrawArrow(testP, this.StartPoint, this.LineSize));
1248 2b69c140 humkyung
                instanceGroup.FillRule = FillRule.Nonzero;
1249
                this.Base_ArrowPath.Fill = this.StrokeColor;
1250
                this.Base_ArrowSubPath.Fill = this.StrokeColor;
1251 787a4489 KangIngu
            }
1252
            else
1253
            {
1254 fa48eb85 taeseongkim
                switch (Math.Abs(this.PageAngle).ToString())
1255 787a4489 KangIngu
                {
1256
                    case "90":
1257
                        {
1258
                            ps.Clear();
1259 ca40e004 ljiyeon
1260 787a4489 KangIngu
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1261
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); // 위 중간
1262
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - this.BoxWidth)); // 위 오른쪽
1263
1264
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1265
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1266
1267
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth / 2)); //중간 하단
1268
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 하단
1269 ca40e004 ljiyeon
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) - this.BoxWidth)); //오른쪽 중간 
1270 787a4489 KangIngu
                        }
1271
                        break;
1272
                    case "270":
1273
                        {
1274
                            ps.Clear();
1275 ca40e004 ljiyeon
                            
1276 787a4489 KangIngu
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1277
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1278
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1279
1280
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1281
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1282
1283
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1284
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1285
1286 ca40e004 ljiyeon
                            ps.Add(new Point(Canvas.GetLeft(Base_TextBox) - this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간 
1287 787a4489 KangIngu
                        }
1288
                        break;
1289 fa48eb85 taeseongkim
                    //case "180":
1290
                    //    {
1291
                    //        ps.Clear();
1292
1293
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox))); //위 왼쪽
1294
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); // 위 중간
1295
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + this.BoxWidth)); // 위 오른쪽
1296
1297
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox))); //왼쪽 중간
1298
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox))); //왼쪽 하단
1299
1300
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth / 2)); //중간 하단
1301
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 하단
1302
1303
                    //        ps.Add(new Point(Canvas.GetLeft(Base_TextBox) + this.BoxHeight / 2, Canvas.GetTop(Base_TextBox) + this.BoxWidth)); //오른쪽 중간 
1304
                    //    }
1305
                    //    break;
1306 787a4489 KangIngu
                    default:
1307
                        break;
1308
                }
1309
1310
1311
                var endP = MathSet.getNearPoint(ps, this.MidPoint);
1312
                connectorMEGeometry.EndPoint = endP; //최상단
1313 ca40e004 ljiyeon
                                                     //connectorMEGeometry.EndPoint = this.EndPoint; //핵심
1314
                                                     //this.MidPoint= MathSet.getMiddlePoint(this.StartPoint, endP);
1315 787a4489 KangIngu
                #region 보정치
1316 ca40e004 ljiyeon
                Point testP = endP;
1317
1318
                //20180910 LJY 각도에 따라.
1319 fa48eb85 taeseongkim
                switch (Math.Abs(this.PageAngle).ToString())
1320 ca40e004 ljiyeon
                {
1321
                    case "90":
1322
                        if (isFixed)
1323
                        {
1324
                            if (ps[0] == endP) //상단
1325
                            {
1326
                                testP = new Point(endP.X - 50, endP.Y);
1327
                                //System.Diagnostics.Debug.WriteLine("상단"+ testP);
1328
                            }
1329
                            else if (ps[1] == endP) //하단
1330
                            {
1331
                                testP = new Point(endP.X + 50, endP.Y);
1332
                                //System.Diagnostics.Debug.WriteLine("하단"+ testP);
1333
                            }
1334
                            else if (ps[2] == endP) //좌단
1335
                            {
1336
                                testP = new Point(endP.X - 50, endP.Y);
1337
                                //System.Diagnostics.Debug.WriteLine("좌단"+ testP);
1338
                            }
1339
                            else if (ps[3] == endP) //우단
1340
                            {
1341
                                testP = new Point(endP.X + 50 , endP.Y);
1342
                                //System.Diagnostics.Debug.WriteLine("우단"+ testP);
1343
                            }
1344
                        }
1345
                        break;
1346
                    case "270":
1347
                        if (isFixed)
1348
                        {
1349
                            if (ps[0] == endP) //상단
1350
                            {
1351
                                testP = new Point(endP.X + 50, endP.Y);
1352
                                //System.Diagnostics.Debug.WriteLine("상단" + testP);
1353
                            }
1354
                            else if (ps[1] == endP) //하단
1355
                            {
1356
                                testP = new Point(endP.X - 50, endP.Y);
1357
                                //System.Diagnostics.Debug.WriteLine("하단" + testP);
1358
                            }
1359
                            else if (ps[2] == endP) //좌단
1360
                            {
1361
                                testP = new Point(endP.X + 50, endP.Y);
1362
                                //System.Diagnostics.Debug.WriteLine("좌단" + testP);
1363
                            }
1364
                            else if (ps[3] == endP) //우단
1365
                            {
1366
                                testP = new Point(endP.X + 50, endP.Y );
1367
                                //System.Diagnostics.Debug.WriteLine("우단" + testP);
1368
                            }
1369
                        }
1370
                        break;
1371
                    default:
1372
                        if (isFixed)
1373
                        {
1374
                            if (ps[0] == endP) //상단
1375
                            {
1376
                                testP = new Point(endP.X, endP.Y - 50);
1377
                                //System.Diagnostics.Debug.WriteLine("상단");
1378
                            }
1379
                            else if (ps[1] == endP) //하단
1380
                            {
1381
                                testP = new Point(endP.X, endP.Y + 50);
1382
                                //System.Diagnostics.Debug.WriteLine("하단");
1383
                            }
1384
                            else if (ps[2] == endP) //좌단
1385
                            {
1386
                                testP = new Point(endP.X - 50, endP.Y);
1387
                                //System.Diagnostics.Debug.WriteLine("좌단");
1388
                            }
1389
                            else if (ps[3] == endP) //우단
1390
                            {
1391
                                testP = new Point(endP.X + 50, endP.Y);
1392
                                //System.Diagnostics.Debug.WriteLine("우단");
1393
                            }
1394
                        }
1395
                        break;
1396
                }
1397
                  
1398
1399 787a4489 KangIngu
                connectorSMGeometry.EndPoint = testP;
1400
                connectorMEGeometry.StartPoint = testP;
1401 d251456f humkyung
                instanceGroup.Children.Add(DrawSet.DrawArrow(testP, this.StartPoint, this.LineSize));
1402 2b69c140 humkyung
                instanceGroup.FillRule = FillRule.Nonzero;
1403
                this.Base_ArrowPath.Fill = this.StrokeColor;
1404
                this.Base_ArrowSubPath.Fill = this.StrokeColor;
1405 787a4489 KangIngu
                #endregion
1406
            }
1407
1408
            switch (this.ArrowTextStyle)
1409
            {
1410
                case ArrowTextStyleSet.Normal:
1411
                    this.BorderSize = new Thickness(0);
1412 05009a0e ljiyeon
                    DrawingRect();
1413 787a4489 KangIngu
                    break;
1414
                case ArrowTextStyleSet.Cloud:
1415
                    this.BorderSize = new Thickness(0);
1416
                    DrawingCloud();
1417
                    break;
1418
                default:
1419
                    {
1420 4fcb686a taeseongkim
                        this.BorderSize = new Thickness(LineSize);
1421 787a4489 KangIngu
                        DrawingRect();
1422
                    }
1423
1424
                    break;
1425
            }
1426
1427
            if (isHighLight)
1428
            {
1429
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1430
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1431
1432
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.Yellow.R, Colors.Yellow.G, Colors.Yellow.B));
1433
            }
1434
            else
1435
            {
1436
                BackInnerColor = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1437
                SubPathFill = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.6), Colors.White.R, Colors.White.G, Colors.White.B));
1438
                TextBoxBackground = new SolidColorBrush(Color.FromArgb(Convert.ToByte(255 * 0.1), Colors.White.R, Colors.White.G, Colors.White.B));
1439
            }
1440
1441
            instanceGroup.Children.Add(connectorSMGeometry);
1442
            instanceGroup.Children.Add(connectorMEGeometry);
1443
1444
            this.PathData = instanceGroup;
1445
            OverViewPathData = PathData;
1446
            OverViewArrowText = ArrowText;
1447
            OverViewEndPoint = connectorMEGeometry.EndPoint;
1448
            OverViewStartPoint = connectorSMGeometry.StartPoint;
1449
1450 4f017ed3 taeseongkim
            var tempAngle = Math.Abs(this.VisualPageAngle);
1451 787a4489 KangIngu
1452
            if (tempAngle == Convert.ToDouble(90) || tempAngle == Convert.ToDouble(270))
1453
            {
1454
                this.RenderTransformOrigin = new Point(0.5, 0.5);
1455
                this.Base_ArrowPath.RenderTransformOrigin = new Point(0, 0);
1456
                this.Base_ArrowSubPath.RenderTransformOrigin = new Point(0, 0);
1457
1458
                Base_TextBox.RenderTransformOrigin = new Point(0, 0);
1459 f011637d 송근호
                BaseTextbox_Caret.RenderTransformOrigin = new Point(0, 0);
1460 787a4489 KangIngu
            }
1461
1462 fa48eb85 taeseongkim
            Base_TextBox.RenderTransform = new RotateTransform
1463
            {
1464
                Angle = this.VisualPageAngle,
1465
                CenterX = this.CenterX,
1466
                CenterY = this.CenterY,
1467
            };
1468
1469 787a4489 KangIngu
            Base_ArrowSubPath.RenderTransform = new RotateTransform
1470
            {
1471 fa48eb85 taeseongkim
                Angle = this.VisualPageAngle,
1472 787a4489 KangIngu
                CenterX = this.EndPoint.X,
1473
                CenterY = this.EndPoint.Y,
1474
            };
1475 fa48eb85 taeseongkim
1476
            if (BaseTextbox_Caret.Visibility == Visibility.Visible)
1477
            {
1478
                BaseTextbox_Caret.RenderTransform = new RotateTransform
1479
                {
1480
                    Angle = this.VisualPageAngle,
1481
                    CenterX = this.CenterX,
1482
                    CenterY = this.CenterY,
1483
                };
1484
1485
                MoveCustomCaret();
1486
            }
1487 787a4489 KangIngu
        }
1488
1489
        private void DrawingCloud()
1490
        {
1491 ca40e004 ljiyeon
            //20180906 LJY Textbox guide
1492 fa48eb85 taeseongkim
            string angle = Math.Abs(this.PageAngle).ToString();
1493 7ad417d8 이지연
            //방지
1494
            if (this.ArcLength == 0) this.ArcLength = 10;
1495 ca40e004 ljiyeon
            if (angle == "180")
1496 787a4489 KangIngu
            {
1497 ca40e004 ljiyeon
                List<Point> pCloud = new List<Point>()
1498
                {
1499
                     new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1500
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxHeight), //왼쪽 아래
1501
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox) - BoxHeight),
1502
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxWidth, Canvas.GetTop(Base_TextBox)),
1503
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1504
                };
1505 b79d6e7f humkyung
                SubPathData = Generate(pCloud, this.ArcLength);
1506 ca40e004 ljiyeon
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1507
            
1508
            }//20180906 LJY Textbox guide
1509
            else
1510 4fcb686a taeseongkim
            {
1511
                var boxWidth = BoxWidth;
1512
                System.Diagnostics.Debug.WriteLine("disp Width : " + BoxWidth);
1513
                //boxWidth = boxWidth + Base_TextBox.Margin.Left + Base_TextBox.Margin.Right + Base_TextBox.Padding.Left + Base_TextBox.Padding.Right;
1514
1515 ca40e004 ljiyeon
                List<Point> pCloud = new List<Point>()
1516
                {
1517
    #if SILVERLIGHT
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
    #else
1525 7ad417d8 이지연
                    new Point(Canvas.GetLeft(Base_TextBox)-(this.LineSize ), Canvas.GetTop(Base_TextBox) -(this.LineSize)), //위
1526
                    new Point(Canvas.GetLeft(Base_TextBox)-(this.LineSize ), Canvas.GetTop(Base_TextBox)+ BoxHeight+(this.LineSize)), //왼쪽 아래
1527
                    new Point(Canvas.GetLeft(Base_TextBox)+ boxWidth+(this.LineSize ), Canvas.GetTop(Base_TextBox) + BoxHeight+(this.LineSize)),
1528
                    new Point(Canvas.GetLeft(Base_TextBox) + boxWidth+(this.LineSize ), Canvas.GetTop(Base_TextBox)-(this.LineSize)),
1529
                    new Point(Canvas.GetLeft(Base_TextBox)-(this.LineSize), Canvas.GetTop(Base_TextBox)-(this.LineSize)), //위  
1530 ca40e004 ljiyeon
1531
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1532
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1533
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1534
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1535
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1536
    #endif
1537
                };
1538
                //instanceGroup.Children.Add(Generate(pCloud));
1539 b79d6e7f humkyung
                SubPathData = Generate(pCloud, this.ArcLength);
1540 ca40e004 ljiyeon
                PathDataInner = (GenerateInnerCloud(pCloud, angle));
1541
                //   }
1542
            }
1543
1544 787a4489 KangIngu
        }
1545
1546
        private void DrawingRect()
1547
        {
1548 ca40e004 ljiyeon
            //20180906 LJY Textbox guide
1549 05009a0e ljiyeon
            if(this.ArrowTextStyle == ArrowTextStyleSet.Normal)
1550
            {
1551
                this.Base_TextBox.BorderBrush = Brushes.Transparent;
1552
            }
1553 43e1d368 taeseongkim
            
1554 fa48eb85 taeseongkim
            if (Math.Abs(this.PageAngle).ToString() == "90")
1555 787a4489 KangIngu
            {
1556 ca40e004 ljiyeon
                List<Point> pCloud = new List<Point>()
1557
                {
1558
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1559
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) - BoxWidth), //왼쪽 아래
1560
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox) - BoxWidth),
1561
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxHeight, Canvas.GetTop(Base_TextBox)),
1562
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1563
                };
1564
                PathDataInner = (GenerateInner(pCloud));
1565
            }
1566 fa48eb85 taeseongkim
            else if(Math.Abs(this.PageAngle).ToString() == "270")
1567 ca40e004 ljiyeon
            {
1568
                List<Point> pCloud = new List<Point>()
1569
                {
1570
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1571
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox) + BoxWidth), //왼쪽 아래
1572
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox) + BoxWidth),
1573
                    new Point(Canvas.GetLeft(Base_TextBox) - BoxHeight, Canvas.GetTop(Base_TextBox)),
1574
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1575
                };
1576
                PathDataInner = (GenerateInner(pCloud));
1577
            }//20180906 LJY Textbox guide
1578
            else
1579
            { 
1580
                List<Point> pCloud = new List<Point>()
1581
                {
1582
    #if SILVERLIGHT
1583
		            new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1584
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1585
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1586
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1587
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1588
1589
    #else
1590
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1591
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight), //왼쪽 아래
1592
                    new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth, Canvas.GetTop(Base_TextBox) + BoxHeight),
1593
                    new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth, Canvas.GetTop(Base_TextBox)),
1594
                    new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위  
1595
1596
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1597
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)+ BoxHeight-4), //왼쪽 아래
1598
                    //new Point(Canvas.GetLeft(Base_TextBox)+ BoxWidth-1, Canvas.GetTop(Base_TextBox) + BoxHeight-4),
1599
                    //new Point(Canvas.GetLeft(Base_TextBox) + BoxWidth-1, Canvas.GetTop(Base_TextBox)),
1600
                    //new Point(Canvas.GetLeft(Base_TextBox), Canvas.GetTop(Base_TextBox)), //위
1601
    #endif
1602
                };
1603
                //instanceGroup.Children.Add(Generate(pCloud));
1604
                PathDataInner = (GenerateInner(pCloud));
1605
            }
1606 787a4489 KangIngu
        }
1607
1608 0d00f9c8 humkyung
        public override void UpdateControl()
1609 787a4489 KangIngu
        {
1610
            this.StartPoint = new Point(this.PointSet[0].X, this.PointSet[0].Y);
1611
            this.MidPoint = new Point(this.PointSet[1].X, this.PointSet[1].Y);
1612
            this.EndPoint = new Point(this.PointSet[2].X, this.PointSet[2].Y);
1613
        }
1614
1615 f513c215 humkyung
        public override void ApplyOverViewData()
1616 787a4489 KangIngu
        {
1617
            this.OverViewPathData = this.PathData;
1618
            if (ArrowText == "")
1619 1b2cf911 taeseongkim
            {
1620
                this.OverViewArrowText = "";
1621 787a4489 KangIngu
                this.ArrowText = this.OverViewArrowText;
1622 1b2cf911 taeseongkim
            }
1623 787a4489 KangIngu
            else
1624
                this.OverViewArrowText = this.ArrowText;
1625
            this.OverViewStartPoint = this.StartPoint;
1626
            this.OverViewEndPoint = this.EndPoint;
1627
        }
1628
1629
        #endregion
1630
1631
        public static PathFigure GenerateLineWithCloud(Point p1, Point p2, double arcLength_, bool reverse)
1632
        {
1633
            PathFigure pathFigure = new PathFigure();
1634
            pathFigure.StartPoint = p1;
1635
1636
            double arcLength = arcLength_;
1637
            /// draw arcs which has arcLength between p1 and p2 - 2012.06.21 added by humkyung 
1638
            double dx = p2.X - p1.X;
1639
            double dy = p2.Y - p1.Y;
1640
            double l = MathSet.DistanceTo(p1, p2); /// distance between p1 and p2
1641
            double theta = Math.Atan2(Math.Abs(dy), Math.Abs(dx)) * 180 / Math.PI;
1642
            Point lastPt = new Point(p1.X, p1.Y);
1643
            double count = l / arcLength;
1644
            /// normalize
1645
            dx /= l;
1646
            dy /= l;
1647
            Double j = 1;
1648 ca40e004 ljiyeon
            for (j = 1; j < (count - 1); j++) 
1649 787a4489 KangIngu
            {
1650
                ArcSegment arcSeg = new ArcSegment();
1651 53393bae KangIngu
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);						/// x size and y size of arc
1652 787a4489 KangIngu
                arcSeg.Point = new Point(p1.X + j * dx * arcLength, p1.Y + j * dy * arcLength);	/// end point of arc
1653
                lastPt = arcSeg.Point;  /// save last point
1654
                arcSeg.RotationAngle = theta + 90;
1655
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1656
                pathFigure.Segments.Add(arcSeg);
1657
            }
1658
1659
            /// draw arc between last point and end point
1660
            if ((count > j) || (count > 0))
1661
            {
1662
                arcLength = MathSet.DistanceTo(lastPt, p2);
1663
                ArcSegment arcSeg = new ArcSegment();
1664 53393bae KangIngu
                arcSeg.Size = new Size(arcLength * _CloudArcDepth, arcLength * _CloudArcDepth);	/// x size and y size of arc
1665 787a4489 KangIngu
                arcSeg.Point = new Point(p2.X, p2.Y);						/// end point of arc
1666
                arcSeg.RotationAngle = theta;
1667
                if (true == reverse) arcSeg.SweepDirection = SweepDirection.Clockwise;
1668
                pathFigure.Segments.Add(arcSeg);
1669
            }
1670
            /// up to here
1671
1672
            return pathFigure;
1673
        }
1674
1675 b79d6e7f humkyung
        public static PathGeometry Generate(List<Point> pData, double _ArcLength)
1676 787a4489 KangIngu
        {
1677
            var _pathGeometry = new PathGeometry();
1678 ca40e004 ljiyeon
            
1679 787a4489 KangIngu
            double area = MathSet.AreaOf(pData);
1680
            bool reverse = (area > 0);
1681
            int count = pData.Count;
1682
            for (int i = 0; i < (count - 1); i++)
1683
            {
1684 b79d6e7f humkyung
                PathFigure pathFigure = Polygon.CloudControl.GenerateLineWithCloud(pData[i], pData[i + 1], _ArcLength, reverse);
1685 787a4489 KangIngu
                pathFigure.IsClosed = false;
1686 43e1d368 taeseongkim
                pathFigure.IsFilled = false;
1687 787a4489 KangIngu
                _pathGeometry.Figures.Add(pathFigure);
1688
            }
1689 ca40e004 ljiyeon
            
1690 787a4489 KangIngu
            return _pathGeometry;
1691
        }
1692 ca40e004 ljiyeon
1693
        
1694 787a4489 KangIngu
        public static PathGeometry GenerateInner(List<Point> pData)
1695
        {
1696
            var _pathGeometry = new PathGeometry();
1697
            double area = MathSet.AreaOf(pData);
1698
            bool reverse = (area > 0);
1699
            int count = pData.Count;
1700
1701
            PathFigure pathFigur2 = new PathFigure();
1702
            pathFigur2.StartPoint = pData[0];
1703
1704
            LineSegment lineSegment0 = new LineSegment();
1705
            lineSegment0.Point = pData[0];
1706
            pathFigur2.Segments.Add(lineSegment0);
1707
1708
            LineSegment lineSegment1 = new LineSegment();
1709
            lineSegment1.Point = pData[1];
1710
            pathFigur2.Segments.Add(lineSegment1);
1711
1712
            LineSegment lineSegment2 = new LineSegment();
1713
            lineSegment2.Point = pData[2];
1714
            pathFigur2.Segments.Add(lineSegment2);
1715
1716
            LineSegment lineSegment3 = new LineSegment();
1717
            lineSegment3.Point = pData[3];
1718
            pathFigur2.Segments.Add(lineSegment3);
1719
1720
1721
            pathFigur2.IsClosed = true;
1722
            pathFigur2.IsFilled = true;
1723 ca40e004 ljiyeon
            _pathGeometry.Figures.Add(pathFigur2);           
1724 787a4489 KangIngu
1725
            return _pathGeometry;
1726
        }
1727
1728 ca40e004 ljiyeon
        //20180910 LJY Cloud rotation 추가
1729
        public static PathGeometry GenerateInnerCloud(List<Point> pData, string angle)
1730
        {
1731
            var _pathGeometry = new PathGeometry();
1732
            double area = MathSet.AreaOf(pData);
1733
            bool reverse = (area > 0);
1734
            int count = pData.Count;
1735
1736
            PathFigure pathFigur2 = new PathFigure();
1737
            pathFigur2.StartPoint = pData[0];
1738
1739
            LineSegment lineSegment0 = new LineSegment();
1740
            lineSegment0.Point = pData[0];
1741
            pathFigur2.Segments.Add(lineSegment0);
1742
1743
            LineSegment lineSegment1 = new LineSegment();
1744
            lineSegment1.Point = pData[1];
1745
            pathFigur2.Segments.Add(lineSegment1);
1746
1747
            LineSegment lineSegment2 = new LineSegment();
1748
            lineSegment2.Point = pData[2];
1749
            pathFigur2.Segments.Add(lineSegment2);
1750
1751
            LineSegment lineSegment3 = new LineSegment();
1752
            lineSegment3.Point = pData[3];
1753
            pathFigur2.Segments.Add(lineSegment3);
1754
            
1755
            RotateTransform transform = new RotateTransform();
1756
            switch (angle)
1757
            {
1758
                case "90":
1759
                    transform.Angle = -90;
1760
                    break;
1761
                case "180":
1762
                    transform.Angle = -180;
1763
                    break;
1764
                case "270":
1765
                    transform.Angle = -270;
1766
                    break;
1767
            }
1768
            transform.CenterX = pData[0].X;
1769
            transform.CenterY = pData[0].Y;
1770
            _pathGeometry.Transform = transform;
1771
1772
            pathFigur2.IsClosed = true;
1773
            pathFigur2.IsFilled = true;
1774
            _pathGeometry.Figures.Add(pathFigur2);
1775
1776
            return _pathGeometry;
1777 91efe37a humkyung
        }
1778
1779
        /// <summary>
1780 a6272c57 humkyung
        /// call when mouse is moving while drawing control
1781
        /// </summary>
1782
        /// <author>humkyung</author>
1783
        /// <param name="pt"></param>
1784
        /// <param name="bAxisLocked"></param>
1785 233ef333 taeseongkim
        public override void OnCreatingMouseMove(Point pt, bool bAxisLocked)
1786 a6272c57 humkyung
        {
1787
            this.EndPoint = pt;
1788
1789 168f8027 taeseongkim
            Point tempPoint = this.EndPoint;
1790 233ef333 taeseongkim
            CommentAngle = MathSet.returnAngle(this.StartPoint, ref tempPoint, bAxisLocked);
1791 168f8027 taeseongkim
1792 233ef333 taeseongkim
            if (bAxisLocked)
1793 a6272c57 humkyung
            {
1794
                this.EndPoint = tempPoint;
1795
            }
1796
1797
            this.MidPoint = MathSet.getMiddlePoint(this.StartPoint, this.EndPoint);
1798
            this.isFixed = (this.ControlType == ControlType.ArrowTransTextControl) || 
1799
                (this.ControlType == ControlType.ArrowTransTextBorderControl) || (this.ControlType == ControlType.ArrowTransTextCloudControl);
1800
1801
            this.PointSet = new List<Point>
1802
            {
1803
                this.StartPoint,
1804
                this.MidPoint,
1805
                this.EndPoint,
1806
            };
1807
        }
1808
1809
        /// <summary>
1810 d2114d3b humkyung
        /// move control point has same location of given pt along given delta
1811
        /// </summary>
1812
        /// <author>humkyung</author>
1813
        /// <date>2019.06.20</date>
1814
        /// <param name="pt"></param>
1815
        /// <param name="dx"></param>
1816
        /// <param name="dy"></param>
1817 233ef333 taeseongkim
        public override void OnMoveCtrlPoint(Point pt, double dx, double dy, bool bAxisLocked = false)
1818 d2114d3b humkyung
        {
1819
            IPath path = (this as IPath);
1820
1821
            Point selected = MathSet.getNearPoint(path.PointSet, pt);
1822 7575b5e5 송근호
1823 50e6a733 송근호
            //StartPoint에 표시된 Thumb는 dx,dy가 +로 더해줘야한다.
1824
            if (path.PointSet.IndexOf(selected) != 0)
1825 7575b5e5 송근호
            {
1826 fa48eb85 taeseongkim
                double radian = this.CommentAngle * Math.PI / 180;
1827 fb1e3af2 djkim
                double cos = Math.Cos(radian);
1828
                double sin = Math.Sin(radian);
1829 ac8521e2 송근호
1830 fb1e3af2 djkim
                double _dx = dx * cos - dy * sin;
1831
                double _dy = dx * sin + dy * cos;
1832
1833 39f208de taeseongkim
                //var transform = new RotateTransform() { Angle = CommentAngle, CenterX = dx, CenterY = dy };
1834
                //var transformedPoint = transform.Transform(pt);
1835
                //selected = transformedPoint;
1836
1837 fb1e3af2 djkim
                selected.X += _dx;
1838
                selected.Y += _dy;
1839 7575b5e5 송근호
            }
1840
            else
1841
            {
1842
                selected.X += dx;
1843
                selected.Y += dy;
1844
            }
1845
1846 b79d6e7f humkyung
            int i = 0;
1847 d2114d3b humkyung
            for (i = 0; i < (this as IPath).PointSet.Count; i++)
1848
            {
1849
                if (pt.Equals((this as IPath).PointSet[i])) break;
1850
            }
1851
1852
            List<Point> pts = path.PointSet;
1853
            if ((pts[0].X > pts[1].X && dx > 0) || (pts[0].X < pts[1].X && dx < 0))
1854
            {
1855
                pts[1] = new Point(pts[1].X + dx, pts[1].Y);
1856
            }
1857
            if ((pts[0].Y > pts[1].Y && dy > 0) || (pts[0].Y < pts[1].Y && dy < 0))
1858
            {
1859
                pts[1] = new Point(pts[1].X, pts[1].Y + dy);
1860
            }
1861 50e6a733 송근호
1862 d2114d3b humkyung
            path.PointSet[1] = pts[1];
1863 7575b5e5 송근호
1864
            if (path.PointSet.Count > i) {
1865
                path.PointSet[i] = selected;
1866
            }
1867 15bbef90 taeseongkim
            //System.Diagnostics.Debug.WriteLine($"OnMoveCtrlPoint end : {path.PointSet[1].X},{path.PointSet[1].Y}");
1868 0d00f9c8 humkyung
            this.UpdateControl();
1869 d2114d3b humkyung
        }
1870
1871
        /// <summary>
1872 91efe37a humkyung
        /// return ArrowTextControl's area
1873
        /// </summary>
1874
        /// <author>humkyung</author>
1875
        /// <date>2019.06.13</date>
1876
        public override Rect ItemRect
1877
        {
1878
            get
1879
            {
1880
                double dMinX = Math.Min(this.StartPoint.X, this.EndPoint.X);
1881
                double dMinY = Math.Min(this.StartPoint.Y, this.EndPoint.Y);
1882
                double dMaxX = Math.Max(this.StartPoint.X, this.EndPoint.X);
1883
                double dMaxY = Math.Max(this.StartPoint.Y, this.EndPoint.Y);
1884
1885
                return new Rect(new Point(dMinX, dMinY), new Point(dMaxX, dMaxY));
1886
            }
1887 ca40e004 ljiyeon
        }
1888 787a4489 KangIngu
1889 036650a0 humkyung
        /// <summary>
1890
        /// Serialize this
1891
        /// </summary>
1892
        /// <param name="sUserId"></param>
1893
        /// <returns></returns>
1894
        public override string Serialize()
1895
        {
1896
            using (S_ArrowTextControl STemp = new S_ArrowTextControl())
1897
            {
1898
                STemp.TransformPoint = "0|0";
1899
                STemp.PointSet = this.PointSet;
1900
                STemp.SizeSet = String.Format("{0}", this.LineSize);
1901
                STemp.StrokeColor = this.StrokeColor.Color.ToString();
1902
                STemp.StartPoint = this.StartPoint;
1903
                STemp.ArrowStyle = this.ArrowTextStyle;
1904
                //STemp.StrokeColor = "#FF00FF00";
1905
                STemp.UserID = this.UserID;
1906
                STemp.ArrowText = this.Base_TextBox.Text;
1907
                STemp.BorderSize = this.BorderSize;
1908
                STemp.isHighLight = this.isHighLight;
1909
                STemp.BoxHeight = this.BoxHeight;
1910
                STemp.BoxWidth = this.BoxWidth;
1911
                STemp.Opac = this.Opacity;
1912
                STemp.EndPoint = this.EndPoint;
1913
                STemp.isFixed = this.isFixed;
1914
                //STemp.DashSize = this.DashSize;
1915
                STemp.Name = this.GetType().Name.ToString();
1916
                STemp.isTrans = this.isTrans;
1917
                STemp.MidPoint = this.MidPoint;
1918 15bbef90 taeseongkim
                STemp.Angle = this.PageAngle;
1919 036650a0 humkyung
                STemp.fontConfig = new List<string>()
1920
                            {
1921 24c5e56c taeseongkim
                                this.TextFamily.FontName(),
1922 036650a0 humkyung
                                this.TextStyle.ToString(),
1923
                                this.TextWeight.ToString(),
1924
                                this.TextSize.ToString(),
1925
                            };
1926
1927
                if (this.UnderLine != null)
1928
                {
1929
                    STemp.fontConfig.Add("true");
1930
                }
1931
1932
                ///강인구 추가(2017.11.02)
1933
                ///Memo 추가
1934
                STemp.Memo = this.Memo;
1935
                STemp.BorderSize = this.BorderSize;
1936 7ad417d8 이지연
                STemp.ArcLength = this.ArcLength;
1937 036650a0 humkyung
                return "|DZ|" + JsonSerializerHelper.CompressString((STemp.JsonSerialize()));
1938
            };
1939
        }
1940
1941 661b7416 humkyung
        /// <summary>
1942
        /// create a arrowtextcontrol from given string
1943
        /// </summary>
1944
        /// <param name="str"></param>
1945
        /// <returns></returns>
1946 4f017ed3 taeseongkim
        public static ArrowTextControl FromString(string str, SolidColorBrush brush, string sProjectNo,double PageAngle)
1947 661b7416 humkyung
        {
1948
            ArrowTextControl instance = null;
1949
            using (S_ArrowTextControl s = JsonSerializerHelper.JsonDeserialize<S_ArrowTextControl>(str))
1950
            {
1951
                string[] data2 = s.SizeSet.Split(delimiterChars2, StringSplitOptions.RemoveEmptyEntries);
1952
                instance = new ArrowTextControl();
1953 4f017ed3 taeseongkim
                instance.PageAngle = s.Angle;
1954 661b7416 humkyung
                instance.LineSize = Convert.ToDouble(data2.First());
1955
                instance.PointSet = s.PointSet;
1956
                instance.StartPoint = s.StartPoint;
1957
                instance.EndPoint = s.EndPoint;
1958
                instance.StrokeColor = brush;
1959 4fcb686a taeseongkim
                //instance.DashSize = s.DashSize; 
1960 661b7416 humkyung
                instance.ArrowTextStyle = s.ArrowStyle;
1961
                instance.isHighLight = s.isHighLight;
1962
                instance.ArrowText = s.ArrowText;
1963
                instance.Opacity = s.Opac;
1964
                instance.BorderSize = s.BorderSize;
1965
                instance.BoxWidth = s.BoxWidth;
1966
                instance.BoxHeight = s.BoxHeight;
1967
                instance.isFixed = s.isFixed;
1968 4f017ed3 taeseongkim
                //instance.VisualPageAngle = s.Angle;
1969 661b7416 humkyung
                instance.UserID = s.UserID;
1970
                instance.isTrans = s.isTrans;
1971
                instance.MidPoint = s.MidPoint;
1972
                instance.Memo = s.Memo;
1973
                if (s.fontConfig == null || s.fontConfig.ToList().Count == 0)
1974
                {
1975
                    s.fontConfig = new List<string>();
1976
1977
                    s.fontConfig.Add("Arial");
1978
                    s.fontConfig.Add("Normal");
1979
                    s.fontConfig.Add("Normal");
1980
                    s.fontConfig.Add("30");
1981
                }
1982 24c5e56c taeseongkim
                instance.TextFamily = Markus.Fonts.FontHelper.GetFontFamily(s.fontConfig[0]);
1983 661b7416 humkyung
                //인구 추가(2018.04.17)
1984
                instance.TextStyle = StringToFont.ConFontStyle(s.fontConfig[1]);
1985
                instance.TextWeight = StringToFont.ConFontWeight(s.fontConfig[2]);
1986
                instance.TextSize = Convert.ToDouble(s.fontConfig[3]);
1987 7ad417d8 이지연
                instance.ArcLength = s.ArcLength;
1988 661b7416 humkyung
                if (s.fontConfig.Count() == 5)
1989
                {
1990
                    instance.UnderLine = TextDecorations.Underline;
1991
                }
1992
            }
1993
1994
            return instance;
1995
        }
1996
1997 787a4489 KangIngu
        #region Dispose
1998
        public void Dispose()
1999
        {
2000 a6f7f9b6 djkim
            //GC.Collect();
2001 24c5e56c taeseongkim
            ////GC.SuppressFinalize(this);
2002 a6f7f9b6 djkim
            this.BaseTextbox_Caret = null;
2003
            this.Base_ArrowPath = null;
2004
            this.Base_ArrowSubPath = null;
2005
            this.Base_TextBlock = null;
2006
            this.Base_TextBox = null;
2007 787a4489 KangIngu
        } 
2008
        #endregion
2009
2010
        #region INotifyPropertyChanged
2011
        private void OnPropertyChanged(string name)
2012
        {
2013
            if (PropertyChanged != null)
2014
            {
2015
                PropertyChanged(this, new PropertyChangedEventArgs(name));
2016
            }
2017
        }
2018
2019 3b938959 taeseongkim
        public Rect GetCommentRect()
2020
        {
2021
            Rect rect = new Rect();
2022
2023
            rect.Location = new Point();
2024
            rect.Size = new Size();
2025
2026
            List<Point> points = new List<Point>();
2027
2028
            points.AddRange(this.PointSet);
2029
2030
            var boxTopleft = new Point(Canvas.GetTop(Base_TextBox), Canvas.GetLeft(Base_TextBox));
2031
            points.Add(boxTopleft);
2032
2033
            var boxBottomRight =new Point(boxTopleft.X + Base_TextBox.ActualWidth, boxTopleft.Y + Base_TextBox.ActualHeight);
2034
            points.Add(boxBottomRight);
2035
2036
            rect = CommentMath.CalculateBoundingRect(points);
2037
2038
            return rect;
2039
        }
2040
2041 787a4489 KangIngu
        public event PropertyChangedEventHandler PropertyChanged; 
2042
        #endregion
2043
    }
2044
}
클립보드 이미지 추가 (최대 크기: 500 MB)