[NUI] fix memory leak problem
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / Layer.cs
1 /*
2  * Copyright(c) 2017 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 using System;
18 using Tizen.NUI.BaseComponents;
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
21
22 namespace Tizen.NUI
23 {
24
25     /// <summary>
26     /// Layers provide a mechanism for overlaying groups of actors on top of each other.
27     /// </summary>
28     /// <since_tizen> 3 </since_tizen>
29     public class Layer : Container
30     {
31         private global::System.Runtime.InteropServices.HandleRef swigCPtr;
32
33         internal Layer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(NDalicPINVOKE.Layer_SWIGUpcast(cPtr), cMemoryOwn)
34         {
35             swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
36         }
37
38         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Layer obj)
39         {
40             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
41         }
42
43         /// From the Container base class.
44
45         /// <summary>
46         /// Adds a child view to this layer.
47         /// </summary>
48         /// <seealso cref="Container.Add">
49         /// </seealso>
50         /// <since_tizen> 4 </since_tizen>
51         public override void Add(View child)
52         {
53             Container oldParent = child.GetParent();
54             if (oldParent != this)
55             {
56                 if (oldParent != null)
57                 {
58                     oldParent.Remove(child);
59                 }
60                 NDalicPINVOKE.Actor_Add(swigCPtr, View.getCPtr(child));
61                 if (NDalicPINVOKE.SWIGPendingException.Pending)
62                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
63                 Children.Add(child);
64             }
65         }
66
67         /// <summary>
68         /// Removes a child view from this layer. If the view was not a child of this layer, this is a no-op.
69         /// </summary>
70         /// <seealso cref="Container.Remove">
71         /// </seealso>
72         /// <since_tizen> 4 </since_tizen>
73         public override void Remove(View child)
74         {
75             NDalicPINVOKE.Actor_Remove(swigCPtr, View.getCPtr(child));
76             if (NDalicPINVOKE.SWIGPendingException.Pending)
77                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
78
79             Children.Remove(child);
80         }
81
82         /// <summary>
83         /// Retrieves a child view by the index.
84         /// </summary>
85         /// <pre>The view has been initialized.</pre>
86         /// <param name="index">The index of the child to retrieve.</param>
87         /// <returns>The view for the given index or empty handle if children not initialized.</returns>
88         /// <since_tizen> 4 </since_tizen>
89         public override View GetChildAt(uint index)
90         {
91             if (index < Children.Count)
92             {
93                 return Children[Convert.ToInt32(index)];
94             }
95             else
96             {
97                 return null;
98             }
99         }
100
101
102         /// <summary>
103         /// Get parent of the layer.
104         /// </summary>
105         /// <returns>The view's container</returns>
106         /// <since_tizen> 4 </since_tizen>
107         public override Container GetParent()
108         {
109             return null;
110         }
111
112         /// <summary>
113         /// Get the child count of the layer.
114         /// </summary>
115         /// <returns>The child count of the layer.</returns>
116         /// <since_tizen> 4 </since_tizen>
117         public override uint GetChildCount()
118         {
119             return Convert.ToUInt32(Children.Count);
120         }
121
122         /// <summary>
123         /// Dispose.
124         /// </summary>
125         /// <since_tizen> 3 </since_tizen>
126         protected override void Dispose(DisposeTypes type)
127         {
128             if(disposed)
129             {
130                 return;
131             }
132
133             if(type == DisposeTypes.Explicit)
134             {
135                 //Called by User
136                 //Release your own managed resources here.
137                 //You should release all of your own disposable objects here.
138             }
139
140             //Release your own unmanaged resources here.
141             //You should not access any managed member here except static instance.
142             //because the execution order of Finalizes is non-deterministic.
143
144             if (swigCPtr.Handle != global::System.IntPtr.Zero)
145             {
146                 if (swigCMemOwn)
147                 {
148                     swigCMemOwn = false;
149                     NDalicPINVOKE.delete_Layer(swigCPtr);
150                 }
151                 swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
152             }
153
154             base.Dispose(type);
155
156         }
157
158
159         internal class Property
160         {
161             internal static readonly int BEHAVIOR = NDalicPINVOKE.Layer_Property_BEHAVIOR_get();
162         }
163
164         /// <summary>
165         /// Creates a Layer object.
166         /// </summary>
167         /// <since_tizen> 3 </since_tizen>
168         public Layer() : this(NDalicPINVOKE.Layer_New(), true)
169         {
170             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
171             if(Window.Instance != null)
172             {
173                 this.SetAnchorPoint(Tizen.NUI.PivotPoint.TopLeft);
174                 this.SetResizePolicy(ResizePolicyType.FillToParent, DimensionType.AllDimensions);
175             }
176         }
177         internal void SetAnchorPoint(Vector3 anchorPoint)
178         {
179             NDalicPINVOKE.Actor_SetAnchorPoint(swigCPtr, Vector3.getCPtr(anchorPoint));
180             if (NDalicPINVOKE.SWIGPendingException.Pending)
181                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
182         }
183         internal void SetResizePolicy(ResizePolicyType policy, DimensionType dimension)
184         {
185             NDalicPINVOKE.Actor_SetResizePolicy(swigCPtr, (int)policy, (int)dimension);
186             if (NDalicPINVOKE.SWIGPendingException.Pending)
187                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
188         }
189
190         /// <summary>
191         /// Downcasts a handle to layer handle.
192         /// </summary>
193         /// <since_tizen> 3 </since_tizen>
194         /// Please do not use! this will be deprecated!
195         /// Instead please use as keyword.
196         [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead!")]
197         [EditorBrowsable(EditorBrowsableState.Never)]
198         public static Layer DownCast(BaseHandle handle)
199         {
200             Layer ret =  Registry.GetManagedBaseHandleFromNativePtr(handle) as Layer;
201             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
202             return ret;
203         }
204
205         /// <summary>
206         /// Search through this layer's hierarchy for a view with the given unique ID.
207         /// </summary>
208         /// <pre>This layer (the parent) has been initialized.</pre>
209         /// <remarks>The actor itself is also considered in the search.</remarks>
210         /// <param name="id">The id of the child to find</param>
211         /// <returns> A handle to the view if found, or an empty handle if not. </returns>
212         /// <since_tizen> 3 </since_tizen>
213         public View FindChildById(uint id)
214         {
215             //to fix memory leak issue, match the handle count with native side.
216             IntPtr cPtr = NDalicPINVOKE.Actor_FindChildById(swigCPtr, id);
217             HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
218             View ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as View;
219             NDalicPINVOKE.delete_BaseHandle(CPtr);
220             CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
221
222             if (NDalicPINVOKE.SWIGPendingException.Pending)
223                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
224             return ret;
225         }
226
227         /// <summary>
228         /// Queries the depth of the layer.<br />
229         /// 0 is the bottommost layer, higher number is on the top.<br />
230         /// </summary>
231         /// <since_tizen> 3 </since_tizen>
232         public uint Depth
233         {
234             get
235             {
236                 return GetDepth();
237             }
238         }
239
240         internal uint GetDepth()
241         {
242             var parentChildren = Window.Instance.LayersChildren;
243             if(parentChildren != null)
244             {
245                 int idx = parentChildren.IndexOf(this);
246                 if (idx >= 0)
247                 {
248                     return Convert.ToUInt32(idx); ;
249                 }
250             }
251             return 0u;
252         }
253
254         /// <summary>
255         /// Increments the depth of the layer.
256         /// </summary>
257         /// <since_tizen> 3 </since_tizen>
258         public void Raise()
259         {
260             var parentChildren = Window.Instance.LayersChildren;
261             if (parentChildren != null)
262             {
263                 int currentIdx = parentChildren.IndexOf(this);
264
265                 if (currentIdx >= 0 && currentIdx < parentChildren.Count - 1)
266                 {
267                     RaiseAbove(parentChildren[currentIdx + 1]);
268
269                     Layer temp = parentChildren[currentIdx + 1];
270                     parentChildren[currentIdx + 1] = this;
271                     parentChildren[currentIdx] = temp;
272
273                     NDalicPINVOKE.Layer_Raise(swigCPtr);
274                     if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
275                 }
276             }
277         }
278
279         /// <summary>
280         /// Decrements the depth of the layer.
281         /// </summary>
282         /// <since_tizen> 3 </since_tizen>
283         public void Lower()
284         {
285             var parentChildren = Window.Instance.LayersChildren;
286             if (parentChildren != null)
287             {
288                 int currentIdx = parentChildren.IndexOf(this);
289
290                 if (currentIdx > 0 && currentIdx < parentChildren.Count)
291                 {
292                     LowerBelow(parentChildren[currentIdx - 1]);
293
294                     Layer temp = parentChildren[currentIdx - 1];
295                     parentChildren[currentIdx - 1] = this;
296                     parentChildren[currentIdx] = temp;
297
298                     NDalicPINVOKE.Layer_Lower(swigCPtr);
299                     if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
300                 }
301             }
302         }
303
304         internal void RaiseAbove(Layer target)
305         {
306             var parentChildren = Window.Instance.LayersChildren;
307             if (parentChildren != null)
308             {
309                 int currentIndex = parentChildren.IndexOf(this);
310                 int targetIndex = parentChildren.IndexOf(target);
311
312                 if(currentIndex < 0 || targetIndex < 0 ||
313                     currentIndex >= parentChildren.Count || targetIndex >= parentChildren.Count)
314                 {
315                     NUILog.Error("index should be bigger than 0 and less than children of layer count");
316                     return;
317                 }
318
319                 // If the currentIndex is less than the target index and the target has the same parent.
320                 if (currentIndex < targetIndex)
321                 {
322                     parentChildren.Remove(this);
323                     parentChildren.Insert(targetIndex, this);
324
325                     NDalicPINVOKE.Layer_RaiseAbove(swigCPtr, Layer.getCPtr(target));
326                     if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
327                 }
328             }
329         }
330
331         internal void LowerBelow(Layer target)
332         {
333             var parentChildren = Window.Instance.LayersChildren;
334
335             if (parentChildren != null)
336             {
337                 int currentIndex = parentChildren.IndexOf(this);
338                 int targetIndex = parentChildren.IndexOf(target);
339
340                 if(currentIndex < 0 || targetIndex < 0 ||
341                     currentIndex >= parentChildren.Count || targetIndex >= parentChildren.Count)
342                 {
343                     NUILog.Error("index should be bigger than 0 and less than children of layer count");
344                     return;
345                 }
346
347                 // If the currentIndex is not already the 0th index and the target has the same parent.
348                 if ((currentIndex != 0) && (targetIndex != -1) &&
349                     (currentIndex > targetIndex))
350                 {
351                     parentChildren.Remove(this);
352                     parentChildren.Insert(targetIndex, this);
353
354                     NDalicPINVOKE.Layer_LowerBelow(swigCPtr, Layer.getCPtr(target));
355                     if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
356                 }
357             }
358         }
359
360         /// <summary>
361         /// Raises the layer to the top.
362         /// </summary>
363         /// <since_tizen> 3 </since_tizen>
364         public void RaiseToTop()
365         {
366             var parentChildren = Window.Instance.LayersChildren;
367
368             if (parentChildren != null)
369             {
370                 parentChildren.Remove(this);
371                 parentChildren.Add(this);
372
373                 NDalicPINVOKE.Layer_RaiseToTop(swigCPtr);
374                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
375             }
376         }
377
378         /// <summary>
379         /// Lowers the layer to the bottom.
380         /// </summary>
381         /// <since_tizen> 3 </since_tizen>
382         public void LowerToBottom()
383         {
384             var parentChildren = Window.Instance.LayersChildren;
385
386             if (parentChildren != null)
387             {
388                 parentChildren.Remove(this);
389                 parentChildren.Insert(0, this);
390
391                 NDalicPINVOKE.Layer_LowerToBottom(swigCPtr);
392                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
393             }
394
395         }
396
397         /// <summary>
398         /// Moves the layer directly above the given layer.<br />
399         /// After the call, this layer's depth will be immediately above target.<br />
400         /// </summary>
401         /// <param name="target">The layer to get on top of.</param>
402         /// <since_tizen> 3 </since_tizen>
403         public void MoveAbove(Layer target)
404         {
405             NDalicPINVOKE.Layer_MoveAbove(swigCPtr, Layer.getCPtr(target));
406             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
407         }
408
409         /// <summary>
410         /// Moves the layer directly below the given layer.<br />
411         /// After the call, this layer's depth will be immediately below target.<br />
412         /// </summary>
413         /// <param name="target">The layer to get below of.</param>
414         /// <since_tizen> 3 </since_tizen>
415         public void MoveBelow(Layer target)
416         {
417             NDalicPINVOKE.Layer_MoveBelow(swigCPtr, Layer.getCPtr(target));
418             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
419         }
420
421         private void SetBehavior(LayerBehavior behavior)
422         {
423             NDalicPINVOKE.Layer_SetBehavior(swigCPtr, (int)behavior);
424             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
425         }
426
427         private LayerBehavior GetBehavior()
428         {
429             Layer.LayerBehavior ret = (Layer.LayerBehavior)NDalicPINVOKE.Layer_GetBehavior(swigCPtr);
430             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
431             return ret;
432         }
433
434         internal void SetSortFunction(SWIGTYPE_p_f_r_q_const__Dali__Vector3__float function)
435         {
436             NDalicPINVOKE.Layer_SetSortFunction(swigCPtr, SWIGTYPE_p_f_r_q_const__Dali__Vector3__float.getCPtr(function));
437             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
438         }
439
440         internal void SetTouchConsumed(bool consume)
441         {
442             NDalicPINVOKE.Layer_SetTouchConsumed(swigCPtr, consume);
443             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
444         }
445
446         internal bool IsTouchConsumed()
447         {
448             bool ret = NDalicPINVOKE.Layer_IsTouchConsumed(swigCPtr);
449             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
450             return ret;
451         }
452
453         internal void SetHoverConsumed(bool consume)
454         {
455             NDalicPINVOKE.Layer_SetHoverConsumed(swigCPtr, consume);
456             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
457         }
458
459         internal bool IsHoverConsumed()
460         {
461             bool ret = NDalicPINVOKE.Layer_IsHoverConsumed(swigCPtr);
462             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
463             return ret;
464         }
465
466         /// <summary>
467         /// Enumeration for the behavior of the layer.
468         /// </summary>
469         /// <since_tizen> 3 </since_tizen>
470         public enum LayerBehavior
471         {
472             /// <summary>
473             /// UI control rendering mode.
474             /// </summary>
475             /// <since_tizen> 3 </since_tizen>
476             Layer2D,
477             /// <summary>
478             /// UI control rendering mode (default mode).
479             /// This mode is designed for UI controls that can overlap. In this
480             /// mode renderer order will be respective to the tree hierarchy of
481             /// Actors.<br />
482             /// The rendering order is depth first, so for the following actor tree,
483             /// A will be drawn first, then B, D, E, then C, F.  This ensures that
484             /// overlapping actors are drawn as expected (whereas, with breadth first
485             /// traversal, the actors would interleave).<br />
486             /// </summary>
487             /// <since_tizen> 3 </since_tizen>
488             LayerUI = Layer2D,
489             /// <summary>
490             /// Layer will use depth test.
491             /// This mode is designed for a 3 dimensional scene where actors in front
492             /// of other actors will obscure them, i.e. the actors are sorted by the
493             /// distance from the camera.<br />
494             /// When using this mode, a depth test will be used. A depth clear will
495             /// happen for each layer, which means actors in a layer "above" other
496             /// layers will be rendered in front of actors in those layers regardless
497             /// of their Z positions (see Layer::Raise() and Layer::Lower()).<br />
498             /// Opaque renderers are drawn first and write to the depth buffer.  Then
499             /// transparent renderers are drawn with depth test enabled but depth
500             /// write switched off.  Transparent renderers are drawn based on their
501             /// distance from the camera.  A renderer's DEPTH_INDEX property is used to
502             /// offset the distance to the camera when ordering transparent renderers.
503             /// This is useful if you want to define the draw order of two or more
504             /// transparent renderers that are equal distance from the camera.  Unlike
505             /// LAYER_UI, parent-child relationship does not affect rendering order at
506             /// all.
507             /// </summary>
508             /// <since_tizen> 3 </since_tizen>
509             Layer3D
510         }
511
512         internal enum TreeDepthMultiplier
513         {
514             TREE_DEPTH_MULTIPLIER = 10000
515         }
516
517         /// <summary>
518         /// Layer behavior, type String (Layer.LayerBehavior).
519         /// </summary>
520         /// <since_tizen> 3 </since_tizen>
521         public Layer.LayerBehavior Behavior
522         {
523             get
524             {
525                 return GetBehavior();
526             }
527             set
528             {
529                 SetBehavior(value);
530             }
531         }
532
533         /// <summary>
534         /// Internal only property to enable or disable clipping, type boolean.
535         /// By default, this is false, i.e., the viewport of the layer is the entire window.
536         /// </summary>
537         internal bool ClippingEnabled
538         {
539             get
540             {
541                 bool ret = NDalicPINVOKE.Layer_IsClipping(swigCPtr);
542                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
543                 return ret;
544             }
545             set
546             {
547                 NDalicPINVOKE.Layer_SetClipping(swigCPtr, value);
548                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
549             }
550         }
551
552         /// <summary>
553         /// Sets the viewport (in window coordinates), type rectangle.
554         /// The contents of the layer will not be visible outside this box, when ViewportEnabled is true.
555         /// </summary>
556         /// <since_tizen> 4 </since_tizen>
557         public Rectangle Viewport
558         {
559             get
560             {
561                 if( ClippingEnabled )
562                 {
563                   Rectangle ret = new Rectangle(NDalicPINVOKE.Layer_GetClippingBox(swigCPtr), true);
564                   if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
565                   return ret;
566                 }
567                 else
568                 {
569                   // Clipping not enabled so return the window size
570                   Size2D windowSize = Window.Instance.Size;
571                   Rectangle ret = new Rectangle(0, 0, windowSize.Width, windowSize.Height);
572                   return ret;
573                 }
574             }
575             set
576             {
577                 NDalicPINVOKE.Layer_SetClippingBox__SWIG_1(swigCPtr, Rectangle.getCPtr(value));
578                 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
579                 ClippingEnabled = true;
580             }
581         }
582
583         /// <summary>
584         /// Retrieves and sets the layer's opacity.<br />
585         /// </summary>
586         /// <since_tizen> 3 </since_tizen>
587         public float Opacity
588         {
589             get
590             {
591                 float temp = 0.0f;
592                 GetProperty(View.Property.OPACITY).Get(out temp);
593                 return temp;
594             }
595             set
596             {
597                 SetProperty(View.Property.OPACITY, new Tizen.NUI.PropertyValue(value));
598             }
599         }
600
601         /// <summary>
602         /// Retrieves and sets the layer's visibility.
603         /// </summary>
604         /// <since_tizen> 3 </since_tizen>
605         public bool Visibility
606         {
607             get
608             {
609                 bool temp = false;
610                 GetProperty(View.Property.VISIBLE).Get(out temp);
611                 return temp;
612             }
613             set
614             {
615                 SetProperty(View.Property.VISIBLE, new Tizen.NUI.PropertyValue(value));
616             }
617         }
618
619         /// <summary>
620         /// Get the number of children held by the layer.
621         /// </summary>
622         /// <since_tizen> 3 </since_tizen>
623         public new uint ChildCount
624         {
625             get
626             {
627                 return Convert.ToUInt32(Children.Count);
628             }
629         }
630
631         /// <summary>
632         /// Gets or sets the layer's name.
633         /// </summary>
634         /// <since_tizen> 3 </since_tizen>
635         public string Name
636         {
637             get
638             {
639                 return GetName();
640             }
641             set
642             {
643                 SetName(value);
644             }
645         }
646
647         internal string GetName()
648         {
649             string ret = NDalicPINVOKE.Actor_GetName(swigCPtr);
650             if (NDalicPINVOKE.SWIGPendingException.Pending)
651                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
652             return ret;
653         }
654
655         internal void SetName(string name)
656         {
657             NDalicPINVOKE.Actor_SetName(swigCPtr, name);
658             if (NDalicPINVOKE.SWIGPendingException.Pending)
659                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
660         }
661
662     }
663 }