[NUI] Change all CallingConvention to `Cdecl`
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / VideoView.cs
1 /*
2  * Copyright(c) 2017 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 using System;
18 using System.ComponentModel;
19 using System.Runtime.InteropServices;
20 using Tizen.NUI.Binding;
21
22 namespace Tizen.NUI.BaseComponents
23 {
24     /// <summary>
25     /// VideoView is a control for video playback and display.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class VideoView : View
29     {
30         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
31         [EditorBrowsable(EditorBrowsableState.Never)]
32         public static readonly BindableProperty VideoProperty = BindableProperty.Create(nameof(Video), typeof(PropertyMap), typeof(VideoView), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
33         {
34             var videoView = (VideoView)bindable;
35             if (newValue != null)
36             {
37                 Tizen.NUI.Object.SetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.VIDEO, new Tizen.NUI.PropertyValue((PropertyMap)newValue));
38             }
39         }),
40         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
41         {
42             var videoView = (VideoView)bindable;
43             PropertyMap temp = new PropertyMap();
44             Tizen.NUI.Object.GetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.VIDEO).Get(temp);
45             return temp;
46         }));
47         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
48         [EditorBrowsable(EditorBrowsableState.Never)]
49         public static readonly BindableProperty LoopingProperty = BindableProperty.Create(nameof(Looping), typeof(bool), typeof(VideoView), false, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
50         {
51             var videoView = (VideoView)bindable;
52             if (newValue != null)
53             {
54                 Tizen.NUI.Object.SetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.LOOPING, new Tizen.NUI.PropertyValue((bool)newValue));
55             }
56         }),
57         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
58         {
59             var videoView = (VideoView)bindable;
60             bool temp = false;
61             Tizen.NUI.Object.GetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.LOOPING).Get(out temp);
62             return temp;
63         }));
64         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
65         [EditorBrowsable(EditorBrowsableState.Never)]
66         public static readonly BindableProperty MutedProperty = BindableProperty.Create(nameof(Muted), typeof(bool), typeof(VideoView), false, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
67         {
68             var videoView = (VideoView)bindable;
69             if (newValue != null)
70             {
71                 Tizen.NUI.Object.SetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.MUTED, new Tizen.NUI.PropertyValue((bool)newValue));
72             }
73         }),
74         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
75         {
76             var videoView = (VideoView)bindable;
77             bool temp = false;
78             Tizen.NUI.Object.GetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.MUTED).Get(out temp);
79             return temp;
80         }));
81         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
82         [EditorBrowsable(EditorBrowsableState.Never)]
83         public static readonly BindableProperty VolumeProperty = BindableProperty.Create(nameof(Volume), typeof(PropertyMap), typeof(VideoView), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
84         {
85             var videoView = (VideoView)bindable;
86             if (newValue != null)
87             {
88                 Tizen.NUI.Object.SetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.VOLUME, new Tizen.NUI.PropertyValue((PropertyMap)newValue));
89             }
90         }),
91         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
92         {
93             var videoView = (VideoView)bindable;
94             PropertyMap temp = new PropertyMap();
95             Tizen.NUI.Object.GetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.VOLUME).Get(temp);
96             return temp;
97         }));
98         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
99         [EditorBrowsable(EditorBrowsableState.Never)]
100         public static readonly BindableProperty UnderlayProperty = BindableProperty.Create(nameof(Underlay), typeof(bool), typeof(VideoView), false, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
101         {
102             var videoView = (VideoView)bindable;
103             if (newValue != null)
104             {
105                 Tizen.NUI.Object.SetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.UNDERLAY, new Tizen.NUI.PropertyValue((bool)newValue));
106             }
107         }),
108         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
109         {
110             var videoView = (VideoView)bindable;
111             bool temp = false;
112             Tizen.NUI.Object.GetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.UNDERLAY).Get(out temp);
113             return temp;
114         }));
115         /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
116         [EditorBrowsable(EditorBrowsableState.Never)]
117         public static readonly BindableProperty ResourceUrlProperty = BindableProperty.Create(nameof(ResourceUrl), typeof(string), typeof(VideoView), string.Empty, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
118         {
119             var videoView = (VideoView)bindable;
120             if (newValue != null)
121             {
122                 Tizen.NUI.Object.SetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.VIDEO, new Tizen.NUI.PropertyValue((string)newValue));
123             }
124         }),
125         defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
126         {
127             var videoView = (VideoView)bindable;
128             string temp;
129             Tizen.NUI.Object.GetProperty((HandleRef)videoView.SwigCPtr, VideoView.Property.VIDEO).Get(out temp);
130             return temp;
131         }));
132
133         private FinishedCallbackDelegate videoViewFinishedCallbackDelegate;
134         private EventHandler<FinishedEventArgs> videoViewFinishedEventHandler;
135
136         /// <summary>
137         /// Creates an initialized VideoView.
138         /// </summary>
139         /// <since_tizen> 3 </since_tizen>
140         public VideoView() : this(Interop.VideoView.New(), true)
141         {
142             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
143         }
144
145         /// <summary>
146         /// Creates an initialized VideoView.<br />
147         /// If the string is empty, VideoView will not display anything.<br />
148         /// </summary>
149         /// <param name="url">The URL of the video resource to display.</param>
150         /// <since_tizen> 3 </since_tizen>
151         public VideoView(string url) : this(Interop.VideoView.New(url), true)
152         {
153             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
154         }
155
156         /// <summary>
157         /// Creates an initialized VideoView.<br />
158         /// If the string is empty, VideoView will not display anything.<br />
159         /// </summary>
160         /// <param name="swCodec">Video rendering by H/W codec if false.</param>
161         [EditorBrowsable(EditorBrowsableState.Never)]
162         public VideoView(bool swCodec) : this(Interop.VideoView.New(swCodec), true)
163         {
164             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
165         }
166
167         /// <summary>
168         /// Creates an initialized VideoView.<br />
169         /// If the string is empty, VideoView will not display anything.<br />
170         /// </summary>
171         /// <param name="url">The URL of the video resource to display.</param>
172         /// <param name="swCodec">Video rendering by H/W codec if false.</param>
173         [EditorBrowsable(EditorBrowsableState.Never)]
174         public VideoView(string url, bool swCodec) : this(Interop.VideoView.New(url, swCodec), true)
175         {
176             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
177         }
178
179         /// <summary>
180         /// Hidden API (Inhouse API).
181         /// Using Uri class to provide safe service and secure API.
182         /// Creates an initialized VideoView.
183         /// If the string is empty, VideoView will not display anything.
184         /// </summary>
185         /// <param name="uri">The URI of the video resource to display.</param>
186         /// <param name="swCodec">Video rendering by H/W codec if false.</param>
187         [EditorBrowsable(EditorBrowsableState.Never)]
188         public VideoView(Uri uri, bool swCodec) : this(Interop.VideoView.New((uri == null) ? String.Empty : uri.AbsoluteUri, swCodec), true)
189         {
190             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
191         }
192
193         internal VideoView(VideoView videoView) : this(Interop.VideoView.NewVideoView(VideoView.getCPtr(videoView)), true)
194         {
195             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
196         }
197
198         internal VideoView(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
199         {
200         }
201
202         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
203         private delegate void FinishedCallbackDelegate(IntPtr data);
204
205         /// <summary>
206         /// Event for the finished signal which can be used to subscribe or unsubscribe the event handler
207         /// The finished signal is emitted when a video playback has finished.<br />
208         /// </summary>
209         /// <since_tizen> 3 </since_tizen>
210         public event EventHandler<FinishedEventArgs> Finished
211         {
212             add
213             {
214                 if (videoViewFinishedEventHandler == null)
215                 {
216                     videoViewFinishedCallbackDelegate = (OnFinished);
217                     FinishedSignal().Connect(videoViewFinishedCallbackDelegate);
218                 }
219                 videoViewFinishedEventHandler += value;
220             }
221             remove
222             {
223                 videoViewFinishedEventHandler -= value;
224                 if (videoViewFinishedEventHandler == null && FinishedSignal().Empty() == false)
225                 {
226                     FinishedSignal().Disconnect(videoViewFinishedCallbackDelegate);
227                 }
228             }
229         }
230
231         /// <summary>
232         /// Video file setting type of PropertyMap.
233         /// </summary>
234         /// <since_tizen> 3 </since_tizen>
235         public PropertyMap Video
236         {
237             get
238             {
239                 return (PropertyMap)GetValue(VideoProperty);
240             }
241             set
242             {
243                 SetValue(VideoProperty, value);
244                 NotifyPropertyChanged();
245             }
246         }
247
248         /// <summary>
249         /// The looping status, true or false.
250         /// </summary>
251         /// <since_tizen> 3 </since_tizen>
252         public bool Looping
253         {
254             get
255             {
256                 return (bool)GetValue(LoopingProperty);
257             }
258             set
259             {
260                 SetValue(LoopingProperty, value);
261                 NotifyPropertyChanged();
262             }
263         }
264
265         /// <summary>
266         /// The mute status, true or false.
267         /// </summary>
268         /// <since_tizen> 3 </since_tizen>
269         public bool Muted
270         {
271             get
272             {
273                 return (bool)GetValue(MutedProperty);
274             }
275             set
276             {
277                 SetValue(MutedProperty, value);
278                 NotifyPropertyChanged();
279             }
280         }
281
282         /// <summary>
283         /// The left and the right volume scalar as float type, PropertyMap with two values ( "left" and "right" ).
284         /// </summary>
285         /// <since_tizen> 3 </since_tizen>
286         public PropertyMap Volume
287         {
288             get
289             {
290                 return (PropertyMap)GetValue(VolumeProperty);
291             }
292             set
293             {
294                 SetValue(VolumeProperty, value);
295                 NotifyPropertyChanged();
296             }
297         }
298
299         /// <summary>
300         /// Video rendering by underlay, true or false.<br />
301         /// This shows video composited underneath the window by the system. This means it may ignore rotation of the video-view.
302         /// </summary>
303         /// <since_tizen> 4 </since_tizen>
304         public bool Underlay
305         {
306             get
307             {
308                 return (bool)GetValue(UnderlayProperty);
309             }
310             set
311             {
312                 SetValue(UnderlayProperty, value);
313                 NotifyPropertyChanged();
314             }
315         }
316
317         /// <summary>
318         /// Video file URL as string type.
319         /// </summary>
320         /// <since_tizen> 4 </since_tizen>
321         public string ResourceUrl
322         {
323             get
324             {
325                 return (string)GetValue(ResourceUrlProperty);
326             }
327             set
328             {
329                 SetValue(ResourceUrlProperty, value);
330                 NotifyPropertyChanged();
331             }
332         }
333
334         /// <summary>
335         /// Starts the video playback.
336         /// </summary>
337         /// <since_tizen> 3 </since_tizen>
338         public void Play()
339         {
340             Interop.VideoView.Play(SwigCPtr);
341             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
342         }
343
344         /// <summary>
345         /// Pauses the video playback.
346         /// </summary>
347         /// <since_tizen> 3 </since_tizen>
348         public void Pause()
349         {
350             Interop.VideoView.Pause(SwigCPtr);
351             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
352         }
353
354         /// <summary>
355         /// Stops the video playback.
356         /// </summary>
357         /// <since_tizen> 3 </since_tizen>
358         public void Stop()
359         {
360             Interop.VideoView.Stop(SwigCPtr);
361             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
362         }
363
364         /// <summary>
365         /// Seeks forward by the specified number of milliseconds.
366         /// </summary>
367         /// <param name="millisecond">The position for forward playback.</param>
368         /// <since_tizen> 3 </since_tizen>
369         public void Forward(int millisecond)
370         {
371             Interop.VideoView.Forward(SwigCPtr, millisecond);
372             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
373         }
374
375         /// <summary>
376         /// Seeks backward by the specified number of milliseconds.
377         /// </summary>
378         /// <param name="millisecond">The position for backward playback.</param>
379         /// <since_tizen> 3 </since_tizen>
380         public void Backward(int millisecond)
381         {
382             Interop.VideoView.Backward(SwigCPtr, millisecond);
383             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
384         }
385
386         /// <summary>
387         /// Get native player handle.
388         /// <example>
389         /// How to get native player handle
390         /// <code>
391         /// VideoView videoView = new VideoView();
392         /// videoView.ResourceUrl = "some video path";
393         /// var handle = videoView.NativeHandle;
394         /// if(handle.IsInvalid == false)
395         /// {
396         ///     IntPtr nativeHandle = handle.DangerousGetHandle();
397         ///     // do something with nativeHandle
398         /// }
399         /// </code>
400         /// </example>
401         /// </summary>
402         /// <since_tizen> 9 </since_tizen>
403         public SafeHandle NativeHandle
404         {
405             get
406             {
407                 return new NUI.SafeNativePlayerHandle(this);
408             }
409         }
410
411         internal VideoViewSignal FinishedSignal()
412         {
413             VideoViewSignal ret = new VideoViewSignal(Interop.VideoView.FinishedSignal(SwigCPtr), false);
414             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
415             return ret;
416         }
417
418         /// <summary>
419         /// Dispose.
420         /// </summary>
421         /// <param name="type">DisposeTypes</param>
422         /// <since_tizen> 3 </since_tizen>
423         protected override void Dispose(DisposeTypes type)
424         {
425             if (disposed)
426             {
427                 return;
428             }
429
430             //Release your own unmanaged resources here.
431             //You should not access any managed member here except static instance.
432             //because the execution order of Finalizes is non-deterministic.
433
434             if (this != null && videoViewFinishedCallbackDelegate != null)
435             {
436                 FinishedSignal().Disconnect(videoViewFinishedCallbackDelegate);
437             }
438
439             base.Dispose(type);
440         }
441
442         /// This will not be public opened.
443         [EditorBrowsable(EditorBrowsableState.Never)]
444         protected override void ReleaseSwigCPtr(System.Runtime.InteropServices.HandleRef swigCPtr)
445         {
446             Interop.VideoView.DeleteVideoView(swigCPtr);
447         }
448
449         // Callback for VideoView Finished signal
450         private void OnFinished(IntPtr data)
451         {
452             if (videoViewFinishedEventHandler != null)
453             {
454                 FinishedEventArgs e = new FinishedEventArgs();
455
456                 // Populate all members of "e" (FinishedEventArgs) with real data
457                 e.VideoView = Registry.GetManagedBaseHandleFromNativePtr(data) as VideoView;
458                 //here we send all data to user event handlers
459                 videoViewFinishedEventHandler(this, e);
460             }
461         }
462
463         /// <summary>
464         /// Event arguments that passed via the finished signal.
465         /// </summary>
466         /// <since_tizen> 3 </since_tizen>
467         public class FinishedEventArgs : EventArgs
468         {
469             private VideoView videoView;
470
471             /// <summary>
472             /// The view for video playback and display.
473             /// </summary>
474             /// <since_tizen> 3 </since_tizen>
475             public VideoView VideoView
476             {
477                 get
478                 {
479                     return videoView;
480                 }
481                 set
482                 {
483                     videoView = value;
484                 }
485             }
486         }
487
488         internal new class Property
489         {
490             internal static readonly int VIDEO = Interop.VideoView.VideoGet();
491             internal static readonly int LOOPING = Interop.VideoView.LoopingGet();
492             internal static readonly int MUTED = Interop.VideoView.MutedGet();
493             internal static readonly int VOLUME = Interop.VideoView.VolumeGet();
494             internal static readonly int UNDERLAY = Interop.VideoView.UnderlayGet();
495         }
496
497         internal System.IntPtr GetNativePlayerHandle()
498         {
499             var ret = Interop.VideoView.GetNativePlayerHandle(SwigCPtr);
500             NUILog.Debug($"NativePlayerHandle=0x{ret:X}");
501             return ret;
502         }
503     }
504
505     /// <summary>
506     /// Contains and encapsulates Native Player handle.
507     /// </summary>
508     [EditorBrowsable(EditorBrowsableState.Never)]
509     [Obsolete("This has been deprecated in API9 and will be removed in API11. Use VideoView.NativeHandle instead.")]
510     public class SafeNativePlayerHandle : SafeHandle
511     {
512         /// <summary>
513         /// Constructor, null handle is set.
514         /// </summary>
515         [EditorBrowsable(EditorBrowsableState.Never)]
516         public SafeNativePlayerHandle() : base(global::System.IntPtr.Zero, false)
517         {
518         }
519
520         /// <summary>
521         /// Constructor, Native player handle is set to handle.
522         /// </summary>
523         [EditorBrowsable(EditorBrowsableState.Never)]
524         public SafeNativePlayerHandle(VideoView videoView) : base(global::System.IntPtr.Zero, false)
525         {
526             if (videoView != null)
527             {
528                 SetHandle(videoView.GetNativePlayerHandle());
529             }
530         }
531
532         /// <summary>
533         /// Null check if the handle is valid or not.
534         /// </summary>
535         [EditorBrowsable(EditorBrowsableState.Never)]
536         public override bool IsInvalid
537         {
538             get
539             {
540                 return handle == global::System.IntPtr.Zero;
541             }
542         }
543         /// <summary>
544         /// Release handle itself.
545         /// </summary>
546         /// <returns>true when released successfully.</returns>
547         [EditorBrowsable(EditorBrowsableState.Never)]
548         protected override bool ReleaseHandle()
549         {
550             SetHandle(global::System.IntPtr.Zero);
551             return true;
552         }
553     }
554 }