using System.Diagnostics;
using System;
using System.Drawing;
/*
* Copyright(c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace Tizen.NUI
{
using global::System;
using global::System.ComponentModel;
using global::System.Runtime.InteropServices;
using global::System.ComponentModel;
using Tizen.NUI.BaseComponents;
///
/// Capture snapshots the current scene and save as a file.
/// Applications should follow the example below to create capture :
///
/// Capture capture = new Capture();
///
/// If required, you can also subscribe Finished event :
///
/// capture.Finished += onCaptureFinished;
///
/// At the subcribed event handler, user can know whether capture finish succeeded state.
///
/// private void onCaptureFinished(object sender, CaptureFinishedEventArgs e)
/// {
/// if(e.Success) { //capture success, do something. }
/// else { //capture failure, do something. }
/// }
///
/// suppose that we want to capture View 'A'. And, the View 'A' is overlapped by another View 'B' that is not a child of 'A'.
/// in this case, if source is root of scene, the captured image includes a part of View 'B' on the 'A'.
/// however, if source is just View 'A', the result includes only 'A'.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public class Capture : BaseHandle
{
///
/// Create an Capture.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public Capture() : this(Interop.Capture.New(), true)
{
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
internal Capture(IntPtr cPtr, bool cMemoryOwn) : base(Interop.Capture.Upcast(cPtr), cMemoryOwn)
{
}
///
/// Dispose
///
///
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void Dispose(DisposeTypes type)
{
if (disposed)
{
return;
}
if (type == DisposeTypes.Explicit)
{
//Called by User
//Release your own managed resources here.
//You should release all of your own disposable objects here.
}
base.Dispose(type);
}
/// This will not be public opened.
[EditorBrowsable(EditorBrowsableState.Never)]
protected override void ReleaseSwigCPtr(HandleRef swigCPtr)
{
Interop.Capture.Delete(swigCPtr);
}
///
/// Start capture and save the image as a file.
///
/// source View or Layer to be used for capture.
/// This source must be added on the window in advance.
/// top-left position of area to be captured.
/// this position is defined in the window.
/// captured size.
/// image file path to be saved as a file.
/// If path is empty string, the captured result is not be saved as a file.
/// background color of captured scene.
/// This exception can be due to the invalid size values, of when width or height is lower than zero.
/// This exception is due to the path is null.
[EditorBrowsable(EditorBrowsableState.Never)]
public void Start(Container source, Position position, Size size, string path, Color color )
{
if (size.Width <= 0 || size.Height <=0)
{
throw new InvalidOperationException("size should larger than zero");
}
else if (null == path)
{
throw new ArgumentNullException("path should not be null");
}
if (source is View || source is Layer)
{
Interop.Capture.Start4(swigCPtr, source.SwigCPtr, new Vector2(position.X, position.Y).SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path, new Vector4(color.R, color.G, color.B, color.A).SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
///
/// Start capture and save the image as a file.
///
/// source View or Layer to be used for capture.
/// This source must be added on the window in advance.
/// captured size.
/// image file path to be saved as a file.
/// If path is empty string, the captured result is not be saved as a file.
/// background color of captured scene.
/// The value to control image quality for jpeg file format in the range [1, 100].
/// This exception can be due to the invalid size values, of when width or height is lower than zero.
/// This exception is due to the path is null.
[EditorBrowsable(EditorBrowsableState.Never)]
public void Start(Container source, Size size, string path, Color color, uint quality )
{
if (size.Width <= 0 || size.Height <=0)
{
throw new InvalidOperationException("size should larger than zero");
}
else if (null == path)
{
throw new ArgumentNullException("path should not be null");
}
else if (quality > 100)
{
throw new InvalidOperationException("quality should between 0 to 100");
}
if (source is View || source is Layer)
{
Interop.Capture.Start3(swigCPtr, source.SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path, new Vector4(color.R, color.G, color.B, color.A).SwigCPtr, quality);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
///
/// Start capture and save the image as a file.
///
/// source View or Layer to be used for capture.
/// This source must be added on the window in advance.
/// captured size.
/// image file path to be saved as a file.
/// If path is empty string, the captured result is not be saved as a file.
/// background color of captured scene.
/// This exception can be due to the invalid size values, of when width or height is lower than zero.
/// This exception is due to the path is null.
[EditorBrowsable(EditorBrowsableState.Never)]
public void Start(Container source, Size size, string path, Color color)
{
if (size.Width <= 0 || size.Height <=0)
{
throw new InvalidOperationException("size should larger than zero");
}
else if (null == path)
{
throw new ArgumentNullException("path should not be null");
}
if (source is View || source is Layer)
{
Interop.Capture.Start1(swigCPtr, source.SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path, new Vector4(color.R, color.G, color.B, color.A).SwigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
///
/// Start capture and save the image as a file.
///
///
/// Background color of captured scene is transparent.
///
/// source View or Layer to be used for capture.
/// This source must be added on the window in advance.
/// captured size.
/// image file path to be saved as a file.
/// If path is empty string, the captured result is not be saved as a file.
/// This exception can be due to the invalid size values, of when width or height is lower than zero.
/// This exception is due to the path is null.
[EditorBrowsable(EditorBrowsableState.Never)]
public void Start(Container source, Size size, string path)
{
if (size.Width <= 0 || size.Height <=0)
{
throw new InvalidOperationException("size should larger than zero");
}
else if (null == path)
{
throw new ArgumentNullException("path should not be null");
}
if (source is View || source is Layer)
{
Interop.Capture.Start2(swigCPtr, source.SwigCPtr, new Vector2(size.Width, size.Height).SwigCPtr, path);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
///
/// Set result image quality in case of jpeg.
///
/// quality The value to control image quality for jpeg file format in the range [1, 100]
/// This exception can be due to the invalid size values, of when quality is lower than zero or over than 100.
[EditorBrowsable(EditorBrowsableState.Never)]
public void SetImageQuality(uint quality)
{
if (quality < 0 || quality > 100)
{
throw new InvalidOperationException("quality should between zero to 100");
}
Interop.Capture.SetImageQuality(swigCPtr, quality);
}
private void onFinished(IntPtr data, int state)
{
if (data != IntPtr.Zero)
{
var arg = new CaptureFinishedEventArgs();
// dali native definition :
// enum class FinishState
// {
// SUCCEEDED, ///< Succeeded in saving the result after capture
// FAILED ///< Failed to capture by time out or to save the result
// };
arg.Success = (state == 0) ? true : false;
finishedEventHandler?.Invoke(this, arg);
}
}
private CaptureSignal finishedSignal;
private delegate void finishedCallbackType(IntPtr data, int state);
private finishedCallbackType finishedCallback;
private EventHandler finishedEventHandler;
///
/// For subscribing Finished event sent by this class.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public event EventHandler Finished
{
add
{
if (finishedEventHandler == null && disposed == false)
{
finishedSignal = new CaptureSignal(Interop.Capture.Get(swigCPtr), false);
finishedCallback = onFinished;
finishedSignal.Connect(finishedCallback);
}
finishedEventHandler += value;
}
remove
{
finishedEventHandler -= value;
if (finishedEventHandler == null && finishedSignal?.Empty() == false)
{
finishedCallback = onFinished;
finishedSignal.Disconnect(finishedCallback);
}
}
}
///
/// Get NativeImageSource that is saved captured image.
///
/// NativeImageSource that is saved captured image.
[EditorBrowsable(EditorBrowsableState.Never)]
public NativeImageSource GetNativeImageSource()
{
Tizen.Log.Debug("NUI", $"GetNativeImageSource()");
return new NativeImageSource(Interop.Capture.GetNativeImageSourcePtr(swigCPtr), true);
}
///
/// Generate captured image's Url
///
/// The Url string representing this captured image source
[EditorBrowsable(EditorBrowsableState.Never)]
public string GenerateUrl()
{
string url = "";
url = Interop.Capture.GenerageUrl(swigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
return url;
}
}
///
/// CaptureFinishedEventArgs
///
[EditorBrowsable(EditorBrowsableState.Never)]
public class CaptureFinishedEventArgs : EventArgs
{
///
/// Status of saving the result after capture.
///
///
/// true when succeeded in saving the result after capture.
/// false when failed to capture by time out or to save the result.
///
public bool Success { get; internal set; }
}
internal class CaptureSignal : Disposable
{
internal CaptureSignal(IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
{
}
protected override void ReleaseSwigCPtr(HandleRef swigCPtr)
{
if (swigCMemOwn)
{
Interop.Capture.DeleteSignal(swigCPtr);
}
}
public bool Empty()
{
bool ret = Interop.Capture.SignalEmpty(swigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
return ret;
}
public uint GetConnectionCount()
{
uint ret = Interop.Capture.SignalGetConnectionCount(swigCPtr);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
return ret;
}
public void Connect(Delegate func)
{
IntPtr ip = Marshal.GetFunctionPointerForDelegate(func);
{
Interop.Capture.SignalConnect(swigCPtr, new HandleRef(this, ip));
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
public void Disconnect(Delegate func)
{
IntPtr ip = Marshal.GetFunctionPointerForDelegate(func);
{
Interop.Capture.SignalDisconnect(swigCPtr, new HandleRef(this, ip));
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
public void Emit(Capture src, bool success)
{
Interop.Capture.SignalEmit(swigCPtr, src.SwigCPtr, (success ? 0 : 1));
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
}
}
}