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