e69c03e60b5d3e905e39270844b89c3c9377d832
[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
21 namespace Tizen.NUI.BaseComponents
22 {
23     /// <summary>
24     /// AnimatedVectorImageView is a class for displaying a vector resource.
25     /// </summary>
26     [EditorBrowsable(EditorBrowsableState.Never)]
27     public partial class AnimatedVectorImageView : LottieAnimationView
28     {
29         #region Constructor, Destructor, Dispose
30         /// <summary>
31         /// Construct VectorAnimationView.
32         /// </summary>
33         [EditorBrowsable(EditorBrowsableState.Never)]
34         public AnimatedVectorImageView() : base()
35         {
36             NUILog.Debug($"[AnimatedVectorImageView START[ constructor objId={GetId()} ] END]");
37         }
38
39         /// <summary>
40         /// Construct VectorAnimationView.
41         /// </summary>
42         /// <param name="scale">Set scaling factor for Vector Animation, while creating.</param>
43         [EditorBrowsable(EditorBrowsableState.Never)]
44         public AnimatedVectorImageView(float scale) : base(scale)
45         {
46             NUILog.Debug($"[AnimatedVectorImageView START[ constructor scale={scale}) objId={GetId()} ] END]");
47         }
48
49         /// <summary>
50         /// You can override it to clean-up your own resources
51         /// </summary>
52         /// <param name="type">DisposeTypes</param>
53         [EditorBrowsable(EditorBrowsableState.Never)]
54         protected override void Dispose(DisposeTypes type)
55         {
56             if (disposed)
57             {
58                 return;
59             }
60             NUILog.Debug($"AnimatedVectorImageView START");
61
62             //Release your own unmanaged resources here.
63             //You should not access any managed member here except static instance.
64             //because the execution order of Finalizes is non-deterministic.
65
66             base.Dispose(type);
67
68             NUILog.Debug($"AnimatedVectorImageView END");
69         }
70         #endregion Constructor, Destructor, Dispose
71
72
73         #region Property
74         /// <summary>
75         /// Set Resource URL
76         /// </summary>
77         // Suppress warning : This has been being used by users, so that the interface can not be changed.
78         [EditorBrowsable(EditorBrowsableState.Never)]
79         public string ResourceURL
80         {
81             get
82             {
83                 return GetValue(ResourceURLProperty) as string;
84             }
85             set
86             {
87                 SetValue(ResourceURLProperty, value);
88                 NotifyPropertyChanged();
89             }
90         }
91
92         private string InternalResourceURL
93         {
94             set
95             {
96                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] ResourceURL SET");
97
98                 if (value == resourceUrl)
99                 {
100                     NUILog.Debug($"set same URL! ");
101                     return;
102                 }
103                 resourceUrl = (value == null) ? "" : value;
104                 URL = resourceUrl;
105                 isMinMaxFrameSet = minMaxSetTypes.NotSetByUser;
106                 NUILog.Debug($" [{GetId()}] resourceUrl={resourceUrl}) ]AnimatedVectorImageView END]");
107             }
108             get => resourceUrl;
109         }
110
111         /// <summary>
112         /// Set Resource URL
113         /// </summary>
114         // Suppress warning : This has been being used by users, so that the interface can not be changed.
115         [EditorBrowsable(EditorBrowsableState.Never)]
116         public new string ResourceUrl
117         {
118             get
119             {
120                 return GetValue(ResourceUrlProperty) as string;
121             }
122             set
123             {
124                 SetValue(ResourceUrlProperty, value);
125                 NotifyPropertyChanged();
126             }
127         }
128
129         private string InternalResourceUrl
130         {
131             set
132             {
133                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] ResourceUrl SET");
134                 this.ResourceURL = value;
135                 NUILog.Debug($" [{GetId()}] value={value}) ]AnimatedVectorImageView END]");
136             }
137             get
138             {
139                 NUILog.Debug($"[AnimatedVectorImageView [ [{GetId()}] ResourceUrl GET");
140                 return this.ResourceURL;
141             }
142         }
143
144
145         /// <summary>
146         /// RepeatCount of animation.
147         /// The repeat count is 0 by default.
148         /// If the RepeatCount is 0, the animation is never repeated.
149         /// If the RepeatCount is greater than 0, the repeat mode will be taken into account.
150         /// If RepeatCount is -1, animation is infinite loops.
151         /// </summary>
152         [EditorBrowsable(EditorBrowsableState.Never)]
153         public int RepeatCount
154         {
155             get
156             {
157                 return (int)GetValue(RepeatCountProperty);
158             }
159             set
160             {
161                 SetValue(RepeatCountProperty, value);
162                 NotifyPropertyChanged();
163             }
164         }
165
166         private int InternalRepeatCount
167         {
168             set
169             {
170                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] RepeatCount SET");
171
172                 repeatCnt = (value < -1) ? -1 : value;
173                 LoopCount = (repeatCnt < 0) ? repeatCnt : repeatCnt + 1;
174
175                 NUILog.Debug($"[{GetId()}] repeatCnt={repeatCnt} ]AnimatedVectorImageView END]");
176             }
177             get => repeatCnt;
178         }
179
180         /// <summary>
181         /// TotalFrame of animation.
182         /// </summary>
183         [EditorBrowsable(EditorBrowsableState.Never)]
184         public new int TotalFrame
185         {
186             get => totalFrameNum;
187         }
188
189         private int totalFrameNum
190         {
191             get => base.TotalFrame;
192         }
193
194         /// <summary>
195         /// CurrentFrame of animation.
196         /// </summary>
197         /// <returns> Returns user set value for the current frame. Cannot provide actual playing current frame. </returns>
198         [EditorBrowsable(EditorBrowsableState.Never)]
199         public new int CurrentFrame
200         {
201             get
202             {
203                 return (int)GetValue(CurrentFrameProperty);
204             }
205             set
206             {
207                 SetValue(CurrentFrameProperty, value);
208                 NotifyPropertyChanged();
209             }
210         }
211
212         private int InternalCurrentFrame
213         {
214             set
215             {
216                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] CurrentFrame SET");
217
218                 if (string.IsNullOrEmpty(resourceUrl))
219                 {
220                     throw new InvalidOperationException("Resource Url not yet Set");
221                 }
222
223                 if (value < 0)
224                 {
225                     value = 0;
226                 }
227
228                 innerCurrentFrame = value;
229                 AnimationState = AnimationStates.Paused;
230
231                 base.CurrentFrame = innerCurrentFrame;
232
233                 NUILog.Debug($" [{GetId()}] innerCurrentFrame={innerCurrentFrame}) ]AnimatedVectorImageView END]");
234             }
235             get => innerCurrentFrame;
236         }
237
238         /// <summary>
239         /// RepeatMode of animation.
240         /// </summary>
241         [EditorBrowsable(EditorBrowsableState.Never)]
242         public RepeatModes RepeatMode
243         {
244             get
245             {
246                 return (RepeatModes)GetValue(RepeatModeProperty);
247             }
248             set
249             {
250                 SetValue(RepeatModeProperty, value);
251                 NotifyPropertyChanged();
252             }
253         }
254
255         private RepeatModes InternalRepeatMode
256         {
257             set
258             {
259                 NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] RepeatMode SET");
260                 repeatMode = value;
261
262                 switch (repeatMode)
263                 {
264                     case RepeatModes.Restart:
265                         LoopingMode = LoopingModeType.Restart;
266                         break;
267                     case RepeatModes.Reverse:
268                         LoopingMode = LoopingModeType.AutoReverse;
269                         break;
270                     default:
271                         LoopingMode = LoopingModeType.Restart;
272                         break;
273                 }
274
275                 NUILog.Debug($" [{GetId()}] repeatMode={repeatMode}) ]AnimatedVectorImageView END]");
276             }
277             get => repeatMode;
278         }
279
280         /// <summary>
281         /// Get state of animation.
282         /// </summary>
283         [EditorBrowsable(EditorBrowsableState.Never)]
284         public AnimationStates AnimationState
285         {
286             private set
287             {
288                 CurrentAnimationState = value;
289             }
290             get
291             {
292                 if (CurrentAnimationState == AnimationStates.Playing)
293                 {
294                     if (PlayState == PlayStateType.Stopped)
295                     {
296                         CurrentAnimationState = AnimationStates.Stopped;
297                     }
298                 }
299                 return CurrentAnimationState;
300             }
301         }
302         #endregion Property
303
304
305         #region Method
306         /// <summary>
307         /// Set minimum frame and maximum frame
308         /// </summary>
309         /// <param name="minFrame">minimum frame.</param>
310         /// <param name="maxFrame">maximum frame.</param>
311         [EditorBrowsable(EditorBrowsableState.Never)]
312         public void SetMinAndMaxFrame(int minFrame, int maxFrame)
313         {
314             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] SetMinAndMaxFrame({minFrame}, {maxFrame})");
315
316             minimumFrame = (minFrame) > 0 ? minFrame : 0;
317             maximumFrame = (maxFrame) > 0 ? maxFrame : 0;
318             isMinMaxFrameSet = minMaxSetTypes.SetByMinAndMaxFrameMethod;
319
320             if (minimumFrame > maximumFrame)
321             {
322                 NUILog.Debug($" [{GetId()}] minimumFrame:{minimumFrame} > maximumFrame:{maximumFrame}) ]AnimatedVectorImageView END]");
323                 return;
324             }
325
326             NUILog.Debug($" [{GetId()}] minimumFrame:{minimumFrame}, maximumFrame:{maximumFrame}) ]AnimatedVectorImageView END]");
327         }
328
329         /// <summary>
330         /// SetMinMaxFrame(int startFrame, int endFrame)
331         /// </summary>
332         /// <param name="minFrame"></param>
333         /// <param name="maxFrame"></param>
334         [EditorBrowsable(EditorBrowsableState.Never)]
335         public new void SetMinMaxFrame(int minFrame, int maxFrame)
336         {
337             NUILog.Debug($"SetMinMaxFrame({minFrame}, {maxFrame})!!!");
338
339             minimumFrame = (minFrame) > 0 ? minFrame : 0;
340             maximumFrame = (maxFrame) > 0 ? maxFrame : 0;
341             isMinMaxFrameSet = minMaxSetTypes.SetByBaseSetMinMaxFrameMethod;
342
343             if (minimumFrame >= totalFrameNum)
344             {
345                 minimumFrame = totalFrameNum - 1;
346             }
347
348             if (maximumFrame >= totalFrameNum)
349             {
350                 maximumFrame = totalFrameNum - 1;
351             }
352
353             base.SetMinMaxFrame(minimumFrame, maximumFrame);
354         }
355
356         /// <summary>
357         /// A marker has its start frame and end frame. 
358         /// Animation will play between the start frame and the end frame of the marker if one marker is specified.
359         /// 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.   *
360         /// </summary>
361         /// <param name="marker1">First marker</param>
362         /// <param name="marker2">Second marker</param>
363         [EditorBrowsable(EditorBrowsableState.Never)]
364         public new void SetMinMaxFrameByMarker(string marker1, string marker2 = null)
365         {
366             NUILog.Debug($"SetMinMaxFrameByMarker({marker1}, {marker2})");
367             isMinMaxFrameSet = minMaxSetTypes.SetByMarker;
368             base.SetMinMaxFrameByMarker(marker1, marker2);
369         }
370
371         /// <summary>
372         /// Play Animation.
373         /// </summary>
374         [EditorBrowsable(EditorBrowsableState.Never)]
375         public new void Play()
376         {
377             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
378
379             if (string.IsNullOrEmpty(resourceUrl))
380             {
381                 throw new InvalidOperationException("Resource Url not yet Set");
382             }
383
384             switch (isMinMaxFrameSet)
385             {
386                 case minMaxSetTypes.NotSetByUser:
387                     base.SetMinMaxFrame(0, totalFrameNum - 1);
388                     base.CurrentFrame = 0;
389                     innerCurrentFrame = 0;
390                     break;
391
392                 case minMaxSetTypes.SetByMinAndMaxFrameMethod:
393                     base.SetMinMaxFrame(minimumFrame, maximumFrame);
394                     base.CurrentFrame = minimumFrame;
395                     innerCurrentFrame = minimumFrame;
396                     break;
397
398                 case minMaxSetTypes.SetByMarker:
399                 case minMaxSetTypes.SetByBaseSetMinMaxFrameMethod:
400                 default:
401                     //do nothing!
402                     break;
403             }
404
405             //temporal fix
406             Extents tmp = base.Margin;
407             base.Margin = tmp;
408
409             base.Play();
410             AnimationState = AnimationStates.Playing;
411
412             NUILog.Debug($" [{GetId()}] isMinMaxFrameSet={isMinMaxFrameSet}) ]AnimatedVectorImageView END]");
413         }
414
415         /// <summary>
416         /// Pause Animation.
417         /// </summary>
418         [EditorBrowsable(EditorBrowsableState.Never)]
419         public new void Pause()
420         {
421             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] AnimationState={AnimationState}, PlayState={PlayState}");
422
423             if (string.IsNullOrEmpty(resourceUrl))
424             {
425                 throw new InvalidOperationException("Resource Url not yet Set");
426             }
427
428             base.Pause();
429             AnimationState = AnimationStates.Paused;
430
431             NUILog.Debug($" [{GetId()}] ]AnimatedVectorImageView END]");
432         }
433
434         /// <summary>
435         /// Stop Animation.
436         /// </summary>
437         /// <param name="endAction">Defines, what should be behaviour after cancel operation
438         /// End action is Cancel, Animation Stops at the Current Frame.
439         /// End action is Discard, Animation Stops at the Min Frame
440         /// End action is StopFinal, Animation Stops at the Max Frame
441         /// </param>
442         [EditorBrowsable(EditorBrowsableState.Never)]
443         public void Stop(EndActions endAction = EndActions.Cancel)
444         {
445             NUILog.Debug($"[AnimatedVectorImageView START[ [{GetId()}] endAction:({endAction}), PlayState={PlayState}");
446
447             if (string.IsNullOrEmpty(resourceUrl))
448             {
449                 throw new InvalidOperationException("Resource Url not yet Set");
450             }
451
452             if (AnimationState == AnimationStates.Stopped)
453             {
454                 return;
455             }
456
457             if (innerEndAction != endAction)
458             {
459                 innerEndAction = endAction;
460                 switch (endAction)
461                 {
462                     case EndActions.Cancel:
463                         StopBehavior = StopBehaviorType.CurrentFrame;
464                         break;
465                     case EndActions.Discard:
466                         StopBehavior = StopBehaviorType.MinimumFrame;
467                         break;
468                     case EndActions.StopFinal:
469                         StopBehavior = StopBehaviorType.MaximumFrame;
470                         break;
471                     default:
472                         NUILog.Debug($" [{GetId()}] no endAction : default set");
473                         break;
474                 }
475             }
476             AnimationState = AnimationStates.Stopped;
477
478             base.Stop();
479
480             NUILog.Debug($"isMinMaxFrameSet:{isMinMaxFrameSet}, base.CurrentFrame:{base.CurrentFrame}, totalFrameNum:{totalFrameNum}, minimumFrame:{minimumFrame}, maximumFrame:{maximumFrame}, StopBehavior:{StopBehavior}, endAction:{endAction}");
481
482             switch (isMinMaxFrameSet)
483             {
484                 case minMaxSetTypes.NotSetByUser:
485                     switch(endAction)
486                     {
487                         case EndActions.Cancel:
488                             innerCurrentFrame = base.CurrentFrame;
489                             break;
490                         case EndActions.Discard:
491                             base.CurrentFrame = innerCurrentFrame = 0;
492                             break;
493                         case EndActions.StopFinal:
494                             base.CurrentFrame = innerCurrentFrame= totalFrameNum - 1;
495                             break;
496                     }
497                     break;
498
499                 case minMaxSetTypes.SetByMinAndMaxFrameMethod:
500                     switch (endAction)
501                     {
502                         case EndActions.Cancel:
503                             innerCurrentFrame = base.CurrentFrame;
504                             break;
505                         case EndActions.Discard:
506                             base.CurrentFrame = innerCurrentFrame = minimumFrame;
507                             break;
508                         case EndActions.StopFinal:
509                             base.CurrentFrame = innerCurrentFrame = maximumFrame;
510                             break;
511                     }
512                     break;
513                 case minMaxSetTypes.SetByMarker:
514                 case minMaxSetTypes.SetByBaseSetMinMaxFrameMethod:
515                 default:
516                     //do nothing!
517                     break;
518             }
519             NUILog.Debug($" [{GetId()}] innerCurrentFrame={innerCurrentFrame}, base.CurrentFrame={base.CurrentFrame}");
520             NUILog.Debug($" [{GetId()}] ]AnimatedVectorImageView END]");
521         }
522         #endregion Method
523
524
525         #region Event, Enum, Struct, ETC
526         /// <summary>
527         /// RepeatMode of animation.
528         /// </summary>
529         // Suppress warning : This has been being used by users, so that the interface can not be changed.
530         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
531         [EditorBrowsable(EditorBrowsableState.Never)]
532         public enum RepeatModes
533         {
534             /// <summary>
535             /// When the animation reaches the end and RepeatCount is nonZero, the animation restarts from the beginning. 
536             /// </summary>
537             [EditorBrowsable(EditorBrowsableState.Never)]
538             Restart = LoopingModeType.Restart,
539             /// <summary>
540             /// When the animation reaches the end and RepeatCount nonZero, the animation reverses direction on every animation cycle. 
541             /// </summary>
542             [EditorBrowsable(EditorBrowsableState.Never)]
543             Reverse = LoopingModeType.AutoReverse
544         }
545
546         /// <summary>
547         /// EndActions of animation.
548         /// </summary>
549         // Suppress warning : This has been being used by users, so that the interface can not be changed.
550         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
551         [EditorBrowsable(EditorBrowsableState.Never)]
552         public enum EndActions
553         {
554             /// <summary> End action is Cancel, Animation Stops at the Current Frame.</summary>
555             [EditorBrowsable(EditorBrowsableState.Never)]
556             Cancel = 0,
557             /// <summary>  End action is Discard, Animation Stops at the Min Frame</summary>
558             [EditorBrowsable(EditorBrowsableState.Never)]
559             Discard = 1,
560             /// <summary> End action is StopFinal, Animation Stops at the Max Frame</summary>
561             [EditorBrowsable(EditorBrowsableState.Never)]
562             StopFinal = 2
563         }
564
565         /// <summary>
566         /// AnimationStates of animation.
567         /// </summary>
568         // Suppress warning : This has been being used by users, so that the interface can not be changed.
569         [System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1717:Only FlagsAttribute enums should have plural names", Justification = "<Pending>")]
570         [EditorBrowsable(EditorBrowsableState.Never)]
571         public enum AnimationStates
572         {
573             /// <summary> The animation has stopped.</summary>
574             [EditorBrowsable(EditorBrowsableState.Never)]
575             Stopped = PlayStateType.Stopped,
576             /// <summary> The animation is playing.</summary>
577             [EditorBrowsable(EditorBrowsableState.Never)]
578             Playing = PlayStateType.Playing,
579             /// <summary> The animation is paused.</summary>
580             [EditorBrowsable(EditorBrowsableState.Never)]
581             Paused = PlayStateType.Paused
582         }
583         #endregion Event, Enum, Struct, ETC
584
585
586         #region Internal
587         #endregion Internal
588
589
590         #region Private
591         private string resourceUrl = null;
592         private int repeatCnt = 0;
593         private RepeatModes repeatMode = RepeatModes.Restart;
594         private int minimumFrame = -1, maximumFrame = -1;
595         private minMaxSetTypes isMinMaxFrameSet = minMaxSetTypes.NotSetByUser;
596         private int innerCurrentFrame = -1;
597         private EndActions innerEndAction = EndActions.Cancel;
598         private enum minMaxSetTypes
599         {
600             NotSetByUser,
601             SetByMinAndMaxFrameMethod,
602             SetByMarker,
603             SetByBaseSetMinMaxFrameMethod,
604         }
605
606         private AnimationStates CurrentAnimationState = AnimationStates.Stopped;
607         #endregion Private
608     }
609 }