[NUI] Change DefaultBorder property (#6099)
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Window / DefaultBorder.cs
1 /*
2  * Copyright(c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using System;
19 using System.ComponentModel;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI;
22 using Tizen.NUI.Binding;
23
24 namespace Tizen.NUI
25 {
26     /// <summary>
27     /// This class creates a border UI.
28     /// </summary>
29     [EditorBrowsable(EditorBrowsableState.Never)]
30     public class DefaultBorder : BindableObject, IDisposable, IBorderInterface
31     {
32         static DefaultBorder()
33         {
34             if(NUIApplication.IsUsingXaml)
35             {
36                 BorderLineThicknessProperty = BindableProperty.Create(nameof(BorderLineThickness), typeof(uint), typeof(DefaultBorder), default(uint), propertyChanged: SetInternalBorderLineThicknessProperty, defaultValueCreator: GetInternalBorderLineThicknessProperty);
37                 
38                 MinSizeProperty = BindableProperty.Create(nameof(MinSize), typeof(Size2D), typeof(DefaultBorder), default(Size2D), propertyChanged: SetInternalMinSizeProperty, defaultValueCreator: GetInternalMinSizeProperty);
39                 
40                 MaxSizeProperty = BindableProperty.Create(nameof(MaxSize), typeof(Size2D), typeof(DefaultBorder), default(Size2D), propertyChanged: SetInternalMaxSizeProperty, defaultValueCreator: GetInternalMaxSizeProperty);
41                 
42                 ResizePolicyProperty = BindableProperty.Create(nameof(ResizePolicy), typeof(Window.BorderResizePolicyType), typeof(DefaultBorder), default(Window.BorderResizePolicyType), propertyChanged: SetInternalResizePolicyProperty, defaultValueCreator: GetInternalResizePolicyProperty);
43             }
44         }
45         #region Constant Fields
46         private static readonly string ResourcePath = FrameworkInformation.ResourcePath;
47         private static readonly string MinimalizeIcon = ResourcePath + "minimalize.png";
48         private static readonly string MaximalizeIcon = ResourcePath + "maximalize.png";
49         private static readonly string CloseIcon = ResourcePath + "close.png";
50         private static readonly string LeftCornerIcon = ResourcePath + "leftCorner.png";
51         private static readonly string RightCornerIcon = ResourcePath + "rightCorner.png";
52
53         private static readonly string DarkMinimalizeIcon = ResourcePath + "dark_minimalize.png";
54         private static readonly string DarkPreviousIcon = ResourcePath + "dark_smallwindow.png";
55         private static readonly string DarkCloseIcon = ResourcePath + "dark_close.png";
56         private static readonly string DarkLeftCornerIcon = ResourcePath + "dark_leftCorner.png";
57         private static readonly string DarkRightCornerIcon = ResourcePath + "dark_rightCorner.png";
58
59
60         private const float DefaultHeight = 50;
61         private const uint DefaultLineThickness = 5;
62         private const uint DefaultTouchThickness = 0;
63         private static readonly Color DefaultBackgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.6f);
64         private static readonly Color DefaultClickedBackgroundColor = new Color(0.7f, 0.7f, 0.7f, 0.7f);
65         private static readonly Size2D DefaultMinSize = new Size2D(100, 0);
66         #endregion //Constant Fields
67
68
69         #region Fields
70         private bool disposed = false;
71         private Color backgroundColor;
72         private View borderView;
73
74         private ImageView minimalizeIcon;
75         private ImageView maximalizeIcon;
76         private ImageView closeIcon;
77         private ImageView leftCornerIcon;
78         private ImageView rightCornerIcon;
79
80         private Window.BorderDirection direction = Window.BorderDirection.None;
81         private float preScale = 0;
82
83         private View windowView = null;
84         private Timer overlayTimer;
85
86         private uint borderLineThickness;
87         private Size2D minSize;
88         private Size2D maxSize;
89         private Window.BorderResizePolicyType resizePolicy;
90
91         #endregion //Fields
92
93         #region Events
94         private PanGestureDetector borderPanGestureDetector;
95         #endregion //Events
96
97         #region Enums
98         #endregion //Enums
99
100         #region Methods
101
102         [EditorBrowsable(EditorBrowsableState.Never)]
103         public static readonly BindableProperty BorderLineThicknessProperty = null;
104         
105         internal static void SetInternalBorderLineThicknessProperty(BindableObject bindable, object oldValue, object newValue)
106         {
107             var instance = (DefaultBorder)bindable;
108             if (newValue != null)
109             {
110                 instance.borderLineThickness = (uint)newValue;
111                 instance.UpdateProperty();
112             }
113         }
114         
115         internal static object GetInternalBorderLineThicknessProperty(BindableObject bindable)
116         {
117             var instance = (DefaultBorder)bindable;
118             return instance.borderLineThickness;
119         }
120
121         [EditorBrowsable(EditorBrowsableState.Never)]
122         public static readonly BindableProperty MinSizeProperty = null;
123         
124         internal static void SetInternalMinSizeProperty(BindableObject bindable, object oldValue, object newValue)
125         {
126             var instance = (DefaultBorder)bindable;
127             if (newValue != null)
128             {
129                 instance.minSize = (Size2D)newValue;
130                 instance.UpdateProperty();
131             }
132         }
133         
134         internal static object GetInternalMinSizeProperty(BindableObject bindable)
135         {
136             var instance = (DefaultBorder)bindable;
137             return instance.minSize;
138         }
139
140         [EditorBrowsable(EditorBrowsableState.Never)]
141         public static readonly BindableProperty MaxSizeProperty = null;
142         
143         internal static void SetInternalMaxSizeProperty(BindableObject bindable, object oldValue, object newValue)
144         {
145             var instance = (DefaultBorder)bindable;
146             if (newValue != null)
147             {
148                 instance.maxSize = (Size2D)newValue;
149                 instance.UpdateProperty();
150             }
151         }
152         
153         internal static object GetInternalMaxSizeProperty(BindableObject bindable)
154         {
155             var instance = (DefaultBorder)bindable;
156             return instance.maxSize;
157         }
158
159         [EditorBrowsable(EditorBrowsableState.Never)]
160         public static readonly BindableProperty ResizePolicyProperty = null;
161         
162         internal static void SetInternalResizePolicyProperty(BindableObject bindable, object oldValue, object newValue)
163         {
164             var instance = (DefaultBorder)bindable;
165             if (newValue != null)
166             {
167                 instance.resizePolicy = (Window.BorderResizePolicyType)newValue;
168                 instance.UpdateProperty();
169             }
170         }
171         
172         internal static object GetInternalResizePolicyProperty(BindableObject bindable)
173         {
174             var instance = (DefaultBorder)bindable;
175             return instance.resizePolicy;
176         }
177
178
179         /// <summary>
180         /// The thickness of the border.
181         /// </summary>
182         [EditorBrowsable(EditorBrowsableState.Never)]
183         public uint BorderLineThickness
184         {
185             get
186             {
187                 if (NUIApplication.IsUsingXaml)
188                 {
189                     return (uint)GetValue(BorderLineThicknessProperty);
190                 }
191                 else
192                 {
193                     return (uint)GetInternalBorderLineThicknessProperty(this);
194                 }
195             }
196             set
197             {
198                 if (NUIApplication.IsUsingXaml)
199                 {
200                     SetValue(BorderLineThicknessProperty, value);
201                 }
202                 else
203                 {
204                     SetInternalBorderLineThicknessProperty(this, null, value);
205                 }
206             }
207         }
208
209         /// <summary>
210         /// The thickness of the border's touch area.
211         /// </summary>
212         [EditorBrowsable(EditorBrowsableState.Never)]
213         public uint TouchThickness {get; set;}
214
215         /// <summary>
216         /// The height of the border.
217         /// This value is the initial value used when creating borders.
218         /// </summary>
219         [EditorBrowsable(EditorBrowsableState.Never)]
220         public float BorderHeight {get; set;}
221
222         /// <summary>
223         /// The minimum size by which the window will small.
224         /// </summary>
225         [EditorBrowsable(EditorBrowsableState.Never)]
226         public Size2D MinSize
227         {
228             get
229             {
230                 if (NUIApplication.IsUsingXaml)
231                 {
232                     return (Size2D)GetValue(MinSizeProperty);
233                 }
234                 else
235                 {
236                     return (Size2D)GetInternalMinSizeProperty(this);
237                 }
238             }
239             set
240             {
241                 if (NUIApplication.IsUsingXaml)
242                 {
243                     SetValue(MinSizeProperty, value);
244                 }
245                 else
246                 {
247                     SetInternalMinSizeProperty(this, null, value);
248                 }
249             }
250         }
251
252         /// <summary>
253         /// The maximum size by which the window will big.
254         /// </summary>
255         [EditorBrowsable(EditorBrowsableState.Never)]
256         public Size2D MaxSize
257         {
258             get
259             {
260                 if (NUIApplication.IsUsingXaml)
261                 {
262                     return (Size2D)GetValue(MaxSizeProperty);
263                 }
264                 else
265                 {
266                     return (Size2D)GetInternalMaxSizeProperty(this);
267                 }
268             }
269             set
270             {
271                 if (NUIApplication.IsUsingXaml)
272                 {
273                     SetValue(MaxSizeProperty, value);
274                 }
275                 else
276                 {
277                     SetInternalMaxSizeProperty(this, null, value); 
278                 }
279             }
280         }
281
282         /// <summary>
283         /// The window with borders added.
284         /// </summary>
285         [EditorBrowsable(EditorBrowsableState.Never)]
286         public Window BorderWindow {get; set;}
287
288         /// <summary>
289         /// Whether overlay mode.
290         /// If overlay mode is true, the border area is hidden when the window is maximized.
291         /// And if you touched at screen, the border area is shown on the screen.
292         /// Default value is false;
293         /// </summary>
294         [EditorBrowsable(EditorBrowsableState.Never)]
295         public bool OverlayMode {get; set;}
296
297         /// <summary>
298         /// Set the window resizing policy.
299         /// Default value is BorderResizePolicyType.Free;
300         /// </summary>
301         [EditorBrowsable(EditorBrowsableState.Never)]
302         public Window.BorderResizePolicyType ResizePolicy
303         {
304             get
305             {
306                 if (NUIApplication.IsUsingXaml)
307                 {
308                     return (Window.BorderResizePolicyType)GetValue(ResizePolicyProperty);
309                 }
310                 else
311                 {
312                     return (Window.BorderResizePolicyType)GetInternalResizePolicyProperty(this);
313                 }
314             }
315             set
316             {
317                 if (NUIApplication.IsUsingXaml)
318                 {
319                     SetValue(ResizePolicyProperty, value);
320                 }
321                 else
322                 {
323                     SetInternalResizePolicyProperty(this, null, value);
324                 }
325             }
326         }
327
328         /// <summary>
329         /// Update properties
330         /// </summary>
331         [EditorBrowsable(EditorBrowsableState.Never)]
332         public void UpdateProperty()
333         {
334             BorderWindow?.UpdateProperty();
335         }
336
337         /// <summary>
338         /// Creates a default border
339         /// </summary>
340         [EditorBrowsable(EditorBrowsableState.Never)]
341         public DefaultBorder() : base()
342         {
343             BorderLineThickness = DefaultLineThickness;
344             TouchThickness = DefaultTouchThickness;
345             BorderHeight = DefaultHeight;
346             MinSize = DefaultMinSize;
347             OverlayMode = false;
348             ResizePolicy = Window.BorderResizePolicyType.Free;
349         }
350
351         /// <summary>
352         /// Create top border UI. User can override this method to draw top border UI.
353         /// </summary>
354         /// <param name="topView">The top view on which the border.</param>
355         [EditorBrowsable(EditorBrowsableState.Never)]
356         public virtual bool CreateTopBorderView(View topView)
357         {
358             return false;
359         }
360
361         /// <summary>
362         /// Create bottom border UI. User can override this method to draw bottom border UI.
363         /// </summary>
364         /// <param name="bottomView">The bottom view on which the border.</param>
365         [EditorBrowsable(EditorBrowsableState.Never)]
366         public virtual bool CreateBottomBorderView(View bottomView)
367         {
368             if (bottomView == null)
369             {
370                 return false;
371             }
372             bottomView.Layout = new RelativeLayout();
373
374             minimalizeIcon = new ImageView()
375             {
376                 Focusable = true,
377                 ResourceUrl = MinimalizeIcon,
378                 AccessibilityHighlightable = true,
379             };
380
381             maximalizeIcon = new ImageView()
382             {
383                 Focusable = true,
384                 ResourceUrl = MaximalizeIcon,
385                 AccessibilityHighlightable = true,
386             };
387
388             closeIcon = new ImageView()
389             {
390                 Focusable = true,
391                 ResourceUrl = CloseIcon,
392                 AccessibilityHighlightable = true,
393             };
394
395             leftCornerIcon = new ImageView()
396             {
397                 Focusable = true,
398                 ResourceUrl = LeftCornerIcon,
399                 AccessibilityHighlightable = true,
400             };
401
402             rightCornerIcon = new ImageView()
403             {
404                 Focusable = true,
405                 ResourceUrl = RightCornerIcon,
406                 AccessibilityHighlightable = true,
407             };
408
409             RelativeLayout.SetRightTarget(minimalizeIcon, maximalizeIcon);
410             RelativeLayout.SetRightRelativeOffset(minimalizeIcon, 0.0f);
411             RelativeLayout.SetHorizontalAlignment(minimalizeIcon, RelativeLayout.Alignment.End);
412             RelativeLayout.SetRightTarget(maximalizeIcon, closeIcon);
413             RelativeLayout.SetRightRelativeOffset(maximalizeIcon, 0.0f);
414             RelativeLayout.SetHorizontalAlignment(maximalizeIcon, RelativeLayout.Alignment.End);
415             RelativeLayout.SetRightTarget(closeIcon, rightCornerIcon);
416             RelativeLayout.SetRightRelativeOffset(closeIcon, 0.0f);
417             RelativeLayout.SetHorizontalAlignment(closeIcon, RelativeLayout.Alignment.End);
418             RelativeLayout.SetRightRelativeOffset(rightCornerIcon, 1.0f);
419             RelativeLayout.SetHorizontalAlignment(rightCornerIcon, RelativeLayout.Alignment.End);
420             bottomView.Add(leftCornerIcon);
421             bottomView.Add(minimalizeIcon);
422             bottomView.Add(maximalizeIcon);
423             bottomView.Add(closeIcon);
424             bottomView.Add(rightCornerIcon);
425
426
427             minimalizeIcon.TouchEvent += OnMinimizeIconTouched;
428             maximalizeIcon.TouchEvent += OnMaximizeIconTouched;
429             closeIcon.TouchEvent += OnCloseIconTouched;
430             leftCornerIcon.TouchEvent += OnLeftBottomCornerIconTouched;
431             rightCornerIcon.TouchEvent += OnRightBottomCornerIconTouched;
432
433             minimalizeIcon.AccessibilityActivated += (s, e) =>
434             {
435                 MinimizeBorderWindow();
436             };
437             maximalizeIcon.AccessibilityActivated += (s, e) =>
438             {
439                 MaximizeBorderWindow();
440             };
441             closeIcon.AccessibilityActivated += (s, e) =>
442             {
443                 CloseBorderWindow();
444             };
445
446             minimalizeIcon.AccessibilityNameRequested += (s, e) =>
447             {
448                 e.Name = "Minimize";
449             };
450             maximalizeIcon.AccessibilityNameRequested += (s, e) =>
451             {
452                 e.Name = "Maximize";
453             };
454             closeIcon.AccessibilityNameRequested += (s, e) =>
455             {
456                 e.Name = "Close";
457             };
458             leftCornerIcon.AccessibilityNameRequested += (s, e) =>
459             {
460                 e.Name = "Resize";
461             };
462             rightCornerIcon.AccessibilityNameRequested += (s, e) =>
463             {
464                 e.Name = "Resize";
465             };
466
467             minimalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
468             maximalizeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
469             closeIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
470             leftCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
471             rightCornerIcon.SetAccessibilityReadingInfoTypes(Tizen.NUI.BaseComponents.AccessibilityReadingInfoTypes.Name);
472
473             return true;
474         }
475
476
477         /// <summary>
478         /// Create border UI. User can override this method to draw border UI.
479         /// A top border and a bottom border are added to this view.
480         /// </summary>
481         /// <param name="borderView">The root view on which the border.</param>
482         [EditorBrowsable(EditorBrowsableState.Never)]
483         public virtual void CreateBorderView(View borderView)
484         {
485             if (borderView == null)
486             {
487                 return;
488             }
489
490             if (string.IsNullOrEmpty(borderView.BackgroundImage))
491             {
492                 borderView.BackgroundColor = DefaultBackgroundColor;
493             }
494             borderView.BorderlineColor = new Color(0.5f, 0.5f, 0.5f, 0.3f);
495             borderView.BorderlineWidth = 1.0f;
496             borderView.BorderlineOffset = -1f;
497             borderView.CornerRadius = new Vector4(0.03f, 0.03f, 0.03f, 0.03f);
498             borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative;
499
500             // Register touch event for effect when border is touched.
501             borderView.LeaveRequired = true;
502             borderView.TouchEvent += OnBorderViewTouched;
503             this.borderView = borderView;
504         }
505
506         private bool OnBorderViewTouched(object sender, View.TouchEventArgs e)
507         {
508             if (string.IsNullOrEmpty(borderView.BackgroundImage))
509             {
510                 if (e.Touch.GetState(0) == PointStateType.Started)
511                 {
512                     backgroundColor = new Color(borderView.BackgroundColor);
513                     borderView.BackgroundColor = DefaultClickedBackgroundColor;
514                 }
515                 else if (e.Touch.GetState(0) == PointStateType.Finished ||
516                         e.Touch.GetState(0) == PointStateType.Leave ||
517                         e.Touch.GetState(0) == PointStateType.Interrupted)
518                 {
519                     borderView.BackgroundColor = backgroundColor;
520                 }
521             }
522             return true;
523         }
524
525         /// Determines the behavior of pinch gesture.
526         private void OnPinchGestureDetected(object source, PinchGestureDetector.DetectedEventArgs e)
527         {
528             if (e == null)
529             {
530                 return;
531             }
532             if (e.PinchGesture.State == Gesture.StateType.Started)
533             {
534                 preScale = e.PinchGesture.Scale;
535             }
536             else if (e.PinchGesture.State == Gesture.StateType.Finished || e.PinchGesture.State == Gesture.StateType.Cancelled)
537             {
538                 if (preScale > e.PinchGesture.Scale)
539                 {
540                     if (BorderWindow.IsMaximized())
541                     {
542                         BorderWindow.Maximize(false);
543                     }
544                     else
545                     {
546                         BorderWindow.Minimize(true);
547                         OnMinimize(true);
548                     }
549                 }
550                 else
551                 {
552                     BorderWindow.Maximize(true);
553                 }
554             }
555         }
556
557         /// Determines the behavior of borders.
558         private void OnPanGestureDetected(object source, PanGestureDetector.DetectedEventArgs e)
559         {
560             if (e == null)
561             {
562                 return;
563             }
564             PanGesture panGesture = e.PanGesture;
565
566             if (panGesture.State == Gesture.StateType.Started && panGesture.Position != null)
567             {
568                 direction = BorderWindow.GetDirection(panGesture.Position.X, panGesture.Position.Y);
569
570                 if (direction == Window.BorderDirection.Move)
571                 {
572                     if (BorderWindow.IsMaximized() == true)
573                     {
574                         BorderWindow.Maximize(false);
575                     }
576                     else
577                     {
578                         OnRequestMove();
579                         BorderWindow.RequestMoveToServer();
580                     }
581                 }
582                 else if (direction != Window.BorderDirection.None && ResizePolicy != Window.BorderResizePolicyType.Fixed)
583                 {
584                     OnRequestResize();
585                     BorderWindow.RequestResizeToServer((Window.ResizeDirection)direction);
586                 }
587             }
588             else if (panGesture.State == Gesture.StateType.Finished || panGesture.State == Gesture.StateType.Cancelled)
589             {
590                 direction = Window.BorderDirection.None;
591             }
592         }
593
594         /// <summary>
595         /// This is an event callback when the left top corner icon is touched.
596         /// </summary>
597         [EditorBrowsable(EditorBrowsableState.Never)]
598         public virtual bool OnLeftTopCornerIconTouched(object sender, View.TouchEventArgs e)
599         {
600             SetDispatchParentGestureEvents(sender as View, false);
601             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
602             {
603               if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
604               {
605                 OnRequestResize();
606                 BorderWindow.RequestResizeToServer(Window.ResizeDirection.TopLeft);
607               }
608             }
609             return true;
610         }
611
612         /// <summary>
613         ///This is an event callback when the right bottom corner icon is touched.
614         /// </summary>
615         [EditorBrowsable(EditorBrowsableState.Never)]
616         public virtual bool OnRightTopCornerIconTouched(object sender, View.TouchEventArgs e)
617         {
618             SetDispatchParentGestureEvents(sender as View, false);
619             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
620             {
621               if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
622               {
623                 OnRequestResize();
624                 BorderWindow.RequestResizeToServer(Window.ResizeDirection.TopRight);
625               }
626             }
627             return true;
628         }
629
630
631         /// <summary>
632         /// This is an event callback when the left bottom corner icon is touched.
633         /// </summary>
634         [EditorBrowsable(EditorBrowsableState.Never)]
635         public virtual bool OnLeftBottomCornerIconTouched(object sender, View.TouchEventArgs e)
636         {
637             SetDispatchParentGestureEvents(sender as View, false);
638             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
639             {
640               if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
641               {
642                 OnRequestResize();
643                 BorderWindow.RequestResizeToServer(Window.ResizeDirection.BottomLeft);
644               }
645             }
646             return true;
647         }
648
649         /// <summary>
650         ///This is an event callback when the right bottom corner icon is touched.
651         /// </summary>
652         [EditorBrowsable(EditorBrowsableState.Never)]
653         public virtual bool OnRightBottomCornerIconTouched(object sender, View.TouchEventArgs e)
654         {
655             SetDispatchParentGestureEvents(sender as View, false);
656             if (e != null && e.Touch.GetState(0) == PointStateType.Down)
657             {
658               if (ResizePolicy != Window.BorderResizePolicyType.Fixed)
659               {
660                 OnRequestResize();
661                 BorderWindow.RequestResizeToServer(Window.ResizeDirection.BottomRight);
662               }
663             }
664             return true;
665         }
666
667
668         /// <summary>
669         /// Minimize border window.
670         /// </summary>
671         [EditorBrowsable(EditorBrowsableState.Never)]
672         protected void MinimizeBorderWindow()
673         {
674             BorderWindow.Minimize(true);
675             OnMinimize(true);
676         }
677
678         /// <summary>
679         /// This is an event callback when the minimize icon is touched.
680         /// </summary>
681         [EditorBrowsable(EditorBrowsableState.Never)]
682         public virtual bool OnMinimizeIconTouched(object sender, View.TouchEventArgs e)
683         {
684             SetDispatchParentGestureEvents(sender as View, false);
685             if (e != null && e.Touch.GetState(0) == PointStateType.Up)
686             {
687                 MinimizeBorderWindow();
688             }
689             return true;
690         }
691
692         /// <summary>
693         /// Maximize border window.
694         /// </summary>
695         [EditorBrowsable(EditorBrowsableState.Never)]
696         protected void MaximizeBorderWindow()
697         {
698             if (BorderWindow.IsMaximized())
699             {
700               BorderWindow.Maximize(false);
701             }
702             else
703             {
704               BorderWindow.Maximize(true);
705             }
706         }
707
708         /// <summary>
709         /// This is an event callback when the maximum icon is touched.
710         /// </summary>
711         [EditorBrowsable(EditorBrowsableState.Never)]
712         public virtual bool OnMaximizeIconTouched(object sender, View.TouchEventArgs e)
713         {
714             SetDispatchParentGestureEvents(sender as View, false);
715             if (e != null && e.Touch.GetState(0) == PointStateType.Up)
716             {
717                 MaximizeBorderWindow();
718             }
719             return true;
720         }
721
722         /// <summary>
723         /// Close border window.
724         /// </summary>
725         [EditorBrowsable(EditorBrowsableState.Never)]
726         protected void CloseBorderWindow()
727         {
728             BorderWindow.BorderDestroy();
729         }
730
731         /// <summary>
732         /// This is an event callback when the close icon is touched.
733         /// </summary>
734         [EditorBrowsable(EditorBrowsableState.Never)]
735         public virtual bool OnCloseIconTouched(object sender, View.TouchEventArgs e)
736         {
737             SetDispatchParentGestureEvents(sender as View, false);
738             if (e != null && e.Touch.GetState(0) == PointStateType.Up)
739             {
740                 CloseBorderWindow();
741             }
742             return true;
743         }
744
745         private void SetDispatchParentGestureEvents(View view, bool dispatch)
746         {
747             if (view != null)
748             {
749                 // If this is set, my parents will not receive gesture events.
750                 // This is to prevent the move action by PanGesture when the icon is touched.
751                 view.DispatchParentGestureEvents = dispatch;
752             }
753         }
754
755
756         private void UpdateIcons()
757         {
758             if (BorderWindow != null && borderView != null)
759             {
760                 if (BorderWindow.IsMaximized() == true)
761                 {
762                     if (maximalizeIcon != null)
763                     {
764                         maximalizeIcon.ResourceUrl = DarkPreviousIcon;
765                     }
766                     if (minimalizeIcon != null)
767                     {
768                         minimalizeIcon.ResourceUrl = DarkMinimalizeIcon;
769                     }
770                     if (closeIcon != null)
771                     {
772                         closeIcon.ResourceUrl = DarkCloseIcon;
773                     }
774                     if (leftCornerIcon != null)
775                     {
776                         leftCornerIcon.ResourceUrl = DarkLeftCornerIcon;
777                     }
778                     if (rightCornerIcon != null)
779                     {
780                         rightCornerIcon.ResourceUrl = DarkRightCornerIcon;
781                     }
782                     borderView.CornerRadius = new Vector4(0, 0, 0, 0);
783                     borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative;
784                 }
785                 else
786                 {
787                     if (maximalizeIcon != null)
788                     {
789                         maximalizeIcon.ResourceUrl = MaximalizeIcon;
790                     }
791                     if (minimalizeIcon != null)
792                     {
793                         minimalizeIcon.ResourceUrl = MinimalizeIcon;
794                     }
795                     if (closeIcon != null)
796                     {
797                         closeIcon.ResourceUrl = CloseIcon;
798                     }
799                     if (leftCornerIcon != null)
800                     {
801                         leftCornerIcon.ResourceUrl = LeftCornerIcon;
802                     }
803                     if (rightCornerIcon != null)
804                     {
805                         rightCornerIcon.ResourceUrl = RightCornerIcon;
806                     }
807                     borderView.CornerRadius = new Vector4(0.03f, 0.03f, 0.03f, 0.03f);
808                     borderView.CornerRadiusPolicy = VisualTransformPolicyType.Relative;
809                 }
810             }
811         }
812
813         /// <summary>
814         /// Called after the border UI is created.
815         /// </summary>
816         /// <param name="borderView">The border view on which the border.</param>
817         [EditorBrowsable(EditorBrowsableState.Never)]
818         public virtual void OnCreated(View borderView)
819         {
820             if (borderView == null)
821             {
822                 return;
823             }
824             this.borderView = borderView;
825
826             BorderWindow.BackgroundColor = Color.Transparent;
827
828             // Register to resize and move through pan gestures.
829             borderPanGestureDetector = new PanGestureDetector();
830             borderPanGestureDetector.Attach(borderView);
831             borderPanGestureDetector.Detected += OnPanGestureDetected;
832
833             UpdateIcons();
834         }
835
836         /// <summary>
837         /// Called when requesting a resize
838         /// </summary>
839         [EditorBrowsable(EditorBrowsableState.Never)]
840         public virtual void OnRequestResize() {}
841
842         /// <summary>
843         /// Called when the window is resized.
844         /// </summary>
845         /// <param name="width">The width of the resized window</param>
846         /// <param name="height">The height of the resized window</param>
847         [EditorBrowsable(EditorBrowsableState.Never)]
848         public virtual void OnResized(int width, int height)
849         {
850             if (overlayTimer != null)
851             {
852                 overlayTimer.Stop();
853                 overlayTimer.Dispose();
854                 overlayTimer = null;
855             }
856             UpdateIcons();
857         }
858
859         /// <summary>
860         /// Called when requesting a move
861         /// </summary>
862         [EditorBrowsable(EditorBrowsableState.Never)]
863         public virtual void OnRequestMove() {}
864
865         /// <summary>
866         /// Called when the window is moved.
867         /// </summary>
868         /// <param name="x">The x of the moved window</param>
869         /// <param name="y">The y of the moved window</param>
870         [EditorBrowsable(EditorBrowsableState.Never)]
871         public virtual void OnMoved(int x, int y) {}
872
873         /// <summary>
874         /// Called when window has been moved the display server.
875         /// </summary>
876         /// <param name="x">The x of the has been moved window</param>
877         /// <param name="y">The y of the has been moved window</param>
878         [EditorBrowsable(EditorBrowsableState.Never)]
879         public virtual void OnMoveCompleted(int x, int y) {}
880
881         /// <summary>
882         /// Called when window has been resized the display server.
883         /// </summary>
884         /// <param name="width">The width of the resized window</param>
885         /// <param name="height">The height of the resized window</param>
886         [EditorBrowsable(EditorBrowsableState.Never)]
887         public virtual void OnResizeCompleted(int width, int height) {}
888
889         /// <summary>
890         /// Called when the window is maximized.
891         /// </summary>
892         /// <param name="isMaximized">If window is maximized or unmaximized.</param>
893         [EditorBrowsable(EditorBrowsableState.Never)]
894         public virtual void OnMaximize(bool isMaximized)
895         {
896             Tizen.Log.Info("NUI", $"OnMaximize {isMaximized}\n");
897             if (BorderWindow.IsMaximized() == true)
898             {
899                 BorderWindow.SetTransparency(false);
900             }
901             else
902             {
903                 BorderWindow.SetTransparency(true);
904             }
905
906         }
907
908         /// <summary>
909         /// Called when the window is minimized.
910         /// </summary>
911         /// <param name="isMinimized">If window is mnimized or unminimized.</param>
912         [EditorBrowsable(EditorBrowsableState.Never)]
913         public virtual void OnMinimize(bool isMinimized)
914         {
915             UpdateIcons();
916         }
917
918         /// <summary>
919         /// Called when there is a change in overlay mode.
920         /// </summary>
921         /// <param name="enabled">If true, borderView has entered overlayMode.</param>
922         [EditorBrowsable(EditorBrowsableState.Never)]
923         public virtual void OnOverlayMode(bool enabled)
924         {
925             if (borderView != null && OverlayMode == true)
926             {
927                 Tizen.Log.Info("NUI", $"OnOverlayMode {enabled}\n");
928                 if (enabled == true)
929                 {
930                     backgroundColor = new Color(borderView.BackgroundColor);
931                     if (string.IsNullOrEmpty(borderView.BackgroundImage))
932                     {
933                         borderView.BackgroundColor = Color.Transparent;
934                     }
935                     borderView.Hide();
936                 }
937                 else
938                 {
939                     if (string.IsNullOrEmpty(borderView.BackgroundImage))
940                     {
941                         borderView.BackgroundColor = backgroundColor;
942                     }
943                     borderView.Show();
944                 }
945             }
946         }
947
948         /// <summary>
949         /// Show the border when OverlayMode is true and the window is now Maximize.
950         /// </summary>
951         /// <param name="time">Time(ms) for borders to disappear again</param>
952         /// <returns>True if border became show, false otherwise</returns>
953         [EditorBrowsable(EditorBrowsableState.Never)]
954         public virtual bool OverlayBorderShow(uint time = 3000)
955         {
956             if (BorderWindow != null && BorderWindow.IsMaximized())
957             {
958                 if (overlayTimer == null)
959                 {
960                     overlayTimer = new Timer(time);
961                     overlayTimer.Tick += (s, e) =>
962                     {
963                         borderView?.Hide();
964                         overlayTimer?.Stop();
965                         overlayTimer?.Dispose();
966                         overlayTimer = null;
967                         return false;
968                     };
969                     overlayTimer.Start();
970                     borderView?.Show();
971                 }
972                 else
973                 {
974                     overlayTimer.Start();
975                 }
976                 return true;
977             }
978             return false;
979         }
980
981         /// <summary>
982         /// Hide the border when OverlayMode is true and the window is now Maximize.
983         /// </summary>
984         /// <returns>True if border became hide, false otherwise</returns>
985         [EditorBrowsable(EditorBrowsableState.Never)]
986         public virtual bool OverlayBorderHide()
987         {
988             if (BorderWindow != null && BorderWindow.IsMaximized())
989             {
990                 borderView?.Hide();
991                 overlayTimer?.Stop();
992                 overlayTimer?.Dispose();
993                 overlayTimer = null;
994                 return true;
995             }
996             return false;
997         }
998
999         [EditorBrowsable(EditorBrowsableState.Never)]
1000         public void Dispose()
1001         {
1002             Dispose(true);
1003             global::System.GC.SuppressFinalize(this);
1004         }
1005
1006         protected virtual void Dispose(bool disposing)
1007         {
1008             if (disposed)
1009             {
1010                 return;
1011             }
1012
1013             if (disposing)
1014             {
1015                 borderView?.Dispose();
1016                 windowView?.Dispose();
1017                 borderPanGestureDetector?.Dispose();
1018                 backgroundColor?.Dispose();
1019                 minimalizeIcon?.Dispose();
1020                 maximalizeIcon?.Dispose();
1021                 closeIcon?.Dispose();
1022                 leftCornerIcon?.Dispose();
1023                 rightCornerIcon?.Dispose();
1024                 overlayTimer?.Dispose();
1025             }
1026             disposed = true;
1027         }
1028
1029         #endregion //Methods
1030
1031     }
1032 }