2 * Copyright(c) 2022 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using Tizen.NUI.BaseComponents;
19 using System.ComponentModel;
20 using Tizen.NUI.Binding;
25 /// Layers provide a mechanism for overlaying groups of actors on top of each other.
27 /// <since_tizen> 3 </since_tizen>
28 public class Layer : Container
30 private Window window;
32 private int layoutCount = 0;
35 /// Creates a Layer object.
37 /// <since_tizen> 3 </since_tizen>
38 public Layer() : this(Interop.Layer.New(), true)
40 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
41 this.SetAnchorPoint(Tizen.NUI.PivotPoint.TopLeft);
42 this.SetResizePolicy(ResizePolicyType.FillToParent, DimensionType.AllDimensions);
45 internal Layer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
50 /// Dispose Explicit or Implicit
52 [EditorBrowsable(EditorBrowsableState.Never)]
53 protected override void Dispose(DisposeTypes type)
66 /// Enumeration for the behavior of the layer.
68 /// <since_tizen> 3 </since_tizen>
69 public enum LayerBehavior
72 /// UI control rendering mode (default mode).
73 /// This mode is designed for UI controls that can overlap. In this
74 /// mode renderer order will be respective to the tree hierarchy of
76 /// The rendering order is depth first, so for the following actor tree,
77 /// A will be drawn first, then B, D, E, then C, F. This ensures that
78 /// overlapping actors are drawn as expected (whereas, with breadth first
79 /// traversal, the actors would interleave).<br />
81 /// <since_tizen> 3 </since_tizen>
85 /// Layer will use depth test.
86 /// This mode is designed for a 3 dimensional scene where actors in front
87 /// of other actors will obscure them, i.e. the actors are sorted by the
88 /// distance from the camera.<br />
89 /// When using this mode, a depth test will be used. A depth clear will
90 /// happen for each layer, which means actors in a layer "above" other
91 /// layers will be rendered in front of actors in those layers regardless
92 /// of their Z positions (see Layer::Raise() and Layer::Lower()).<br />
93 /// Opaque renderers are drawn first and write to the depth buffer. Then
94 /// transparent renderers are drawn with depth test enabled but depth
95 /// write switched off. Transparent renderers are drawn based on their
96 /// distance from the camera. A renderer's DEPTH_INDEX property is used to
97 /// offset the distance to the camera when ordering transparent renderers.
98 /// This is useful if you want to define the draw order of two or more
99 /// transparent renderers that are equal distance from the camera. Unlike
100 /// LAYER_UI, parent-child relationship does not affect rendering order at
103 /// <since_tizen> 3 </since_tizen>
107 internal enum TreeDepthMultiplier
109 TREE_DEPTH_MULTIPLIER = 10000
113 /// Layer behavior, type String (Layer.LayerBehavior).
115 /// <since_tizen> 3 </since_tizen>
116 public Layer.LayerBehavior Behavior
120 return GetBehavior();
129 /// Sets the viewport (in window coordinates), type rectangle.
130 /// The contents of the layer will not be visible outside this box, when ViewportEnabled is true.
132 /// <since_tizen> 4 </since_tizen>
133 public Rectangle Viewport
139 Rectangle ret = new Rectangle(Interop.Layer.GetClippingBox(SwigCPtr), true);
140 if (NDalicPINVOKE.SWIGPendingException.Pending) throw new InvalidOperationException("FATAL: get Exception", NDalicPINVOKE.SWIGPendingException.Retrieve());
145 // Clipping not enabled so return the window size
146 Size2D windowSize = window?.Size;
147 Rectangle ret = new Rectangle(0, 0, windowSize.Width, windowSize.Height);
153 Interop.Layer.SetClippingBox(SwigCPtr, Rectangle.getCPtr(value));
154 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
155 ClippingEnabled = true;
160 /// Retrieves and sets the layer's opacity.<br />
162 /// <since_tizen> 3 </since_tizen>
168 var pValue = GetProperty(View.Property.OPACITY);
169 pValue.Get(out temp);
175 var temp = new Tizen.NUI.PropertyValue(value);
176 SetProperty(View.Property.OPACITY, temp);
182 /// Retrieves and sets the layer's visibility.
184 /// <since_tizen> 3 </since_tizen>
185 public bool Visibility
190 var pValue = GetProperty(View.Property.VISIBLE);
191 pValue.Get(out temp);
197 var temp = new Tizen.NUI.PropertyValue(value);
198 SetProperty(View.Property.VISIBLE, temp);
204 /// Get the number of children held by the layer.
206 /// <since_tizen> 3 </since_tizen>
207 public new uint ChildCount
211 return Convert.ToUInt32(Children.Count);
216 /// Gets or sets the layer's name.
218 /// <since_tizen> 3 </since_tizen>
232 /// Queries the depth of the layer.<br />
233 /// 0 is the bottommost layer, higher number is on the top.<br />
235 /// <since_tizen> 3 </since_tizen>
245 /// Internal only property to enable or disable clipping, type boolean.
246 /// By default, this is false, i.e., the viewport of the layer is the entire window.
248 internal bool ClippingEnabled
252 bool ret = Interop.Layer.IsClipping(SwigCPtr);
253 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
258 Interop.Layer.SetClipping(SwigCPtr, value);
259 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
263 /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
264 [EditorBrowsable(EditorBrowsableState.Never)]
265 public ResourceDictionary XamlResources
269 return Application.Current.XamlResources;
273 Application.Current.XamlResources = value;
278 /// Gets the Layer's ID
281 /// <remarks>Hidden-API</remarks>
282 [EditorBrowsable(EditorBrowsableState.Never)]
292 /// From the Container base class.
295 /// Adds a child view to this layer.
297 /// <seealso cref="Container.Add">
299 /// <exception cref="ArgumentNullException"> Thrown when child is null. </exception>
300 /// <since_tizen> 4 </since_tizen>
301 public override void Add(View child)
305 throw new ArgumentNullException(nameof(child));
308 Container oldParent = child.GetParent();
310 if (oldParent != this)
312 if (oldParent != null)
314 oldParent.Remove(child);
318 child.InternalParent = this;
321 LayoutCount += child.LayoutCount;
323 Interop.Actor.Add(SwigCPtr, View.getCPtr(child));
324 if (NDalicPINVOKE.SWIGPendingException.Pending)
325 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
327 BindableObject.SetInheritedBindingContext(child, this?.BindingContext);
332 /// Removes a child view from this layer. If the view was not a child of this layer, this is a no-op.
334 /// <seealso cref="Container.Remove">
336 /// <exception cref="ArgumentNullException"> Thrown when child is null. </exception>
337 /// <since_tizen> 4 </since_tizen>
338 public override void Remove(View child)
342 throw new ArgumentNullException(nameof(child));
344 if (child.GetParent() == null) // Early out if child parent is null.
347 if (child.GetParent() != this)
349 //throw new System.InvalidOperationException("You have deleted a view that is not a child of this layer.");
350 Tizen.Log.Error("NUI", "You have deleted a view that is not a child of this layer.");
353 Interop.Actor.Remove(SwigCPtr, View.getCPtr(child));
354 if (NDalicPINVOKE.SWIGPendingException.Pending)
355 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
357 Children.Remove(child);
358 child.InternalParent = null;
360 LayoutCount -= child.LayoutCount;
364 /// Retrieves a child view by the index.
366 /// <pre>The view has been initialized.</pre>
367 /// <param name="index">The index of the child to retrieve.</param>
368 /// <returns>The view for the given index or empty handle if children not initialized.</returns>
369 /// <since_tizen> 4 </since_tizen>
370 public override View GetChildAt(uint index)
372 if (index < Children.Count)
374 return Children[Convert.ToInt32(index)];
383 /// Get parent of the layer.
385 /// <returns>The view's container</returns>
386 /// <since_tizen> 4 </since_tizen>
387 public override Container GetParent()
393 /// Get the child count of the layer.
395 /// <returns>The child count of the layer.</returns>
396 /// <since_tizen> 4 </since_tizen>
397 [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
398 public override uint GetChildCount()
400 return Convert.ToUInt32(Children.Count);
404 /// Downcasts a handle to layer handle.
406 /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
407 /// <since_tizen> 3 </since_tizen>
408 /// Please do not use! this will be deprecated!
409 /// Instead please use as keyword.
410 [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead!")]
411 [EditorBrowsable(EditorBrowsableState.Never)]
412 public static Layer DownCast(BaseHandle handle)
416 throw new ArgumentNullException(nameof(handle));
418 Layer ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as Layer;
419 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
424 /// Search through this layer's hierarchy for a view with the given unique ID.
426 /// <pre>This layer (the parent) has been initialized.</pre>
427 /// <remarks>The actor itself is also considered in the search.</remarks>
428 /// <param name="id">The id of the child to find</param>
429 /// <returns> A handle to the view if found, or an empty handle if not. </returns>
430 /// <since_tizen> 3 </since_tizen>
431 public View FindChildById(uint id)
433 //to fix memory leak issue, match the handle count with native side.
434 IntPtr cPtr = Interop.Actor.FindChildById(SwigCPtr, id);
435 View ret = this.GetInstanceSafely<View>(cPtr);
436 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
440 internal override View FindCurrentChildById(uint id)
442 return FindChildById(id);
445 /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
446 [EditorBrowsable(EditorBrowsableState.Never)]
447 public View FindChildByName(string viewName)
449 //to fix memory leak issue, match the handle count with native side.
450 IntPtr cPtr = Interop.Actor.FindChildByName(SwigCPtr, viewName);
451 View ret = this.GetInstanceSafely<View>(cPtr);
452 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
457 /// Increments the depth of the layer.
459 /// <since_tizen> 3 </since_tizen>
462 var parentChildren = window?.LayersChildren;
463 if (parentChildren != null)
465 int currentIdx = parentChildren.IndexOf(this);
467 if (currentIdx >= 0 && currentIdx < parentChildren.Count - 1)
469 var upper = parentChildren[currentIdx + 1];
476 /// Decrements the depth of the layer.
478 /// <since_tizen> 3 </since_tizen>
481 var parentChildren = window?.LayersChildren;
482 if (parentChildren != null)
484 int currentIdx = parentChildren.IndexOf(this);
486 if (currentIdx > 0 && currentIdx < parentChildren.Count)
488 var low = parentChildren[currentIdx - 1];
495 /// Raises the layer to the top.
497 /// <since_tizen> 3 </since_tizen>
498 public void RaiseToTop()
500 var parentChildren = window?.LayersChildren;
502 if (parentChildren != null)
504 parentChildren.Remove(this);
505 parentChildren.Add(this);
507 Interop.Layer.RaiseToTop(SwigCPtr);
508 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
513 /// Lowers the layer to the bottom.
515 /// <since_tizen> 3 </since_tizen>
516 public void LowerToBottom()
518 var parentChildren = window?.LayersChildren;
520 if (parentChildren != null)
522 parentChildren.Remove(this);
523 parentChildren.Insert(0, this);
525 Interop.Layer.LowerToBottom(SwigCPtr);
526 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
531 /// Moves the layer directly above the given layer.<br />
532 /// After the call, this layer's depth will be immediately above target.<br />
534 /// <param name="target">The layer to get on top of.</param>
535 /// <since_tizen> 3 </since_tizen>
536 public void MoveAbove(Layer target)
538 Interop.Layer.MoveAbove(SwigCPtr, Layer.getCPtr(target));
539 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
543 /// Moves the layer directly below the given layer.<br />
544 /// After the call, this layer's depth will be immediately below target.<br />
546 /// <param name="target">The layer to get below of.</param>
547 /// <since_tizen> 3 </since_tizen>
548 public void MoveBelow(Layer target)
550 Interop.Layer.MoveBelow(SwigCPtr, Layer.getCPtr(target));
551 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
554 /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API.
555 [EditorBrowsable(EditorBrowsableState.Never)]
556 public void SetAnchorPoint(Vector3 anchorPoint)
558 Interop.Actor.SetAnchorPoint(SwigCPtr, Vector3.getCPtr(anchorPoint));
559 if (NDalicPINVOKE.SWIGPendingException.Pending)
560 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
563 /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API.
564 [EditorBrowsable(EditorBrowsableState.Never)]
565 public void SetSize(float width, float height)
567 Interop.ActorInternal.SetSize(SwigCPtr, width, height);
568 if (NDalicPINVOKE.SWIGPendingException.Pending)
569 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
572 /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API.
573 [EditorBrowsable(EditorBrowsableState.Never)]
574 public void SetParentOrigin(Vector3 parentOrigin)
576 Interop.ActorInternal.SetParentOrigin(SwigCPtr, Vector3.getCPtr(parentOrigin));
577 if (NDalicPINVOKE.SWIGPendingException.Pending)
578 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
581 /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API.
582 [EditorBrowsable(EditorBrowsableState.Never)]
583 public void SetResizePolicy(ResizePolicyType policy, DimensionType dimension)
585 Interop.Actor.SetResizePolicy(SwigCPtr, (int)policy, (int)dimension);
586 if (NDalicPINVOKE.SWIGPendingException.Pending)
587 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
592 /// This allows the user to specify whether this layer should consume touch (including gestures).
593 /// If set, any layers behind this layer will not be hit-test.
595 /// <param name="consume">Whether the layer should consume touch (including gestures).</param>
596 [EditorBrowsable(EditorBrowsableState.Never)]
597 public void SetTouchConsumed(bool consume)
599 Interop.Layer.SetTouchConsumed(SwigCPtr, consume);
600 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
605 /// This allows the user to specify whether this layer should consume hover.
606 /// If set, any layers behind this layer will not be hit-test.
608 /// <param name="consume">Whether the layer should consume hover</param>
609 [EditorBrowsable(EditorBrowsableState.Never)]
610 public void SetHoverConsumed(bool consume)
612 Interop.Layer.SetHoverConsumed(SwigCPtr, consume);
613 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
616 internal uint GetDepth()
618 var parentChildren = window?.LayersChildren;
619 if (parentChildren != null)
621 int idx = parentChildren.IndexOf(this);
624 return Convert.ToUInt32(idx); ;
629 internal void RaiseAbove(Layer target)
631 var parentChildren = window?.LayersChildren;
632 if (parentChildren != null)
634 int currentIndex = parentChildren.IndexOf(this);
635 int targetIndex = parentChildren.IndexOf(target);
637 if (currentIndex < 0 || targetIndex < 0 ||
638 currentIndex >= parentChildren.Count || targetIndex >= parentChildren.Count)
640 NUILog.Error("index should be bigger than 0 and less than children of layer count");
644 // If the currentIndex is less than the target index and the target has the same parent.
645 if (currentIndex < targetIndex)
647 parentChildren.Remove(this);
648 parentChildren.Insert(targetIndex, this);
650 Interop.Layer.MoveAbove(SwigCPtr, Layer.getCPtr(target));
651 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
656 internal void LowerBelow(Layer target)
658 var parentChildren = window?.LayersChildren;
660 if (parentChildren != null)
662 int currentIndex = parentChildren.IndexOf(this);
663 int targetIndex = parentChildren.IndexOf(target);
665 if (currentIndex < 0 || targetIndex < 0 ||
666 currentIndex >= parentChildren.Count || targetIndex >= parentChildren.Count)
668 NUILog.Error("index should be bigger than 0 and less than children of layer count");
672 // If the currentIndex is not already the 0th index and the target has the same parent.
673 if ((currentIndex != 0) && (targetIndex != -1) &&
674 (currentIndex > targetIndex))
676 parentChildren.Remove(this);
677 parentChildren.Insert(targetIndex, this);
679 Interop.Layer.MoveBelow(SwigCPtr, Layer.getCPtr(target));
680 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
685 internal void SetSortFunction(SWIGTYPE_p_f_r_q_const__Dali__Vector3__float function)
687 Interop.Layer.SetSortFunction(SwigCPtr, SWIGTYPE_p_f_r_q_const__Dali__Vector3__float.getCPtr(function));
688 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
691 internal bool IsTouchConsumed()
693 bool ret = Interop.Layer.IsTouchConsumed(SwigCPtr);
694 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
697 internal bool IsHoverConsumed()
699 bool ret = Interop.Layer.IsHoverConsumed(SwigCPtr);
700 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
704 internal void AddViewToLayerList(View view)
709 internal void RemoveViewFromLayerList(View view)
711 Children.Remove(view);
714 internal string GetName()
716 string ret = Interop.Actor.GetName(SwigCPtr);
717 if (NDalicPINVOKE.SWIGPendingException.Pending)
718 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
722 internal void SetName(string name)
724 Interop.Actor.SetName(SwigCPtr, name);
725 if (NDalicPINVOKE.SWIGPendingException.Pending)
726 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
729 internal void SetWindow(Window win)
731 if (window == win) return;
735 window.LayoutController.LayoutCount -= LayoutCount;
742 window.LayoutController.LayoutCount += LayoutCount;
746 internal uint GetId()
748 uint ret = Interop.Actor.GetId(SwigCPtr);
749 if (NDalicPINVOKE.SWIGPendingException.Pending)
750 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
755 /// The number of layouts of children views.
756 /// This can be used to set/unset Process callback to calculate Layout.
758 internal int LayoutCount
767 if (layoutCount == value) return;
769 if (value < 0) throw new global::System.ArgumentOutOfRangeException(nameof(LayoutCount), "LayoutCount(" + LayoutCount + ") should not be less than zero");
771 int diff = value - layoutCount;
776 window.LayoutController.LayoutCount += diff;
781 /// This will not be public opened.
782 [EditorBrowsable(EditorBrowsableState.Never)]
783 protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
785 Interop.Layer.DeleteLayer(swigCPtr);
788 private void SetBehavior(LayerBehavior behavior)
790 Interop.Layer.SetBehavior(SwigCPtr, (int)behavior);
791 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
794 private LayerBehavior GetBehavior()
796 Layer.LayerBehavior ret = (Layer.LayerBehavior)Interop.Layer.GetBehavior(SwigCPtr);
797 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
801 internal class Property
803 internal static readonly int BEHAVIOR = Interop.Layer.BehaviorGet();