/*
- * Copyright(c) 2019 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 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.
using System;
using Tizen.NUI.BaseComponents;
using System.ComponentModel;
-using Tizen.NUI.Binding;
+using System.Runtime.InteropServices;
namespace Tizen.NUI
{
public class Layer : Container
{
private Window window;
+ private int layoutCount = 0;
+ private EventHandler<VisibilityChangedEventArgs> visibilityChangedEventHandler;
+ private VisibilityChangedEventCallbackType visibilityChangedEventCallback;
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ private delegate void VisibilityChangedEventCallbackType(IntPtr data, bool visibility, VisibilityChangeType type);
/// <summary>
/// Creates a Layer object.
}
/// <summary>
+ /// Dispose Explicit or Implicit
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+
+ if (visibilityChangedEventCallback != null)
+ {
+ NUILog.Debug($"[Dispose] visibilityChangedEventCallback");
+
+ Interop.ActorSignal.VisibilityChangedDisconnect(GetBaseHandleCPtrHandleRef, visibilityChangedEventCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExistsDebug();
+ visibilityChangedEventCallback = null;
+ }
+
+ LayoutCount = 0;
+
+ base.Dispose(type);
+ }
+
+ /// <summary>
/// Enumeration for the behavior of the layer.
/// </summary>
/// <since_tizen> 3 </since_tizen>
LayerUI,
/// <summary>
- /// Deprecated in API6; Will be removed in API9. Please use LayerUI instead.
- /// </summary>
- /// <since_tizen> 3 </since_tizen>
- [Obsolete("Deprecated in API6; Will be removed in API9. Please use LayerUI instead.")]
- [EditorBrowsable(EditorBrowsableState.Never)]
- Layer2D = LayerUI,
-
- /// <summary>
/// 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
}
}
- /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
+ /// <summary>
+ /// Gets the Layer's ID
+ /// Readonly
+ /// </summary>
+ /// <remarks>Hidden-API</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
- public ResourceDictionary XamlResources
+ public uint ID
{
get
{
- return Application.Current.XamlResources;
- }
- set
- {
- Application.Current.XamlResources = value;
+ return GetId();
}
}
+
/// From the Container base class.
/// <summary>
{
child.InternalParent = this;
}
- Interop.Actor.Add( SwigCPtr , View.getCPtr(child));
+
+ LayoutCount += child.LayoutCount;
+
+ Interop.Actor.Add(SwigCPtr, View.getCPtr(child));
if (NDalicPINVOKE.SWIGPendingException.Pending)
throw NDalicPINVOKE.SWIGPendingException.Retrieve();
Children.Add(child);
- BindableObject.SetInheritedBindingContext(child, this?.BindingContext);
+ OnChildAdded(child);
}
}
{
throw new ArgumentNullException(nameof(child));
}
- Interop.Actor.Remove( SwigCPtr, View.getCPtr(child));
+ if (child.GetParent() == null) // Early out if child parent is null.
+ return;
+
+ if (child.GetParent() != this)
+ {
+ //throw new System.InvalidOperationException("You have deleted a view that is not a child of this layer.");
+ Tizen.Log.Error("NUI", "You have deleted a view that is not a child of this layer.");
+ return;
+ }
+ // If the view had focus, it clears focus.
+ if (child == FocusManager.Instance.GetCurrentFocusView())
+ {
+ FocusManager.Instance.ClearFocus();
+ }
+
+ Interop.Actor.Remove(SwigCPtr, View.getCPtr(child));
if (NDalicPINVOKE.SWIGPendingException.Pending)
throw NDalicPINVOKE.SWIGPendingException.Retrieve();
Children.Remove(child);
child.InternalParent = null;
+ OnChildRemoved(child);
+ LayoutCount -= child.LayoutCount;
}
/// <summary>
/// </summary>
/// <returns>The child count of the layer.</returns>
/// <since_tizen> 4 </since_tizen>
- [Obsolete("Deprecated in API9, will be removed in API11. Please use ChildCount property instead!")]
+ [Obsolete("This has been deprecated in API9 and will be removed in API11. Use ChildCount property instead")]
public override uint GetChildCount()
{
return Convert.ToUInt32(Children.Count);
/// </summary>
/// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
/// <since_tizen> 3 </since_tizen>
- /// 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!")]
+ /// Do not use this, that will be deprecated. Use as keyword instead.
+ [Obsolete("Do not use this, that will be deprecated. Use as keyword instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public static Layer DownCast(BaseHandle handle)
{
if (parentChildren != null)
{
int currentIdx = parentChildren.IndexOf(this);
+ int idx = window.IsBorderEnabled ? 1 : 0;
- if (currentIdx > 0 && currentIdx < parentChildren.Count)
+ if (currentIdx > idx && currentIdx < parentChildren.Count)
{
var low = parentChildren[currentIdx - 1];
LowerBelow(low);
parentChildren.Insert(0, this);
Interop.Layer.LowerToBottom(SwigCPtr);
+
+ if (window.IsBorderEnabled)
+ {
+ Layer bottomLayer = window.GetBorderWindowBottomLayer();
+ parentChildren.Remove(bottomLayer);
+ parentChildren.Insert(0, bottomLayer);
+ Interop.Layer.LowerToBottom(Layer.getCPtr(bottomLayer));
+ }
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
/// <since_tizen> 3 </since_tizen>
public void MoveAbove(Layer target)
{
- Interop.Layer.MoveAbove(SwigCPtr, Layer.getCPtr(target));
- if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ RaiseAbove(target);
}
/// <summary>
/// <since_tizen> 3 </since_tizen>
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;
+ LowerBelow(target);
}
/// This will be public opened in next tizen after ACR done. Before ACR, need to be hidden as inhouse API.
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
+ /// <summary>
+ /// An event for visibility change which can be used to subscribe or unsubscribe the event handler.<br />
+ /// This signal is emitted when the visible property of this or a parent view is changed.<br />
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public event EventHandler<VisibilityChangedEventArgs> VisibilityChanged
+ {
+ add
+ {
+ if (visibilityChangedEventHandler == null)
+ {
+ visibilityChangedEventCallback = OnVisibilityChanged;
+ Interop.ActorSignal.VisibilityChangedConnect(SwigCPtr, visibilityChangedEventCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+ visibilityChangedEventHandler += value;
+ }
+
+ remove
+ {
+ visibilityChangedEventHandler -= value;
+ if (visibilityChangedEventHandler == null && visibilityChangedEventCallback != null)
+ {
+ Interop.ActorSignal.VisibilityChangedDisconnect(SwigCPtr, visibilityChangedEventCallback.ToHandleRef(this));
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ visibilityChangedEventCallback = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Event arguments of visibility changed.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class VisibilityChangedEventArgs : EventArgs
+ {
+ private Layer layer;
+ private bool visibility;
+
+ /// <summary>
+ /// The layer whose visibility has changed.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Layer Layer
+ {
+ get
+ {
+ return layer;
+ }
+ set
+ {
+ layer = value;
+ }
+ }
+
+ /// <summary>
+ /// Whether the layer is now visible or not.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool Visibility
+ {
+ get
+ {
+ return visibility;
+ }
+ set
+ {
+ visibility = value;
+ }
+ }
+ }
+
internal uint GetDepth()
{
var parentChildren = window?.LayersChildren;
internal void SetWindow(Window win)
{
+ if (window == win) return;
+
+ if (window != null)
+ {
+ window.LayoutController.LayoutCount -= LayoutCount;
+ }
+
window = win;
+
+ if (window != null)
+ {
+ window.LayoutController.LayoutCount += LayoutCount;
+ }
+ }
+
+ internal uint GetId()
+ {
+ uint ret = Interop.Actor.GetId(SwigCPtr);
+ if (NDalicPINVOKE.SWIGPendingException.Pending)
+ throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ return ret;
+ }
+
+ /// <summary>
+ /// The number of layouts of children views.
+ /// This can be used to set/unset Process callback to calculate Layout.
+ /// </summary>
+ internal int LayoutCount
+ {
+ get
+ {
+ return layoutCount;
+ }
+
+ set
+ {
+ if (layoutCount == value) return;
+
+ if (value < 0) throw new global::System.ArgumentOutOfRangeException(nameof(LayoutCount), "LayoutCount(" + LayoutCount + ") should not be less than zero");
+
+ if (window != null)
+ {
+ int diff = value - layoutCount;
+ window.LayoutController.LayoutCount += diff;
+ }
+ layoutCount = value;
+ }
}
/// This will not be public opened.
{
internal static readonly int BEHAVIOR = Interop.Layer.BehaviorGet();
}
+
+ // Callback for View visibility change signal
+ // type is not used because layer does not have parent so layer's visibility cannot be changed by its parent.
+ private void OnVisibilityChanged(IntPtr data, bool visibility, VisibilityChangeType type)
+ {
+ VisibilityChangedEventArgs e = new VisibilityChangedEventArgs();
+ if (data != IntPtr.Zero)
+ {
+ e.Layer = Registry.GetManagedBaseHandleFromNativePtr(data) as Layer;
+ }
+ e.Visibility = visibility;
+
+ if (visibilityChangedEventHandler != null)
+ {
+ visibilityChangedEventHandler(this, e);
+ }
+ }
}
}