/*
* Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
*
* 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.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace ElmSharp
{
///
/// IInvalidatable is a interface which can be overrided by its children class.
/// Inherits IDisposable
///
public interface IInvalidatable : IDisposable
{
void MakeInvalidate();
}
///
/// Enumeration for EvasObjectCallbackType
///
public enum EvasObjectCallbackType
{
///
/// Mouse In Event CallbackType.
///
MouseIn,
///
/// Mouse Out Event CallbackType
///
MouseOut,
///
/// Mouse Button Down Event CallbackType
///
MouseDown,
///
/// Mouse Button Up Event CallbackType
///
MouseUp,
///
/// Mouse Move Event CallbackType
///
MouseMove,
///
/// Mouse Wheel Event CallbackType
///
MouseWheel,
///
/// Multi-touch Down Event CallbackType
///
MultiDown,
///
/// Multi-touch Up Event CallbackType
///
MultiUp,
///
/// Multi-touch Move Event CallbackType
///
MultiMove,
///
/// Object Being Freed (Called after Del)
///
Free,
///
/// Key Press Event CallbackType
///
KeyDown,
///
/// Key Release Event CallbackType
///
KeyUp,
///
/// Focus In Event CallbackType
///
FocusIn,
///
/// Focus Out Event CallbackType
///
FocusOut,
///
/// Show Event CallbackType
///
Show,
///
/// Hide Event CallbackType
///
Hide,
///
/// Move Event CallbackType
///
Move,
///
/// Resize Event CallbackType
///
Resize,
///
/// Restack Event CallbackType
///
Restack,
///
/// Object Being Deleted (called before Free)
///
Del,
///
/// Hold Event CallbackType, Informational purpose event to indicate something
///
Hold,
///
/// Size hints changed Event CallbackType
///
ChangedSizeHints,
///
/// Image has been preloaded
///
ImagePreloaded,
///
/// Canvas got focus as a whole
///
CanvasFocusIn,
///
/// Canvas lost focus as a whole
///
CanvasFocusOut,
///
/// Called just before rendering is updated on the canvas target
///
RenderFlushPre,
///
/// Called just after rendering is updated on the canvas target
///
RenderFlushPost,
///
/// Canvas object got focus
///
CanvasObjectFocusIn,
///
/// Canvas object lost focus
///
CanvasObjectFocusOut,
///
/// Image data has been unloaded (by some mechanism in Evas that throw out original image data)
///
ImageUnloaded,
///
/// Called just before rendering starts on the canvas target
///
RenderPre,
///
/// Called just after rendering stops on the canvas target
///
RenderPost,
///
/// Image size is changed
///
ImageResize,
///
/// Devices added, removed or changed on canvas
///
DeviceChanged,
///
/// Axis is changed
///
AxisUpdate,
///
/// Canvas Viewport size is changed
///
CanvasViewportResize
}
///
/// Event class for EvasObject
///
/// Kinds of EventArgs
public class EvasObjectEvent : IInvalidatable where TEventArgs : EventArgs
{
///
/// SmartEventInfoParser delegate of EvasObjectEvent class
///
/// data
/// obj
/// info
/// delegate handle
public delegate TEventArgs SmartEventInfoParser(IntPtr data, IntPtr obj, IntPtr info);
private bool _disposed = false;
private EvasObject _sender;
private IntPtr _handle;
private readonly EvasObjectCallbackType _type;
private readonly SmartEventInfoParser _parser;
private readonly List _nativeCallbacks = new List();
///
/// Creates and initializes a new instance of the EvasObjectEvent.
///
/// EvasObject class belong to
/// EvasObjectCallbackType
/// SmartEventInfoParser
public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type, SmartEventInfoParser parser) : this(sender, sender.Handle, type, parser)
{
}
[EditorBrowsableAttribute(EditorBrowsableState.Never)]
public EvasObjectEvent(EvasObject sender, IntPtr handle, EvasObjectCallbackType type, SmartEventInfoParser parser)
{
_sender = sender;
_handle = handle;
_type = type;
_parser = parser;
sender.AddToEventLifeTracker(this);
}
///
/// Creates and initializes a new instance of the EvasObjectEvent.
///
/// EvasObject class belong with
/// SmartEventInfoParser
public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type) : this(sender, type, null)
{
}
~EvasObjectEvent()
{
Dispose(false);
}
private struct NativeCallback
{
public Interop.Evas.EventCallback callback;
public EventHandler eventHandler;
}
///
/// On Event Handler of EvasObjectEvent
///
public event EventHandler On
{
add
{
if (_handle == IntPtr.Zero)
{
return;
}
EventHandler handler = value;
var cb = new Interop.Evas.EventCallback((data, evas, obj, info) =>
{
TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, obj, info);
handler(_sender, ea);
});
_nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler });
int i = _nativeCallbacks.Count - 1;
Interop.Evas.evas_object_event_callback_add(_handle, (Interop.Evas.ObjectCallbackType)_type, _nativeCallbacks[i].callback, IntPtr.Zero);
}
remove
{
if (_handle == IntPtr.Zero)
{
return;
}
EventHandler handler = value;
var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
foreach (var cb in callbacks)
{
Interop.Evas.evas_object_event_callback_del(_handle, (Interop.Evas.ObjectCallbackType)_type, cb.callback);
}
}
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Place holder to dispose managed state (managed objects).
}
if (_handle != IntPtr.Zero)
{
foreach (var cb in _nativeCallbacks)
{
Interop.Evas.evas_object_event_callback_del(_handle, (Interop.Evas.ObjectCallbackType)_type, cb.callback);
}
}
_nativeCallbacks.Clear();
_disposed = true;
}
}
///
/// Destroy Current Obj
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Make current instance invalidate
///
public void MakeInvalidate()
{
_sender = null;
_handle = IntPtr.Zero;
}
}
///
/// Event class for EvasObject
///
public class EvasObjectEvent : IInvalidatable
{
private EvasObjectEvent _evasObjectEvent;
private event EventHandler _handlers;
private bool _disposed = false;
///
/// Creates and initializes a new instance of the EvasObjectEvent.
///
/// EvasObject class belong to
/// EvasObjectCallbackType
public EvasObjectEvent(EvasObject sender, EvasObjectCallbackType type) : this(sender, sender.Handle, type)
{
}
[EditorBrowsableAttribute(EditorBrowsableState.Never)]
public EvasObjectEvent(EvasObject sender, IntPtr handle, EvasObjectCallbackType type)
{
_evasObjectEvent = new EvasObjectEvent(sender, handle, type, null);
}
~EvasObjectEvent()
{
Dispose(false);
}
///
/// On Event Handler of EvasObjectEvent
///
public event EventHandler On
{
add
{
if (_handlers == null)
{
_evasObjectEvent.On += SendEvent;
}
_handlers += value;
}
remove
{
_handlers -= value;
if (_handlers == null)
{
_evasObjectEvent.On -= SendEvent;
}
}
}
private void SendEvent(object sender, EventArgs e)
{
_handlers?.Invoke(sender, e);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_evasObjectEvent.Dispose();
}
_disposed = true;
}
}
///
/// Destroy Current Obj
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// Make current instance invalidate
///
public void MakeInvalidate()
{
_evasObjectEvent.MakeInvalidate();
}
}
}