3b0cc1b23e44e07c5041b470efd2dfebb3510afe
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Window / BorderWindow.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 extern alias TizenSystemInformation;
18 using TizenSystemInformation.Tizen.System;
19
20 using System;
21 using System.Collections.Generic;
22 using System.ComponentModel;
23 using System.Linq;
24 using System.Threading;
25 using Tizen.NUI.BaseComponents;
26
27 namespace Tizen.NUI
28 {
29     public partial class Window
30     {
31         #region Constant Fields
32         #endregion //Constant Fields
33
34         #region Fields
35         private IBorderInterface borderInterface = null;
36         private Layer borderWindowRootLayer = null;
37         private Layer borderWindowBottomLayer = null;
38
39         // for border area
40         private View rootView = null;
41         private BorderView borderView = null;
42         private View topView = null;
43         private View contentsView = null;
44         private View bottomView = null;
45         private float borderHeight = 0;
46         private int screenWidth = 0;
47         private int screenHeight = 0;
48
49         private bool isBorderWindow = false;
50         private bool hasTopView = false;
51         private bool hasBottomView = false;
52         private bool isEnabledOverlayMode = false;
53         private bool isMaximized = false;
54
55         // for config
56         private Size2D minSize = null;
57         private Size2D maxSize = null;
58         private uint borderLineThickness = 0;
59         private BorderResizePolicyType borderResizePolicy = BorderResizePolicyType.Free;
60         #endregion //Fields
61
62         #region Constructors
63         #endregion //Constructors
64
65         #region Distructors
66         #endregion //Distructors
67
68         #region Delegates
69         internal delegate void BorderCloseDelegate();
70         private BorderCloseDelegate borderCloseDelegate = null;
71
72         #endregion //Delegates
73
74         #region Events
75         #endregion //Events
76
77         #region Enums
78         /// <summary>
79         /// This is an enum for the resize direction or move value when the border area is touched.
80         /// </summary>
81         [EditorBrowsable(EditorBrowsableState.Never)]
82         public enum BorderDirection
83         {
84             None        = ResizeDirection.None,
85             TopLeft     = ResizeDirection.TopLeft,
86             Top         = ResizeDirection.Top,
87             TopRight    = ResizeDirection.TopRight,
88             Left        = ResizeDirection.Left,
89             Right       = ResizeDirection.Right,
90             BottomLeft  = ResizeDirection.BottomLeft,
91             Bottom      = ResizeDirection.Bottom,
92             BottomRight = ResizeDirection.BottomRight,
93             Move,
94         }
95
96         /// <summary>
97         /// This enum is the policy when resizing the border window.
98         /// </summary>
99         [EditorBrowsable(EditorBrowsableState.Never)]
100         public enum BorderResizePolicyType
101         {
102           /// <summary>
103           /// The window can be resized freely.
104           /// </summary>
105           Free = 0,
106           /// <summary>
107           /// The window is resized according to the ratio.
108           /// </summary>
109           KeepRatio = 1,
110           /// <summary>
111           /// The window is not resized and is fixed.
112           /// </summary>
113           Fixed = 2,
114         }
115         #endregion //Enums
116
117         #region Interfaces
118         #endregion //Interfaces
119
120         #region Properties
121         /// <summary>
122         /// Whether the border is enabled.
123         /// </summary>
124         [EditorBrowsable(EditorBrowsableState.Never)]
125         public bool IsBorderEnabled => isBorderWindow;
126         #endregion //Properties
127
128         #region Indexers
129         #endregion //Indexers
130
131         #region Methods
132
133         /// <summary>
134         /// Update BorderProperty
135         /// </summary>
136         internal void UpdateProperty()
137         {
138             if (borderInterface != null)
139             {
140                 bool isNeedResizeByLine = false;
141                 bool isNeedResizeByBorder = false;
142                 using var val = new Uint16Pair(Interop.Window.GetSize(SwigCPtr), true);
143                 if (borderLineThickness != borderInterface.BorderLineThickness)
144                 {
145                     isNeedResizeByLine = true;
146                     int diffBorderLine = (int)borderInterface.BorderLineThickness - (int)borderLineThickness;
147                     borderLineThickness = borderInterface.BorderLineThickness;
148
149                     if (borderView != null)
150                     {
151                         Extents extents = borderView.Padding;
152                         ushort start = (extents.Start + diffBorderLine) > 0 ? (ushort)(extents.Start + diffBorderLine) : (ushort)0;
153                         ushort end = (extents.End + diffBorderLine) > 0 ? (ushort)(extents.End + diffBorderLine) : (ushort)0;
154                         ushort top = (extents.Top + diffBorderLine) > 0 ? (ushort)(extents.Top + diffBorderLine) : (ushort)0;
155                         ushort bottom = (extents.Bottom + diffBorderLine) > 0 ? (ushort)(extents.Bottom + diffBorderLine) : (ushort)0;
156                         borderView.Padding = new Extents(start, end, top, bottom);
157                         if (IsMaximized() == true)
158                         {
159                             borderView.OnMaximize(true);
160                         }
161                     }
162
163                     val.SetWidth((ushort)(val.GetWidth() + diffBorderLine * 2));
164                     val.SetHeight((ushort)(val.GetHeight() + diffBorderLine * 2));
165                 }
166
167                 float height = 0;
168                 if (hasTopView) height += topView.SizeHeight;
169                 if (hasBottomView) height += bottomView.SizeHeight;
170                 if (height != borderHeight)
171                 {
172                     isNeedResizeByBorder = true;
173                     float diff = height - borderHeight;
174                     borderHeight = height;
175                     val.SetHeight((ushort)(val.GetHeight() + diff));
176                 }
177
178                 if (isNeedResizeByLine == true || isNeedResizeByBorder == true)
179                 {
180                     Interop.Window.SetSize(SwigCPtr, Uint16Pair.getCPtr(val));
181                 }
182
183                 if (minSize != borderInterface.MinSize || (borderInterface.MinSize != null && isNeedResizeByLine == true))
184                 {
185                     using Size2D mimimumSize = new Size2D((borderInterface.MinSize?.Width + (int)borderLineThickness * 2 ?? 0), (borderInterface.MinSize?.Height ?? 0) + (int)(borderHeight + borderLineThickness * 2));
186                     SetMimimumSize(mimimumSize);
187                     minSize = borderInterface.MinSize;
188                 }
189                 
190                 if (maxSize != borderInterface.MaxSize || (borderInterface.MaxSize != null && isNeedResizeByLine == true))
191                 {
192                     using Size2D maximumSize = new Size2D((borderInterface.MaxSize?.Width + (int)borderLineThickness * 2 ?? 0), (borderInterface.MaxSize?.Height ?? 0) + (int)(borderHeight + borderLineThickness * 2));
193                     SetMaximumSize(maximumSize);
194                     maxSize = borderInterface.MaxSize;
195                 }
196                 
197                 if (borderResizePolicy != borderInterface.ResizePolicy)
198                 {
199                     AddAuxiliaryHint("wm.policy.win.resize_aspect_ratio", "0");
200                     borderResizePolicy = borderInterface.ResizePolicy;
201                     if (borderResizePolicy == BorderResizePolicyType.KeepRatio)
202                     {
203                         AddAuxiliaryHint("wm.policy.win.resize_aspect_ratio", "1");
204                     }
205                 }
206                 
207             }
208         }
209         /// <summary>
210         /// Called when the border is closed.
211         /// If the delegate is declared, the delegate is called, otherwise window is destroyed.
212         /// </summary>
213         internal void BorderDestroy()
214         {
215             if (borderCloseDelegate != null)
216             {
217                 borderCloseDelegate();
218             }
219             else
220             {
221                 Destroy();
222             }
223         }
224         /// <summary>
225         /// Enable the border window with IBorderInterface.
226         /// This adds a border area to the Window.
227         /// The border's UI is configured using IBorderInterface.
228         /// Users can reisze and move by touching the border area.
229         /// </summary>
230         /// <param name="borderInterface">The IBorderInterface.</param>
231         /// <param name="borderCloseDelegate">The BorderCloseDelegate. When close, this delegate is called.</param>
232         /// <returns>Whether the border window is enabled</returns>
233         internal bool EnableBorder(IBorderInterface borderInterface, BorderCloseDelegate borderCloseDelegate = null)
234         {
235             if (isBorderWindow == true)
236             {
237                 Tizen.Log.Error("NUI", $"Already EnableBorderWindow\n");
238                 return false;
239             }
240
241             try
242             {
243                 Information.TryGetValue<int>("http://tizen.org/feature/screen.width", out screenWidth);
244                 Information.TryGetValue<int>("http://tizen.org/feature/screen.height", out screenHeight);
245             }
246             catch (DllNotFoundException e)
247             {
248                 Tizen.Log.Fatal("NUI", $"{e}\n");
249             }
250
251             if (borderInterface == null)
252             {
253                 borderInterface = new DefaultBorder();
254             }
255             this.borderInterface = borderInterface;
256             this.borderCloseDelegate = borderCloseDelegate;
257
258             GetDefaultLayer().Name = "OriginalRootLayer";
259
260             borderInterface.BorderWindow = this;
261
262             if (CreateBorder() == true)
263             {
264                 using var realWindowSize = new Size2D(WindowSize.Width, WindowSize.Height);
265
266                 isBorderWindow = true;
267
268                 Resized += OnBorderWindowResized;
269
270                 Moved += OnBorderWindowMoved;
271
272                 borderInterface.OnCreated(borderView);
273
274                 // Increase the window size as much as the border area.
275                 borderHeight = 0;
276                 if (hasTopView) borderHeight += topView.SizeHeight;
277                 if (hasBottomView) borderHeight += bottomView.SizeHeight;
278
279                 // Sets the minimum / maximum size to be resized by RequestResizeToServer.
280                 if (borderInterface.MinSize != null)
281                 {
282                     using Size2D mimimumSize = new Size2D(borderInterface.MinSize.Width + (int)borderInterface.BorderLineThickness * 2, borderInterface.MinSize.Height + (int)(borderHeight + borderInterface.BorderLineThickness * 2));
283                     SetMimimumSize(mimimumSize);
284                 }
285                 if (borderInterface.MaxSize != null)
286                 {
287                     using Size2D maximumSize = new Size2D(borderInterface.MaxSize.Width + (int)borderInterface.BorderLineThickness * 2, borderInterface.MaxSize.Height + (int)(borderHeight + borderInterface.BorderLineThickness * 2));
288                     SetMaximumSize(maximumSize);
289                 }
290
291                 // When running the app for the first time, if it runs in full size, do Maximize(true).
292                 if (screenWidth != 0 && screenHeight != 0 &&
293                     realWindowSize.Width >= screenWidth && realWindowSize.Height >= screenHeight &&
294                     IsMaximized() == false)
295                 {
296                     Maximize(true);
297                     borderInterface.OnMaximize(true);
298                     ResizedEventArgs e = new ResizedEventArgs();
299                     e.WindowSize = WindowSize;
300                     windowResizeEventHandler?.Invoke(this, e);
301                 }
302                 else
303                 {
304                     borderInterface.OnMaximize(IsMaximized());
305                     if (borderHeight > 0)
306                     {
307                         borderLineThickness = borderInterface.BorderLineThickness;
308                         WindowSize += new Size2D((int)borderLineThickness * 2, (int)(borderHeight + borderLineThickness * 2));
309                     }
310                 }
311
312                 // If it is BorderResizePolicyType.KeepRatio type, it will be resized according to the ratio.
313                 if (borderInterface.ResizePolicy == BorderResizePolicyType.KeepRatio)
314                 {
315                     AddAuxiliaryHint("wm.policy.win.resize_aspect_ratio", "1");
316                 }
317
318                 // Add a view to the border layer.
319                 GetBorderWindowBottomLayer().Add(rootView);
320
321                 FocusChanged += OnWindowFocusChanged;
322
323                 return true;
324             }
325             else
326             {
327                 this.borderInterface.Dispose();
328                 return false;
329             }
330         }
331
332         private void OnWindowFocusChanged(object sender, Window.FocusChangedEventArgs e)
333         {
334             if (e.FocusGained == true && IsMaximized() == false)
335             {
336                 // Raises the window when the window is focused.
337                 Raise();
338             }
339         }
340
341         /// Create the border UI.
342         private bool CreateBorder()
343         {
344             rootView = new View()
345             {
346                 WidthResizePolicy = ResizePolicyType.FillToParent,
347                 HeightResizePolicy = ResizePolicyType.FillToParent,
348                 BackgroundColor = Color.Transparent,
349             };
350
351             ushort padding = (ushort) borderLineThickness;
352             borderView = new BorderView()
353             {
354                 GrabTouchAfterLeave = true,
355                 WidthResizePolicy = ResizePolicyType.FillToParent,
356                 HeightResizePolicy = ResizePolicyType.FillToParent,
357                 BackgroundColor = Color.Transparent,
358                 Layout = new LinearLayout() {
359                     LinearOrientation = LinearLayout.Orientation.Vertical,
360                     LinearAlignment = LinearLayout.Alignment.Top
361                 },
362                 Padding = new Extents(padding, padding, padding, padding),
363             };
364             borderInterface.CreateBorderView(borderView);
365
366             topView = new View()
367             {
368                 WidthSpecification = LayoutParamPolicies.MatchParent,
369                 SizeHeight = borderInterface.BorderHeight,
370                 BackgroundColor = Color.Transparent,
371             };
372
373             contentsView = new View()
374             {
375                 BackgroundColor = Color.Transparent,
376                 WidthSpecification = LayoutParamPolicies.MatchParent,
377             };
378
379             bottomView = new View()
380             {
381                 WidthSpecification = LayoutParamPolicies.MatchParent,
382                 SizeHeight = borderInterface.BorderHeight,
383                 BackgroundColor = Color.Transparent,
384             };
385
386             // // Gets the Border's UI.
387             if (borderInterface.CreateTopBorderView(topView) == true && topView != null)
388             {
389                 borderView.Add(topView);
390                 hasTopView = true;
391             }
392             borderView.Add(contentsView);
393             if (borderInterface.CreateBottomBorderView(bottomView) == true && bottomView != null)
394             {
395                 borderView.Add(bottomView);
396                 hasBottomView = true;
397             }
398             rootView.Add(borderView);
399
400             return hasTopView || hasBottomView;
401         }
402
403         /// <summary>
404         /// Calculates which direction to resize or to move.
405         /// </summary>
406         /// <param name="xPosition">The X position.</param>
407         /// <param name="yPosition">The Y position.</param>
408         /// <returns>The BorderDirection</returns>
409         [EditorBrowsable(EditorBrowsableState.Never)]
410         public BorderDirection GetDirection(float xPosition, float yPosition)
411         {
412             BorderDirection direction = BorderDirection.None;
413
414             // check bottom left corner
415             if (xPosition < borderInterface.TouchThickness && yPosition > WindowSize.Height + borderHeight - borderInterface.TouchThickness)
416             {
417                 direction = BorderDirection.BottomLeft;
418             }
419             // check bottom right corner
420             else if (xPosition > WindowSize.Width + (float)(borderLineThickness * 2) - borderInterface.TouchThickness && yPosition > WindowSize.Height + borderHeight - borderInterface.TouchThickness)
421             {
422                 direction = BorderDirection.BottomRight;
423             }
424             // check top left corner
425             else if (xPosition < borderInterface.TouchThickness && yPosition <  borderInterface.TouchThickness)
426             {
427                 direction = BorderDirection.TopLeft;
428             }
429             // check top right corner
430             else if (xPosition > WindowSize.Width + (float)(borderLineThickness * 2) - borderInterface.TouchThickness && yPosition < borderInterface.TouchThickness)
431             {
432                 direction = BorderDirection.TopRight;
433             }
434             // check left side
435             else if (xPosition < borderInterface.TouchThickness)
436             {
437                 direction = BorderDirection.Left;
438             }
439             // check right side
440             else if (xPosition > WindowSize.Width + (float)(borderLineThickness * 2) - borderInterface.TouchThickness)
441             {
442                 direction = BorderDirection.Right;
443             }
444             // check bottom side
445             else if (yPosition > WindowSize.Height + borderHeight + borderLineThickness - borderInterface.TouchThickness)
446             {
447                 direction = BorderDirection.Bottom;
448             }
449             // check top side
450             else if (yPosition < borderInterface.TouchThickness)
451             {
452                 direction = BorderDirection.Top;
453             }
454             // check move
455             else if ((yPosition > WindowSize.Height) || (hasTopView == true && yPosition < topView.SizeHeight))
456             {
457                 direction = BorderDirection.Move;
458             }
459
460             return direction;
461         }
462
463         /// <summary>
464         /// Gets position and size of the border window
465         /// </summary>
466         /// <returns>The total window size including the border area in the default window.</returns>
467         [EditorBrowsable(EditorBrowsableState.Never)]
468         public Rectangle WindowPositionSizeWithBorder
469         {
470             get
471             {
472                 using var position = GetPosition();
473                 using var size = GetWindowSizeWithBorder();
474                 Rectangle ret = new Rectangle(position?.X ?? 0, position?.Y ?? 0, size?.Width ?? 0, size?.Height ?? 0);
475                 return ret;
476             }
477         }
478
479         /// <summary>
480         /// Gets size of the border window
481         /// </summary>
482         /// <returns>The total window size including the border area in the default window.</returns>
483         [EditorBrowsable(EditorBrowsableState.Never)]
484         public Size2D WindowSizeWithBorder
485         {
486             get
487             {
488                 return GetWindowSizeWithBorder();
489             }
490         }
491
492         private Size2D GetWindowSizeWithBorder()
493         {
494             var val = new Uint16Pair(Interop.Window.GetSize(SwigCPtr), true);
495             Size2D size = new Size2D(val.GetWidth(), val.GetHeight());
496             val.Dispose();
497             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
498             return size;
499         }
500
501         private void DoOverlayMode(bool enable)
502         {
503             if (borderInterface.OverlayMode == true)
504             {
505                 if (isEnabledOverlayMode != enable)
506                 {
507                     borderView?.OverlayMode(enable);
508                     borderInterface.OnOverlayMode(enable);
509                     if (enable == true)
510                     {
511                         GetBorderWindowBottomLayer().RaiseToTop();
512                     }
513                     else
514                     {
515                         GetBorderWindowBottomLayer().LowerToBottom();
516                     }
517                     isEnabledOverlayMode = enable;
518                 }
519             }
520         }
521
522         private void DoMaximize(bool isMaximized)
523         {
524             if (this.isMaximized != isMaximized)
525             {
526                 borderView?.OnMaximize(isMaximized);
527                 borderInterface.OnMaximize(isMaximized);
528             }
529             this.isMaximized = isMaximized;
530         }
531
532         // Called when the window position has changed.
533         private void OnBorderWindowMoved(object sender, WindowMovedEventArgs e)
534         {
535             Tizen.Log.Info("NUI", $"OnBorderWindowMoved {e.WindowPosition.X}, {e.WindowPosition.Y}\n");
536             borderInterface.OnMoved(e.WindowPosition.X, e.WindowPosition.X);
537         }
538
539
540         // Called when the window size has changed.
541         private void OnBorderWindowResized(object sender, Window.ResizedEventArgs e)
542         {
543             Tizen.Log.Info("NUI", $"OnBorderWindowResized {e.WindowSize.Width},{e.WindowSize.Height}\n");
544             int resizeWidth = e.WindowSize.Width;
545             int resizeHeight = e.WindowSize.Height;
546
547             borderInterface.OnResized(resizeWidth, resizeHeight);
548
549              // reset borderHeight
550             borderHeight = 0;
551             if (hasTopView) borderHeight += topView.SizeHeight;
552             if (hasBottomView) borderHeight += bottomView.SizeHeight;
553
554             bool isMaximized = IsMaximized();
555             bool isEnabledOverlay = (borderInterface.OverlayMode == true && isMaximized == true);
556
557             float width = 0;
558             float height = isEnabledOverlay ? 0 : borderHeight;
559             float y = isEnabledOverlay ? 0 : ((hasTopView == true) ? topView.SizeHeight : 0);
560
561             if (isMaximized == false)
562             {
563                 width = (float)(borderLineThickness * 2);
564                 height += (float)(borderLineThickness * 2);
565                 y += borderLineThickness;
566             }
567
568             Interop.ActorInternal.SetSize(GetBorderWindowRootLayer().SwigCPtr, resizeWidth, resizeHeight);
569             Interop.ActorInternal.SetSize(GetBorderWindowBottomLayer().SwigCPtr, resizeWidth + width, resizeHeight + height);
570             Interop.ActorInternal.SetPosition(GetBorderWindowRootLayer().SwigCPtr, 0, y);
571
572             if (contentsView != null)
573             {
574                 contentsView.SizeHeight = resizeHeight - (isEnabledOverlay ? borderHeight : 0);
575             }
576             DoMaximize(isMaximized);
577
578             DoOverlayMode(isEnabledOverlay);
579
580             if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); }
581         }
582
583         internal Layer GetBorderWindowBottomLayer()
584         {
585             if (borderWindowBottomLayer == null)
586             {
587                 borderWindowBottomLayer = new Layer();
588                 borderWindowBottomLayer.Name = "BorderWindowBottomLayer";
589                 using Vector3 topCentor = new Vector3(0.5f, 0.0f, 0.5f);
590                 Interop.ActorInternal.SetParentOrigin(borderWindowBottomLayer.SwigCPtr, topCentor.SwigCPtr);
591                 Interop.Actor.SetAnchorPoint(borderWindowBottomLayer.SwigCPtr, topCentor.SwigCPtr);
592                 Interop.Actor.Add(rootLayer.SwigCPtr, borderWindowBottomLayer.SwigCPtr);
593                 Interop.ActorInternal.SetSize(borderWindowBottomLayer.SwigCPtr, WindowSize.Width + (float)(borderLineThickness * 2), WindowSize.Height + (float)(borderLineThickness * 2));
594                 borderWindowBottomLayer.SetWindow(this);
595                 borderWindowBottomLayer.LowerToBottom();
596
597                 if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); }
598             }
599             return borderWindowBottomLayer;
600         }
601
602         internal Layer GetBorderWindowRootLayer()
603         {
604             if (borderWindowRootLayer == null)
605             {
606                 borderWindowRootLayer = new Layer();
607                 borderWindowRootLayer.Name = "RootLayer";
608                 using Vector3 topCentor = new Vector3(0.5f, 0.0f, 0.5f);
609                 Interop.ActorInternal.SetParentOrigin(borderWindowRootLayer.SwigCPtr, topCentor.SwigCPtr);
610                 Interop.Actor.SetAnchorPoint(borderWindowRootLayer.SwigCPtr, topCentor.SwigCPtr);
611                 Interop.Actor.Add(rootLayer.SwigCPtr, borderWindowRootLayer.SwigCPtr);
612                 Interop.ActorInternal.SetSize(borderWindowRootLayer.SwigCPtr, WindowSize.Width, WindowSize.Height - borderHeight - borderLineThickness * 2);
613                 float height = (hasTopView == true) ? topView.SizeHeight : 0;
614                 Interop.ActorInternal.SetPosition(borderWindowRootLayer.SwigCPtr, 0, height + borderLineThickness);
615                 using PropertyValue propertyValue = new Tizen.NUI.PropertyValue((int)Tizen.NUI.ClippingModeType.ClipToBoundingBox);
616                 Tizen.NUI.Object.SetProperty(borderWindowRootLayer.SwigCPtr, Tizen.NUI.BaseComponents.View.Property.ClippingMode, propertyValue);
617
618                 if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); }
619             }
620
621             return borderWindowRootLayer;
622         }
623
624         internal void DisposeBorder()
625         {
626             Resized -= OnBorderWindowResized;
627             FocusChanged -= OnWindowFocusChanged;
628             borderInterface.Dispose();
629             GetBorderWindowBottomLayer().Dispose();
630         }
631
632         private void convertBorderWindowSizeToRealWindowSize(Uint16Pair size)
633         {
634             if (isBorderWindow == true)
635             {
636                 var height = (ushort)(size.GetHeight() + borderHeight + borderLineThickness * 2);
637                 var width = (ushort)(size.GetWidth() + borderLineThickness * 2);
638                 size.SetHeight(height);
639                 size.SetWidth(width);
640             }
641         }
642
643         private void convertRealWindowSizeToBorderWindowSize(Uint16Pair size)
644         {
645             if (isBorderWindow == true && !(borderInterface.OverlayMode == true && IsMaximized() == true))
646             {
647                 var borderLine = IsMaximized() == true ? 0 : borderLineThickness * 2;
648                 var height = (ushort)(size.GetHeight() - borderHeight - borderLine);
649                 var width = (ushort)(size.GetWidth() - borderLine);
650                 size.SetHeight(height);
651                 size.SetWidth(width);
652             }
653         }
654         #endregion //Methods
655
656         #region Structs
657         #endregion //Structs
658
659         #region Classes
660         // View class for border view.
661         private class BorderView : View
662         {
663             private bool isEnabledOverlay = false;
664             private Extents prePadding = new Extents(0, 0, 0, 0);
665
666             internal BorderView() : base()
667             {
668                 // BorderView will use custom HitTest function.
669                 RegisterHitTestCallback();
670             }
671
672             /// <summary>
673             /// Set whether or not it is in overlay mode.
674             /// The borderView's OverlayMode means that it is displayed at the top of the screen.
675             /// In this case, the borderView should pass the event so that lower layers can receive the event.
676             /// </summary>
677             /// <param name="enabled">The true if borderView is Overlay mode. false otherwise.</param>
678             [EditorBrowsable(EditorBrowsableState.Never)]
679             public void OverlayMode(bool enabled)
680             {
681                 isEnabledOverlay = enabled;
682             }
683
684             /// <summary>
685             /// Called when the window is maximized.
686             /// </summary>
687             /// <param name="isMaximized">If window is maximized or unmaximized.</param>
688             [EditorBrowsable(EditorBrowsableState.Never)]
689             public void OnMaximize(bool isMaximized)
690             {
691                 // When maximized, it is displayed in full without border lines.
692                 if (isMaximized == true)
693                 {
694                     prePadding = Padding;
695                     Padding = new Extents(0, 0, 0, 0);
696                 }
697                 else
698                 {
699                     Padding = prePadding;
700                 }
701
702             }
703
704             protected override bool HitTest(Touch touch)
705             {
706                 // If borderView is in overlay mode, pass the hittest.
707                 return (isEnabledOverlay == false);
708             }
709         }
710         #endregion //Classes
711     }
712 }