// ----------------------------------------------------------------------- // // Copyright 2014 MIT Licence. See licence.md for more information. // // ----------------------------------------------------------------------- namespace Perspex { using System; using System.Collections.Generic; using System.Reactive; using System.Reactive.Linq; using Perspex.Layout; public class Interactive : Layoutable { private Dictionary> eventHandlers = new Dictionary>(); public void AddHandler(RoutedEvent routedEvent, Delegate handler) { Contract.Requires(routedEvent != null); Contract.Requires(handler != null); List delegates; if (!this.eventHandlers.TryGetValue(routedEvent, out delegates)) { delegates = new List(); this.eventHandlers.Add(routedEvent, delegates); } delegates.Add(handler); } public IObservable> GetObservable(RoutedEvent routedEvent) where T : RoutedEventArgs { Contract.Requires(routedEvent != null); return Observable.FromEventPattern( handler => this.AddHandler(routedEvent, handler), handler => this.RemoveHandler(routedEvent, handler)); } public void RemoveHandler(RoutedEvent routedEvent, Delegate handler) { Contract.Requires(routedEvent != null); Contract.Requires(handler != null); List delegates; if (this.eventHandlers.TryGetValue(routedEvent, out delegates)) { delegates.Remove(handler); } } public void RaiseEvent(RoutedEventArgs e) { Contract.Requires(e != null); if (e.RoutedEvent != null) { switch (e.RoutedEvent.RoutingStrategy) { case RoutingStrategy.Bubble: this.BubbleEvent(e); break; case RoutingStrategy.Direct: this.RaiseEventImpl(e); break; default: throw new NotImplementedException(); } } } private void BubbleEvent(RoutedEventArgs e) { Contract.Requires(e != null); Interactive target = this; while (target != null) { target.RaiseEventImpl(e); target = target.GetVisualAncestor(); } } private void RaiseEventImpl(RoutedEventArgs e) { Contract.Requires(e != null); List delegates; if (this.eventHandlers.TryGetValue(e.RoutedEvent, out delegates)) { foreach (Delegate handler in delegates) { // TODO: Implement the Handled stuff. handler.DynamicInvoke(this, e); } } } } }