/* * 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(); } } }