[NUI] TCSACR-226 code change (#1032)
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / Transit.cs
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
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 using System;
18 using System.Collections;
19 using System.Collections.Generic;
20 using System.Collections.ObjectModel;
21 using System.Collections.Specialized;
22 using static Interop.Elementary;
23
24 namespace ElmSharp
25 {
26     /// <summary>
27     /// Transit is designed to apply various animated transition effects, such as translation, rotation, etc.
28     /// For using these effects, create a transit and add the desired transition effects.
29     /// </summary>
30     /// <remarks>Transit is not reusable. If the effect ends, the transit is destroyed automatically.</remarks>
31     /// <since_tizen> preview </since_tizen>
32     public class Transit : IDisposable
33     {
34         IntPtr _handle = IntPtr.Zero;
35         bool _isDisposed = false;
36         ObservableCollection<EvasObject> _objects = new ObservableCollection<EvasObject>();
37         ObservableCollection<Transit> _chains = new ObservableCollection<Transit>();
38         HashSet<object> _checker = new HashSet<object>();
39         Elm_Transit_Del_Cb DeletedCallback;
40         Elm_Transit_Effect_End_Cb EffectEndCallback;
41         Elm_Transit_Effect_Transition_Cb EffectTransitionCallback;
42
43         /// <summary>
44         /// A callback is called when the transit is deleted.
45         /// </summary>
46         /// <since_tizen> preview </since_tizen>
47         public event EventHandler Deleted;
48
49         /// <summary>
50         /// Creates and initializes a new instance of the Transit class.
51         /// </summary>
52         /// <since_tizen> preview </since_tizen>
53         public Transit()
54         {
55             _handle = Interop.Elementary.elm_transit_add();
56             DeletedCallback = (ptr1, ptr2) =>
57             {
58                 Deleted?.Invoke(this, EventArgs.Empty);
59                 Dispose(true);
60             };
61             Interop.Elementary.elm_transit_del_cb_set(_handle, DeletedCallback, IntPtr.Zero);
62             ((INotifyCollectionChanged)_objects).CollectionChanged += OnObjectCollectionChanged;
63             ((INotifyCollectionChanged)_chains).CollectionChanged += OnChaninCollectionChanged;
64         }
65
66         /// <summary>
67         /// Destroys the transit object.
68         /// </summary>
69         ~Transit()
70         {
71             Dispose(false);
72         }
73
74         /// <summary>
75         /// Gets or sets the transit animation time.
76         /// </summary>
77         /// <since_tizen> preview </since_tizen>
78         public double Duration
79         {
80             get
81             {
82                 return Interop.Elementary.elm_transit_duration_get(_handle);
83             }
84             set
85             {
86                 Interop.Elementary.elm_transit_duration_set(_handle, value);
87             }
88         }
89
90         /// <summary>
91         /// Gets or sets a value whether the objects states will be kept or not.
92         /// If it is not kept, the objects states will be reset when the transition ends.
93         /// </summary>
94         /// <since_tizen> preview </since_tizen>
95         public bool ObjectStateKeep
96         {
97             get
98             {
99                 return Interop.Elementary.elm_transit_objects_final_state_keep_get(_handle);
100             }
101             set
102             {
103                 Interop.Elementary.elm_transit_objects_final_state_keep_set(_handle, value);
104             }
105         }
106
107         /// <summary>
108         /// Gets or sets the transit animation acceleration type.
109         /// </summary>
110         /// <since_tizen> preview </since_tizen>
111         public TweenMode TweenMode
112         {
113             get
114             {
115                 return (TweenMode)Interop.Elementary.elm_transit_tween_mode_get(_handle);
116             }
117             set
118             {
119                 Interop.Elementary.elm_transit_tween_mode_set(_handle, (int)value);
120             }
121         }
122
123         /// <summary>
124         /// Gets or sets the transit repeat count.
125         /// If the repeat is a negative number, it will repeat infinite times.
126         /// </summary>
127         /// <since_tizen> preview </since_tizen>
128         public int Repeat
129         {
130             get
131             {
132                 return Interop.Elementary.elm_transit_repeat_times_get(_handle);
133             }
134             set
135             {
136                 Interop.Elementary.elm_transit_repeat_times_set(_handle, value);
137             }
138         }
139
140         /// <summary>
141         /// Gets or sets if auto reverse is on.
142         /// </summary>
143         /// <since_tizen> preview </since_tizen>
144         public bool AutoReverse
145         {
146             get
147             {
148                 return Interop.Elementary.elm_transit_auto_reverse_get(_handle);
149             }
150             set
151             {
152                 Interop.Elementary.elm_transit_auto_reverse_set(_handle, value);
153             }
154         }
155
156         /// <summary>
157         /// Gets or sets the event enabled when transit is operating.
158         /// </summary>
159         /// <since_tizen> preview </since_tizen>
160         public bool EventEnabled
161         {
162             get
163             {
164                 return Interop.Elementary.elm_transit_event_enabled_get(_handle);
165             }
166             set
167             {
168                 Interop.Elementary.elm_transit_event_enabled_set(_handle, value);
169             }
170         }
171
172         /// <summary>
173         /// Gets or sets the smooth scaling for transit map rendering.
174         /// This gets the smooth scaling for transit map rendering.
175         /// </summary>
176         /// <since_tizen> preview </since_tizen>
177         public bool Smooth
178         {
179             get
180             {
181                 return Interop.Elementary.elm_transit_smooth_get(_handle);
182             }
183             set
184             {
185                 Interop.Elementary.elm_transit_smooth_set(_handle, value);
186             }
187         }
188
189         /// <summary>
190         /// Gets the time progression of the animation (a double value between 0.0 and 1.0).
191         /// The value returned is a fraction (current time/total time).
192         /// It represents the progression position relative to the total.
193         /// </summary>
194         /// <since_tizen> preview </since_tizen>
195         public double Progress
196         {
197             get
198             {
199                 return Interop.Elementary.elm_transit_progress_value_get(_handle);
200             }
201         }
202
203         /// <summary>
204         /// Gets or sets the transit animation tween mode acceleration factor.
205         /// </summary>
206         /// <returns>A factor value from 0.0 to 1.0.</returns>
207         /// <since_tizen> preview </since_tizen>
208         public double BeginAccelerationFactor
209         {
210             get
211             {
212                 double begin = 1.0, end = 0.0;
213                 Interop.Elementary.elm_transit_tween_mode_factor_get(_handle, out begin, out end);
214                 return begin;
215             }
216             set
217             {
218                 Interop.Elementary.elm_transit_tween_mode_factor_set(_handle, value, EndAccelerationFactor);
219             }
220         }
221
222         /// <summary>
223         /// Gets or sets the transit animation tween mode acceleration factor.
224         /// </summary>
225         /// <returns>A factor value from 0.0 to 1.0.</returns>
226         /// <since_tizen> preview </since_tizen>
227         public double EndAccelerationFactor
228         {
229             get
230             {
231                 double begin = 1.0, end = 0.0;
232                 Interop.Elementary.elm_transit_tween_mode_factor_get(_handle, out begin, out end);
233                 return end;
234             }
235             set
236             {
237                 Interop.Elementary.elm_transit_tween_mode_factor_set(_handle, BeginAccelerationFactor, value);
238             }
239         }
240
241         /// <summary>
242         /// Starts the transition in given seconds.
243         /// Once this API is called, the transit begins to measure the time.
244         /// </summary>
245         /// <param name="interval">The interval value in seconds.</param>
246         /// <since_tizen> preview </since_tizen>
247         public void Go(double interval = 0)
248         {
249             Interop.Elementary.elm_transit_go_in(_handle, interval);
250         }
251
252         /// <summary>
253         /// Pauses the transition.
254         /// </summary>
255         /// <since_tizen> preview </since_tizen>
256         public void Pause()
257         {
258             if (Interop.Elementary.elm_transit_paused_get(_handle) == false)
259                 Interop.Elementary.elm_transit_paused_set(_handle, true);
260         }
261
262         /// <summary>
263         /// Resumes the transition.
264         /// </summary>
265         /// <since_tizen> preview </since_tizen>
266         public void Resume()
267         {
268             if (Interop.Elementary.elm_transit_paused_get(_handle) == true)
269                 Interop.Elementary.elm_transit_paused_set(_handle, false);
270         }
271
272         /// <summary>
273         /// Gets the current chained transit list.
274         /// </summary>
275         /// <remarks>Cannot add the duplicate transit.</remarks>
276         /// <since_tizen> preview </since_tizen>
277         public IList<Transit> Chains
278         {
279             get { return _chains; }
280         }
281
282         /// <summary>
283         /// Gets the objects list of the transit.
284         /// </summary>
285         /// <remarks>Cannot add the duplicate object.</remarks>
286         /// <since_tizen> preview </since_tizen>
287         public IList<EvasObject> Objects
288         {
289             get { return _objects; }
290         }
291
292         /// <summary>
293         /// Adds the effect.
294         /// </summary>
295         /// <param name="effect">EffectBase object.</param>
296         /// <since_tizen> preview </since_tizen>
297         public void AddEffect(EffectBase effect)
298         {
299             IntPtr _effect = effect.CreateEffect(_handle);
300             EffectEndCallback = (effectPtr, transitPtr) => { effect.SendEffectEnd(); };
301             EffectTransitionCallback = (effectPtr, transitPtr, progress) => { };
302             Interop.Elementary.elm_transit_effect_add(_handle, EffectTransitionCallback, _effect, EffectEndCallback);
303         }
304
305         /// <summary>
306         /// Destroys the current object.
307         /// </summary>
308         /// <since_tizen> preview </since_tizen>
309         public void Dispose()
310         {
311             Dispose(true);
312             GC.SuppressFinalize(this);
313         }
314
315         /// <summary>
316         /// Releases all the resources currently used by this instance.
317         /// </summary>
318         /// <param name="disposing">
319         /// true if the managed resources should be disposed,
320         /// otherwise false.
321         /// </param>
322         /// <since_tizen> preview </since_tizen>
323         protected virtual void Dispose(bool disposing)
324         {
325             if (_isDisposed)
326                 return;
327
328             if (disposing)
329             {
330                 ((INotifyCollectionChanged)_chains).CollectionChanged -= OnChaninCollectionChanged;
331                 _chains.Clear();
332                 ((INotifyCollectionChanged)_objects).CollectionChanged -= OnObjectCollectionChanged;
333                 _objects.Clear();
334                 _checker.Clear();
335             }
336
337             _isDisposed = true;
338         }
339
340         void OnObjectCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
341         {
342             if (e.Action == NotifyCollectionChangedAction.Add)
343             {
344                 foreach (EvasObject item in e.NewItems)
345                     AddObject(item);
346             }
347             else if (e.Action == NotifyCollectionChangedAction.Remove)
348             {
349                 foreach (EvasObject item in e.OldItems)
350                     RemoveObject(item);
351             }
352         }
353
354         void OnChaninCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
355         {
356             if (e.Action == NotifyCollectionChangedAction.Add)
357             {
358                 foreach (Transit item in e.NewItems)
359                     AddChainedTransit(item);
360             }
361             else if (e.Action == NotifyCollectionChangedAction.Remove)
362             {
363                 foreach (Transit item in e.OldItems)
364                     DeleteChainedTransit(item);
365             }
366         }
367
368         /// <summary>
369         /// Adds a new object to apply the effects.
370         /// After the first addition of an object to transit, if its object list becomes empty again, the transit will be killed.
371         /// If the object belongs to another transit, the object will be removed from it and it will only belong to the other transit.
372         /// </summary>
373         /// <remarks>It is not allowed to add a new object after the transit begins.</remarks>
374         /// <param name="obj">Object to be animated.</param>
375         void AddObject(EvasObject obj)
376         {
377             if (_checker.Contains(obj))
378                 throw new InvalidOperationException("Cannot add the duplicate object.");
379
380             _checker.Add(obj);
381             Interop.Elementary.elm_transit_object_add(_handle, obj);
382         }
383
384         /// <summary>
385         /// Removes an added object from the transit.
386         /// </summary>
387         /// <param name="obj">Object to be removed from transit.</param>
388         void RemoveObject(EvasObject obj)
389         {
390             if (_checker.Contains(obj))
391                 _checker.Remove(obj);
392
393             Interop.Elementary.elm_transit_object_remove(_handle, obj);
394         }
395
396         /// <summary>
397         /// Makes the chain relationship between two transits.
398         /// </summary>
399         /// <param name="transit">The chain transit object. This transit will be operated after the transit is done.</param>
400         void AddChainedTransit(Transit transit)
401         {
402             if (_checker.Contains(transit))
403                 throw new InvalidOperationException("Cannot add the duplicate transit.");
404
405             _checker.Add(transit);
406             Interop.Elementary.elm_transit_chain_transit_add(_handle, transit._handle);
407         }
408
409         /// <summary>
410         /// Cuts off the chain relationship between two transits.
411         /// </summary>
412         /// <param name="transit">The chain transit object.</param>
413         void DeleteChainedTransit(Transit transit)
414         {
415             if (_checker.Contains(transit))
416                 _checker.Remove(transit);
417
418             Interop.Elementary.elm_transit_chain_transit_del(_handle, transit._handle);
419         }
420     }
421 }