namespace Tizen.NUI.BaseComponents
{
-#if (NUI_DEBUG_ON)
- using tlog = Tizen.Log;
-#endif
-
/// <summary>
/// LottieAnimationView renders an animated vector image (Lottie file).
/// </summary>
/// <since_tizen> 7 </since_tizen>
- public class LottieAnimationView : ImageView
+ public partial class LottieAnimationView : ImageView
{
+
#region Constructor, Destructor, Dispose
/// <summary>
/// LottieAnimationView constructor
/// <since_tizen> 7 </since_tizen>
public LottieAnimationView(float scale = 1.0f, bool shown = true) : base()
{
- tlog.Fatal(tag, $"< constructor GetId={GetId()} >");
+ ActionPlay = Interop.LottieAnimationView.AnimatedVectorImageVisualActionPlayGet();
+ ActionPause = Interop.LottieAnimationView.AnimatedVectorImageVisualActionPauseGet();
+ ActionStop = Interop.LottieAnimationView.AnimatedVectorImageVisualActionStopGet();
+
+ NUILog.Debug($"< constructor GetId={GetId()} >");
currentStates.url = "";
- currentStates.frame = -1;
currentStates.loopCount = 1;
currentStates.loopMode = LoopingModeType.Restart;
currentStates.stopEndAction = StopBehaviorType.CurrentFrame;
currentStates.framePlayRangeMin = -1;
currentStates.framePlayRangeMax = -1;
- currentStates.changed = false;
currentStates.totalFrame = -1;
currentStates.scale = scale;
currentStates.redrawInScalingDown = true;
+
+ // Set changed flag as true when initalized state.
+ // After some properties change, LottieAnimationView.UpdateImage will apply these inital values.
+ currentStates.changed = true;
SetVisible(shown);
}
return;
}
- tlog.Fatal(tag, $"<[{GetId()}] type={type}");
+ CleanCallbackDictionaries();
//Release your own unmanaged resources here.
//You should not access any managed member here except static instance.
//disconnect event signal
if (finishedEventHandler != null && visualEventSignalCallback != null)
{
- VisualEventSignal().Disconnect(visualEventSignalCallback);
+ using VisualEventSignal visualEvent = VisualEventSignal();
+ visualEvent.Disconnect(visualEventSignalCallback);
finishedEventHandler = null;
- tlog.Fatal(tag, $"disconnect event signal");
+ NUILog.Debug($"disconnect event signal");
}
base.Dispose(type);
- tlog.Fatal(tag, $"[{GetId()}]>");
+ }
+
+ // This is used for internal purpose. hidden API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void Dispose(bool disposing)
+ {
+ CleanCallbackDictionaries();
+ base.Dispose(disposing);
}
#endregion Constructor, Destructor, Dispose
/// <since_tizen> 7 </since_tizen>
public string URL
{
+ get
+ {
+ return GetValue(URLProperty) as string;
+ }
+ set
+ {
+ SetValue(URLProperty, value);
+ NotifyPropertyChanged();
+ }
+ }
+
+ private string InternalURL
+ {
set
{
string ret = (value == null ? "" : value);
currentStates.url = ret;
- currentStates.changed = true;
-
- tlog.Fatal(tag, $"<[{GetId()}]SET url={currentStates.url}");
-
- PropertyMap map = new PropertyMap();
- map.Add(Visual.Property.Type, new PropertyValue((int)DevelVisual.Type.AnimatedVectorImage))
- .Add(ImageVisualProperty.URL, new PropertyValue(currentStates.url))
- .Add(ImageVisualProperty.LoopCount, new PropertyValue(currentStates.loopCount))
- .Add(ImageVisualProperty.StopBehavior, new PropertyValue((int)currentStates.stopEndAction))
- .Add(ImageVisualProperty.LoopingMode, new PropertyValue((int)currentStates.loopMode));
+ currentStates.totalFrame = -1; // Reset cached totalFrame value;
+
+ NUILog.Debug($"<[{GetId()}]SET url={currentStates.url}");
+
+ // TODO : Could create new Image without additional creation?
+ using PropertyMap map = new PropertyMap();
+ using PropertyValue type = new PropertyValue((int)Visual.Type.AnimatedVectorImage);
+ using PropertyValue url = new PropertyValue(currentStates.url);
+ using PropertyValue loopCnt = new PropertyValue(currentStates.loopCount);
+ using PropertyValue stopAction = new PropertyValue((int)currentStates.stopEndAction);
+ using PropertyValue loopMode = new PropertyValue((int)currentStates.loopMode);
+ using PropertyValue redrawInScalingDown = new PropertyValue(currentStates.redrawInScalingDown);
+
+ map.Add(Visual.Property.Type, type)
+ .Add(ImageVisualProperty.URL, url)
+ .Add(ImageVisualProperty.LoopCount, loopCnt)
+ .Add(ImageVisualProperty.StopBehavior, stopAction)
+ .Add(ImageVisualProperty.LoopingMode, loopMode)
+ .Add(ImageVisualProperty.RedrawInScalingDown, redrawInScalingDown);
Image = map;
+ // All states applied well.
+ currentStates.changed = false;
+
currentStates.contentInfo = null;
if (currentStates.scale != 1.0f)
{
- Scale = new Vector3(currentStates.scale, currentStates.scale, 0.0f);
+ Scale = new Vector3(currentStates.scale, currentStates.scale, currentStates.scale);
}
- tlog.Fatal(tag, $"<[{GetId()}]>");
+ NUILog.Debug($"<[{GetId()}]>");
}
get
{
string ret = currentStates.url;
- tlog.Fatal(tag, $"<[{GetId()}] GET");
-
- PropertyMap map = Image;
- if (map != null)
- {
- PropertyValue val = map.Find(ImageVisualProperty.URL);
- if (val != null)
- {
- if (val.Get(out ret))
- {
- tlog.Fatal(tag, $"gotten url={ret} >");
- return ret;
- }
- }
- }
- Tizen.Log.Error(tag, $" [ERROR][{GetId()}](LottieAnimationView) Fail to get URL from dali >");
+ NUILog.Debug($"<[{GetId()}] GET");
+ NUILog.Debug($"gotten url={ret} >");
return ret;
}
}
{
get
{
- tlog.Fatal(tag, $"< Get!");
- PropertyMap map = base.Image;
+ NUILog.Debug($"< Get!");
+ using PropertyMap map = base.Image;
var ret = 0;
if (map != null)
{
- PropertyValue val = map.Find(ImageVisualProperty.PlayState);
+ using PropertyValue val = map.Find(ImageVisualProperty.PlayState);
if (val != null)
{
if (val.Get(out ret))
{
currentStates.playState = (PlayStateType)ret;
- tlog.Fatal(tag, $"gotten play state={ret} >");
+ NUILog.Debug($"gotten play state={ret} >");
}
}
}
{
get
{
- int ret = -1;
- PropertyMap map = Image;
- if (map != null)
+ int ret = currentStates.totalFrame;
+ if (ret == -1)
{
- PropertyValue val = map.Find(ImageVisualProperty.TotalFrameNumber);
- if (val != null)
+ // TODO : Could we get this value without base.Image?
+ using PropertyMap map = base.Image;
+ if (map != null)
{
- if (val.Get(out ret))
+ using PropertyValue val = map.Find(ImageVisualProperty.TotalFrameNumber);
+ if (val != null)
{
- //tlog.Fatal(tag, $"TotalFrameNumber get! ret={ret}");
- currentStates.totalFrame = ret;
- return ret;
+ if (val.Get(out ret))
+ {
+ NUILog.Debug($"TotalFrameNumber get! ret={ret}");
+ currentStates.totalFrame = ret;
+ return ret;
+ }
}
}
+ Tizen.Log.Error(tag, $"<[ERROR][{GetId()}](LottieAnimationView) Fail to get TotalFrameNumber from dali>");
}
- Tizen.Log.Error(tag, $"<[ERROR][{GetId()}](LottieAnimationView) Fail to get TotalFrameNumber from dali>");
return ret;
}
}
/// <since_tizen> 7 </since_tizen>
public int CurrentFrame
{
+ get
+ {
+ return (int)GetValue(CurrentFrameProperty);
+ }
set
{
- currentStates.frame = value;
- tlog.Fatal(tag, $"<[{GetId()}]SET frame={currentStates.frame}>");
- DoAction(ImageView.Property.IMAGE, (int)actionType.jumpTo, new PropertyValue(currentStates.frame));
+ SetValue(CurrentFrameProperty, value);
+ NotifyPropertyChanged();
+ }
+ }
+
+ private int InternalCurrentFrame
+ {
+ set
+ {
+ NUILog.Debug($"<[{GetId()}]SET frame={value}>");
+ using PropertyValue attribute = new PropertyValue(value);
+ DoAction(ImageView.Property.IMAGE, ActionJumpTo, attribute);
}
get
{
+ // TODO : Could we get this value without base.Image?
int ret = 0;
- PropertyMap map = Image;
+ using PropertyMap map = base.Image;
if (map != null)
{
- PropertyValue val = map.Find(ImageVisualProperty.CurrentFrameNumber);
+ using PropertyValue val = map.Find(ImageVisualProperty.CurrentFrameNumber);
if (val != null)
{
if (val.Get(out ret))
{
- //tlog.Fatal(tag, $"CurrentFrameNumber get! val={ret}");
+ NUILog.Debug($"CurrentFrameNumber get! val={ret}");
return ret;
}
}
/// <since_tizen> 7 </since_tizen>
public LoopingModeType LoopingMode
{
+ get
+ {
+ return (LoopingModeType)GetValue(LoopingModeProperty);
+ }
set
{
- currentStates.loopMode = (LoopingModeType)value;
- currentStates.changed = true;
-
- tlog.Fatal(tag, $"<[{GetId()}] SET loopMode={currentStates.loopMode}>");
- PropertyMap map = new PropertyMap();
- map.Add(ImageVisualProperty.LoopingMode, new PropertyValue((int)currentStates.loopMode));
- DoAction(ImageView.Property.IMAGE, (int)actionType.updateProperty, new PropertyValue(map));
+ SetValue(LoopingModeProperty, value);
+ NotifyPropertyChanged();
}
- get
+ }
+
+ private LoopingModeType InternalLoopingMode
+ {
+ set
{
- //tlog.Fatal(tag, $"LoopMode get!");
- PropertyMap map = base.Image;
- var ret = 0;
- if (map != null)
+ if (currentStates.loopMode != (LoopingModeType)value)
{
- PropertyValue val = map.Find(ImageVisualProperty.LoopingMode);
- if (val != null)
- {
- if (val.Get(out ret))
- {
- //tlog.Fatal(tag, $"gotten LoopMode={ret}");
- if (ret != (int)currentStates.loopMode && ret > 0)
- {
- tlog.Fatal(tag, $" [ERROR][{GetId()}](LottieAnimationView) different LoopMode! gotten={ret}, loopMode={currentStates.loopMode}");
- }
- currentStates.loopMode = (LoopingModeType)ret;
- return (LoopingModeType)ret;
- }
- }
+ currentStates.changed = true;
+ currentStates.loopMode = (LoopingModeType)value;
+
+ NUILog.Debug($"<[{GetId()}] SET loopMode={currentStates.loopMode}>");
+ using PropertyMap map = new PropertyMap();
+ using PropertyValue loopMode = new PropertyValue((int)currentStates.loopMode);
+ map.Add(ImageVisualProperty.LoopingMode, loopMode);
+ using PropertyValue attribute = new PropertyValue(map);
+ DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, attribute);
}
- Tizen.Log.Error(tag, $"<[ERROR][{GetId()}](LottieAnimationView) Fail to get loopMode from dali>");
+ }
+ get
+ {
+ NUILog.Debug($"LoopMode get! {currentStates.loopMode}");
return currentStates.loopMode;
}
}
/// <since_tizen> 7 </since_tizen>
public int LoopCount
{
+ get
+ {
+ return (int)GetValue(LoopCountProperty);
+ }
set
{
- currentStates.changed = true;
- currentStates.loopCount = value;
- tlog.Fatal(tag, $"<[{GetId()}]SET currentStates.loopCount={currentStates.loopCount}>");
- PropertyMap map = new PropertyMap();
- map.Add(ImageVisualProperty.LoopCount, new PropertyValue(currentStates.loopCount));
- DoAction(ImageView.Property.IMAGE, (int)actionType.updateProperty, new PropertyValue(map));
+ SetValue(LoopCountProperty, value);
+ NotifyPropertyChanged();
}
- get
+ }
+
+ private int InternalLoopCount
+ {
+ set
{
- //tlog.Fatal(tag, $"LoopCount get!");
- PropertyMap map = base.Image;
- var ret = 0;
- if (map != null)
+ if (currentStates.loopCount != value)
{
- PropertyValue val = map.Find(ImageVisualProperty.LoopCount);
- if (val != null)
- {
- if (val.Get(out ret))
- {
- //tlog.Fatal(tag, $"gotten loop count={ret}");
- if (ret != currentStates.loopCount && ret > 0)
- {
- tlog.Fatal(tag, $"<[ERROR][{GetId()}](LottieAnimationView) different loop count! gotten={ret}, loopCount={currentStates.loopCount}>");
- }
- currentStates.loopCount = ret;
- return currentStates.loopCount;
- }
- }
+ currentStates.changed = true;
+ currentStates.loopCount = value;
+
+ NUILog.Debug($"<[{GetId()}]SET currentStates.loopCount={currentStates.loopCount}>");
+ using PropertyMap map = new PropertyMap();
+ using PropertyValue loopCnt = new PropertyValue(currentStates.loopCount);
+ map.Add(ImageVisualProperty.LoopCount, loopCnt);
+ using PropertyValue attribute = new PropertyValue(map);
+ DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, attribute);
}
- Tizen.Log.Error(tag, $"<[ERROR][{GetId()}](LottieAnimationView) Fail to get LoopCount from dali currentStates.loopCount={currentStates.loopCount}>");
+ }
+ get
+ {
+ NUILog.Debug($"LoopCount get! {currentStates.loopCount}");
return currentStates.loopCount;
}
}
/// <since_tizen> 7 </since_tizen>
public StopBehaviorType StopBehavior
{
+ get
+ {
+ return (StopBehaviorType)GetValue(StopBehaviorProperty);
+ }
set
{
- currentStates.stopEndAction = (StopBehaviorType)value;
- currentStates.changed = true;
-
- tlog.Fatal(tag, $"<[{GetId()}]SET val={currentStates.stopEndAction}>");
- PropertyMap map = new PropertyMap();
- map.Add(ImageVisualProperty.StopBehavior, new PropertyValue((int)currentStates.stopEndAction));
- DoAction(ImageView.Property.IMAGE, (int)actionType.updateProperty, new PropertyValue(map));
+ SetValue(StopBehaviorProperty, value);
+ NotifyPropertyChanged();
}
- get
+ }
+
+ private StopBehaviorType InternalStopBehavior
+ {
+ set
{
- //tlog.Fatal(tag, $"StopBehavior get!");
- PropertyMap map = base.Image;
- var ret = 0;
- if (map != null)
+ if (currentStates.stopEndAction != (StopBehaviorType)value)
{
- PropertyValue val = map.Find(ImageVisualProperty.StopBehavior);
- if (val != null)
- {
- if (val.Get(out ret))
- {
- //tlog.Fatal(tag, $"gotten StopBehavior={ret}");
- if (ret != (int)currentStates.stopEndAction)
- {
- tlog.Fatal(tag, $"<[ERROR][{GetId()}](LottieAnimationView) different StopBehavior! gotten={ret}, StopBehavior={currentStates.stopEndAction}>");
- }
- currentStates.stopEndAction = (StopBehaviorType)ret;
- return (StopBehaviorType)ret;
- }
- }
+ currentStates.changed = true;
+ currentStates.stopEndAction = (StopBehaviorType)value;
+
+ NUILog.Debug($"<[{GetId()}]SET val={currentStates.stopEndAction}>");
+ using PropertyMap map = new PropertyMap();
+ using PropertyValue stopAction = new PropertyValue((int)currentStates.stopEndAction);
+ map.Add(ImageVisualProperty.StopBehavior, stopAction);
+ using PropertyValue attribute = new PropertyValue(map);
+ DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, attribute);
}
- Tizen.Log.Error(tag, $"<[ERROR][{GetId()}](LottieAnimationView) Fail to get StopBehavior from dali>");
+ }
+ get
+ {
+ NUILog.Debug($"StopBehavior get! {currentStates.stopEndAction}");
return currentStates.stopEndAction;
}
}
[EditorBrowsable(EditorBrowsableState.Never)]
public bool RedrawInScalingDown
{
+ get
+ {
+ return (bool)GetValue(RedrawInScalingDownProperty);
+ }
set
{
- currentStates.changed = true;
- currentStates.redrawInScalingDown = value;
- tlog.Fatal(tag, $"<[{GetId()}]SET currentStates.redrawInScalingDown={currentStates.redrawInScalingDown}>");
- PropertyMap map = new PropertyMap();
- map.Add(ImageVisualProperty.RedrawInScalingDown, new PropertyValue(currentStates.redrawInScalingDown));
- DoAction(ImageView.Property.IMAGE, (int)actionType.updateProperty, new PropertyValue(map));
+ SetValue(RedrawInScalingDownProperty, value);
+ NotifyPropertyChanged();
}
- get
+ }
+
+ private bool InternalRedrawInScalingDown
+ {
+ set
{
- PropertyMap map = base.Image;
- var ret = true;
- if (map != null)
+ if (currentStates.redrawInScalingDown != value)
{
- PropertyValue val = map.Find(ImageVisualProperty.RedrawInScalingDown);
- if (val != null)
- {
- if (val.Get(out ret))
- {
- if (ret != currentStates.redrawInScalingDown)
- {
- tlog.Fatal(tag, $"<[ERROR][{GetId()}](LottieAnimationView) different redrawInScalingDown! gotten={ret}, redrawInScalingDown={currentStates.redrawInScalingDown}>");
- }
- currentStates.redrawInScalingDown = ret;
- return currentStates.redrawInScalingDown;
- }
- }
+ currentStates.changed = true;
+ currentStates.redrawInScalingDown = value;
+
+ NUILog.Debug($"<[{GetId()}]SET currentStates.redrawInScalingDown={currentStates.redrawInScalingDown}>");
+ using PropertyMap map = new PropertyMap();
+ using PropertyValue redraw = new PropertyValue(currentStates.redrawInScalingDown);
+ map.Add(ImageVisualProperty.RedrawInScalingDown, redraw);
+ using PropertyValue action = new PropertyValue(map);
+ DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, action);
}
- Tizen.Log.Error(tag, $"<[ERROR][{GetId()}](LottieAnimationView) Fail to get redrawInScalingDown from dali currentStates.redrawInScalingDown={currentStates.redrawInScalingDown}>");
+ }
+ get
+ {
+ NUILog.Debug($"RedrawInScalingDown get! {currentStates.redrawInScalingDown}");
return currentStates.redrawInScalingDown;
}
}
+
+
+ /// <summary>
+ /// Actions property value to Jump to the specified frame.
+ /// This property can be redefined by child class if it use different value.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected int ActionJumpTo { get; set; } = Interop.LottieAnimationView.AnimatedVectorImageVisualActionJumpToGet();
+
+ // This is used for internal purpose. hidden API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected int SetDynamicProperty => ActionJumpTo + 1;
#endregion Property
/// <since_tizen> 7 </since_tizen>
public void SetMinMaxFrame(int minFrame, int maxFrame)
{
- tlog.Fatal(tag, $"< [{GetId()}] SetPlayRange({minFrame}, {maxFrame})");
-
- currentStates.changed = true;
- currentStates.framePlayRangeMin = minFrame;
- currentStates.framePlayRangeMax = maxFrame;
-
- PropertyArray array = new PropertyArray();
- array.PushBack(new PropertyValue(currentStates.framePlayRangeMin));
- array.PushBack(new PropertyValue(currentStates.framePlayRangeMax));
-
- PropertyMap map = new PropertyMap();
- map.Add(ImageVisualProperty.PlayRange, new PropertyValue(array));
- DoAction(ImageView.Property.IMAGE, (int)actionType.updateProperty, new PropertyValue(map));
- tlog.Fatal(tag, $" [{GetId()}] currentStates.min:({currentStates.framePlayRangeMin}, max:{currentStates.framePlayRangeMax})>");
+ if (currentStates.framePlayRangeMin != minFrame || currentStates.framePlayRangeMax != maxFrame)
+ {
+ NUILog.Debug($"< [{GetId()}] SetPlayRange({minFrame}, {maxFrame})");
+ currentStates.changed = true;
+ currentStates.framePlayRangeMin = minFrame;
+ currentStates.framePlayRangeMax = maxFrame;
+
+ using PropertyArray array = new PropertyArray();
+ using PropertyValue min = new PropertyValue(currentStates.framePlayRangeMin);
+ using PropertyValue max = new PropertyValue(currentStates.framePlayRangeMax);
+ array.PushBack(min);
+ array.PushBack(max);
+
+ using PropertyMap map = new PropertyMap();
+ using PropertyValue range = new PropertyValue(array);
+ map.Add(ImageVisualProperty.PlayRange, range);
+ using PropertyValue action = new PropertyValue(map);
+ DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, action);
+ NUILog.Debug($" [{GetId()}] currentStates.min:({currentStates.framePlayRangeMin}, max:{currentStates.framePlayRangeMax})>");
+ }
}
/// <summary>
/// <since_tizen> 7 </since_tizen>
public new void Play()
{
- tlog.Fatal(tag, $"<[{GetId()}] Play()");
+ NUILog.Debug($"<[{GetId()}] Play()");
debugPrint();
base.Play();
- tlog.Fatal(tag, $"[{GetId()}]>");
+ NUILog.Debug($"[{GetId()}]>");
}
/// <summary>
/// <since_tizen> 7 </since_tizen>
public new void Pause()
{
- tlog.Fatal(tag, $"<[{GetId()}] Pause()>");
+ NUILog.Debug($"<[{GetId()}] Pause()>");
debugPrint();
base.Pause();
- tlog.Fatal(tag, $"[{GetId()}]>");
+ NUILog.Debug($"[{GetId()}]>");
}
/// <summary>
/// <since_tizen> 7 </since_tizen>
public new void Stop()
{
- tlog.Fatal(tag, $"<[{GetId()}] Stop()");
+ NUILog.Debug($"<[{GetId()}] Stop()");
debugPrint();
base.Stop();
- tlog.Fatal(tag, $"[{GetId()}]>");
+ NUILog.Debug($"[{GetId()}]>");
}
/// <summary>
/// <since_tizen> 7 </since_tizen>
public List<Tuple<string, int, int>> GetContentInfo()
{
- tlog.Fatal(tag, $"<");
if (currentStates.contentInfo != null)
{
return currentStates.contentInfo;
}
+ NUILog.Debug($"<");
+
PropertyMap imageMap = base.Image;
- PropertyMap contentMap = new PropertyMap();
if (imageMap != null)
{
PropertyValue val = imageMap.Find(ImageVisualProperty.ContentInfo);
- if (val != null)
+ PropertyMap contentMap = new PropertyMap();
+ if (val?.Get(ref contentMap) == true)
{
- if (val.Get(contentMap))
+ currentStates.contentInfo = new List<Tuple<string, int, int>>();
+ for (uint i = 0; i < contentMap.Count(); i++)
{
- currentStates.contentInfo = new List<Tuple<string, int, int>>();
- for (uint i = 0; i < contentMap.Count(); i++)
+ using PropertyKey propertyKey = contentMap.GetKeyAt(i);
+ string key = propertyKey.StringKey;
+
+ using PropertyValue arrVal = contentMap.GetValue(i);
+ using PropertyArray arr = new PropertyArray();
+ if (arrVal.Get(arr))
{
- string key = contentMap.GetKeyAt(i).StringKey;
- PropertyArray arr = new PropertyArray();
- contentMap.GetValue(i).Get(arr);
- if (arr != null)
- {
- int startFrame, endFrame;
- arr.GetElementAt(0).Get(out startFrame);
- arr.GetElementAt(1).Get(out endFrame);
+ int startFrame = -1;
+ using PropertyValue start = arr.GetElementAt(0);
+ start?.Get(out startFrame);
- tlog.Fatal(tag, $"[{i}] layer name={key}, startFrame={startFrame}, endFrame={endFrame}");
+ int endFrame = -1;
+ using PropertyValue end = arr.GetElementAt(1);
+ end?.Get(out endFrame);
- Tuple<string, int, int> item = new Tuple<string, int, int>(key, startFrame, endFrame);
+ NUILog.Debug($"[{i}] layer name={key}, startFrame={startFrame}, endFrame={endFrame}");
- currentStates.contentInfo?.Add(item);
- }
+ Tuple<string, int, int> item = new Tuple<string, int, int>(key, startFrame, endFrame);
+
+ currentStates.contentInfo?.Add(item);
}
}
}
+ contentMap.Dispose();
+ val?.Dispose();
}
- tlog.Fatal(tag, $">");
+ NUILog.Debug($">");
+
return currentStates.contentInfo;
}
[EditorBrowsable(EditorBrowsableState.Never)]
public void SetMinMaxFrameByMarker(string marker1, string marker2 = null)
{
- tlog.Fatal(tag, $"< [{GetId()}] SetMinMaxFrameByMarker({marker1}, {marker2})");
+ if (currentStates.mark1 != marker1 || currentStates.mark2 != marker2)
+ {
+ NUILog.Debug($"< [{GetId()}] SetMinMaxFrameByMarker({marker1}, {marker2})");
- currentStates.changed = true;
- currentStates.mark1 = marker1;
- currentStates.mark2 = marker2;
+ currentStates.changed = true;
+ currentStates.mark1 = marker1;
+ currentStates.mark2 = marker2;
+
+ using PropertyArray array = new PropertyArray();
+ using PropertyValue mark1 = new PropertyValue(currentStates.mark1);
+ array.PushBack(mark1);
+ using PropertyValue mark2 = new PropertyValue(currentStates.mark2);
+ if (marker2 != null)
+ {
+ array.PushBack(mark2);
+ }
- PropertyArray array = new PropertyArray();
- array.PushBack(new PropertyValue(currentStates.mark1));
- if (marker2 != null)
- {
- array.PushBack(new PropertyValue(currentStates.mark2));
+ using PropertyMap map = new PropertyMap();
+ using PropertyValue range = new PropertyValue(array);
+ map.Add(ImageVisualProperty.PlayRange, range);
+ using PropertyValue actionProperty = new PropertyValue(map);
+ DoAction(ImageView.Property.IMAGE, ActionUpdateProperty, actionProperty);
+ NUILog.Debug($" [{GetId()}] currentStates.mark1:{currentStates.mark1}, mark2:{currentStates.mark2} >");
}
-
- PropertyMap map = new PropertyMap();
- map.Add(ImageVisualProperty.PlayRange, new PropertyValue(array));
- DoAction(ImageView.Property.IMAGE, (int)actionType.updateProperty, new PropertyValue(map));
- tlog.Fatal(tag, $" [{GetId()}] currentStates.mark1:{currentStates.mark1}, mark2:{currentStates.mark2} >");
}
/// <summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public Tuple<int, int> GetMinMaxFrame()
{
- tlog.Fatal(tag, $"< [{GetId()}] GetMinMaxFrame()! total frame={currentStates.totalFrame}");
+ NUILog.Debug($"< [{GetId()}] GetMinMaxFrame()! total frame={currentStates.totalFrame}");
- PropertyMap map = Image;
+ using PropertyMap map = Image;
if (map != null)
{
- PropertyValue val = map.Find(ImageVisualProperty.PlayRange);
+ using PropertyValue val = map.Find(ImageVisualProperty.PlayRange);
if (val != null)
{
- PropertyArray array = new PropertyArray();
+ using PropertyArray array = new PropertyArray();
if (val.Get(array))
{
uint cnt = array.Count();
int item1 = -1, item2 = -1;
for (uint i = 0; i < cnt; i++)
{
- PropertyValue v = array.GetElementAt(i);
+ using PropertyValue v = array.GetElementAt(i);
int intRet;
if (v.Get(out intRet))
{
- tlog.Fatal(tag, $"Got play range of string [{i}]: {intRet}");
+ NUILog.Debug($"Got play range of string [{i}]: {intRet}");
if (i == 0)
{
item1 = intRet;
Tizen.Log.Error("NUI", $"[ERR] fail to get play range from dali! case#1");
}
}
- tlog.Fatal(tag, $" [{GetId()}] GetMinMaxFrame(min:{item1}, max:{item2})! >");
+ NUILog.Debug($" [{GetId()}] GetMinMaxFrame(min:{item1}, max:{item2})! >");
return new Tuple<int, int>(item1, item2);
}
}
Tizen.Log.Error("NUI", $"[ERR] fail to get play range from dali! case#2");
return new Tuple<int, int>(-1, -1);
}
+
+ // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public void DoActionExtension(LottieAnimationViewDynamicProperty info)
+ {
+ dynamicPropertyCallbackId++;
+
+ weakReferencesOfLottie?.Add(dynamicPropertyCallbackId, new WeakReference<LottieAnimationView>(this));
+ InternalSavedDynamicPropertyCallbacks?.Add(dynamicPropertyCallbackId, info.Callback);
+
+ Interop.View.DoActionExtension(SwigCPtr, ImageView.Property.IMAGE, SetDynamicProperty, dynamicPropertyCallbackId, info.KeyPath, (int)info.Property, Marshal.GetFunctionPointerForDelegate<System.Delegate>(rootCallback));
+
+ if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
+ }
+
+ private void CleanCallbackDictionaries()
+ {
+ if (weakReferencesOfLottie?.Count > 0 && InternalSavedDynamicPropertyCallbacks != null)
+ {
+ foreach (var key in InternalSavedDynamicPropertyCallbacks?.Keys)
+ {
+ if (weakReferencesOfLottie.ContainsKey(key))
+ {
+ weakReferencesOfLottie.Remove(key);
+ }
+ }
+ }
+ InternalSavedDynamicPropertyCallbacks?.Clear();
+ InternalSavedDynamicPropertyCallbacks = null;
+ }
+
+ /// <summary>
+ /// Update lottie-image-relative properties synchronously.
+ /// After call this API, All image properties updated.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void UpdateImage()
+ {
+ if (!imagePropertyUpdatedFlag) return;
+
+ // Update currentStates properties to cachedImagePropertyMap
+ if(currentStates.changed)
+ {
+ UpdateImage(ImageVisualProperty.LoopCount, new PropertyValue(currentStates.loopCount), false);
+ UpdateImage(ImageVisualProperty.StopBehavior, new PropertyValue((int)currentStates.stopEndAction), false);
+ UpdateImage(ImageVisualProperty.LoopingMode, new PropertyValue((int)currentStates.loopMode), false);
+ UpdateImage(ImageVisualProperty.RedrawInScalingDown, new PropertyValue(currentStates.redrawInScalingDown), false);
+
+ // Do not cache PlayRange and TotalFrameNumber into cachedImagePropertyMap.
+ // (To keep legacy implements behaviour)
+ currentStates.changed = false;
+ }
+
+ using PropertyValue animatiedImage = new PropertyValue((int)Visual.Type.AnimatedVectorImage);
+ UpdateImage(Visual.Property.Type, animatiedImage, false);
+
+ base.UpdateImage();
+ }
+
+ /// <summary>
+ /// Update NUI cached animated image visual property map by inputed property map.
+ /// And call base.MergeCachedImageVisualProperty()
+ /// </summary>
+ /// <remarks>
+ /// For performance issue, we will collect only "cachedLottieAnimationPropertyKeyList" hold in this class.
+ /// </remarks>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void MergeCachedImageVisualProperty(PropertyMap map)
+ {
+ if (map == null) return;
+ if (cachedImagePropertyMap == null)
+ {
+ cachedImagePropertyMap = new PropertyMap();
+ }
+ foreach (var key in cachedLottieAnimationPropertyKeyList)
+ {
+ PropertyValue value = map.Find(key);
+ if (value != null)
+ {
+ // Update-or-Insert new value
+ cachedImagePropertyMap[key] = value;
+ }
+ }
+ base.MergeCachedImageVisualProperty(map);
+ }
#endregion Method
{
if (finishedEventHandler == null)
{
- tlog.Fatal(tag, $"<[{GetId()}] Finished eventhandler added>");
+ NUILog.Debug($"<[{GetId()}] Finished eventhandler added>");
visualEventSignalCallback = onVisualEventSignal;
- VisualEventSignal().Connect(visualEventSignalCallback);
+ using VisualEventSignal visualEvent = VisualEventSignal();
+ visualEvent.Connect(visualEventSignalCallback);
}
finishedEventHandler += value;
}
remove
{
- tlog.Fatal(tag, $"<[{GetId()}] Finished eventhandler removed>");
+ NUILog.Debug($"<[{GetId()}] Finished eventhandler removed>");
finishedEventHandler -= value;
if (finishedEventHandler == null && visualEventSignalCallback != null)
{
- VisualEventSignal().Disconnect(visualEventSignalCallback);
+ using VisualEventSignal visualEvent = VisualEventSignal();
+ visualEvent.Disconnect(visualEventSignalCallback);
+ if (visualEvent?.Empty() == true)
+ {
+ visualEventSignalCallback = null;
+ }
}
}
}
/// <since_tizen> 7 </since_tizen>
AutoReverse
}
+
+ /// <summary>
+ /// Vector Property
+ /// </summary>
+ // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public enum VectorProperty
+ {
+ /// <summary>
+ /// Fill color of the object, Type of <see cref="Vector3"/>
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ FillColor,
+
+ /// <summary>
+ /// Fill opacity of the object, Type of float
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ FillOpacity,
+
+ /// <summary>
+ /// Stroke color of the object, Type of <see cref="Vector3"/>
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ StrokeColor,
+
+ /// <summary>
+ /// Stroke opacity of the object, Type of float
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ StrokeOpacity,
+
+ /// <summary>
+ /// Stroke width of the object, Type of float
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ StrokeWidth,
+
+ /// <summary>
+ /// Transform anchor of the Layer and Group object, Type of <see cref="Vector2"/>
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ TransformAnchor,
+
+ /// <summary>
+ /// Transform position of the Layer and Group object, Type of <see cref="Vector2"/>
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ TransformPosition,
+
+ /// <summary>
+ /// Transform scale of the Layer and Group object, Type of <see cref="Vector2"/>, Value range of [0..100]
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ TransformScale,
+
+ /// <summary>
+ /// Transform rotation of the Layer and Group object, Type of float, Value range of [0..360] in degrees
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ TransformRotation,
+
+ /// <summary>
+ /// Transform opacity of the Layer and Group object, Type of float
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ TransformOpacity
+ };
+
+ // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate PropertyValue DynamicPropertyCallbackType(int returnType, uint frameNumber);
#endregion Event, Enum, Struct, ETC
if (visualEventSignalHandler == null)
{
visualEventSignalCallback = onVisualEventSignal;
- VisualEventSignal().Connect(visualEventSignalCallback);
+ using VisualEventSignal visualEvent = VisualEventSignal();
+ visualEvent?.Connect(visualEventSignalCallback);
}
visualEventSignalHandler += value;
}
remove
{
visualEventSignalHandler -= value;
- if (visualEventSignalHandler == null && VisualEventSignal().Empty() == false)
+ if (visualEventSignalHandler == null && visualEventSignalCallback != null)
{
- VisualEventSignal().Disconnect(visualEventSignalCallback);
+ using VisualEventSignal visualEvent = VisualEventSignal();
+ visualEvent?.Disconnect(visualEventSignalCallback);
+ if (visualEvent?.Empty() == true)
+ {
+ visualEventSignalCallback = null;
+ }
}
}
}
internal void EmitVisualEventSignal(int visualIndex, int signalId)
{
- VisualEventSignal().Emit(this, visualIndex, signalId);
+ using VisualEventSignal visualEvent = VisualEventSignal();
+ visualEvent?.Emit(this, visualIndex, signalId);
}
internal VisualEventSignal VisualEventSignal()
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
return ret;
}
+
+ internal Dictionary<int, DynamicPropertyCallbackType> InternalSavedDynamicPropertyCallbacks = new Dictionary<int, DynamicPropertyCallbackType>();
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void RootCallbackType(int id, int returnType, uint frameNumber, ref float val1, ref float val2, ref float val3);
+
+ internal RootCallbackType rootCallback = RootCallback;
+
+ static internal void RootCallback(int id, int returnType, uint frameNumber, ref float val1, ref float val2, ref float val3)
+ {
+ WeakReference<LottieAnimationView> current = null;
+ LottieAnimationView currentView = null;
+ DynamicPropertyCallbackType currentCallback = null;
+ PropertyValue ret = null;
+
+ if (weakReferencesOfLottie.TryGetValue(id, out current))
+ {
+ if (current.TryGetTarget(out currentView))
+ {
+ if (currentView != null && currentView.InternalSavedDynamicPropertyCallbacks != null &&
+ currentView.InternalSavedDynamicPropertyCallbacks.TryGetValue(id, out currentCallback))
+ {
+ ret = currentCallback?.Invoke(returnType, frameNumber);
+ }
+ else
+ {
+ Tizen.Log.Error("NUI", "can't find the callback in LottieAnimationView, just return here!");
+ return;
+ }
+ }
+ else
+ {
+ Tizen.Log.Error("NUI", "can't find the callback in LottieAnimationView, just return here!");
+ return;
+ }
+ }
+ else
+ {
+ Tizen.Log.Error("NUI", "can't find LottieAnimationView by id, just return here!");
+ return;
+ }
+
+ switch (returnType)
+ {
+ case (int)(VectorProperty.FillColor):
+ case (int)(VectorProperty.StrokeColor):
+ Vector3 tmpVector3 = new Vector3(-1, -1, -1);
+ if ((ret != null) && ret.Get(tmpVector3))
+ {
+ val1 = tmpVector3.X;
+ val2 = tmpVector3.Y;
+ val3 = tmpVector3.Z;
+ }
+ tmpVector3.Dispose();
+ break;
+
+ case (int)(VectorProperty.TransformAnchor):
+ case (int)(VectorProperty.TransformPosition):
+ case (int)(VectorProperty.TransformScale):
+ Vector2 tmpVector2 = new Vector2(-1, -1);
+ if ((ret != null) && ret.Get(tmpVector2))
+ {
+ val1 = tmpVector2.X;
+ val2 = tmpVector2.Y;
+ }
+ tmpVector2.Dispose();
+ break;
+
+ case (int)(VectorProperty.FillOpacity):
+ case (int)(VectorProperty.StrokeOpacity):
+ case (int)(VectorProperty.StrokeWidth):
+ case (int)(VectorProperty.TransformRotation):
+ case (int)(VectorProperty.TransformOpacity):
+ float tmpFloat = -1;
+ if ((ret != null) && ret.Get(out tmpFloat))
+ {
+ val1 = tmpFloat;
+ }
+ break;
+ default:
+ //do nothing
+ break;
+ }
+ ret?.Dispose();
+ }
#endregion Internal
#region Private
+
+ // Collection of lottie-image-sensitive properties.
+ private static readonly List<int> cachedLottieAnimationPropertyKeyList = new List<int> {
+ ImageVisualProperty.LoopCount,
+ ImageVisualProperty.StopBehavior,
+ ImageVisualProperty.LoopingMode,
+ ImageVisualProperty.RedrawInScalingDown,
+ };
+
private struct states
{
internal string url;
- internal int frame;
internal int loopCount;
internal LoopingModeType loopMode;
internal StopBehaviorType stopEndAction;
internal int framePlayRangeMin;
internal int framePlayRangeMax;
- internal bool changed;
internal int totalFrame;
internal float scale;
internal PlayStateType playState;
internal List<Tuple<string, int, int>> contentInfo;
internal string mark1, mark2;
internal bool redrawInScalingDown;
+ internal bool changed;
};
private states currentStates;
- private enum actionType
- {
- play,
- pause,
- stop,
- jumpTo,
- updateProperty,
- };
-
- private struct DevelVisual
- {
- internal enum Type
- {
- AnimatedGradient = Visual.Type.AnimatedImage + 1,
- AnimatedVectorImage = Visual.Type.AnimatedImage + 2,
- }
- }
-
private const string tag = "NUITEST";
private event EventHandler finishedEventHandler;
private void OnFinished()
{
- tlog.Fatal(tag, $"<[{GetId()}] OnFinished()>");
+ NUILog.Debug($"<[{GetId()}] OnFinished()>");
finishedEventHandler?.Invoke(this, null);
}
View v = Registry.GetManagedBaseHandleFromNativePtr(targetView) as View;
if (v != null)
{
- tlog.Fatal(tag, $"targetView is not null! name={v.Name}");
+ NUILog.Debug($"targetView is not null! name={v.Name}");
}
else
{
- tlog.Fatal(tag, $"target is something created from dali");
+ NUILog.Debug($"target is something created from dali");
}
}
VisualEventSignalArgs e = new VisualEventSignalArgs();
e.SignalId = signalId;
visualEventSignalHandler?.Invoke(this, e);
- tlog.Fatal(tag, $"<[{GetId()}] onVisualEventSignal()! visualIndex={visualIndex}, signalId={signalId}>");
+ NUILog.Debug($"<[{GetId()}] onVisualEventSignal()! visualIndex={visualIndex}, signalId={signalId}>");
}
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
private VisualEventSignalCallbackType visualEventSignalCallback;
private EventHandler<VisualEventSignalArgs> visualEventSignalHandler;
+ static private int dynamicPropertyCallbackId = 0;
+ //static private Dictionary<int, DynamicPropertyCallbackType> dynamicPropertyCallbacks = new Dictionary<int, DynamicPropertyCallbackType>();
+ static private Dictionary<int, WeakReference<LottieAnimationView>> weakReferencesOfLottie = new Dictionary<int, WeakReference<LottieAnimationView>>();
+
private void debugPrint()
{
- tlog.Fatal(tag, $"===================================");
- tlog.Fatal(tag, $"<[{GetId()}] get currentStates : url={currentStates.url}, loopCount={currentStates.loopCount}, \nframePlayRangeMin/Max({currentStates.framePlayRangeMin},{currentStates.framePlayRangeMax}) ");
- tlog.Fatal(tag, $" get from Property : StopBehavior={StopBehavior}, LoopMode={LoopingMode}, LoopCount={LoopCount}, PlayState={PlayState}");
- tlog.Fatal(tag, $" RedrawInScalingDown={RedrawInScalingDown} >");
- tlog.Fatal(tag, $"===================================");
+ NUILog.Debug($"===================================");
+ NUILog.Debug($"<[{GetId()}] get currentStates : url={currentStates.url}, loopCount={currentStates.loopCount}, \nframePlayRangeMin/Max({currentStates.framePlayRangeMin},{currentStates.framePlayRangeMax}) ");
+ NUILog.Debug($" get from Property : StopBehavior={StopBehavior}, LoopMode={LoopingMode}, LoopCount={LoopCount}, PlayState={PlayState}");
+ NUILog.Debug($" RedrawInScalingDown={RedrawInScalingDown} >");
+ NUILog.Debug($"===================================");
}
+
#endregion Private
}
/// <param name="lottieView">The target LottieAnimationView to play.</param>
/// <param name="noPlay">Whether go direct to the EndFrame. It is false by default.</param>
[EditorBrowsable(EditorBrowsableState.Never)]
+ [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062: Validate arguments of public methods", Justification = "The null checking is done by BeReadyToShow()")]
public void Show(LottieAnimationView lottieView, bool noPlay = false)
{
if (!BeReadyToShow(lottieView))
return true;
}
}
+
+ // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API)
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public struct LottieAnimationViewDynamicProperty : IEquatable<LottieAnimationViewDynamicProperty>
+ {
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public string KeyPath { get; set; }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public LottieAnimationView.VectorProperty Property { get; set; }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public LottieAnimationView.DynamicPropertyCallbackType Callback { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (obj is LottieAnimationViewDynamicProperty target)
+ {
+ if (KeyPath == target.KeyPath && Property == target.Property && Callback == target.Callback)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public override int GetHashCode()
+ {
+ return base.GetHashCode();
+ }
+
+ public static bool operator ==(LottieAnimationViewDynamicProperty left, LottieAnimationViewDynamicProperty right)
+ {
+ return left.Equals(right);
+ }
+
+ public static bool operator !=(LottieAnimationViewDynamicProperty left, LottieAnimationViewDynamicProperty right)
+ {
+ return !(left == right);
+ }
+
+ public bool Equals(LottieAnimationViewDynamicProperty other)
+ {
+ if (other != null)
+ {
+ if (KeyPath == other.KeyPath && Property == other.Property && Callback == other.Callback)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
}