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