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