Let we bind custom constraints generate API.
Relative dali patch :
https://review.tizen.org/gerrit/c/platform/core/uifw/dali-toolkit/+/322672 (To make CornerRadius as constraint input)
https://review.tizen.org/gerrit/c/platform/core/uifw/dali-csharp-binder/+/322068
Signed-off-by: Eunki, Hong <eunkiki.hong@samsung.com>
*
*/
-using System.ComponentModel;
+using global::System;
+using global::System.ComponentModel;
+using global::System.Runtime.InteropServices;
namespace Tizen.NUI
{
- using global::System;
- using global::System.Runtime.InteropServices;
-
/// <summary>
/// An abstract base class for Constraints.
+ /// Callback invoked every frame after Apply(), and stop to Remove().
/// This class only use for inhouse currently.
- ///
+ /// </summary>
+ /// <remarks>
/// This can be used to constrain a property of an object, after animations have been applied.
/// Constraints are applied in the following order:
/// - Constraints are applied to on-stage views in a depth-first traversal.
/// - For each view, the constraints are applied in the same order as the calls to Apply().
- /// - Constraints are not applied to off-stage views.
- ///
+ ///
+ /// Use GenerateConstraint() to create new constraints.
+ /// We need three parameter to create constraints : Animatable, Property (string or int), and callback.
+ ///
+ /// Property type and callback type not matched. For example,
+ /// "SizeWidth" only allow to use Constraint.ConstraintFloatFunctionCallbackType.
+ /// "Position" only allow to use Constraint.ConstraintVector3FunctionCallbackType.
+ ///
+ /// Vector4 type property is special. We can use both ConstraintVector4FunctionCallbackType and ConstraintColorFunctionCallbackType.
+ /// "Color" allow to use Constraint.ConstraintVector4FunctionCallbackType and ConstraintColorFunctionCallbackType.
+ ///
+ /// You can register constraint callback at generate time, and cannot unregister or remove.
+ ///
+ /// AddSource used for get input inside of constraint callback.
+ /// AddLocalSource is special API s.t. will use target's property.
+ /// In the callback, you can get additional values ordered by AddSource API.
+ ///
+ /// Constraints are not applied to off-stage views.
+ /// Constraints be invalidate if the target object, or any of source input objects be disposed.
+ ///
/// Create a constraint using one of the New method depending on the type of callback functions used.
- ///
+ ///
+ /// Note : Callback could be called even after target object or Constraint itself disposed.
/// Note : This function will called every frame. Maybe reduce performance if you applyed too many constraints.
- ///
- /// TODO : AddSource(ConstraintSource); API need to be implemented.
- /// To implement this, we have to bind ConstraintSource.
- /// TODO : Currently We don't support custom functions.
- /// To implement this, we have to bind PropertyInputContainer
- /// </summary>
+ /// </remarks>
+ /// <example><code>
+ /// Constraint constraint = Constraint.GenerateConstraint(view, "SizeWidth", new Constraint.ConstraintFloatFunctionCallbackType(YourCallback));
+ /// constraint.AddSource(otherView, "SizeWidth");
+ /// constraint.AddLocalSource("Position");
+ /// constraint.ApplyAction = ConstraintApplyActionType.Discard;
+ /// constraint.Apply();
+ ///
+ /// SetExtraDataById(constraint.ID, 0.0f); // You can use ID value.
+ ///
+ /// float YourCallback(float current, uint id, in PropertyInputContainer inputContainer)
+ /// {
+ /// float input0 = inputContainer.GetFloat(0u); // Match with AddSource or AddLocalSource order.
+ /// UIVector3 input1 = inputContainer.GetVector3(1u); // Match with AddSource or AddLocalSource order.
+ ///
+ /// // Get extra data by id if you need.
+ /// float extraValue = GetExtraDataById(id);
+ ///
+ /// // Implement custom logic.
+ /// float finalValue = current + input0 * 0.1f + input1.X * 0.3f + extraValue;
+ ///
+ /// return finalValue;
+ /// }
+ /// </code></example>
internal class Constraint : BaseHandle
{
- internal Constraint(IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
+ public delegate bool ConstraintBooleanFunctionCallbackType(bool current, uint id, in PropertyInputContainer inputContainer);
+ public delegate float ConstraintFloatFunctionCallbackType(float current, uint id, in PropertyInputContainer inputContainer);
+ public delegate int ConstraintIntegerFunctionCallbackType(int current, uint id, in PropertyInputContainer inputContainer);
+ public delegate UIVector2 ConstraintVector2FunctionCallbackType(UIVector2 current, uint id, in PropertyInputContainer inputContainer);
+ public delegate UIVector3 ConstraintVector3FunctionCallbackType(UIVector3 current, uint id, in PropertyInputContainer inputContainer);
+ public delegate UIColor ConstraintColorFunctionCallbackType(UIColor current, uint id, in PropertyInputContainer inputContainer);
+ public delegate Vector4 ConstraintVector4FunctionCallbackType(in Vector4 current, uint id, in PropertyInputContainer inputContainer);
+ public delegate Matrix3 ConstraintMatrix3FunctionCallbackType(in Matrix3 current, uint id, in PropertyInputContainer inputContainer);
+ public delegate Matrix ConstraintMatrixFunctionCallbackType(in Matrix current, uint id, in PropertyInputContainer inputContainer);
+ public delegate Rotation ConstraintRotationFunctionCallbackType(in Rotation current, uint id, in PropertyInputContainer inputContainer);
+
+ /// <summary>
+ /// Static custructor.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"> Thrown when the target or callback is null. </exception>
+ /// <exception cref="ArgumentException"> Thrown when the property is not animatable. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static Constraint GenerateConstraint(Animatable target, int propertyIndex, System.Delegate callback)
{
+ if (target == null)
+ {
+ throw new ArgumentNullException(nameof(target));
+ }
+ if (callback == null)
+ {
+ throw new ArgumentNullException(nameof(callback));
+ }
+ if (propertyIndex == Property.InvalidIndex)
+ {
+ throw new ArgumentException(nameof(propertyIndex));
+ }
+ if (!target.IsPropertyAnimatable(propertyIndex))
+ {
+ throw new ArgumentException("PropertyIndex is not animatable! index : " + propertyIndex);
+ }
+
+ PropertyType type = target.GetPropertyType(propertyIndex);
+
+ ConstraintFunctionBase function;
+ IntPtr cPtr;
+ switch (type)
+ {
+ case PropertyType.Boolean:
+ {
+ if (!(callback is ConstraintBooleanFunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintBooleanFunctionCallbackType!");
+ }
+ function = new ConstraintBooleanFunction(callback as ConstraintBooleanFunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintBooleanNew(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Float:
+ {
+ if (!(callback is ConstraintFloatFunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintFloatFunctionCallbackType!");
+ }
+ function = new ConstraintFloatFunction(callback as ConstraintFloatFunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintFloatNew(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Integer:
+ {
+ if (!(callback is ConstraintIntegerFunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintIntegerFunctionCallbackType!");
+ }
+ function = new ConstraintIntegerFunction(callback as ConstraintIntegerFunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintIntegerNew(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Vector2:
+ {
+ if (!(callback is ConstraintVector2FunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintVector2FunctionCallbackType!");
+ }
+ function = new ConstraintVector2Function(callback as ConstraintVector2FunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintVector2New(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Vector3:
+ {
+ if (!(callback is ConstraintVector3FunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintVector3FunctionCallbackType!");
+ }
+ function = new ConstraintVector3Function(callback as ConstraintVector3FunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintVector3New(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Vector4:
+ {
+ if (!(callback is ConstraintVector4FunctionCallbackType || callback is ConstraintColorFunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintVector4FunctionCallbackType or ConstraintColorFunctionCallbackType");
+ }
+ if (callback is ConstraintVector4FunctionCallbackType)
+ {
+ function = new ConstraintVector4Function(callback as ConstraintVector4FunctionCallbackType);
+ }
+ else
+ {
+ function = new ConstraintColorFunction(callback as ConstraintColorFunctionCallbackType);
+ }
+ cPtr = Interop.Constraint.ConstraintVector4New(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Matrix3:
+ {
+ if (!(callback is ConstraintMatrix3FunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintMatrix3FunctionCallbackType!");
+ }
+ function = new ConstraintMatrix3Function(callback as ConstraintMatrix3FunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintMatrix3New(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Matrix:
+ {
+ if (!(callback is ConstraintMatrixFunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintMatrixFunctionCallbackType!");
+ }
+ function = new ConstraintMatrixFunction(callback as ConstraintMatrixFunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintMatrixNew(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ case PropertyType.Rotation:
+ {
+ if (!(callback is ConstraintRotationFunctionCallbackType))
+ {
+ throw new ArgumentException("Callback is not ConstraintRotationFunctionCallbackType!");
+ }
+ function = new ConstraintRotationFunction(callback as ConstraintRotationFunctionCallbackType);
+ cPtr = Interop.Constraint.ConstraintRotationNew(Animatable.getCPtr(target), propertyIndex, ConstraintFunctionBase.getCPtr(function));
+ break;
+ }
+ default:
+ {
+ throw new ArgumentException("PropertyIndex is not animatable type! index : " + propertyIndex + " type : " + type);
+ }
+ }
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ Constraint ret = new Constraint(target, propertyIndex, function, cPtr);
+ return ret;
}
/// <summary>
- /// Apply current constraint.
- /// Constraint will work until Remove called.
+ /// Static custructor.
/// </summary>
- internal void Apply()
+ /// <exception cref="ArgumentNullException"> Thrown when the target or callback is null. </exception>
+ /// <exception cref="ArgumentException"> Thrown when the property is not animatable. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static Constraint GenerateConstraint(Animatable target, string propertyName, System.Delegate callback)
{
- Interop.Constraint.Apply(SwigCPtr);
+ if (target == null)
+ {
+ throw new ArgumentNullException(nameof(target));
+ }
+ if (callback == null)
+ {
+ throw new ArgumentNullException(nameof(callback));
+ }
+
+ int propertyIndex = target.GetPropertyIndex(propertyName);
+ if (propertyIndex == Property.InvalidIndex)
+ {
+ throw new ArgumentException("Invalid property! input name : " + propertyName);
+ }
+
+ return GenerateConstraint(target, propertyIndex, callback);
+ }
+
+ private ConstraintFunctionBase Function { get; init; }
+ private WeakReference<Animatable> internalTarget { get; init; }
+
+ internal Constraint(Animatable target, int propertyIndex, ConstraintFunctionBase function, IntPtr cPtr) : this(cPtr, true)
+ {
+ internalTarget = new WeakReference<Animatable>(target);
+ PropertyIndex = propertyIndex;
+ Function = function;
+ }
+
+ internal Constraint(IntPtr cPtr, bool cMemoryOwn) : this(cPtr, cMemoryOwn, cMemoryOwn)
+ {
+ }
+
+ internal Constraint(IntPtr cPtr, bool cMemoryOwn, bool cRegister) : base(cPtr, cMemoryOwn, cRegister)
+ {
+ }
+
+ /// <summary>
+ /// Gets the target of constarint
+ /// Read-only
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Animatable Target
+ {
+ get
+ {
+ if (internalTarget.TryGetTarget(out Animatable ret) && (ret != null) && !ret.IsDisposedOrQueued)
+ {
+ return ret;
+ }
+ return null;
+ }
+ }
+
+ /// <summary>
+ /// Gets the property index of constarint
+ /// Read-only
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public int PropertyIndex { get; init; }
+
+ /// <summary>
+ /// Gets the constraint's ID.
+ /// Read-only
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public uint ID
+ {
+ get => (Function?.Id ?? 0u);
+ }
+
+ /// <summary>
+ /// Remove action.
+ /// Determine the target values action after apply current constriant.
+ /// Default is ConstraintApplyActionType.Bake
+ /// </summary>
+ /// <remarks>
+ /// If ApplyAction is ConstraintApplyActionType.Bake, next frame's current value comes as previous returned value.
+ /// For example, if current value was 1.0f and callback return 2.0f, next frame's current value is 2.0f.
+ ///
+ /// If ApplyAction is ConstraintApplyActionType.Discard, next frame's current value comes as base value.
+ /// For example, if current value was 1.0f and callback return 2.0f, next frame's current value is 1.0f.
+ /// </remarks>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ConstraintApplyActionType ApplyAction
+ {
+ set => Interop.Constraint.SetApplyAction(SwigCPtr, (int)value);
+ get => (ConstraintApplyActionType) Interop.Constraint.GetApplyAction(SwigCPtr);
+ }
+
+ /// <summary>
+ /// Tag number. It will be useful when you want to seperate constraints.
+ /// We can only use [ConstraintTagRanges.TagMin ConstraintTagRanges.TagMax] and ConstraintTagRanges.Default.
+ /// </summary>
+ /// <exception cref="ArgumentException"> Thrown when the tag value out of ranges. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public uint Tag
+ {
+ set
+ {
+ if (value > ConstraintTagRanges.TagMax)
+ {
+ throw new ArgumentException($"The given tag '{value}' is bigger than maximum tag {ConstraintTagRanges.TagMax}");
+ }
+ Interop.Constraint.SetTag(SwigCPtr, value);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+ get => Interop.Constraint.GetTag(SwigCPtr);
+ }
+
+ /// <summary>
+ /// Add source input.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"> Thrown when the source is null. </exception>
+ /// <exception cref="ArgumentException"> Thrown when the property index is invalid. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void AddSource(Animatable source, int propertyIndex)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ if (!source.IsPropertyAConstraintInput(propertyIndex))
+ {
+ throw new ArgumentException("PropertyIndex is not a valid constraint input! index : " + propertyIndex);
+ }
+
+ Interop.Constraint.AddSource(SwigCPtr, Animatable.getCPtr(source), propertyIndex);
NDalicPINVOKE.ThrowExceptionIfExists();
}
/// <summary>
- /// Remove current constraint.
+ /// Add source input.
+ /// </summary>
+ /// <exception cref="ArgumentNullException"> Thrown when the source is null. </exception>
+ /// <exception cref="ArgumentException"> Thrown when the property name is invalid. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void AddSource(Animatable source, string propertyName)
+ {
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+
+ AddSource(source, source.GetPropertyIndex(propertyName));
+ }
+
+ /// <summary>
+ /// Add local source input.
/// </summary>
- internal void Remove()
+ /// <exception cref="ArgumentException"> Thrown when the property index is invalid. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void AddLocalSource(int propertyIndex)
{
- Interop.Constraint.Remove(SwigCPtr);
+ var target = Target;
+ if (target == null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint {ID} lost target! Skip AddLocalSource\n");
+ return;
+ }
+
+ if (!target.IsPropertyAConstraintInput(propertyIndex))
+ {
+ throw new ArgumentException("PropertyIndex is not a valid constraint input! index : " + propertyIndex);
+ }
+ Interop.Constraint.AddLocalSource(SwigCPtr, propertyIndex);
NDalicPINVOKE.ThrowExceptionIfExists();
}
/// <summary>
- /// Remove action. Determine the target values action after remove current constriant.
- /// Default is RemoveActionType.Bake
+ /// Add local source input.
/// </summary>
- internal RemoveActionType RemoveAction
+ /// <exception cref="ArgumentException"> Thrown when the property name is invalid. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void AddLocalSource(string propertyName)
{
- set => Interop.Constraint.SetRemoveAction(SwigCPtr, (int)value);
- get => (RemoveActionType) Interop.Constraint.GetRemoveAction(SwigCPtr);
+ var target = Target;
+ if (target == null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint {ID} lost target! Skip AddLocalSource\n");
+ return;
+ }
+
+ AddLocalSource(target.GetPropertyIndex(propertyName));
}
/// <summary>
- /// Tag number. It will be useful when you want to seperate constraints
+ /// Apply current constraint.
+ /// Constraint will work until Remove called.
/// </summary>
- internal uint Tag
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Apply()
{
- set => Interop.Constraint.SetTag(SwigCPtr, value);
- get => Interop.Constraint.GetTag(SwigCPtr);
+ Interop.Constraint.Apply(SwigCPtr);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+
+ /// <summary>
+ /// Apply current constraint after transform update finished.
+ /// Constraint will work until Remove called.
+ /// </summary>
+ /// <remarks>
+ /// Transform relative properties (e.g. Size, Position, Orientation) will not be changed this frame.
+ /// </remarks>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void ApplyPost()
+ {
+ Interop.Constraint.ApplyPost(SwigCPtr);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+
+ /// <summary>
+ /// Remove current constraint.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Remove()
+ {
+ Interop.Constraint.Remove(SwigCPtr);
+ NDalicPINVOKE.ThrowExceptionIfExists();
}
/// <summary>
/// Get constrainted target object
/// </summary>
- internal BaseHandle GetTargetObject()
+ internal Animatable GetTargetObject()
{
- BaseHandle handle = new BaseHandle(Interop.Constraint.GetTargetObject(SwigCPtr), true);
+ IntPtr cPtr = Interop.Constraint.GetTargetObject(SwigCPtr);
+ Animatable ret = Registry.GetManagedBaseHandleFromNativePtr(cPtr) as Animatable;
+ if (ret != null)
+ {
+ Interop.BaseHandle.DeleteBaseHandle(new global::System.Runtime.InteropServices.HandleRef(this, cPtr));
+ }
+ else
+ {
+ ret = new Animatable(cPtr, true);
+ }
NDalicPINVOKE.ThrowExceptionIfExists();
- return handle;
+ return ret;
}
+
/// <summary>
/// Get constrainted target property index
/// </summary>
return index;
}
+ /// <summary>
+ /// Add parent source input. Only availiable for BaseComponents.View.
+ /// </summary>
+ /// <remarks>
+ /// We cannot throw exception even if propertyIndex is valid or not. Please use this API carefully
+ /// </remarks>
+ /// <exception cref="InvalidOperationException"> Thrown when the target is not a BaseComponents.View. </exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal void AddParentSource(int propertyIndex)
+ {
+ var target = Target;
+ if (target == null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint {ID} lost target! Skip AddParentSource\n");
+ return;
+ }
+
+ if (!(target is BaseComponents.View))
+ {
+ throw new InvalidOperationException($"Error! Target is not a View! type:{target.GetType()}");
+ }
+ Interop.Constraint.AddParentSource(SwigCPtr, propertyIndex);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+
/// <summary>
/// Dispose
/// </summary>
//Release your own managed resources here.
//You should release all of your own disposable objects here.
Remove();
+ Function?.Dispose();
}
base.Dispose(type);
}
Interop.Constraint.DeleteConstraint(swigCPtr);
NDalicPINVOKE.ThrowExceptionIfExists();
}
-
- /// <summary>
- /// Determinate how objects property will be when constraint removed.
- /// Default is Bake.
- /// </summary>
- internal enum RemoveActionType
- {
- /// <summary>
- /// Target objects property will bake when constraint removed.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- Bake,
- /// <summary>
- /// Target objects property will be original value when constraint removed.
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- Discard,
- }
}
}
--- /dev/null
+/*
+ * Copyright(c) 2025 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 global::System;
+using global::System.ComponentModel;
+using global::System.Runtime.InteropServices;
+namespace Tizen.NUI
+{
+ /// <summary>
+ /// Determinate how objects property will be when constraint apply.
+ /// Default is Bake.
+ /// </summary>
+ internal enum ConstraintApplyActionType
+ {
+ /// <summary>
+ /// Target objects property will bake when constraint applied.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ Bake,
+
+ /// <summary>
+ /// Target objects property will be original value when constraint applied.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ Discard,
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2025 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 global::System;
+using global::System.ComponentModel;
+using global::System.Runtime.InteropServices;
+namespace Tizen.NUI
+{
+ /// <summary>
+ /// An abstract base class for ConstraintsFunction.
+ /// Must not be open to public.
+ /// </summary>
+ internal class ConstraintFunctionBase : Disposable
+ {
+ internal ConstraintFunctionBase(IntPtr cPtr, System.Delegate callback) : this(cPtr, true)
+ {
+ Callback = callback;
+ }
+
+ internal ConstraintFunctionBase(IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
+ {
+ }
+
+ internal PropertyType Type { get; init; }
+ internal System.Delegate Callback { get; init; } // Invoke to user
+ internal System.Delegate InternalCallback { get; init; } // Comes from native
+ internal uint Id { get; init; }
+
+ /// <summary>
+ /// Dispose
+ /// </summary>
+ /// <param name="type"></param>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void Dispose(DisposeTypes type)
+ {
+ 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.
+
+ RenderThreadObjectHolder.RegisterDelegate(Callback);
+ RenderThreadObjectHolder.RegisterDelegate(InternalCallback);
+ }
+ base.Dispose(type);
+ }
+
+ /// This will not be public opened.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void ReleaseSwigCPtr(HandleRef swigCPtr)
+ {
+ switch (Type)
+ {
+ case PropertyType.Boolean:
+ {
+ Interop.ConstraintFunction.DeleteBooleanFunction(swigCPtr);
+ break;
+ }
+ case PropertyType.Float:
+ {
+ Interop.ConstraintFunction.DeleteFloatFunction(swigCPtr);
+ break;
+ }
+ case PropertyType.Integer:
+ {
+ Interop.ConstraintFunction.DeleteIntegerFunction(swigCPtr);
+ break;
+ }
+ case PropertyType.Vector2:
+ {
+ Interop.ConstraintFunction.DeleteVector2Function(swigCPtr);
+ break;
+ }
+ case PropertyType.Vector3:
+ {
+ Interop.ConstraintFunction.DeleteVector3Function(swigCPtr);
+ break;
+ }
+ case PropertyType.Vector4:
+ {
+ Interop.ConstraintFunction.DeleteVector4Function(swigCPtr);
+ break;
+ }
+ case PropertyType.Matrix3:
+ {
+ Interop.ConstraintFunction.DeleteMatrix3Function(swigCPtr);
+ break;
+ }
+ case PropertyType.Matrix:
+ {
+ Interop.ConstraintFunction.DeleteMatrixFunction(swigCPtr);
+ break;
+ }
+ case PropertyType.Rotation:
+ {
+ Interop.ConstraintFunction.DeleteRotationFunction(swigCPtr);
+ break;
+ }
+ default:
+ {
+ throw new ArgumentException("Type : " + Type);
+ }
+ }
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for boolean.
+ /// </summary>
+ internal class ConstraintBooleanFunction : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(ref bool current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintBooleanFunction(Constraint.ConstraintBooleanFunctionCallbackType callback) : base(Interop.ConstraintFunction.BooleanFunctionNew(), callback)
+ {
+ Type = PropertyType.Boolean;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetBooleanFunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetBooleanFunction(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(ref bool current, uint id, IntPtr inputContainerCPtr)
+ {
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+ bool ret = (Callback as Constraint.ConstraintBooleanFunctionCallbackType).Invoke(current, id, in container);
+ current = ret;
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for float.
+ /// </summary>
+ internal class ConstraintFloatFunction : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(ref float current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintFloatFunction(Constraint.ConstraintFloatFunctionCallbackType callback) : base(Interop.ConstraintFunction.FloatFunctionNew(), callback)
+ {
+ Type = PropertyType.Float;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetFloatFunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetFloatFunction(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(ref float current, uint id, IntPtr inputContainerCPtr)
+ {
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+ float ret = (Callback as Constraint.ConstraintFloatFunctionCallbackType).Invoke(current, id, in container);
+ current = ret;
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for int.
+ /// </summary>
+ internal class ConstraintIntegerFunction : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(ref int current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintIntegerFunction(Constraint.ConstraintIntegerFunctionCallbackType callback) : base(Interop.ConstraintFunction.IntegerFunctionNew(), callback)
+ {
+ Type = PropertyType.Integer;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetIntegerFunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetIntegerFunction(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(ref int current, uint id, IntPtr inputContainerCPtr)
+ {
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+ int ret = (Callback as Constraint.ConstraintIntegerFunctionCallbackType).Invoke(current, id, in container);
+ current = ret;
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for Vector2.
+ /// </summary>
+ internal class ConstraintVector2Function : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(IntPtr current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintVector2Function(Constraint.ConstraintVector2FunctionCallbackType callback) : base(Interop.ConstraintFunction.Vector2FunctionNew(), callback)
+ {
+ Type = PropertyType.Vector2;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetVector2FunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetVector2Function(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(IntPtr current, uint id, IntPtr inputContainerCPtr)
+ {
+ using Vector2 tempVector2 = new Vector2(current, false);
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+
+ UIVector2 realCurrent = new UIVector2(tempVector2.X, tempVector2.Y);
+ UIVector2 ret = (Callback as Constraint.ConstraintVector2FunctionCallbackType).Invoke(realCurrent, id, in container);
+
+ Interop.Vector2.XSet(Vector2.getCPtr(tempVector2), ret.X);
+ Interop.Vector2.YSet(Vector2.getCPtr(tempVector2), ret.Y);
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for Vector3.
+ /// </summary>
+ internal class ConstraintVector3Function : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(IntPtr current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintVector3Function(Constraint.ConstraintVector3FunctionCallbackType callback) : base(Interop.ConstraintFunction.Vector3FunctionNew(), callback)
+ {
+ Type = PropertyType.Vector3;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetVector3FunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetVector3Function(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(IntPtr current, uint id, IntPtr inputContainerCPtr)
+ {
+ using Vector3 tempVector3 = new Vector3(current, false);
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+
+ UIVector3 realCurrent = new UIVector3(tempVector3.X, tempVector3.Y, tempVector3.Z);
+ UIVector3 ret = (Callback as Constraint.ConstraintVector3FunctionCallbackType).Invoke(realCurrent, id, in container);
+
+ Interop.Vector3.XSet(Vector3.getCPtr(tempVector3), ret.X);
+ Interop.Vector3.YSet(Vector3.getCPtr(tempVector3), ret.Y);
+ Interop.Vector3.ZSet(Vector3.getCPtr(tempVector3), ret.Z);
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for Color. (Special case of Vector4, that we can use UIColor)
+ /// </summary>
+ internal class ConstraintColorFunction : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(IntPtr current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintColorFunction(Constraint.ConstraintColorFunctionCallbackType callback) : base(Interop.ConstraintFunction.Vector4FunctionNew(), callback)
+ {
+ Type = PropertyType.Vector4;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetVector4FunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetVector4Function(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(IntPtr current, uint id, IntPtr inputContainerCPtr)
+ {
+ using Vector4 tempVector4 = new Vector4(current, false);
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+
+ UIColor realCurrent = new UIColor(tempVector4.X, tempVector4.Y, tempVector4.Z, tempVector4.W);
+ UIColor ret = (Callback as Constraint.ConstraintColorFunctionCallbackType).Invoke(realCurrent, id, in container);
+
+ Interop.Vector4.XSet(Vector3.getCPtr(tempVector4), ret.R);
+ Interop.Vector4.YSet(Vector3.getCPtr(tempVector4), ret.G);
+ Interop.Vector4.ZSet(Vector3.getCPtr(tempVector4), ret.B);
+ Interop.Vector4.WSet(Vector3.getCPtr(tempVector4), ret.A);
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for Vector4.
+ /// </summary>
+ internal class ConstraintVector4Function : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(IntPtr current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintVector4Function(Constraint.ConstraintVector4FunctionCallbackType callback) : base(Interop.ConstraintFunction.Vector4FunctionNew(), callback)
+ {
+ Type = PropertyType.Vector4;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetVector4FunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetVector4Function(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(IntPtr current, uint id, IntPtr inputContainerCPtr)
+ {
+ using Vector4 tempVector4 = new Vector4(current, false);
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+
+ // TODO : Chane below logic if UIVector4 Implemented.
+ using Vector4 ret = (Callback as Constraint.ConstraintVector4FunctionCallbackType).Invoke(in tempVector4, id, in container);
+
+ if (ret != null)
+ {
+ Interop.Vector4.XSet(Vector4.getCPtr(tempVector4), ret.X);
+ Interop.Vector4.YSet(Vector4.getCPtr(tempVector4), ret.Y);
+ Interop.Vector4.ZSet(Vector4.getCPtr(tempVector4), ret.Z);
+ Interop.Vector4.WSet(Vector4.getCPtr(tempVector4), ret.W);
+ }
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for Matrix3.
+ /// </summary>
+ internal class ConstraintMatrix3Function : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(IntPtr current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintMatrix3Function(Constraint.ConstraintMatrix3FunctionCallbackType callback) : base(Interop.ConstraintFunction.Matrix3FunctionNew(), callback)
+ {
+ Type = PropertyType.Matrix3;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetMatrix3FunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetMatrix3Function(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(IntPtr current, uint id, IntPtr inputContainerCPtr)
+ {
+ using Matrix3 tempMatix3 = new Matrix3(current, false);
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+
+ using Matrix3 ret = (Callback as Constraint.ConstraintMatrix3FunctionCallbackType).Invoke(in tempMatix3, id, in container);
+
+ if (ret != null)
+ {
+ // Copy to native result. TODO : Can we optimize here?
+ tempMatix3.Assign(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for Matrix.
+ /// </summary>
+ internal class ConstraintMatrixFunction : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(IntPtr current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintMatrixFunction(Constraint.ConstraintMatrixFunctionCallbackType callback) : base(Interop.ConstraintFunction.MatrixFunctionNew(), callback)
+ {
+ Type = PropertyType.Matrix;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetMatrixFunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetMatrixFunction(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(IntPtr current, uint id, IntPtr inputContainerCPtr)
+ {
+ using Matrix tempMatix = new Matrix(current, false);
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+
+ using Matrix ret = (Callback as Constraint.ConstraintMatrixFunctionCallbackType).Invoke(in tempMatix, id, in container);
+
+ if (ret != null)
+ {
+ // Copy to native result. TODO : Can we optimize here?
+ tempMatix.Assign(ret);
+ }
+ }
+ }
+
+ /// <summary>
+ /// An class for ConstraintsFunction for Rotation.
+ /// </summary>
+ internal class ConstraintRotationFunction : ConstraintFunctionBase
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void InternalCallbackType(IntPtr current, uint id, IntPtr inputContainerCPtr);
+
+ public ConstraintRotationFunction(Constraint.ConstraintRotationFunctionCallbackType callback) : base(Interop.ConstraintFunction.RotationFunctionNew(), callback)
+ {
+ Type = PropertyType.Rotation;
+
+ InternalCallback = (InternalCallbackType)OnCallback;
+
+ Id = Interop.ConstraintFunction.GetRotationFunctionId(SwigCPtr);
+
+ var ip = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(InternalCallback);
+
+ Interop.ConstraintFunction.SetRotationFunction(SwigCPtr, new HandleRef(this, ip));
+ }
+
+ private void OnCallback(IntPtr current, uint id, IntPtr inputContainerCPtr)
+ {
+ using Rotation tempRotation = new Rotation(current, false);
+ using PropertyInputContainer container = new PropertyInputContainer(inputContainerCPtr);
+
+ using Rotation ret = (Callback as Constraint.ConstraintRotationFunctionCallbackType).Invoke(in tempRotation, id, in container);
+
+ if (ret != null)
+ {
+ // Copy to native result. TODO : Can we optimize here?
+ tempRotation.Assign(ret);
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2025 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 global::System;
+using global::System.ComponentModel;
+using global::System.Runtime.InteropServices;
+namespace Tizen.NUI
+{
+ /// <summary>
+ /// Determinate the range of constraint tag
+ /// </summary>
+ internal sealed class ConstraintTagRanges
+ {
+ /// <summary>
+ /// Default tag of constraint.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static readonly uint Default = 0;
+
+ /// <summary>
+ /// Minimum number of tag we can use.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static readonly uint TagMin = 1;
+
+ /// <summary>
+ /// Maximum number of tag we can use.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static readonly uint TagMax = 999999999;
+ }
+}
/// Specialized Constraint.
/// Make handle's targetIndex value always equal with handle's parent's parentIndex value
/// </summary>
- internal class EqualConstraintWithParentFloat : Constraint
+ internal sealed class EqualConstraintWithParentFloat : Constraint
{
internal EqualConstraintWithParentFloat(HandleRef handle, int targetIndex, int parentIndex)
: base(Interop.Constraint.NewEqualConstraintWithParentFloat(handle, targetIndex, parentIndex), true)
--- /dev/null
+/*
+ * Copyright(c) 2025 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 global::System;
+using global::System.ComponentModel;
+using global::System.Runtime.InteropServices;
+namespace Tizen.NUI
+{
+ /// <summary>
+ /// An class for Constraints Function.
+ /// </summary>
+ internal class PropertyInputContainer : IDisposable
+ {
+ private HandleRef swigCPtr;
+ private bool disposed;
+
+ internal PropertyInputContainer(IntPtr cPtr)
+ {
+ swigCPtr = new HandleRef(this, cPtr);
+ Count = Interop.PropertyInputContainer.GetCount(swigCPtr);
+ }
+
+ ~PropertyInputContainer() => Dispose(false);
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public uint Count { get; init; }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public PropertyType GetPropertyType(uint index)
+ {
+ int ret = Interop.PropertyInputContainer.GetPropertyType(swigCPtr, index);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return (PropertyType)ret;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool GetBoolean(uint index)
+ {
+ bool ret = Interop.PropertyInputContainer.GetBoolean(swigCPtr, index);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public float GetFloat(uint index)
+ {
+ float ret = Interop.PropertyInputContainer.GetFloat(swigCPtr, index);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public int GetInteger(uint index)
+ {
+ int ret = Interop.PropertyInputContainer.GetInteger(swigCPtr, index);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public UIVector2 GetVector2(uint index)
+ {
+ Interop.PropertyInputContainer.GetVector2Componentwise(swigCPtr, index, out float x, out float y);
+ UIVector2 ret = new UIVector2(x, y);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public UIVector3 GetVector3(uint index)
+ {
+ Interop.PropertyInputContainer.GetVector3Componentwise(swigCPtr, index, out float x, out float y, out float z);
+ UIVector3 ret = new UIVector3(x, y, z);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public UIColor GetColor(uint index)
+ {
+ Interop.PropertyInputContainer.GetVector4Componentwise(swigCPtr, index, out float x, out float y, out float z, out float w);
+ UIColor ret = new UIColor(x, y, z, w);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ public Vector4 GetVector4(uint index)
+ {
+ Interop.PropertyInputContainer.GetVector4Componentwise(swigCPtr, index, out float x, out float y, out float z, out float w);
+ Vector4 ret = new Vector4(x, y, z, w);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ public Matrix3 GetMatrix3(uint index)
+ {
+ Matrix3 ret = new Matrix3(Interop.PropertyInputContainer.GetMatrix3(swigCPtr, index), true);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ public Matrix GetMatrix(uint index)
+ {
+ Matrix ret = new Matrix(Interop.PropertyInputContainer.GetMatrix(swigCPtr, index), true);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ public Rotation GetRotation(uint index)
+ {
+ Rotation ret = new Rotation(Interop.PropertyInputContainer.GetRotation(swigCPtr, index), true);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
+ /// <summary>
+ /// Dispose
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposed)
+ {
+ return;
+ }
+
+ if (swigCPtr.Handle != global::System.IntPtr.Zero)
+ {
+ var nativeSwigCPtr = swigCPtr.Handle;
+ swigCPtr = new HandleRef(null, global::System.IntPtr.Zero);
+ }
+
+ disposed = true;
+ }
+
+ }
+}
/// Specialized Constraint.
/// Make handle's targetIndex value always equal with handle's parent's parentIndex value
/// </summary>
- internal class RelativeConstraintWithParentFloat : Constraint
+ internal sealed class RelativeConstraintWithParentFloat : Constraint
{
internal RelativeConstraintWithParentFloat(HandleRef handle, int targetIndex, int parentIndex, float rate)
: base(Interop.Constraint.NewRelativeConstraintWithParentFloat(handle, targetIndex, parentIndex, rate), true)
{
internal static partial class Constraint
{
-
+ // Property type specific API
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Boolean")]
+ public static extern global::System.IntPtr ConstraintBooleanNew(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Float")]
+ public static extern global::System.IntPtr ConstraintFloatNew(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Integer")]
+ public static extern global::System.IntPtr ConstraintIntegerNew(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Vector2")]
+ public static extern global::System.IntPtr ConstraintVector2New(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Vector3")]
+ public static extern global::System.IntPtr ConstraintVector3New(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Vector4")]
+ public static extern global::System.IntPtr ConstraintVector4New(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Matrix3")]
+ public static extern global::System.IntPtr ConstraintMatrix3New(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Matrix")]
+ public static extern global::System.IntPtr ConstraintMatrixNew(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_New_Quaternion")]
+ public static extern global::System.IntPtr ConstraintRotationNew(global::System.Runtime.InteropServices.HandleRef target, int propertyIndex, global::System.Runtime.InteropServices.HandleRef constraintFunction);
+
+ // Common API
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint")]
public static extern global::System.IntPtr DeleteConstraint(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_AddSource")]
+ public static extern void AddSource(global::System.Runtime.InteropServices.HandleRef jarg1, global::System.Runtime.InteropServices.HandleRef sourceHandle, int sourceIndex);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_AddLocalSource")]
+ public static extern void AddLocalSource(global::System.Runtime.InteropServices.HandleRef jarg1, int sourceIndex);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_AddParentSource")]
+ public static extern void AddParentSource(global::System.Runtime.InteropServices.HandleRef jarg1, int sourceIndex);
+
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Apply")]
public static extern void Apply(global::System.Runtime.InteropServices.HandleRef jarg1);
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_ApplyPost")]
+ public static extern void ApplyPost(global::System.Runtime.InteropServices.HandleRef jarg1);
+
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Remove")]
public static extern void Remove(global::System.Runtime.InteropServices.HandleRef jarg1);
+ // Note : Dali use RemoveAction as apply action behavior.
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_SetRemoveAction")]
- public static extern void SetRemoveAction(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2);
+ public static extern void SetApplyAction(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2);
+ // Note : Dali use RemoveAction as apply action behavior.
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_GetRemoveAction")]
- public static extern int GetRemoveAction(global::System.Runtime.InteropServices.HandleRef jarg1);
+ public static extern int GetApplyAction(global::System.Runtime.InteropServices.HandleRef jarg1);
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_SetTag")]
public static extern void SetTag(global::System.Runtime.InteropServices.HandleRef jarg1, uint jarg2);
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ *
+ */
+
+namespace Tizen.NUI
+{
+ internal static partial class Interop
+ {
+ internal static partial class ConstraintFunction
+ {
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Boolean_New")]
+ public static extern global::System.IntPtr BooleanFunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Boolean_SetHandler")]
+ public static extern void SetBooleanFunction(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Boolean_GetId")]
+ public static extern uint GetBooleanFunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Boolean")]
+ public static extern void DeleteBooleanFunction(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Float_New")]
+ public static extern global::System.IntPtr FloatFunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Float_SetHandler")]
+ public static extern void SetFloatFunction(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Float_GetId")]
+ public static extern uint GetFloatFunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Float")]
+ public static extern void DeleteFloatFunction(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Integer_New")]
+ public static extern global::System.IntPtr IntegerFunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Integer_SetHandler")]
+ public static extern void SetIntegerFunction(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Integer_GetId")]
+ public static extern uint GetIntegerFunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Integer")]
+ public static extern void DeleteIntegerFunction(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector2_New")]
+ public static extern global::System.IntPtr Vector2FunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector2_SetHandler")]
+ public static extern void SetVector2Function(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector2_GetId")]
+ public static extern uint GetVector2FunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Vector2")]
+ public static extern void DeleteVector2Function(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector3_New")]
+ public static extern global::System.IntPtr Vector3FunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector3_SetHandler")]
+ public static extern void SetVector3Function(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector3_GetId")]
+ public static extern uint GetVector3FunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Vector3")]
+ public static extern void DeleteVector3Function(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector4_New")]
+ public static extern global::System.IntPtr Vector4FunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector4_SetHandler")]
+ public static extern void SetVector4Function(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Vector4_GetId")]
+ public static extern uint GetVector4FunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Vector4")]
+ public static extern void DeleteVector4Function(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Matrix3_New")]
+ public static extern global::System.IntPtr Matrix3FunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Matrix3_SetHandler")]
+ public static extern void SetMatrix3Function(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Matrix3_GetId")]
+ public static extern uint GetMatrix3FunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Matrix3")]
+ public static extern void DeleteMatrix3Function(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Matrix_New")]
+ public static extern global::System.IntPtr MatrixFunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Matrix_SetHandler")]
+ public static extern void SetMatrixFunction(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Matrix_GetId")]
+ public static extern uint GetMatrixFunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Matrix")]
+ public static extern void DeleteMatrixFunction(global::System.Runtime.InteropServices.HandleRef function);
+
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Quaternion_New")]
+ public static extern global::System.IntPtr RotationFunctionNew();
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Quaternion_SetHandler")]
+ public static extern void SetRotationFunction(global::System.Runtime.InteropServices.HandleRef function, global::System.Runtime.InteropServices.HandleRef handler);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Constraint_Function_Quaternion_GetId")]
+ public static extern uint GetRotationFunctionId(global::System.Runtime.InteropServices.HandleRef function);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_delete_Constraint_Function_Quaternion")]
+ public static extern void DeleteRotationFunction(global::System.Runtime.InteropServices.HandleRef function);
+ }
+ }
+}
[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
public static extern bool IsPropertyAnimatable(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2);
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Handle_IsPropertyAConstraintInput")]
+ [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
+ public static extern bool IsPropertyAConstraintInput(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2);
+
[global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Handle_GetPropertyType")]
public static extern int GetPropertyType(global::System.Runtime.InteropServices.HandleRef jarg1, int jarg2);
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ *
+ */
+
+namespace Tizen.NUI
+{
+ internal static partial class Interop
+ {
+ internal static partial class PropertyInputContainer
+ {
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetCount")]
+ public static extern uint GetCount(global::System.Runtime.InteropServices.HandleRef jarg1);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetType")]
+ public static extern int GetPropertyType(global::System.Runtime.InteropServices.HandleRef jarg1, uint index);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetBoolean")]
+ [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.U1)]
+ public static extern bool GetBoolean(global::System.Runtime.InteropServices.HandleRef jarg1, uint index);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetFloat")]
+ public static extern float GetFloat(global::System.Runtime.InteropServices.HandleRef jarg1, uint index);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetInteger")]
+ public static extern int GetInteger(global::System.Runtime.InteropServices.HandleRef jarg1, uint index);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetVector2_Componentwise")]
+ public static extern void GetVector2Componentwise(global::System.Runtime.InteropServices.HandleRef jarg1, uint index, out float x, out float y);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetVector3_Componentwise")]
+ public static extern void GetVector3Componentwise(global::System.Runtime.InteropServices.HandleRef jarg1, uint index, out float x, out float y, out float z);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetVector4_Componentwise")]
+ public static extern void GetVector4Componentwise(global::System.Runtime.InteropServices.HandleRef jarg1, uint index, out float x, out float y, out float z, out float w);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetMatrix3")]
+ public static extern global::System.IntPtr GetMatrix3(global::System.Runtime.InteropServices.HandleRef jarg1, uint index);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetMatrix")]
+ public static extern global::System.IntPtr GetMatrix(global::System.Runtime.InteropServices.HandleRef jarg1, uint index);
+
+ [global::System.Runtime.InteropServices.DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_PropertyInputContainer_GetQuaternion")]
+ public static extern global::System.IntPtr GetRotation(global::System.Runtime.InteropServices.HandleRef jarg1, uint index);
+ }
+ }
+}
return ret;
}
+ /// <summary>
+ /// whether a writable property can be the source of an constraint.
+ /// </summary>
+ /// <param name="index">The index of the property.</param>
+ /// <returns>True if the property is a constraint input.</returns>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ internal bool IsPropertyAConstraintInput(int index)
+ {
+ bool ret = Interop.Handle.IsPropertyAConstraintInput(SwigCPtr, index);
+ NDalicPINVOKE.ThrowExceptionIfExists();
+ return ret;
+ }
+
/// <summary>
/// Queries the type of a property.
/// </summary>
--- /dev/null
+using System;
+using System.Runtime.InteropServices;
+using Tizen.NUI.BaseComponents;
+using System.Collections.Generic;
+
+namespace Tizen.NUI.Samples
+{
+ public class ConstraintWithCustomShaderTest : IExample
+ {
+ static readonly string VERTEX_SHADER =
+ "//@name ConstraintWithCustomShaderTest.vert\n" +
+ "\n" +
+ "//@version 100\n" +
+ "\n" +
+ "precision highp float;\n" +
+ "INPUT highp vec2 aPosition;\n" +
+ "OUTPUT highp vec2 vPosition;\n" +
+ "FLAT OUTPUT highp float vCornerRadius;\n" +
+ "\n" +
+ "UNIFORM_BLOCK VertBlock\n" +
+ "{\n" +
+ " UNIFORM highp mat4 uMvpMatrix;\n" +
+ " UNIFORM highp float uCornerRadius;\n" +
+ "};\n" +
+ "UNIFORM_BLOCK SharedBlock\n" +
+ "{\n" +
+ " UNIFORM highp vec3 uSize;\n" +
+ "}\n" +
+ "void main()\n" +
+ "{\n" +
+ " vec4 pos = vec4(aPosition, 0.0, 1.0) * vec4(uSize.xy, 0.0, 1.0);\n" +
+ " vPosition = (aPosition + vec2(0.5)) * uSize.xy;\n" +
+ " vCornerRadius = max(0.0, min(uCornerRadius, min(uSize.x, uSize.y)));\n" +
+ "\n" +
+ " gl_Position = uMvpMatrix * pos;\n" +
+ "}\n";
+
+ static readonly string FRAGMENT_SHADER =
+ "//@name ConstraintWithCustomShaderTest.frag\n" +
+ "\n" +
+ "//@version 100\n" +
+ "\n" +
+ "precision highp float;\n" +
+ "INPUT highp vec2 vPosition;\n" +
+ "FLAT INPUT highp float vCornerRadius;\n" +
+ "\n" +
+ "UNIFORM_BLOCK SharedBlock\n" +
+ "{\n" +
+ " UNIFORM highp vec3 uSize;\n" +
+ "}\n" +
+ "UNIFORM_BLOCK FragBlock\n" +
+ "{\n" +
+ " UNIFORM lowp vec4 uColor;\n" +
+ " UNIFORM highp vec2 CursorPosition;\n" +
+ " UNIFORM highp float uCornerSquareness;\n" +
+ " UNIFORM highp float uCustomCursorRadius;\n" +
+ "};\n" +
+ "\n" +
+ "// Simplest CornerRadius implements\n" +
+ "float roundedBoxSDF(vec2 pixelPositionFromCenter, vec2 rectangleEdgePositionFromCenter, float radius, float squareness) {\n" +
+ " highp vec2 diff = pixelPositionFromCenter\n" +
+ " - rectangleEdgePositionFromCenter\n" +
+ " + radius;\n" +
+ "\n" +
+ " // If squareness is near 1.0 or 0.0, it make some numeric error. Let we avoid this situation by heuristic value.\n" +
+ " if(squareness < 0.01)\n" +
+ " {\n" +
+ " return length(max(diff, 0.0)) + min(0.0, max(diff.x, diff.y)) - radius;\n" +
+ " }\n" +
+ " if(squareness > 0.99)\n" +
+ " {\n" +
+ " return max(diff.x, diff.y) - radius;\n" +
+ " }\n" +
+ "\n" +
+ " highp vec2 positiveDiff = max(diff, 0.0);\n" +
+ "\n" +
+ " // make sqr to avoid duplicate codes.\n" +
+ " positiveDiff *= positiveDiff;\n" +
+ "\n" +
+ " // TODO : Could we remove this double-sqrt code?\n" +
+ " return sqrt(((positiveDiff.x + positiveDiff.y)\n" +
+ " + sqrt(positiveDiff.x * positiveDiff.x\n" +
+ " + positiveDiff.y * positiveDiff.y\n" +
+ " + (2.0 - 4.0 * squareness * squareness) * positiveDiff.x * positiveDiff.y))\n" +
+ " * 0.5)\n" +
+ " + min(0.0, max(diff.x, diff.y)) ///< Consider negative potential, to avoid visual defect when radius is zero\n" +
+ " - radius;\n" +
+ "}\n" +
+ "\n" +
+ "void main()\n" +
+ "{\n" +
+ " highp float dist = length(vPosition - CursorPosition);\n" +
+ " dist /= uCustomCursorRadius;\n" +
+ " gl_FragColor = uColor * vec4(dist, 0.0, 1.0, 1.0);\n" +
+ " \n" +
+ " highp vec2 location = abs(vPosition.xy - vec2(0.5) * uSize.xy);\n" +
+ " highp vec2 halfSize = uSize.xy * 0.5;\n" +
+ " highp float radius = vCornerRadius;\n" +
+ " highp float edgeSoftness = min(1.0, radius);" +
+ "\n" +
+ " highp float signedDistance = roundedBoxSDF(location, halfSize, radius, uCornerSquareness);\n" +
+ " mediump float smoothedAlpha = 1.0 - smoothstep(-edgeSoftness, edgeSoftness, signedDistance);\n" +
+ "\n" +
+ " gl_FragColor.a *= smoothedAlpha;\n" +
+ "}\n";
+
+
+ struct SimpleQuadVertex
+ {
+ public UIVector2 position;
+ }
+
+ private PropertyBuffer CreateQuadPropertyBuffer()
+ {
+ /* Create Property buffer */
+ PropertyMap vertexFormat = new PropertyMap();
+ vertexFormat.Add("aPosition", (int)PropertyType.Vector2);
+
+ PropertyBuffer vertexBuffer = new PropertyBuffer(vertexFormat);
+
+ SimpleQuadVertex vertex1 = new SimpleQuadVertex();
+ SimpleQuadVertex vertex2 = new SimpleQuadVertex();
+ SimpleQuadVertex vertex3 = new SimpleQuadVertex();
+ SimpleQuadVertex vertex4 = new SimpleQuadVertex();
+ vertex1.position = new UIVector2(-0.5f, -0.5f);
+ vertex2.position = new UIVector2(-0.5f, 0.5f);
+ vertex3.position = new UIVector2(0.5f, -0.5f);
+ vertex4.position = new UIVector2(0.5f, 0.5f);
+
+ SimpleQuadVertex[] texturedQuadVertexData = new SimpleQuadVertex[4] { vertex1, vertex2, vertex3, vertex4 };
+
+ int size = Marshal.SizeOf(vertex1);
+ IntPtr pA = Marshal.AllocHGlobal(checked(size * texturedQuadVertexData.Length));
+
+ try
+ {
+ for (int i = 0; i < texturedQuadVertexData.Length; i++)
+ {
+ Marshal.StructureToPtr(texturedQuadVertexData[i], pA + i * size, true);
+ }
+
+ vertexBuffer.SetData(pA, (uint)texturedQuadVertexData.Length);
+ }
+ catch(Exception e)
+ {
+ Tizen.Log.Error("NUI", "Exception in PropertyBuffer : " + e.Message);
+ }
+ finally
+ {
+ // Free AllocHGlobal memory after call PropertyBuffer.SetData()
+ Marshal.FreeHGlobal(pA);
+ }
+
+ vertexFormat.Dispose();
+
+ return vertexBuffer;
+ }
+
+ private enum ConstraintBehaviorType
+ {
+ None = 0,
+ Noise,
+ Max,
+ };
+ private static ConstraintBehaviorType constraintType;
+ private static float gWindowWidth = 0.0f;
+ private static float gWindowHeight = 0.0f;
+ private static Random rand = new Random();
+
+ private static object lockObject = new object();
+
+ private const bool _printLogs = false; // Make it true if you want to see the logs
+
+ private static UIVector2 OnConstraintVector2(UIVector2 current, uint id, in PropertyInputContainer container)
+ {
+ float viewWidth = container.GetFloat(0u);
+ float viewHeight = container.GetFloat(1u);
+ UIVector3 viewPosition = container.GetVector3(2u);
+ UIColor viewColor = container.GetColor(3u);
+ using Rotation viewRotation = container.GetRotation(4u);
+ using Matrix viewModelMatrix = container.GetMatrix(5u);
+
+ float hoveViewX = container.GetFloat(6u);
+ float hoveViewY = container.GetFloat(7u);
+
+ using Vector3 axis = new Vector3();
+ using Radian angle = new Radian();
+ bool converted = viewRotation.GetAxisAngle(axis, angle);
+
+ ConstraintBehaviorType type;
+ lock (lockObject)
+ {
+ type = constraintType;
+ }
+
+ UIVector2 result = new UIVector2(hoveViewX - viewPosition.X + viewWidth * 0.5f, hoveViewY - viewPosition.Y + viewHeight * 0.5f);
+ switch(type)
+ {
+ case ConstraintBehaviorType.Noise:
+ {
+ result = new UIVector2(result.X + rand.Next(-1000, 1000) * 0.01f, result.Y + rand.Next(-1000, 1000) * 0.01f);
+ break;
+ }
+ default:
+ {
+ // Do nothing.
+ break;
+ }
+ }
+
+ if (_printLogs)
+ {
+ Tizen.Log.Error("NUI", $"ID : {id}, container size : {container.Count}, current : {current.X}, {current.Y}\n");
+ Tizen.Log.Error("NUI", $"w:{viewWidth} h:{viewHeight}, x:{viewPosition.X}, y:{viewPosition.Y}, z:{viewPosition.Z}\n");
+ Tizen.Log.Error("NUI", $"r:{viewColor.R} g:{viewColor.G}, b:{viewColor.B}, a:{viewColor.A}\n");
+ Tizen.Log.Error("NUI", $"{converted} / angle:{angle.Value} axis:{axis.X}, {axis.Y}, {axis.Z}\n");
+ Tizen.Log.Error("NUI", $"hover : {hoveViewX}, {hoveViewY}\n");
+
+ Tizen.Log.Error("NUI", $" Model Matrix :\n");
+ for (uint i = 0; i < 4; i++)
+ {
+ Tizen.Log.Error("NUI", $" {viewModelMatrix.ValueOfIndex(i, 0)}, {viewModelMatrix.ValueOfIndex(i, 1)}, {viewModelMatrix.ValueOfIndex(i, 2)}, {viewModelMatrix.ValueOfIndex(i, 3)}\n");
+ }
+ Tizen.Log.Error("NUI", $"ID : {id}, result : {result.X}, {result.Y}\n");
+ }
+
+ return result;
+ }
+
+ private static float OnConstraintFloat(float current, uint id, in PropertyInputContainer container)
+ {
+ float result = container.GetVector4(0u).X;
+ if(container.Count > 1)
+ {
+ switch((VisualTransformPolicyType)container.GetInteger(1u))
+ {
+ case VisualTransformPolicyType.Relative:
+ {
+ result *= Math.Min(container.GetFloat(2u), container.GetFloat(3u));
+ break;
+ }
+ case VisualTransformPolicyType.Absolute:
+ {
+ break;
+ }
+ }
+ }
+
+ if (_printLogs)
+ {
+ Tizen.Log.Error("NUI", $"ID : {id}, container size : {container.Count}, current : {current}, input : {container.GetVector4(0u).X}, result : {result}\n");
+ if(container.Count > 1)
+ {
+ Tizen.Log.Error("NUI", $"Type : {container.GetPropertyType(1u)}, value : {container.GetInteger(1u)}\n");
+ switch((VisualTransformPolicyType)container.GetInteger(1u))
+ {
+ case VisualTransformPolicyType.Relative:
+ {
+ Tizen.Log.Error("NUI", $"Relative\n");
+ break;
+ }
+ case VisualTransformPolicyType.Absolute:
+ {
+ Tizen.Log.Error("NUI", $"Absolute\n");
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ private static Rotation OnConstraintRotation(in Rotation current, uint id, in PropertyInputContainer container)
+ {
+ float windowWidth, windowHeight;
+ lock (lockObject)
+ {
+ windowWidth = gWindowWidth;
+ windowHeight = gWindowHeight;
+ }
+ float cursorX = container.GetFloat(0u) / windowWidth;
+ float cursorY = container.GetFloat(1u) / windowHeight;
+
+ using Radian pitch = new Radian(-cursorY * 0.2f);
+ using Radian yaw = new Radian(cursorX * 0.2f);
+ using Radian roll = new Radian(0.0f);
+ Rotation rotation = new Rotation(pitch, yaw, roll);
+ if (_printLogs)
+ {
+ Tizen.Log.Error("NUI", $"ID : {id}, container size : {container.Count}, cursor pos : {cursorX}, {cursorY}\n");
+
+ using Vector3 axis = new Vector3();
+ using Radian angle = new Radian();
+ bool converted = current.GetAxisAngle(axis, angle);
+ Tizen.Log.Error("NUI", $"Current : {converted} / angle:{angle.Value} axis:{axis.X}, {axis.Y}, {axis.Z}\n");
+
+ converted = rotation.GetAxisAngle(axis, angle);
+ Tizen.Log.Error("NUI", $"Result : {converted} / angle:{angle.Value} axis:{axis.X}, {axis.Y}, {axis.Z}\n");
+ }
+ return rotation;
+ }
+
+ private Window win;
+ private View root;
+ private Layer overlayLayer;
+
+ private View view; // Custom renderable holder
+ private View hoverView;
+
+ private static Geometry geometry;
+ private static Shader shader;
+ private Renderable renderable;
+
+ private Constraint constraint;
+ private bool constraintApplied;
+
+ private Constraint cornerConstraint;
+ private Constraint cornerConstraint2;
+
+ private Constraint orientationConstraint;
+
+ private Animation radiusAnimation;
+
+ private Animation cursorMoveAnimation;
+ private int cursorPositionIndex;
+
+ public void Activate()
+ {
+ win = NUIApplication.GetDefaultWindow();
+
+ lock (lockObject)
+ {
+ gWindowWidth = win.Size.Width;
+ gWindowHeight = win.Size.Height;
+ }
+
+ win.OrientationChanged += OnWindowOrientationChangedEvent;
+ win.Resized += WindowResized;
+ win.KeyEvent += WindowKeyEvent;
+
+ root = new View()
+ {
+ Name = "root",
+ WidthResizePolicy = ResizePolicyType.FillToParent,
+ HeightResizePolicy = ResizePolicyType.FillToParent,
+ };
+ win.Add(root);
+
+ CreateCustomRenderableView();
+ GenerateConstraint();
+
+ var infoLabel = new TextLabel()
+ {
+ Text = "Constraint the mouse cursor position, and use this value as custom shader uniform.\n" +
+ "If touch down and release, curosr position animate.\n" +
+ "\n" +
+ " Press 0 to give noise at cursor constraint result\n" +
+ " Press 1 to test re-generate new constraints\n" +
+ " Press 2 to test Apply / Remove cursor constraint\n" +
+ " Press 3 to test re-generate source view\n" +
+ " Press 4 to test re-generate target renderer\n" +
+ " Press 5 to test corner radius / squareness change of view\n",
+ MultiLine = true,
+ };
+ overlayLayer = new Layer();
+ win.AddLayer(overlayLayer);
+ overlayLayer.Add(infoLabel);
+ }
+
+ public void Deactivate()
+ {
+ root?.Unparent();
+ root?.DisposeRecursively();
+
+ if (constraint != null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint with ID : {constraint.ID} will be Disposed(), but callback could be comes after now\n");
+ constraint?.Dispose();
+ }
+
+ if (cornerConstraint != null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint with ID : {cornerConstraint.ID} will be Disposed(), but callback could be comes after now\n");
+ cornerConstraint?.Dispose();
+ }
+
+ if (cornerConstraint2 != null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint with ID : {cornerConstraint2.ID} will be Disposed(), but callback could be comes after now\n");
+ cornerConstraint2?.Dispose();
+ }
+
+ if (orientationConstraint != null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint with ID : {orientationConstraint.ID} will be Disposed(), but callback could be comes after now\n");
+ orientationConstraint?.Dispose();
+ }
+
+ if (overlayLayer != null)
+ {
+ win?.RemoveLayer(overlayLayer);
+ }
+
+ renderable?.Dispose();
+ overlayLayer?.Dispose();
+
+ if (win != null)
+ {
+ win.OrientationChanged -= OnWindowOrientationChangedEvent;
+ win.Resized -= WindowResized;
+ win.KeyEvent -= WindowKeyEvent;
+ }
+ }
+
+ private void OnWindowOrientationChangedEvent(object sender, WindowOrientationChangedEventArgs e)
+ {
+ Window.WindowOrientation orientation = e.WindowOrientation;
+ Tizen.Log.Error("NUI", $"OnWindowOrientationChangedEvent() called!, orientation:{orientation}");
+ }
+
+ private void WindowResized(object sender, Window.ResizedEventArgs e)
+ {
+ lock (lockObject)
+ {
+ gWindowWidth = e.WindowSize.Width;
+ gWindowHeight = e.WindowSize.Height;
+ }
+ Tizen.Log.Error("NUI", $"Window resized : {gWindowWidth}, {gWindowHeight}\n");
+ }
+
+ private void WindowKeyEvent(object sender, Window.KeyEventArgs e)
+ {
+ if (e.Key.State == Key.StateType.Down)
+ {
+ if (e.Key.KeyPressedName == "0")
+ {
+ lock (lockObject)
+ {
+ constraintType = (ConstraintBehaviorType)(((int)constraintType + 1) % ((int)ConstraintBehaviorType.Max));
+
+ Tizen.Log.Error("NUI", $"Constraint : {constraint.ID} will act by {constraintType}\n");
+ }
+ }
+ if (e.Key.KeyPressedName == "1")
+ {
+ GenerateConstraint();
+ }
+ if (e.Key.KeyPressedName == "2")
+ {
+ ToggleConstraintActivation();
+ }
+ if (e.Key.KeyPressedName == "3")
+ {
+ RegenerateView();
+ }
+ if (e.Key.KeyPressedName == "4")
+ {
+ RegenerateRenderable();
+ }
+ if (e.Key.KeyPressedName == "5")
+ {
+ float v = view.CornerRadius.X;
+ view.CornerRadius = 0.35f - v;
+ }
+ }
+ }
+
+ private void CreateCustomRenderableView()
+ {
+ view = new View()
+ {
+ SizeWidth = 300,
+ SizeHeight = 500,
+ PositionX = 50,
+ PositionY = 100,
+
+ CornerRadius = 0.35f,
+ CornerRadiusPolicy = VisualTransformPolicyType.Relative,
+ CornerSquareness = 0.6f,
+ };
+
+ hoverView = new View()
+ {
+ BackgroundColor = Color.Black,
+ SizeWidth = 4,
+ SizeHeight = 4,
+ PositionX = 200,
+ PositionY = 350,
+ };
+
+ cursorMoveAnimation = new Animation(500);
+
+ root.HoverEvent += (o, e) =>
+ {
+ //if (cursorMoveAnimation.State == Animation.States.Stopped)
+ {
+ using var localPosition = e.Hover.GetLocalPosition(0u);
+ hoverView.PositionX = localPosition.X;
+ hoverView.PositionY = localPosition.Y;
+ }
+ return true;
+ };
+
+ root.TouchEvent += (o, e) =>
+ {
+ if (e.Touch.GetState(0) == PointStateType.Down)
+ {
+ cursorMoveAnimation.Stop();
+ cursorMoveAnimation.Clear();
+ }
+ else if (e.Touch.GetState(0) == PointStateType.Up)
+ {
+ cursorMoveAnimation.Stop();
+ cursorMoveAnimation.Clear();
+
+ // Reverse the animation localPosition -> currentPosition.
+ // If than, it will works like currentPositoin -> latest position what updated by Hover
+ using var localPosition = e.Touch.GetLocalPosition(0u);
+ cursorMoveAnimation.AnimateTo(hoverView, "PositionX", hoverView.PositionX, new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutBack));
+ cursorMoveAnimation.AnimateTo(hoverView, "PositionY", hoverView.PositionY, new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseOutBack));
+ cursorMoveAnimation.SpeedFactor = -1;
+ cursorMoveAnimation.Play();
+
+ hoverView.PositionX = localPosition.X;
+ hoverView.PositionY = localPosition.Y;
+ }
+ return true;
+ };
+
+ renderable = GenerateRenderable();
+ view.AddRenderable(renderable);
+
+ root.Add(view);
+ root.Add(hoverView);
+ }
+
+ private void GenerateConstraint()
+ {
+ if (constraint != null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint with ID : {constraint.ID} will be Disposed(), but callback could be comes after now\n");
+ constraint.Dispose();
+ }
+
+ // Create constraint for renderable
+ // Note that we cannot use "CursorPosition" as input of property name, because
+ // the first charactor of property name become lower case internally.
+ // To avoid this situation, we should use the index of property.
+ constraint = Constraint.GenerateConstraint(renderable, cursorPositionIndex, new Constraint.ConstraintVector2FunctionCallbackType(OnConstraintVector2));
+ constraint.AddSource(view, "SizeWidth");
+ constraint.AddSource(view, "SizeHeight");
+ constraint.AddSource(view, view.GetPropertyIndex("WorldPosition")); // Test for Vector3
+ constraint.AddSource(view, view.GetPropertyIndex("Color")); // Test for Vector4
+ constraint.AddSource(view, view.GetPropertyIndex("Orientation")); // Test for rotation
+ constraint.AddSource(view, view.GetPropertyIndex("WorldMatrix")); // Test for matrix
+ constraint.AddSource(hoverView, "WorldPositionX");
+ constraint.AddSource(hoverView, hoverView.GetPropertyIndex("WorldPositionY"));
+ constraint.Apply();
+
+ cornerConstraint?.Dispose();
+ cornerConstraint2?.Dispose();
+ orientationConstraint?.Dispose();
+ cornerConstraint = null;
+ cornerConstraint2 = null;
+ orientationConstraint = null;
+
+ // Set corner radius as input of constraints
+ cornerConstraint = Constraint.GenerateConstraint(renderable, "uCornerRadius", new Constraint.ConstraintFloatFunctionCallbackType(OnConstraintFloat));
+ cornerConstraint.AddSource(view, "CornerRadius");
+ cornerConstraint.AddSource(view, "CornerRadiusPolicy");
+ cornerConstraint.AddSource(view, "sizeWidth");
+ cornerConstraint.AddSource(view, "sizeHeight");
+ cornerConstraint.Apply();
+
+ // Note that the first charactor of property name become lower case internally.
+ // Here, "UCornerSquareness" -> "uCornerSquareness", "CornerSquareness" -> "cornerSquareness"
+ cornerConstraint2 = Constraint.GenerateConstraint(renderable, "UCornerSquareness", new Constraint.ConstraintFloatFunctionCallbackType(OnConstraintFloat));
+ cornerConstraint2.AddSource(view, "CornerSquareness");
+ cornerConstraint2.Apply();
+
+ // Set orientation as input of constraints
+ orientationConstraint = Constraint.GenerateConstraint(view, "Orientation", new Constraint.ConstraintRotationFunctionCallbackType(OnConstraintRotation));
+ orientationConstraint.AddSource(hoverView, "worldPositionX");
+ orientationConstraint.AddSource(hoverView, "WorldPositionY");
+ orientationConstraint.Apply();
+
+ constraintApplied = true;
+
+ Tizen.Log.Error("NUI", $"Constraint with ID : {constraint.ID} {cornerConstraint.ID} {cornerConstraint2.ID} {orientationConstraint.ID} Created and applied\n");
+ }
+
+ private void ToggleConstraintActivation()
+ {
+ if (constraint != null)
+ {
+ if (constraintApplied)
+ {
+ constraint.Remove();
+ Tizen.Log.Error("NUI", $"Constraint with ID : {constraint.ID} removed\n");
+ }
+ else
+ {
+ constraint.Apply();
+ Tizen.Log.Error("NUI", $"Constraint with ID : {constraint.ID} applied\n");
+ }
+ constraintApplied ^= true;
+ }
+ }
+
+ private void RegenerateView()
+ {
+ view.Dispose();
+ hoverView.Dispose();
+
+ view = new View()
+ {
+ SizeWidth = 300,
+ SizeHeight = 500,
+ PositionX = 50,
+ PositionY = 100,
+
+ CornerRadius = 0.35f,
+ CornerRadiusPolicy = VisualTransformPolicyType.Relative,
+ CornerSquareness = 0.6f,
+ };
+
+ hoverView = new View()
+ {
+ BackgroundColor = Color.Black,
+ SizeWidth = 4,
+ SizeHeight = 4,
+ PositionX = 200,
+ PositionY = 350,
+ };
+
+ view.AddRenderable(renderable);
+ root.Add(view);
+ root.Add(hoverView);
+
+ if (constraint != null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint with ID : {constraint.ID} {orientationConstraint.ID} {cornerConstraint.ID} {cornerConstraint2.ID} invalidate after RenderThread object destroyed\n");
+ }
+ }
+
+ private void RegenerateRenderable()
+ {
+ view.RemoveRenderable(renderable);
+ renderable.Dispose();
+
+ renderable = GenerateRenderable();
+ view.AddRenderable(renderable);
+
+ if (constraint != null)
+ {
+ Tizen.Log.Error("NUI", $"Constraint with ID : {constraint.ID} {cornerConstraint.ID} {cornerConstraint2.ID} invalidate after RenderThread object destroyed\n");
+ }
+ }
+
+ private Geometry GenerateGeometry()
+ {
+ if (geometry == null)
+ {
+ using PropertyBuffer vertexBuffer = CreateQuadPropertyBuffer();
+ geometry = new Geometry();
+ geometry.AddVertexBuffer(vertexBuffer);
+ geometry.SetType(Geometry.Type.TRIANGLE_STRIP);
+ }
+ return geometry;
+ }
+
+ private Shader GenerateShader()
+ {
+ if (shader == null)
+ {
+ shader = new Shader(VERTEX_SHADER, FRAGMENT_SHADER, "ConstraintWithCustomShaderTest");
+ }
+ return shader;
+ }
+
+ private Renderable GenerateRenderable()
+ {
+ if (renderable == null)
+ {
+ renderable = new Renderable()
+ {
+ Geometry = GenerateGeometry(),
+ Shader = GenerateShader(),
+ };
+
+ // Note that if the first charactor of custom registered property name is not lower case,
+ // We cannot access to that property by name.
+ // In this case, we should keep the index of property to access, or animate, or constraint it.
+ cursorPositionIndex = renderable.RegisterProperty("CursorPosition", new PropertyValue(100.0f, 200.0f));
+
+ renderable.RegisterProperty("uCustomCursorRadius", new PropertyValue(300.0f));
+ renderable.RegisterProperty("uCornerRadius", new PropertyValue(0.0f));
+ renderable.RegisterProperty("uCornerSquareness", new PropertyValue(0.0f));
+
+ //renderable.BlendPreMultipliedAlpha = true;
+ renderable.BlendMode = BlendMode.On;
+
+ radiusAnimation = new Animation(10000);
+ radiusAnimation.LoopingMode = Animation.LoopingModes.AutoReverse;
+ radiusAnimation.Looping = true;
+ radiusAnimation.AnimateTo(renderable, "uCustomCursorRadius", 50.0f, new AlphaFunction(AlphaFunction.BuiltinFunctions.EaseInOutSine));
+ radiusAnimation.Play();
+ }
+
+ return renderable;
+ }
+ }
+}