// Traverse the tree looking for a root node that is a layout. // Once found, it's children can be assigned Layouts and the Measure process started. private void FindRootLayouts(View rootNode, float parentWidth, float parentHeight) { if (rootNode.Layout != null) { NUILog.Debug("LayoutController Root found:" + rootNode.Name); // rootNode has a layout, start measuring and layouting from here. MeasureAndLayout(rootNode, parentWidth, parentHeight); } else { float rootWidth = rootNode.SizeWidth; float rootHeight = rootNode.SizeHeight; // Search children of supplied node for a layout. for (uint i = 0; i < rootNode.ChildCount; i++) { FindRootLayouts(rootNode.GetChildAt(i), rootWidth, rootHeight); } } }
/// <summary> /// The function which registers a view and all it's scriptable properties with DALi's type registry. /// Means the view can be created or configured from a JSON script. /// /// The function uses introspection to scan a views C# properties, then selects the ones with ///[ScriptableProperty] attribute to be registered. /// Example of a Spin view registering itself: /// static Spin() /// { /// ViewRegistry registers control type with DALi type registery /// also uses introspection to find any properties that need to be registered with type registry /// ViewRegistry.Instance.Register(CreateInstance, typeof(Spin) ); /// } /// /// </summary> /// <since_tizen> 3 </since_tizen> public void Register(Func <CustomView> createFunction, System.Type viewType) { // add the mapping between the view name and it's create function _constructorMap.Add(viewType.ToString(), createFunction); // Call into DALi C++ to register the control with the type registry TypeRegistration.RegisterControl(viewType.ToString(), _createCallback); // Cycle through each property in the class foreach (System.Reflection.PropertyInfo propertyInfo in viewType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public)) { if (propertyInfo.CanRead) { IEnumerable <Attribute> ie_attrs = propertyInfo.GetCustomAttributes <Attribute>(); List <Attribute> li_attrs = new List <Attribute>(ie_attrs); System.Attribute[] attrs = li_attrs.ToArray(); foreach (System.Attribute attr in attrs) { // If the Scriptable attribute exists, then register it with the type registry. if (attr is ScriptableProperty) { NUILog.Debug("Got a DALi JSON scriptable property = " + propertyInfo.Name + ", of type " + propertyInfo.PropertyType.Name); // first get the attribute type, ( default, or animatable) ScriptableProperty scriptableProp = attr as ScriptableProperty; // we get the start property index, based on the type and it's heirachy, e.g. DateView (70,000)-> Spin (60,000) -> View (50,000) int propertyIndex = _propertyRangeManager.GetPropertyIndex(viewType.ToString(), viewType, scriptableProp.type); // get the enum for the property type... E.g. registering a string property returns Tizen.NUI.PropertyType.String Tizen.NUI.PropertyType propertyType = GetDaliPropertyType(propertyInfo.PropertyType.Name); // Example RegisterProperty("spin","maxValue", 50001, FLOAT, set, get ); // Native call to register the property TypeRegistration.RegisterProperty(viewType.ToString(), propertyInfo.Name, propertyIndex, propertyType, _setPropertyCallback, _getPropertyCallback); } } NUILog.Debug("property name = " + propertyInfo.Name); } } }
private void SetupAnimationForPosition(LayoutData layoutPositionData, TransitionComponents positionTransitionComponents) { // A removed item does not have a valid target position within the layout so don't try to position. if (layoutPositionData.ConditionForAnimation != TransitionCondition.Remove) { coreAnimation.AnimateTo(layoutPositionData.Item.Owner, "Position", new Vector3(layoutPositionData.Left, layoutPositionData.Top, layoutPositionData.Item.Owner.Position.Z), positionTransitionComponents.Delay, positionTransitionComponents.Duration, positionTransitionComponents.AlphaFunction); NUILog.Debug("LayoutController SetupAnimationForPosition View:" + layoutPositionData.Item.Owner.Name + " left:" + layoutPositionData.Left + " top:" + layoutPositionData.Top + " delay:" + positionTransitionComponents.Delay + " duration:" + positionTransitionComponents.Duration); } }
/// <summary> /// Set up the animation from each LayoutItems position data. /// Iterates the transition stack, adding an Animator to the core animation. /// </summary> private void SetupCoreAnimation() { NUILog.Debug("LayoutController SetupCoreAnimation for:" + layoutTransitionDataQueue.Count); if (!coreAnimation) { coreAnimation = new Animation(); coreAnimation.EndAction = Animation.EndActions.StopFinal; coreAnimation.Finished += AnimationFinished; } // Iterate all items that have been queued for repositioning. foreach (var layoutPositionData in layoutTransitionDataQueue) { AddAnimatorsToAnimation(layoutPositionData); } // transitions have now been applied, clear stack, ready for new transitions on // next layout traversal. layoutTransitionDataQueue.Clear(); }
/// <summary> /// Stores the mapping between this instance of BaseHandle (C# base class) and native part. /// </summary> /// <param name="baseHandle">The instance of BaseHandle (C# base class).</param> internal static void Register(BaseHandle baseHandle) { if (savedApplicationThread?.ManagedThreadId != Thread.CurrentThread.ManagedThreadId) { throw new global::System.ApplicationException("NUI object is attempt to be created in another thread. It should be created in main thread only!"); } // We store a pointer to the RefObject for the control RefObject refObj = baseHandle.GetObjectPtr(); IntPtr refCptr = (IntPtr)RefObject.getCPtr(refObj); NUILog.Debug("Storing ref object cptr in control map Hex: {0:X}" + refCptr); if (!Instance._controlMap.ContainsKey(refCptr)) { Instance._controlMap.Add(refCptr, new WeakReference(baseHandle, false)); } return; }
/// <summary> /// Called directly from DALi C++ type registry to create a control (view) using no marshalling. /// </summary> /// <returns>Pointer to the control (views) handle.</returns> /// <param name="cPtrControlName">C pointer to the control (view) name.</param> private static IntPtr CreateControl(IntPtr cPtrControlName) { string controlName = System.Runtime.InteropServices.Marshal.PtrToStringAnsi(cPtrControlName); NUILog.Debug("Create controlled called from C++ create a " + controlName); Func <CustomView> controlConstructor; // find the control constructor if (Instance._constructorMap.TryGetValue(controlName, out controlConstructor)) { // Create the control CustomView newControl = controlConstructor(); return(newControl.GetPtrfromView()); // return pointer to handle } else { throw new global::System.InvalidOperationException("C# View not registererd with ViewRegistry" + controlName); } }
/// <summary> /// Dispose. /// </summary> /// <since_tizen> 3 </since_tizen> protected override void Dispose(DisposeTypes type) { NUILog.Debug($"(0x{swigCPtr.Handle:X}) Timer.Dispose(type={type}, disposed={disposed})"); if (this != null && _timerTickCallbackDelegate != null) { TickSignal().Disconnect(_timerTickCallbackOfNative); } if (disposed) { return; } if (type == DisposeTypes.Explicit) { //Called by User //Release your own managed resources here. //You should release all of your own disposable objects here. } //Release your own unmanaged resources here. //You should not access any managed member here except static instance. //because the execution order of Finalizes is non-deterministic. if (swigCPtr.Handle != global::System.IntPtr.Zero) { if (swigCMemOwn) { swigCMemOwn = false; Interop.Timer.delete_Timer(swigCPtr); } swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); } played = false; base.Dispose(type); }
internal BaseHandle(global::System.IntPtr cPtr, bool cMemoryOwn) { //to catch derived classes dali native exceptions if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } NUILog.Debug($"[Dispose] BaseHandle.contructor with cMemeryOwn:{cMemoryOwn} START"); registerMe = swigCMemOwn = cMemoryOwn; swigCPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr); // using copy constructor to create another native handle so Registry.Unregister works fine. swigCPtrCopy = new global::System.Runtime.InteropServices.HandleRef(this, Interop.BaseHandle.NewBaseHandle(swigCPtr)); if (NDalicPINVOKE.SWIGPendingException.Pending) { throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } if (registerMe) { // Register this instance of BaseHandle in the registry. Registry.Register(this); } #if NUI_DEBUG_ON NUILog.Debug($"[Dispose] type:{GetType()} copyNativeHandle:{swigCPtrCopy.Handle.ToString("X8")}"); debuggingCount++; if (this is BaseComponents.View view) { NUILog.Debug($"[Dispose] ID:{view.ID} Name:{view.Name} debuggingCount:{debuggingCount}"); } NUILog.Debug($"[Dispose] BaseHandle.contructor with cMemeryOwn END"); NUILog.Debug($"============================="); #endif }
void SetupAnimationForCustomTransitions(TransitionList transitionsToAnimate, View view) { if (transitionsToAnimate?.Count > 0) { foreach (LayoutTransition transition in transitionsToAnimate) { if (transition.AnimatableProperty != AnimatableProperties.Position && transition.AnimatableProperty != AnimatableProperties.Size) { coreAnimation.AnimateTo(view, transition.AnimatableProperty.ToString(), transition.TargetValue, transition.Animator.Delay, transition.Animator.Duration, transition.Animator.AlphaFunction); NUILog.Debug("LayoutController SetupAnimationForCustomTransitions View:" + view.Name + " Property:" + transition.AnimatableProperty.ToString() + " delay:" + transition.Animator.Delay + " duration:" + transition.Animator.Duration); } } } }
/// <summary> /// Dispose. /// </summary> /// <since_tizen> 3 </since_tizen> protected virtual void Dispose(DisposeTypes type) { if (disposed) { return; } DebugFileLogging.Instance.WriteLog($"BaseHandle.Dispose({type}) START"); if (type == DisposeTypes.Explicit) { //Called by User //Release your own managed resources here. //You should release all of your own disposable objects here. } //Release your own unmanaged resources here. //You should not access any managed member here except static instance. //because the execution order of Finalizes is non-deterministic. //Unreference this instance from Registry. if (registerMe) { Registry.Unregister(this); } disposeDebuggingDispose(type); if (SwigCPtr.Handle != IntPtr.Zero) { if (swigCMemOwn) { swigCMemOwn = false; ReleaseSwigCPtr(SwigCPtr); } swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); } else { var me = this.GetType().FullName; DebugFileLogging.Instance.WriteLog($"[ERR] SwigCPtr is NULL, need to check! me:{me}"); Log.Error("NUI", $"[ERR] SwigCPtr is NULL, need to check! me:{me}"); } if (swigCPtrCopy.Handle != global::System.IntPtr.Zero) { swigCMemOwn = false; Interop.BaseHandle.DeleteBaseHandle(swigCPtrCopy); swigCPtrCopy = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); } else { var me = this.GetType().FullName; DebugFileLogging.Instance.WriteLog($"[ERR] swigCPtrCopy is NULL, need to check! me:{me}"); Log.Error("NUI", $"[ERR] swigCPtrCopy is NULL, need to check! me:{me}"); } disposed = true; DebugFileLogging.Instance.WriteLog($"BaseHandle.Dispose({type}) END"); DebugFileLogging.Instance.WriteLog($"============================="); NUILog.Debug($"BaseHandle.Dispose({type}) END"); NUILog.Debug($"============================="); }
/// <summary> /// Play the animation. /// </summary> private void PlayAnimation() { NUILog.Debug("LayoutController Playing, Core Duration:" + coreAnimation.Duration); coreAnimation.Play(); }
/// <summary> /// Sets a property value on a view. /// </summary> private void SetPropertyValue(IntPtr refObjectPtr, string propertyName, IntPtr propertyValuePtr) { // Get the C# control that maps to the C++ control NUILog.Debug("SetPropertyValue refObjectPtr = {0:X}" + refObjectPtr); PropertyValue propValue = new PropertyValue(propertyValuePtr, false); // Get the C# control that maps to the C++ control View view = Registry.GetManagedBaseHandleFromRefObject(refObjectPtr) as View; if (view != null) { System.Reflection.PropertyInfo propertyInfo = view.GetType().GetProperty(propertyName); // We know the property name, we know it's type, we just need to convert from a DALi property value to native C# type System.Type type = propertyInfo.PropertyType; bool ok = false; if (type.Equals(typeof(Int32))) { int value = 0; ok = propValue.Get(out value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(bool))) { bool value = false; ok = propValue.Get(out value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(float))) { float value = 0; ok = propValue.Get(out value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(string))) { string value = ""; ok = propValue.Get(out value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(Vector2))) { Vector2 value = new Vector2(); ok = propValue.Get(value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(Vector3))) { Vector3 value = new Vector3(); ok = propValue.Get(value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(Vector4))) { Vector4 value = new Vector4(); ok = propValue.Get(value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(Position))) { Position value = new Position(); ok = propValue.Get(value); if (ok) { propertyInfo.SetValue(view, value); } } else if (type.Equals(typeof(Size))) { Size value = new Size(); ok = propValue.Get(value); if (ok) { propertyInfo.SetValue(view, new Size(value.Width, value.Height, value.Depth)); } ; } else if (type.Equals(typeof(Color))) { // Colors are stored as Vector4's in DALi Color value = new Color(); ok = propValue.Get(value); if (ok) { propertyInfo.SetValue(view, (Color)value); } ; } else if (type.Equals(typeof(PropertyMap))) { PropertyMap map = new PropertyMap(); ok = propValue.Get(map); if (ok) { propertyInfo.SetValue(view, map); } } else if (type.Equals(typeof(PropertyArray))) { PropertyArray array = new PropertyArray(); ok = propValue.Get(array); if (ok) { propertyInfo.SetValue(view, array); } } else { throw new global::System.InvalidOperationException("SetPropertyValue Unimplemented type for Property Value for " + type.FullName); } if (!ok) { throw new global::System.InvalidOperationException("SetPropertyValue propValue.Get failed"); } } else { throw new global::System.InvalidOperationException("failed to find the control to write a property to: cptr = " + refObjectPtr); } }
private bool SetFrame(float left, float top, float right, float bottom, bool independent) { bool changed = false; if (layoutPositionData.Left != left || layoutPositionData.Right != right || layoutPositionData.Top != top || layoutPositionData.Bottom != bottom) { changed = true; // Set condition to layout changed as currently unspecified. Add, Remove would have specified a condition. if (ConditionForAnimation.Equals(TransitionCondition.Unspecified)) { ConditionForAnimation = TransitionCondition.LayoutChanged; } // Store new layout position data layoutPositionData = new LayoutData(this, ConditionForAnimation, left, top, right, bottom); NUILog.Debug("LayoutItem FramePositionData View:" + layoutPositionData.Item.Owner.Name + " left:" + layoutPositionData.Left + " top:" + layoutPositionData.Top + " right:" + layoutPositionData.Right + " bottom:" + layoutPositionData.Bottom); View ownerView = Owner.GetParent() as View; if (ownerView?.Layout?.LayoutWithTransition ?? false) { var win = Window.Get(Owner); if (win == null) { NUIApplication.GetDefaultWindow().LayoutController.AddTransitionDataEntry(layoutPositionData); } else { win.LayoutController.AddTransitionDataEntry(layoutPositionData); } } else { if (independent) { // If height or width specification is not explicitly defined, // the size of the owner view must be reset even the ExcludeLayouting is true. if (Owner.HeightSpecification < 0 || Owner.WidthSpecification < 0) { Owner.SetSize(right - left, bottom - top); } } else { Owner.SetSize(right - left, bottom - top); Owner.SetPosition(left, top); } } // Reset condition for animation ready for next transition when required. ConditionForAnimation = TransitionCondition.Unspecified; } return(changed); }
/// <summary> /// Dispose. /// </summary> /// <since_tizen> 3 </since_tizen> protected virtual void Dispose(DisposeTypes type) { if (disposed) { return; } NUILog.Debug($"[Dispose] BaseHandle.Dispose({type}) START"); if (type == DisposeTypes.Explicit) { //Called by User //Release your own managed resources here. //You should release all of your own disposable objects here. } //Release your own unmanaged resources here. //You should not access any managed member here except static instance. //because the execution order of Finalizes is non-deterministic. //Unreference this instance from Registry. if (registerMe) { Registry.Unregister(this); } #if NUI_DEBUG_ON debuggingCount--; NUILog.Debug($"[Dispose] swigCMemOwn:{swigCMemOwn} debuggingCount:{debuggingCount} type:{GetType()} copyNativeHandle:{swigCPtrCopy.Handle.ToString("X8")}"); #endif // this is temporary test code. will be removed laster { if (swigCPtr.Handle != IntPtr.Zero && swigCPtrCopy.Handle != IntPtr.Zero) { var process = global::System.Diagnostics.Process.GetCurrentProcess().Id; var thread = global::System.Threading.Thread.CurrentThread.ManagedThreadId; var me = this.GetType().FullName; var daliId = "unknown"; var hash = this.GetType().GetHashCode(); var name = "unknown"; if (this is BaseComponents.View) { daliId = Interop.Actor.GetId(swigCPtrCopy).ToString(); name = Interop.Actor.GetName(swigCPtrCopy); BaseObject tmp = new BaseObject(Interop.BaseHandle.GetBaseObject(swigCPtrCopy), false); var refCnt = tmp.ReferenceCount(); tmp.Dispose(); if (refCnt > 2) { Log.Error("NUI", $"[ERR] reference count is over than 2. Could be a memory leak. Need to check! \n" + $" process:{process} thread:{thread}, isDisposed:{this.disposed}, isDisposeQueued:{this.isDisposeQueued}, me:{me} \n" + $" disposeType:{type}, name:{name}, daliID:{daliId}, hash:{hash}, refCnt:{refCnt}"); } } } } if (SwigCPtr.Handle != IntPtr.Zero) { if (swigCMemOwn) { swigCMemOwn = false; ReleaseSwigCPtr(SwigCPtr); } swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); } else { var me = this.GetType().FullName; Log.Error("NUI", $"[ERR] SwigCPtr is NULL, need to check! me:{me}"); } if (swigCPtrCopy.Handle != global::System.IntPtr.Zero) { swigCMemOwn = false; Interop.BaseHandle.DeleteBaseHandle(swigCPtrCopy); swigCPtrCopy = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero); } else { var me = this.GetType().FullName; Log.Error("NUI", $"[ERR] swigCPtrCopy is NULL, need to check! me:{me}"); } disposed = true; if (null != Application.Current) { Application.Current.XamlResourceChanged -= OnResourcesChanged; } NUILog.Debug($"[Dispose] BaseHandle.Dispose({type}) END"); NUILog.Debug($"============================="); }
/// <summary> /// Entry point into the C# Layouting that starts the Processing /// </summary> private void Process(int id) { NUILog.Debug("layoutController Process id:" + id ); }