/* * Copyright(c) 2019 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ using System; using Tizen.NUI.BaseComponents; using System.ComponentModel; using Tizen.NUI.Binding; namespace Tizen.NUI { /// /// Layers provide a mechanism for overlaying groups of actors on top of each other. /// /// 3 public class Layer : Container { private Window window; /// /// Creates a Layer object. /// /// 3 public Layer() : this(Interop.Layer.New(), true) { if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); this.SetAnchorPoint(Tizen.NUI.PivotPoint.TopLeft); this.SetResizePolicy(ResizePolicyType.FillToParent, DimensionType.AllDimensions); } internal Layer(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) { } /// /// Enumeration for the behavior of the layer. /// /// 3 public enum LayerBehavior { /// /// UI control rendering mode (default mode). /// This mode is designed for UI controls that can overlap. In this /// mode renderer order will be respective to the tree hierarchy of /// Actors.
/// The rendering order is depth first, so for the following actor tree, /// A will be drawn first, then B, D, E, then C, F. This ensures that /// overlapping actors are drawn as expected (whereas, with breadth first /// traversal, the actors would interleave).
///
/// 3 LayerUI, /// /// Deprecated in API6; Will be removed in API9. Please use LayerUI instead. /// /// 3 [Obsolete("Deprecated in API6; Will be removed in API9. Please use LayerUI instead.")] [EditorBrowsable(EditorBrowsableState.Never)] Layer2D = LayerUI, /// /// Layer will use depth test. /// This mode is designed for a 3 dimensional scene where actors in front /// of other actors will obscure them, i.e. the actors are sorted by the /// distance from the camera.
/// When using this mode, a depth test will be used. A depth clear will /// happen for each layer, which means actors in a layer "above" other /// layers will be rendered in front of actors in those layers regardless /// of their Z positions (see Layer::Raise() and Layer::Lower()).
/// Opaque renderers are drawn first and write to the depth buffer. Then /// transparent renderers are drawn with depth test enabled but depth /// write switched off. Transparent renderers are drawn based on their /// distance from the camera. A renderer's DEPTH_INDEX property is used to /// offset the distance to the camera when ordering transparent renderers. /// This is useful if you want to define the draw order of two or more /// transparent renderers that are equal distance from the camera. Unlike /// LAYER_UI, parent-child relationship does not affect rendering order at /// all. ///
/// 3 Layer3D } internal enum TreeDepthMultiplier { TREE_DEPTH_MULTIPLIER = 10000 } /// /// Layer behavior, type String (Layer.LayerBehavior). /// /// 3 public Layer.LayerBehavior Behavior { get { return GetBehavior(); } set { SetBehavior(value); } } /// /// Sets the viewport (in window coordinates), type rectangle. /// The contents of the layer will not be visible outside this box, when ViewportEnabled is true. /// /// 4 public Rectangle Viewport { get { if (ClippingEnabled) { Rectangle ret = new Rectangle(Interop.Layer.GetClippingBox(SwigCPtr), true); if (NDalicPINVOKE.SWIGPendingException.Pending) throw new InvalidOperationException("FATAL: get Exception", NDalicPINVOKE.SWIGPendingException.Retrieve()); return ret; } else { // Clipping not enabled so return the window size Size2D windowSize = window?.Size; Rectangle ret = new Rectangle(0, 0, windowSize.Width, windowSize.Height); return ret; } } set { Interop.Layer.SetClippingBox(SwigCPtr, Rectangle.getCPtr(value)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); ClippingEnabled = true; } } /// /// Retrieves and sets the layer's opacity.
///
/// 3 public float Opacity { get { float temp = 0.0f; var pValue = GetProperty(View.Property.OPACITY); pValue.Get(out temp); pValue.Dispose(); return temp; } set { var temp = new Tizen.NUI.PropertyValue(value); SetProperty(View.Property.OPACITY, temp); temp.Dispose(); } } /// /// Retrieves and sets the layer's visibility. /// /// 3 public bool Visibility { get { bool temp = false; var pValue = GetProperty(View.Property.VISIBLE); pValue.Get(out temp); pValue.Dispose(); return temp; } set { var temp = new Tizen.NUI.PropertyValue(value); SetProperty(View.Property.VISIBLE, temp); temp.Dispose(); } } /// /// Get the number of children held by the layer. /// /// 3 public new uint ChildCount { get { return Convert.ToUInt32(Children.Count); } } /// /// Gets or sets the layer's name. /// /// 3 public string Name { get { return GetName(); } set { SetName(value); } } /// /// Queries the depth of the layer.
/// 0 is the bottommost layer, higher number is on the top.
///
/// 3 public uint Depth { get { return GetDepth(); } } /// /// Internal only property to enable or disable clipping, type boolean. /// By default, this is false, i.e., the viewport of the layer is the entire window. /// internal bool ClippingEnabled { get { bool ret = Interop.Layer.IsClipping(SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } set { Interop.Layer.SetClipping(SwigCPtr, value); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } } /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public ResourceDictionary XamlResources { get { return Application.Current.XamlResources; } set { Application.Current.XamlResources = value; } } /// From the Container base class. /// /// Adds a child view to this layer. /// /// /// /// Thrown when child is null. /// 4 public override void Add(View child) { if (null == child) { throw new ArgumentNullException(nameof(child)); } Container oldParent = child.GetParent(); if (oldParent != this) { if (oldParent != null) { oldParent.Remove(child); } else { child.InternalParent = this; } Interop.Actor.Add( SwigCPtr , View.getCPtr(child)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); Children.Add(child); BindableObject.SetInheritedBindingContext(child, this?.BindingContext); } } /// /// Removes a child view from this layer. If the view was not a child of this layer, this is a no-op. /// /// /// /// Thrown when child is null. /// 4 public override void Remove(View child) { if (null == child) { throw new ArgumentNullException(nameof(child)); } Interop.Actor.Remove( SwigCPtr, View.getCPtr(child)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); Children.Remove(child); child.InternalParent = null; } /// /// Retrieves a child view by the index. /// ///
The view has been initialized.
/// The index of the child to retrieve. /// The view for the given index or empty handle if children not initialized. /// 4 public override View GetChildAt(uint index) { if (index < Children.Count) { return Children[Convert.ToInt32(index)]; } else { return null; } } /// /// Get parent of the layer. /// /// The view's container /// 4 public override Container GetParent() { return null; } /// /// Get the child count of the layer. /// /// The child count of the layer. /// 4 [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")] public override uint GetChildCount() { return Convert.ToUInt32(Children.Count); } /// /// Downcasts a handle to layer handle. /// /// Thrown when handle is null. /// 3 /// Please do not use! this will be deprecated! /// Instead please use as keyword. [Obsolete("Please do not use! This will be deprecated! Please use as keyword instead!")] [EditorBrowsable(EditorBrowsableState.Never)] public static Layer DownCast(BaseHandle handle) { if (null == handle) { throw new ArgumentNullException(nameof(handle)); } Layer ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as Layer; if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } /// /// Search through this layer's hierarchy for a view with the given unique ID. /// ///
This layer (the parent) has been initialized.
/// The actor itself is also considered in the search. /// The id of the child to find /// A handle to the view if found, or an empty handle if not. /// 3 public View FindChildById(uint id) { //to fix memory leak issue, match the handle count with native side. IntPtr cPtr = Interop.Actor.FindChildById(SwigCPtr, id); View ret = this.GetInstanceSafely(cPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } internal override View FindCurrentChildById(uint id) { return FindChildById(id); } /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public View FindChildByName(string viewName) { //to fix memory leak issue, match the handle count with native side. IntPtr cPtr = Interop.Actor.FindChildByName(SwigCPtr, viewName); View ret = this.GetInstanceSafely(cPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } /// /// Increments the depth of the layer. /// /// 3 public void Raise() { var parentChildren = window?.LayersChildren; if (parentChildren != null) { int currentIdx = parentChildren.IndexOf(this); if (currentIdx >= 0 && currentIdx < parentChildren.Count - 1) { var upper = parentChildren[currentIdx + 1]; RaiseAbove(upper); } } } /// /// Decrements the depth of the layer. /// /// 3 public void Lower() { var parentChildren = window?.LayersChildren; if (parentChildren != null) { int currentIdx = parentChildren.IndexOf(this); if (currentIdx > 0 && currentIdx < parentChildren.Count) { var low = parentChildren[currentIdx - 1]; LowerBelow(low); } } } /// /// Raises the layer to the top. /// /// 3 public void RaiseToTop() { var parentChildren = window?.LayersChildren; if (parentChildren != null) { parentChildren.Remove(this); parentChildren.Add(this); Interop.Layer.RaiseToTop(SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } } /// /// Lowers the layer to the bottom. /// /// 3 public void LowerToBottom() { var parentChildren = window?.LayersChildren; if (parentChildren != null) { parentChildren.Remove(this); parentChildren.Insert(0, this); Interop.Layer.LowerToBottom(SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } } /// /// Moves the layer directly above the given layer.
/// After the call, this layer's depth will be immediately above target.
///
/// The layer to get on top of. /// 3 public void MoveAbove(Layer target) { Interop.Layer.MoveAbove(SwigCPtr, Layer.getCPtr(target)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } /// /// Moves the layer directly below the given layer.
/// After the call, this layer's depth will be immediately below target.
///
/// The layer to get below of. /// 3 public void MoveBelow(Layer target) { Interop.Layer.MoveBelow(SwigCPtr, Layer.getCPtr(target)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } internal static global::System.Runtime.InteropServices.HandleRef getCPtr(Layer obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr; } /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public void SetAnchorPoint(Vector3 anchorPoint) { Interop.Actor.SetAnchorPoint(SwigCPtr, Vector3.getCPtr(anchorPoint)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public void SetSize(float width, float height) { Interop.ActorInternal.SetSize(SwigCPtr, width, height); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public void SetParentOrigin(Vector3 parentOrigin) { Interop.ActorInternal.SetParentOrigin(SwigCPtr, Vector3.getCPtr(parentOrigin)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } /// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public void SetResizePolicy(ResizePolicyType policy, DimensionType dimension) { Interop.Actor.SetResizePolicy(SwigCPtr, (int)policy, (int)dimension); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } /// /// Inhouse API. /// This allows the user to specify whether this layer should consume touch (including gestures). /// If set, any layers behind this layer will not be hit-test. /// /// Whether the layer should consume touch (including gestures). [EditorBrowsable(EditorBrowsableState.Never)] public void SetTouchConsumed(bool consume) { Interop.Layer.SetTouchConsumed(SwigCPtr, consume); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } /// /// Inhouse API. /// This allows the user to specify whether this layer should consume hover. /// If set, any layers behind this layer will not be hit-test. /// /// Whether the layer should consume hover [EditorBrowsable(EditorBrowsableState.Never)] public void SetHoverConsumed(bool consume) { Interop.Layer.SetHoverConsumed(SwigCPtr, consume); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } internal uint GetDepth() { var parentChildren = window?.LayersChildren; if (parentChildren != null) { int idx = parentChildren.IndexOf(this); if (idx >= 0) { return Convert.ToUInt32(idx); ; } } return 0u; } internal void RaiseAbove(Layer target) { var parentChildren = window?.LayersChildren; if (parentChildren != null) { int currentIndex = parentChildren.IndexOf(this); int targetIndex = parentChildren.IndexOf(target); if (currentIndex < 0 || targetIndex < 0 || currentIndex >= parentChildren.Count || targetIndex >= parentChildren.Count) { NUILog.Error("index should be bigger than 0 and less than children of layer count"); return; } // If the currentIndex is less than the target index and the target has the same parent. if (currentIndex < targetIndex) { parentChildren.Remove(this); parentChildren.Insert(targetIndex, this); Interop.Layer.MoveAbove(SwigCPtr, Layer.getCPtr(target)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } } } internal void LowerBelow(Layer target) { var parentChildren = window?.LayersChildren; if (parentChildren != null) { int currentIndex = parentChildren.IndexOf(this); int targetIndex = parentChildren.IndexOf(target); if (currentIndex < 0 || targetIndex < 0 || currentIndex >= parentChildren.Count || targetIndex >= parentChildren.Count) { NUILog.Error("index should be bigger than 0 and less than children of layer count"); return; } // If the currentIndex is not already the 0th index and the target has the same parent. if ((currentIndex != 0) && (targetIndex != -1) && (currentIndex > targetIndex)) { parentChildren.Remove(this); parentChildren.Insert(targetIndex, this); Interop.Layer.MoveBelow(SwigCPtr, Layer.getCPtr(target)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } } } internal void SetSortFunction(SWIGTYPE_p_f_r_q_const__Dali__Vector3__float function) { Interop.Layer.SetSortFunction(SwigCPtr, SWIGTYPE_p_f_r_q_const__Dali__Vector3__float.getCPtr(function)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } internal bool IsTouchConsumed() { bool ret = Interop.Layer.IsTouchConsumed(SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } internal bool IsHoverConsumed() { bool ret = Interop.Layer.IsHoverConsumed(SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } internal void AddViewToLayerList(View view) { Children.Add(view); } internal void RemoveViewFromLayerList(View view) { Children.Remove(view); } internal string GetName() { string ret = Interop.Actor.GetName(SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } internal void SetName(string name) { Interop.Actor.SetName(SwigCPtr, name); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } internal void SetWindow(Window win) { window = win; } /// This will not be public opened. [EditorBrowsable(EditorBrowsableState.Never)] protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr) { Interop.Layer.DeleteLayer(swigCPtr); } private void SetBehavior(LayerBehavior behavior) { Interop.Layer.SetBehavior(SwigCPtr, (int)behavior); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } private LayerBehavior GetBehavior() { Layer.LayerBehavior ret = (Layer.LayerBehavior)Interop.Layer.GetBehavior(SwigCPtr); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } internal class Property { internal static readonly int BEHAVIOR = Interop.Layer.BehaviorGet(); } } }