/*
* 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.Linq;
using System.Runtime.InteropServices;
namespace ElmSharp
{
///
/// The EcoreEventType is type of EcoreEvent.
/// It includes some predefined instance.
///
public class EcoreEventType
{
///
/// Key down Ecore event type.
///
public static readonly EcoreEventType KeyDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_DOWN");
///
/// Key Up Ecore event type.
///
public static readonly EcoreEventType KeyUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_UP");
///
/// Mouse Button Down Ecore event type.
///
public static readonly EcoreEventType MouseButtonDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_DOWN");
///
/// Mouse Button Up Ecore event type.
///
public static readonly EcoreEventType MouseButtonUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_UP");
///
/// Mouse Button Cancel Ecore event type.
///
public static readonly EcoreEventType MouseButtonCancel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_CANCEL");
///
/// Mouse Move Ecore event type.
///
public static readonly EcoreEventType MouseMove = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_MOVE");
///
/// Mouse Wheel Ecore event type.
///
public static readonly EcoreEventType MouseWheel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_WHEEL");
///
/// Mouse In Ecore event type.
///
public static readonly EcoreEventType MouseIn = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_IN");
///
/// Mouse Out Ecore event type.
///
public static readonly EcoreEventType MouseOut = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_OUT");
private string _lib;
private string _name;
private int _typeValue;
private EcoreEventType(string lib, string name)
{
_lib = lib;
_name = name;
_typeValue = -1;
}
///
/// Gets the value associated with the specified type.
///
/// The value of type.
public int GetValue()
{
if (_typeValue < 0)
{
IntPtr hDll = Interop.Libdl.LoadLibrary(_lib);
if (hDll != IntPtr.Zero)
{
IntPtr pValue = Interop.Libdl.GetProcAddress(hDll, _name);
if (pValue != IntPtr.Zero)
{
_typeValue = Marshal.ReadInt32(pValue);
}
Interop.Libdl.FreeLibrary(hDll);
}
}
return _typeValue;
}
}
///
/// The EcoreEvent is a class to help to create events are being notified of events.
///
/// Kinds of EventArgs
public class EcoreEvent : IDisposable where TEventArgs : EventArgs
{
///
/// EventInfoParser delegate of EcoreEvent class
///
/// IntPtr
/// EcoreEventType
/// IntPtr
///
public delegate TEventArgs EventInfoParser(IntPtr data, EcoreEventType type, IntPtr info);
private bool _disposed = false;
private EcoreEventType _eventType;
private readonly EventInfoParser _parser;
private readonly List _nativeCallbacks = new List();
///
/// Creates and initializes a new instance of the EcoreEvent class.
///
/// EcoreEventType
public EcoreEvent(EcoreEventType type) : this(type, null)
{
}
///
/// Creates and initializes a new instance of the EcoreEvent class.
///
/// EcoreEventType
/// EventInfoParser
public EcoreEvent(EcoreEventType type, EventInfoParser parser)
{
_eventType = type;
_parser = parser;
}
///
/// Destructor for EcoreEvent class.
///
~EcoreEvent()
{
Dispose(false);
}
private struct NativeCallback
{
public Interop.Ecore.EcoreEventCallback callback;
public IntPtr nativeHandler;
public EventHandler eventHandler;
}
///
/// On Event Handler of EcoreEvent.
///
public event EventHandler On
{
add
{
EventHandler handler = value;
var cb = new Interop.Ecore.EcoreEventCallback((data, type, info) =>
{
TEventArgs ea = _parser == null ? (TEventArgs)EventArgs.Empty : _parser(data, _eventType, info);
handler(this, ea);
});
IntPtr hNative = Interop.Ecore.ecore_event_handler_add(_eventType.GetValue(), cb, IntPtr.Zero);
_nativeCallbacks.Add(new NativeCallback { callback = cb, eventHandler = handler, nativeHandler = hNative });
}
remove
{
EventHandler handler = value;
var callbacks = _nativeCallbacks.Where(cb => cb.eventHandler == handler);
foreach (var cb in callbacks)
{
Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
}
}
}
///
/// Releases all resources currently used by this instance.
///
///
/// true if managed resources should be disposed
/// otherwise, false.
///
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
// Place holder to dispose managed state (managed objects).
}
foreach (var cb in _nativeCallbacks)
{
Interop.Ecore.ecore_event_handler_del(cb.nativeHandler);
}
_nativeCallbacks.Clear();
_disposed = true;
}
}
///
/// Destroy Current Obj
///
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
///
/// Event class for EcoreEvent
///
public class EcoreEvent : EcoreEvent
{
///
/// Creates and initializes a new instance of the EcoreEvent class.
///
/// EcoreEventType
public EcoreEvent(EcoreEventType type) : base(type)
{
}
}
}