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