/* * 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 a type of EcoreEvent. /// It includes some predefined instance. /// /// preview public class EcoreEventType { /// /// Key down Ecore event type. /// /// preview public static readonly EcoreEventType KeyDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_DOWN"); /// /// Key Up Ecore event type. /// /// preview public static readonly EcoreEventType KeyUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_KEY_UP"); /// /// Mouse Button Down Ecore event type. /// /// preview public static readonly EcoreEventType MouseButtonDown = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_DOWN"); /// /// Mouse Button Up Ecore event type. /// /// preview public static readonly EcoreEventType MouseButtonUp = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_UP"); /// /// Mouse Button Cancel Ecore event type. /// /// preview public static readonly EcoreEventType MouseButtonCancel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_BUTTON_CANCEL"); /// /// Mouse Move Ecore event type. /// /// preview public static readonly EcoreEventType MouseMove = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_MOVE"); /// /// Mouse Wheel Ecore event type. /// /// preview public static readonly EcoreEventType MouseWheel = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_WHEEL"); /// /// Mouse In Ecore event type. /// /// preview public static readonly EcoreEventType MouseIn = new EcoreEventType(Interop.Libraries.EcoreInput, "ECORE_EVENT_MOUSE_IN"); /// /// Mouse Out Ecore event type. /// /// preview 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. /// preview 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 create events that are being notified of events. /// /// Kinds of EventArgs. /// preview public class EcoreEvent : IDisposable where TEventArgs : EventArgs { /// /// EventInfoParser delegate of the EcoreEvent class. /// /// IntPtr /// EcoreEventType /// IntPtr /// /// preview 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 /// preview public EcoreEvent(EcoreEventType type) : this(type, null) { } /// /// Creates and initializes a new instance of the EcoreEvent class. /// /// EcoreEventType /// EventInfoParser /// preview public EcoreEvent(EcoreEventType type, EventInfoParser parser) { _eventType = type; _parser = parser; } /// /// Destructor for the EcoreEvent class. /// ~EcoreEvent() { Dispose(false); } private struct NativeCallback { public Interop.Ecore.EcoreEventCallback callback; public IntPtr nativeHandler; public EventHandler eventHandler; } /// /// On Event Handler of the EcoreEvent. /// /// preview 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); return true; }); 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 the resources currently used by this instance. /// /// /// true if the managed resources should be disposed, /// otherwise false. /// /// preview 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; } } /// /// Destroys the current object. /// /// preview public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } } /// /// The event class for EcoreEvent. /// /// preview public class EcoreEvent : EcoreEvent { /// /// Creates and initializes a new instance of the EcoreEvent class. /// /// EcoreEventType /// preview public EcoreEvent(EcoreEventType type) : base(type) { } } }