[NUI] View Transition with page switching
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Transition / TransitionSet.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 namespace Tizen.NUI
19 {
20     using System;
21     using System.ComponentModel;
22     using System.Runtime.InteropServices;
23
24     /// <summary>
25     /// TransitionSet is used to control lifetime of multiple Transitions.
26     /// For the one page transition, may multiple transitions are played coincidently.
27     /// Every transitions added on a TransitionSet have same play lifetime. And emit a single Finished signal.
28     /// </summary>
29     internal class TransitionSet : BaseHandle
30     {
31         private TransitionSetFinishedEventCallbackType transitionSetFinishedEventCallback;
32         private System.IntPtr finishedCallbackOfNative;
33
34         /// <summary>
35         /// Creates an initialized transitionSet.<br />
36         /// </summary>
37         /// <remarks>DurationmSeconds must be greater than zero.</remarks>
38         public TransitionSet() : this(Interop.TransitionSet.New(), true)
39         {
40             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
41         }
42
43         internal TransitionSet(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
44         {
45             transitionSetFinishedEventCallback = OnFinished;
46             finishedCallbackOfNative = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate<System.Delegate>(transitionSetFinishedEventCallback);
47         }
48
49         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
50         private delegate void TransitionSetFinishedEventCallbackType(IntPtr data);
51
52         private event EventHandler transitionSetFinishedEventHandler;
53
54         /**
55         * @brief Event for the finished signal which can be used to subscribe or unsubscribe the event handler.
56         * The finished signal is emitted when an transitionSet's transitionSets have finished.
57         */
58         public event EventHandler Finished
59         {
60             add
61             {
62                 if (transitionSetFinishedEventHandler == null && disposed == false)
63                 {
64                     TransitionSetFinishedSignal finishedSignal = FinishedSignal();
65                     finishedSignal.Connect(finishedCallbackOfNative);
66                     finishedSignal.Dispose();
67                 }
68                 transitionSetFinishedEventHandler += value;
69             }
70             remove
71             {
72                 transitionSetFinishedEventHandler -= value;
73
74                 TransitionSetFinishedSignal finishedSignal = FinishedSignal();
75                 if (transitionSetFinishedEventHandler == null && finishedSignal.Empty() == false)
76                 {
77                     finishedSignal.Disconnect(finishedCallbackOfNative);
78                 }
79                 finishedSignal.Dispose();
80             }
81         }
82
83         /// <summary>
84         /// Downcasts a handle to transitionSet handle.<br />
85         /// If handle points to an transitionSet object, the downcast produces a valid handle.<br />
86         /// If not, the returned handle is left uninitialized.<br />
87         /// </summary>
88         /// <param name="handle">Handle to an object.</param>
89         /// <returns>Handle to an transitionSet object or an uninitialized handle.</returns>
90         /// <exception cref="ArgumentNullException"> Thrown when handle is null. </exception>
91         internal static TransitionSet DownCast(BaseHandle handle)
92         {
93             if (handle == null)
94             {
95                 throw new ArgumentNullException(nameof(handle));
96             }
97             TransitionSet ret = Registry.GetManagedBaseHandleFromNativePtr(handle) as TransitionSet;
98             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
99             return ret;
100         }
101
102         public void AddTransition(TransitionItemBase transition)
103         {
104             Interop.TransitionSet.AddTransition(SwigCPtr, transition.SwigCPtr);
105             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
106         }
107
108         public TransitionItemBase GetTransitionAt(uint index)
109         {
110             //to fix memory leak issue, match the handle count with native side.
111             IntPtr cPtr = Interop.TransitionSet.GetTransitionAt(SwigCPtr, index);
112             HandleRef CPtr = new global::System.Runtime.InteropServices.HandleRef(this, cPtr);
113             TransitionItemBase ret = Registry.GetManagedBaseHandleFromNativePtr(CPtr.Handle) as TransitionItemBase;
114             if (cPtr != null && ret == null)
115             {
116                 ret = new TransitionItemBase(cPtr, false);
117                 if (NDalicPINVOKE.SWIGPendingException.Pending)
118                     throw NDalicPINVOKE.SWIGPendingException.Retrieve();
119                 return ret;
120             }
121             Interop.BaseHandle.DeleteBaseHandle(CPtr);
122             CPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
123
124             if (NDalicPINVOKE.SWIGPendingException.Pending)
125                 throw NDalicPINVOKE.SWIGPendingException.Retrieve();
126             return ret;
127         }
128
129         public uint GetTransitionCount()
130         {
131             uint ret = Interop.TransitionSet.GetTransitionCount(SwigCPtr);
132             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
133             return ret;
134         }
135
136         /// <summary>
137         /// Plays the transitionSet.
138         /// </summary>
139         public void Play()
140         {
141             Interop.TransitionSet.Play(SwigCPtr);
142             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
143         }
144
145         internal static global::System.Runtime.InteropServices.HandleRef getCPtr(TransitionSet obj)
146         {
147             return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.SwigCPtr;
148         }
149
150         internal TransitionSet(TransitionSet handle) : this(Interop.TransitionSet.NewTransitionSet(TransitionSet.getCPtr(handle)), true)
151         {
152             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
153         }
154
155         internal TransitionSet Assign(TransitionSet rhs)
156         {
157             TransitionSet ret = new TransitionSet(Interop.TransitionSet.Assign(SwigCPtr, TransitionSet.getCPtr(rhs)), false);
158             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
159             return ret;
160         }
161
162         internal TransitionSetFinishedSignal FinishedSignal()
163         {
164             TransitionSetFinishedSignal ret = new TransitionSetFinishedSignal(Interop.TransitionSet.FinishedSignal(SwigCPtr), false);
165             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
166             return ret;
167         }
168
169         /// <summary>
170         /// To make transitionSet instance be disposed.
171         /// </summary>
172         protected override void Dispose(DisposeTypes type)
173         {
174             if (disposed)
175             {
176                 return;
177             }
178
179             if (transitionSetFinishedEventHandler != null)
180             {
181                 TransitionSetFinishedSignal finishedSignal = FinishedSignal();
182                 finishedSignal?.Disconnect(finishedCallbackOfNative);
183                 finishedSignal?.Dispose();
184                 transitionSetFinishedEventHandler = null;
185             }
186
187             base.Dispose(type);
188         }
189
190         /// This will not be public opened.
191         [EditorBrowsable(EditorBrowsableState.Never)]
192         protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
193         {
194             if (swigCPtr.Handle == IntPtr.Zero || this.HasBody() == false)
195             {
196                 Tizen.Log.Fatal("NUI", $"[ERROR] TransitionSet ReleaseSwigCPtr()! IntPtr=0x{swigCPtr.Handle:X} HasBody={this.HasBody()}");
197                 return;
198             }
199             Interop.TransitionSet.Delete(swigCPtr);
200         }
201
202         private void OnFinished(IntPtr data)
203         {
204             if (transitionSetFinishedEventHandler != null)
205             {
206                 //here we send all data to user event handlers
207                 transitionSetFinishedEventHandler(this, null);
208             }
209         }
210     }
211 }