[NUI] Add IsUsingXaml flag in properties of View and AnimatedVectorImageView
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / AnimatedVectorImageView.cs
1 /*
2  * Copyright(c) 2021 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 using global::System;
19 using System.ComponentModel;
20 using Tizen.NUI.Binding;
21
22 namespace Tizen.NUI.BaseComponents
23 {
24     /// <summary>
25     /// AnimatedVectorImageView is a class for displaying a vector resource.
26     /// </summary>
27     [EditorBrowsable(EditorBrowsableState.Never)]
28     public partial class AnimatedVectorImageView : LottieAnimationView
29     {
30         #region Constructor, Destructor, Dispose
31
32         static AnimatedVectorImageView()
33         {
34             //to get "IsUsingXaml" feature working at preload, we need to remove readonly for BindableProperty.
35             //this AnimatedVectorImageView is not preloaded.
36             if (NUIApplication.IsUsingXaml)
37             {
38                 ResourceURLProperty = BindableProperty.Create(nameof(ResourceURL), typeof(string), typeof(AnimatedVectorImageView), string.Empty,
39                     propertyChanged: SetInternalResourceURLProperty, defaultValueCreator: GetInternalResourceURLProperty);
40
41                 ResourceUrlProperty = BindableProperty.Create(nameof(ResourceUrl), typeof(string), typeof(AnimatedVectorImageView), string.Empty,
42                     propertyChanged: SetInternalResourceUrlProperty, defaultValueCreator: GetInternalResourceUrlProperty);
43
44                 RepeatCountProperty = BindableProperty.Create(nameof(RepeatCount), typeof(int), typeof(AnimatedVectorImageView), 0,
45                     propertyChanged: SetInternalRepeatCountProperty, defaultValueCreator: GetInternalRepeatCountProperty);
46
47                 CurrentFrameProperty = BindableProperty.Create(nameof(CurrentFrame), typeof(int), typeof(AnimatedVectorImageView), 0,
48                     propertyChanged: SetInternalCurrentFrameProperty, defaultValueCreator: GetInternalCurrentFrameProperty);
49
50                 RepeatModeProperty = BindableProperty.Create(nameof(RepeatMode), typeof(RepeatModes), typeof(AnimatedVectorImageView), default(RepeatModes),
51                     propertyChanged: SetInternalRepeatModeProperty, defaultValueCreator: GetInternalRepeatModeProperty);
52             }
53         }
54
55         /// <summary>
56         /// Construct VectorAnimationView.
57         /// </summary>
58         [EditorBrowsable(EditorBrowsableState.Never)]
59         public AnimatedVectorImageView() : base()
60         {
61             NUILog.Debug($"[AnimatedVectorImageView START[ constructor objId={GetId()} ] END]");
62         }
63
64         /// <summary>
65         /// Construct VectorAnimationView.
66         /// </summary>
67         /// <param name="scale">Set scaling factor for Vector Animation, while creating.</param>
68         [EditorBrowsable(EditorBrowsableState.Never)]
69         public AnimatedVectorImageView(float scale) : base(scale)
70         {
71             NUILog.Debug($"[AnimatedVectorImageView START[ constructor scale={scale}) objId={GetId()} ] END]");
72         }
73
74         /// <summary>
75         /// You can override it to clean-up your own resources
76         /// </summary>
77         /// <param name="type">DisposeTypes</param>
78         [EditorBrowsable(EditorBrowsableState.Never)]
79         protected override void Dispose(DisposeTypes type)
80         {
81             if (disposed)
82             {
83                 return;
84             }
85             NUILog.Debug($"AnimatedVectorImageView START");
86
87             //Release your own unmanaged resources here.
88             //You should not access any managed member here except static instance.
89             //because the execution order of Finalizes is non-deterministic.
90
91             base.Dispose(type);
92
93             NUILog.Debug($"AnimatedVectorImageView END");
94         }
95         #endregion Constructor, Destructor, Dispose
96
97
98         #region Property
99         /// <summary>
100         /// Set Resource URL
101         /// </summary>
102         // Suppress warning : This has been being used by users, so that the interface can not be changed.
103         [EditorBrowsable(EditorBrowsableState.Never)]
104         public string ResourceURL
105         {
106             get
107             {
108                 if (NUIApplication.IsUsingXaml)
109                 {
110                     return GetValue(ResourceURLProperty) as string;
111                 }
112                 else
113                 {
114                     return GetInternalResourceURLProperty(this) as string;
115                 }
116             }
117             set
118             {
119                 if (NUIApplication.IsUsingXaml)
120                 {
121                     SetValue(ResourceURLProperty, value);
122                 }
123                 else
124                 {
125                     SetInternalResourceURLProperty(this, null, value);
126                 }
127                 NotifyPropertyChanged();
128             }
129         }
130
131         private string InternalResourceURL
132         {
133             set
134             {
135                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] ResourceURL SET");
136
137                 if (value == resourceUrl)
138                 {
139                     NUILog.Debug($"set same URL! ");
140                     return;
141                 }
142                 resourceUrl = (value == null) ? "" : value;
143                 URL = resourceUrl;
144                 isMinMaxFrameSet = minMaxSetTypes.NotSetByUser;
145                 NUILog.Debug($" [{GetId()}] resourceUrl={resourceUrl}) ]AnimatedVectorImageView END]");
146             }
147             get => resourceUrl;
148         }
149
150         /// <summary>
151         /// Set Resource URL
152         /// </summary>
153         // Suppress warning : This has been being used by users, so that the interface can not be changed.
154         [EditorBrowsable(EditorBrowsableState.Never)]
155         public new string ResourceUrl
156         {
157             get
158             {
159                 if (NUIApplication.IsUsingXaml)
160                 {
161                     return GetValue(ResourceUrlProperty) as string;
162                 }
163                 else
164                 {
165                     return GetInternalResourceUrlProperty(this) as string;
166                 }
167             }
168             set
169             {
170                 if (NUIApplication.IsUsingXaml)
171                 {
172                     SetValue(ResourceUrlProperty, value);
173                 }
174                 else
175                 {
176                     SetInternalResourceUrlProperty(this, null, value);
177                 }
178                 NotifyPropertyChanged();
179             }
180         }
181
182         private string InternalResourceUrl
183         {
184             set
185             {
186                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] ResourceUrl SET");
187                 this.ResourceURL = value;
188                 NUILog.Debug($" [{GetId()}] value={value}) ]AnimatedVectorImageView END]");
189             }
190             get
191             {
192                 NUILog.Debug($"[AnimatedVectorImageView [ [{GetId()}] ResourceUrl GET");
193                 return this.ResourceURL;
194             }
195         }
196
197
198         /// <summary>
199         /// RepeatCount of animation.
200         /// The repeat count is 0 by default.
201         /// If the RepeatCount is 0, the animation is never repeated.
202         /// If the RepeatCount is greater than 0, the repeat mode will be taken into account.
203         /// If RepeatCount is -1, animation is infinite loops.
204         /// </summary>
205         [EditorBrowsable(EditorBrowsableState.Never)]
206         public int RepeatCount
207         {
208             get
209             {
210                 if (NUIApplication.IsUsingXaml)
211                 {
212                     return (int)GetValue(RepeatCountProperty);
213                 }
214                 else
215                 {
216                     return (int)GetInternalRepeatCountProperty(this);
217                 }
218             }
219             set
220             {
221                 if (NUIApplication.IsUsingXaml)
222                 {
223                     SetValue(RepeatCountProperty, value);
224                 }
225                 else
226                 {
227                     SetInternalRepeatCountProperty(this, null, value);
228                 }
229                 NotifyPropertyChanged();
230             }
231         }
232         
233         private int InternalRepeatCount
234         {
235             set
236             {
237                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] RepeatCount SET");
238
239                 repeatCnt = (value < -1) ? -1 : value;
240                 LoopCount = (repeatCnt < 0) ? repeatCnt : repeatCnt + 1;
241
242                 NUILog.Debug($"[{GetId()}] repeatCnt={repeatCnt} ]AnimatedVectorImageView END]");
243             }
244             get => repeatCnt;
245         }
246
247         /// <summary>
248         /// TotalFrame of animation.
249         /// If resouce is still not be loaded, or invalid resource, the value is 0.
250         /// </summary>
251         [EditorBrowsable(EditorBrowsableState.Never)]
252         public new int TotalFrame
253         {
254             get => totalFrameNum;
255         }
256
257         private int totalFrameNum
258         {
259             get => base.TotalFrame;
260         }
261
262         /// <summary>
263         /// CurrentFrame of animation.
264         /// </summary>
265         /// <returns> Returns user set value for the current frame. Cannot provide actual playing current frame. </returns>
266         [EditorBrowsable(EditorBrowsableState.Never)]
267         public new int CurrentFrame
268         {
269             get
270             {
271                 if (NUIApplication.IsUsingXaml)
272                 {
273                     return (int)GetValue(CurrentFrameProperty);
274                 }
275                 else
276                 {
277                     return (int)GetInternalCurrentFrameProperty(this);
278                 }
279             }
280             set
281             {
282                 if (NUIApplication.IsUsingXaml)
283                 {
284                     SetValue(CurrentFrameProperty, value);
285                 }
286                 else
287                 {
288                     SetInternalCurrentFrameProperty(this, null, value);
289                 }
290                 NotifyPropertyChanged();
291             }
292         }
293
294         private int InternalCurrentFrame
295         {
296             set
297             {
298                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] CurrentFrame SET");
299
300                 if (string.IsNullOrEmpty(resourceUrl))
301                 {
302                     throw new InvalidOperationException("Resource Url not yet Set");
303                 }
304
305                 if (value < 0)
306                 {
307                     value = 0;
308                 }
309
310                 innerCurrentFrame = value;
311                 AnimationState = AnimationStates.Paused;
312
313                 base.SetMinMaxFrame(0, IntegerMaxValue);
314                 base.CurrentFrame = innerCurrentFrame;
315
316                 NUILog.Debug($" [{GetId()}] innerCurrentFrame={innerCurrentFrame}) ]AnimatedVectorImageView END]");
317             }
318             get => innerCurrentFrame;
319         }
320
321         /// <summary>
322         /// RepeatMode of animation.
323         /// </summary>
324         [EditorBrowsable(EditorBrowsableState.Never)]
325         public RepeatModes RepeatMode
326         {
327             get
328             {
329                 if (NUIApplication.IsUsingXaml)
330                 {
331                     return (RepeatModes)GetValue(RepeatModeProperty);
332                 }
333                 else
334                 {
335                     return (RepeatModes)GetInternalRepeatModeProperty(this);
336                 }
337             }
338             set
339             {
340                 if (NUIApplication.IsUsingXaml)
341                 {
342                     SetValue(RepeatModeProperty, value);
343                 }
344                 else
345                 {
346                     SetInternalRepeatModeProperty(this, null, value);
347                 }
348                 NotifyPropertyChanged();
349             }
350         }
351
352         private RepeatModes InternalRepeatMode
353         {
354             set
355             {
356                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] RepeatMode SET");
357                 repeatMode = value;
358
359                 switch (repeatMode)
360                 {
361                     case RepeatModes.Restart:
362                         LoopingMode = LoopingModeType.Restart;
363                         break;
364                     case RepeatModes.Reverse:
365                         LoopingMode = LoopingModeType.AutoReverse;
366                         break;
367                     default:
368                         LoopingMode = LoopingModeType.Restart;
369                         break;
370                 }
371
372                 NUILog.Debug($" [{GetId()}] repeatMode={repeatMode}) ]AnimatedVectorImageView END]");
373             }
374             get => repeatMode;
375         }
376
377         /// <summary>
378         /// Get state of animation.
379         /// </summary>
380         [EditorBrowsable(EditorBrowsableState.Never)]
381         public AnimationStates AnimationState
382         {
383             private set
384             {
385                 CurrentAnimationState = value;
386             }
387             get
388             {
389                 if (CurrentAnimationState == AnimationStates.Playing)
390                 {
391                     if (PlayState == PlayStateType.Stopped)
392                     {
393                         CurrentAnimationState = AnimationStates.Stopped;
394                     }
395                 }
396                 return CurrentAnimationState;
397             }
398         }
399         #endregion Property
400
401
402         #region Method
403         /// <summary>
404         /// Set minimum frame and maximum frame
405         /// </summary>
406         /// <param name="minFrame">minimum frame.</param>
407         /// <param name="maxFrame">maximum frame.</param>
408         [EditorBrowsable(EditorBrowsableState.Never)]
409         public void SetMinAndMaxFrame(int minFrame, int maxFrame)
410         {
411             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] SetMinAndMaxFrame({minFrame}, {maxFrame})");
412
413             minimumFrame = (minFrame) > 0 ? minFrame : 0;
414             maximumFrame = (maxFrame) > 0 ? maxFrame : 0;
415             isMinMaxFrameSet = minMaxSetTypes.SetByMinAndMaxFrameMethod;
416
417             // Remove marker information.
418             minimumFrameMarker = null;
419             maximumFrameMarker = null;
420
421             if (minimumFrame > maximumFrame)
422             {
423                 NUILog.Debug($" [{GetId()}] minimumFrame:{minimumFrame} > maximumFrame:{maximumFrame}) ]AnimatedVectorImageView END]");
424                 return;
425             }
426
427             NUILog.Debug($" [{GetId()}] minimumFrame:{minimumFrame}, maximumFrame:{maximumFrame}) ]AnimatedVectorImageView END]");
428         }
429
430         /// <summary>
431         /// Set minimum frame and maximum frame by marker.
432         /// Animation will play between the start frame and the end frame of the marker if one marker is specified.
433         /// Or animation will play between the start frame of the first marker and the end frame of the second marker if two markers are specified.
434         /// </summary>
435         /// <remarks>
436         /// If we use invaliad markers, or we load image asynchronous and load is not finished yet,
437         /// CurrentFrame might not be matched with real value.
438         /// </remarks>
439         /// <param name="marker1">First marker</param>
440         /// <param name="marker2">Second marker</param>
441         [EditorBrowsable(EditorBrowsableState.Never)]
442         public void SetMinAndMaxFrameByMarker(string marker1, string marker2 = null)
443         {
444             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] SetMinAndMaxFrameByMarker({marker1}, {marker2})");
445
446             minimumFrameMarker = marker1;
447             maximumFrameMarker = marker2;
448             isMinMaxFrameSet = minMaxSetTypes.SetByMinAndMaxFrameByMarkerMethod;
449
450             // Remove frame information.
451             minimumFrame = -1;
452             maximumFrame = -1;
453
454             NUILog.Debug($" [{GetId()}] minimumFrameMarker:{minimumFrameMarker}, maximumFrameMarker:{maximumFrameMarker}) ]AnimatedVectorImageView END]");
455         }
456
457         /// <summary>
458         /// SetMinMaxFrame(int startFrame, int endFrame)
459         /// </summary>
460         /// <param name="minFrame"></param>
461         /// <param name="maxFrame"></param>
462         [EditorBrowsable(EditorBrowsableState.Never)]
463         public new void SetMinMaxFrame(int minFrame, int maxFrame)
464         {
465             NUILog.Debug($"SetMinMaxFrame({minFrame}, {maxFrame})!!!");
466
467             minimumFrame = (minFrame) > 0 ? minFrame : 0;
468             maximumFrame = (maxFrame) > 0 ? maxFrame : 0;
469             isMinMaxFrameSet = minMaxSetTypes.SetByBaseSetMinMaxFrameMethod;
470
471             // Remove marker information.
472             minimumFrameMarker = null;
473             maximumFrameMarker = null;
474
475             if (minimumFrame >= totalFrameNum)
476             {
477                 minimumFrame = totalFrameNum - 1;
478             }
479
480             if (maximumFrame >= totalFrameNum)
481             {
482                 maximumFrame = totalFrameNum - 1;
483             }
484
485             base.SetMinMaxFrame(minimumFrame, maximumFrame);
486         }
487
488         /// <summary>
489         /// A marker has its start frame and end frame.
490         /// Animation will play between the start frame and the end frame of the marker if one marker is specified.
491         /// Or animation will play between the start frame of the first marker and the end frame of the second marker if two markers are specified.
492         /// </summary>
493         /// <param name="marker1">First marker</param>
494         /// <param name="marker2">Second marker</param>
495         [EditorBrowsable(EditorBrowsableState.Never)]
496         public new void SetMinMaxFrameByMarker(string marker1, string marker2 = null)
497         {
498             NUILog.Debug($"SetMinMaxFrameByMarker({marker1}, {marker2})");
499
500             minimumFrameMarker = marker1;
501             maximumFrameMarker = marker2;
502             isMinMaxFrameSet = minMaxSetTypes.SetByMarker;
503
504             // Remove frame information.
505             minimumFrame = -1;
506             maximumFrame = -1;
507
508             base.SetMinMaxFrameByMarker(marker1, marker2);
509         }
510
511         /// <summary>
512         /// Play Animation.
513         /// </summary>
514         [EditorBrowsable(EditorBrowsableState.Never)]
515         public new void Play()
516         {
517             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
518
519             if (string.IsNullOrEmpty(resourceUrl))
520             {
521                 throw new InvalidOperationException("Resource Url not yet Set");
522             }
523
524             switch (isMinMaxFrameSet)
525             {
526                 case minMaxSetTypes.NotSetByUser:
527                     base.SetMinMaxFrame(0, totalFrameNum - 1);
528                     base.CurrentFrame = 0;
529                     innerCurrentFrame = 0;
530                     break;
531
532                 case minMaxSetTypes.SetByMinAndMaxFrameByMarkerMethod:
533                     base.SetMinMaxFrameByMarker(minimumFrameMarker, maximumFrameMarker);
534                     if (GetFrameValueFromMarkerInfo())
535                     {
536                         base.CurrentFrame = minimumFrame;
537                         innerCurrentFrame = minimumFrame;
538                     }
539                     else
540                     {
541                         Tizen.Log.Error("NUI", $"[Warning] Play with invalid marker! Current frame become 0\n");
542                         base.CurrentFrame = 0;
543                         innerCurrentFrame = 0;
544                     }
545                     break;
546
547                 case minMaxSetTypes.SetByMinAndMaxFrameMethod:
548                     base.SetMinMaxFrame(minimumFrame, maximumFrame);
549                     base.CurrentFrame = minimumFrame;
550                     innerCurrentFrame = minimumFrame;
551                     break;
552
553                 case minMaxSetTypes.SetByMarker:
554                 case minMaxSetTypes.SetByBaseSetMinMaxFrameMethod:
555                 default:
556                     //do nothing!
557                     break;
558             }
559
560             base.Play();
561             AnimationState = AnimationStates.Playing;
562
563             NUILog.Debug($" [{GetId()}] isMinMaxFrameSet={isMinMaxFrameSet}) ]AnimatedVectorImageView END]");
564         }
565
566         /// <summary>
567         /// Pause Animation.
568         /// </summary>
569         [EditorBrowsable(EditorBrowsableState.Never)]
570         public new void Pause()
571         {
572             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
573
574             if (string.IsNullOrEmpty(resourceUrl))
575             {
576                 throw new InvalidOperationException("Resource Url not yet Set");
577             }
578
579             base.Pause();
580             AnimationState = AnimationStates.Paused;
581
582             NUILog.Debug($" [{GetId()}] ]AnimatedVectorImageView END]");
583         }
584
585         /// <summary>
586         /// Stop Animation.
587         /// </summary>
588         /// <param name="endAction">Defines, what should be behaviour after cancel operation
589         /// End action is Cancel, Animation Stops at the Current Frame.
590         /// End action is Discard, Animation Stops at the Min Frame
591         /// End action is StopFinal, Animation Stops at the Max Frame
592         /// </param>
593         [EditorBrowsable(EditorBrowsableState.Never)]
594         public void Stop(EndActions endAction = EndActions.Cancel)
595         {
596             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] endAction:({endAction}), PlayState={PlayState}");
597
598             if (string.IsNullOrEmpty(resourceUrl))
599             {
600                 throw new InvalidOperationException("Resource Url not yet Set");
601             }
602
603             if (AnimationState == AnimationStates.Stopped)
604             {
605                 return;
606             }
607
608             if (innerEndAction != endAction)
609             {
610                 innerEndAction = endAction;
611                 switch (endAction)
612                 {
613                     case EndActions.Cancel:
614                         StopBehavior = StopBehaviorType.CurrentFrame;
615                         break;
616                     case EndActions.Discard:
617                         StopBehavior = StopBehaviorType.MinimumFrame;
618                         break;
619                     case EndActions.StopFinal:
620                         StopBehavior = StopBehaviorType.MaximumFrame;
621                         break;
622                     default:
623                         NUILog.Debug($" [{GetId()}] no endAction : default set");
624                         break;
625                 }
626             }
627             AnimationState = AnimationStates.Stopped;
628
629             base.Stop();
630
631             NUILog.Debug($"isMinMaxFrameSet:{isMinMaxFrameSet}, base.CurrentFrame:{base.CurrentFrame}, totalFrameNum:{totalFrameNum}, minimumFrame:{minimumFrame}, maximumFrame:{maximumFrame}, StopBehavior:{StopBehavior}, endAction:{endAction}");
632
633             switch (isMinMaxFrameSet)
634             {
635                 case minMaxSetTypes.NotSetByUser:
636                     switch (endAction)
637                     {
638                         case EndActions.Cancel:
639                             innerCurrentFrame = base.CurrentFrame;
640                             break;
641                         case EndActions.Discard:
642                             base.CurrentFrame = innerCurrentFrame = 0;
643                             break;
644                         case EndActions.StopFinal:
645                             base.CurrentFrame = innerCurrentFrame = totalFrameNum - 1;
646                             break;
647                     }
648                     break;
649
650                 case minMaxSetTypes.SetByMinAndMaxFrameByMarkerMethod:
651                     if (GetFrameValueFromMarkerInfo())
652                     {
653                         goto case minMaxSetTypes.SetByMinAndMaxFrameMethod;
654                     }
655                     else
656                     {
657                         switch (endAction)
658                         {
659                             case EndActions.Cancel:
660                                 innerCurrentFrame = base.CurrentFrame;
661                                 break;
662                             case EndActions.Discard:
663                                 Tizen.Log.Error("NUI", $"[Warning] Stop(Discard) with invalid marker! Current frame become 0\n");
664                                 base.CurrentFrame = innerCurrentFrame = 0;
665                                 break;
666                             case EndActions.StopFinal:
667                                 Tizen.Log.Error("NUI", $"[Warning] Stop(StopFinal) with invalid marker! Current frame become {totalFrameNum - 1}\n");
668                                 base.CurrentFrame = innerCurrentFrame = totalFrameNum - 1;
669                                 break;
670                         }
671                         break;
672                     }
673
674                 case minMaxSetTypes.SetByMinAndMaxFrameMethod:
675                     switch (endAction)
676                     {
677                         case EndActions.Cancel:
678                             innerCurrentFrame = base.CurrentFrame;
679                             break;
680                         case EndActions.Discard:
681                             base.CurrentFrame = innerCurrentFrame = minimumFrame;
682                             break;
683                         case EndActions.StopFinal:
684                             base.CurrentFrame = innerCurrentFrame = maximumFrame;
685                             break;
686                     }
687                     break;
688
689                 case minMaxSetTypes.SetByMarker:
690                 case minMaxSetTypes.SetByBaseSetMinMaxFrameMethod:
691                 default:
692                     //do nothing!
693                     break;
694             }
695             NUILog.Debug($" [{GetId()}] innerCurrentFrame={innerCurrentFrame}, base.CurrentFrame={base.CurrentFrame}");
696             NUILog.Debug($" [{GetId()}] ]AnimatedVectorImageView END]");
697         }
698         #endregion Method
699
700
701         #region Event, Enum, Struct, ETC
702         /// <summary>
703         /// RepeatMode of animation.
704         /// </summary>
705         // Suppress warning : This has been being used by users, so that the interface can not be changed.
706         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
707         [EditorBrowsable(EditorBrowsableState.Never)]
708         public enum RepeatModes
709         {
710             /// <summary>
711             /// When the animation reaches the end and RepeatCount is nonZero, the animation restarts from the beginning. 
712             /// </summary>
713             [EditorBrowsable(EditorBrowsableState.Never)]
714             Restart = LoopingModeType.Restart,
715             /// <summary>
716             /// When the animation reaches the end and RepeatCount nonZero, the animation reverses direction on every animation cycle. 
717             /// </summary>
718             [EditorBrowsable(EditorBrowsableState.Never)]
719             Reverse = LoopingModeType.AutoReverse
720         }
721
722         /// <summary>
723         /// EndActions of animation.
724         /// </summary>
725         // Suppress warning : This has been being used by users, so that the interface can not be changed.
726         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
727         [EditorBrowsable(EditorBrowsableState.Never)]
728         public enum EndActions
729         {
730             /// <summary> End action is Cancel, Animation Stops at the Current Frame.</summary>
731             [EditorBrowsable(EditorBrowsableState.Never)]
732             Cancel = 0,
733             /// <summary>  End action is Discard, Animation Stops at the Min Frame</summary>
734             [EditorBrowsable(EditorBrowsableState.Never)]
735             Discard = 1,
736             /// <summary> End action is StopFinal, Animation Stops at the Max Frame</summary>
737             [EditorBrowsable(EditorBrowsableState.Never)]
738             StopFinal = 2
739         }
740
741         /// <summary>
742         /// AnimationStates of animation.
743         /// </summary>
744         // Suppress warning : This has been being used by users, so that the interface can not be changed.
745         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
746         [EditorBrowsable(EditorBrowsableState.Never)]
747         public enum AnimationStates
748         {
749             /// <summary> The animation has stopped.</summary>
750             [EditorBrowsable(EditorBrowsableState.Never)]
751             Stopped = PlayStateType.Stopped,
752             /// <summary> The animation is playing.</summary>
753             [EditorBrowsable(EditorBrowsableState.Never)]
754             Playing = PlayStateType.Playing,
755             /// <summary> The animation is paused.</summary>
756             [EditorBrowsable(EditorBrowsableState.Never)]
757             Paused = PlayStateType.Paused
758         }
759         #endregion Event, Enum, Struct, ETC
760
761
762         #region Internal
763         internal bool GetFrameValueFromMarkerInfo()
764         {
765             bool minimumMarkerFoundSuccess = false;
766             bool maximumMarkerFoundSuccess = false;
767             int foundedMinimumFrame = 0;
768             int foundedMaximumFrame = 0;
769
770             NUILog.Debug($" [{GetId()}] GetFrameValueFromMarkerInfo : marker = (minimumFrameMarker:{minimumFrameMarker}, maximumFrameMarker:{maximumFrameMarker})");
771
772             var markerInfoList = GetMarkerInfo();
773             if (markerInfoList != null)
774             {
775                 foreach (var markerInfo in markerInfoList)
776                 {
777                     if (markerInfo.Item1 == minimumFrameMarker)
778                     {
779                         if (string.IsNullOrEmpty(maximumFrameMarker))
780                         {
781                             minimumMarkerFoundSuccess = true;
782                             maximumMarkerFoundSuccess = true;
783                             foundedMinimumFrame = markerInfo.Item2;
784                             foundedMaximumFrame = markerInfo.Item3;
785                         }
786                         else
787                         {
788                             minimumMarkerFoundSuccess = true;
789                             foundedMinimumFrame = markerInfo.Item2;
790                         }
791                     }
792                     else if (markerInfo.Item1 == maximumFrameMarker)
793                     {
794                         maximumMarkerFoundSuccess = true;
795                         foundedMaximumFrame = markerInfo.Item2;
796                     }
797                 }
798             }
799
800             if (minimumMarkerFoundSuccess && maximumMarkerFoundSuccess)
801             {
802                 minimumFrame = (foundedMinimumFrame) > 0 ? foundedMinimumFrame : 0;
803                 maximumFrame = (foundedMaximumFrame) > 0 ? foundedMaximumFrame : 0;
804                 NUILog.Debug($" [{GetId()}] GetFrameValueFromMarkerInfo Sucess! frame set as {minimumFrame} ~ {maximumFrame} : marker = (minimumFrameMarker:{minimumFrameMarker}, maximumFrameMarker:{maximumFrameMarker})");
805                 if (minimumFrame > maximumFrame)
806                 {
807                     NUILog.Debug($" [{GetId()}] minimumFrame:{minimumFrame} > maximumFrame:{maximumFrame})");
808                 }
809
810                 // Note : let we insure to get marker frame value only one time per each frame marker setter
811                 minimumFrameMarker = null;
812                 maximumFrameMarker = null;
813                 isMinMaxFrameSet = minMaxSetTypes.SetByMinAndMaxFrameMethod;
814                 return true;
815             }
816             else
817             {
818                 Tizen.Log.Error("NUI", $"Fail to get frame from marker = (minimumFrameMarker:{minimumFrameMarker}, maximumFrameMarker:{maximumFrameMarker}). Maybe file is not loaded yet, or invalid marker used. url : {resourceUrl}\n");
819                 NUILog.Debug($" [{GetId()}] GetFrameValueFromMarkerInfo Failed! frame set as {minimumFrame} ~ {maximumFrame} : marker = (minimumFrameMarker:{minimumFrameMarker}, maximumFrameMarker:{maximumFrameMarker})");
820                 return false;
821             }
822         }
823         #endregion Internal
824
825
826         #region Private
827         private string resourceUrl = null;
828         private int repeatCnt = 0;
829         private RepeatModes repeatMode = RepeatModes.Restart;
830         private int minimumFrame = -1, maximumFrame = -1;
831         private string minimumFrameMarker = null;
832         private string maximumFrameMarker = null;
833         private minMaxSetTypes isMinMaxFrameSet = minMaxSetTypes.NotSetByUser;
834         private int innerCurrentFrame = -1;
835         private EndActions innerEndAction = EndActions.Cancel;
836         private enum minMaxSetTypes
837         {
838             NotSetByUser,
839             SetByMinAndMaxFrameMethod,
840             SetByMinAndMaxFrameByMarkerMethod,
841             SetByMarker,
842             SetByBaseSetMinMaxFrameMethod,
843         }
844
845         private AnimationStates CurrentAnimationState = AnimationStates.Stopped;
846         private const int IntegerMaxValue = 0x7FFFFFFF;
847         #endregion Private
848     }
849 }