From b42d472b65d1745539cd5eaa826c3a8d00c40b5a Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 28 Jan 2015 11:56:36 +0100 Subject: [PATCH] Added class RoutedEvent handlers. --- Perspex.Controls/Button.cs | 62 +++++++++++++-------- Perspex.Controls/Primitives/Thumb.cs | 8 +-- Perspex.Controls/Primitives/ToggleButton.cs | 6 +- Perspex.Input/InputElement.cs | 27 ++++----- Perspex.Interactivity/Interactive.cs | 2 + Perspex.Interactivity/RoutedEvent.cs | 25 +++++++++ 6 files changed, 86 insertions(+), 44 deletions(-) diff --git a/Perspex.Controls/Button.cs b/Perspex.Controls/Button.cs index 4f92794c93..64c4b4d34f 100644 --- a/Perspex.Controls/Button.cs +++ b/Perspex.Controls/Button.cs @@ -7,6 +7,7 @@ namespace Perspex.Controls { using System; + using Perspex.Input; using Perspex.Interactivity; public class Button : ContentControl @@ -19,30 +20,6 @@ namespace Perspex.Controls FocusableProperty.OverrideDefaultValue(typeof(Button), true); } - public Button() - { - this.PointerPressed += (s, e) => - { - this.Classes.Add(":pressed"); - e.Device.Capture(this); - }; - - this.PointerReleased += (s, e) => - { - e.Device.Capture(null); - this.Classes.Remove(":pressed"); - - if (this.Classes.Contains(":pointerover")) - { - RoutedEventArgs click = new RoutedEventArgs - { - RoutedEvent = ClickEvent, - }; - this.RaiseEvent(click); - } - }; - } - public event EventHandler Click { add { this.AddHandler(ClickEvent, value); } @@ -58,5 +35,42 @@ namespace Perspex.Controls { return base.ArrangeOverride(finalSize); } + + protected virtual void OnClick() + { + } + + protected override void OnPointerPressed(PointerPressEventArgs e) + { + base.OnPointerPressed(e); + + this.Classes.Add(":pressed"); + e.Device.Capture(this); + } + + protected override void OnPointerReleased(PointerEventArgs e) + { + base.OnPointerReleased(e); + + e.Device.Capture(null); + this.Classes.Remove(":pressed"); + + if (this.Classes.Contains(":pointerover")) + { + this.RaiseClickEvent(); + } + } + + private void RaiseClickEvent() + { + this.OnClick(); + + RoutedEventArgs click = new RoutedEventArgs + { + RoutedEvent = ClickEvent, + }; + + this.RaiseEvent(click); + } } } diff --git a/Perspex.Controls/Primitives/Thumb.cs b/Perspex.Controls/Primitives/Thumb.cs index 6d02f9e409..0f97bff2eb 100644 --- a/Perspex.Controls/Primitives/Thumb.cs +++ b/Perspex.Controls/Primitives/Thumb.cs @@ -23,11 +23,11 @@ namespace Perspex.Controls.Primitives private Point? lastPoint; - public Thumb() + static Thumb() { - this.DragStarted += (_, e) => this.OnDragStarted(e); - this.DragDelta += (_, e) => this.OnDragDelta(e); - this.DragCompleted += (_, e) => this.OnDragCompleted(e); + DragStartedEvent.AddClassHandler(x => x.OnDragStarted); + DragDeltaEvent.AddClassHandler(x => x.OnDragDelta); + DragCompletedEvent.AddClassHandler(x => x.OnDragCompleted); } public event EventHandler DragStarted diff --git a/Perspex.Controls/Primitives/ToggleButton.cs b/Perspex.Controls/Primitives/ToggleButton.cs index adaa5f0bcb..ac20992379 100644 --- a/Perspex.Controls/Primitives/ToggleButton.cs +++ b/Perspex.Controls/Primitives/ToggleButton.cs @@ -20,7 +20,6 @@ namespace Perspex.Controls.Primitives public ToggleButton() { - this.Click += (s, e) => this.Toggle(); } public bool IsChecked @@ -29,6 +28,11 @@ namespace Perspex.Controls.Primitives set { this.SetValue(IsCheckedProperty, value); } } + protected override void OnClick() + { + this.Toggle(); + } + protected virtual void Toggle() { this.IsChecked = !this.IsChecked; diff --git a/Perspex.Input/InputElement.cs b/Perspex.Input/InputElement.cs index 2c3a12c612..263d9579d5 100644 --- a/Perspex.Input/InputElement.cs +++ b/Perspex.Input/InputElement.cs @@ -56,26 +56,23 @@ namespace Perspex.Input public static readonly RoutedEvent PointerReleasedEvent = RoutedEvent.Register("PointerReleased", RoutingStrategy.Bubble); - public static readonly RoutedEvent PointerWheelChangedEvent = - RoutedEvent.Register("PointerWheelChanged", RoutingStrategy.Bubble); + public static readonly RoutedEvent PointerWheelChangedEvent = + RoutedEvent.Register("PointerWheelChanged", RoutingStrategy.Bubble); static InputElement() { IsEnabledProperty.Changed.Subscribe(IsEnabledChanged); - } - public InputElement() - { - this.GotFocus += (_, e) => this.OnGotFocus(e); - this.LostFocus += (_, e) => this.OnLostFocus(e); - this.KeyDown += (_, e) => this.OnKeyDown(e); - this.PreviewKeyDown += (_, e) => this.OnPreviewKeyDown(e); - this.PointerEnter += (_, e) => this.OnPointerEnter(e); - this.PointerLeave += (_, e) => this.OnPointerLeave(e); - this.PointerMoved += (_, e) => this.OnPointerMoved(e); - this.PointerPressed += (_, e) => this.OnPointerPressed(e); - this.PointerReleased += (_, e) => this.OnPointerReleased(e); - this.PointerWheelChanged += (_, e) => this.OnPointerWheelChanged(e); + GotFocusEvent.AddClassHandler(x => x.OnGotFocus); + LostFocusEvent.AddClassHandler(x => x.OnLostFocus); + KeyDownEvent.AddClassHandler(x => x.OnKeyDown); + PreviewKeyDownEvent.AddClassHandler(x => x.OnPreviewKeyDown); + PointerEnterEvent.AddClassHandler(x => x.OnPointerEnter); + PointerLeaveEvent.AddClassHandler(x => x.OnPointerLeave); + PointerMovedEvent.AddClassHandler(x => x.OnPointerMoved); + PointerPressedEvent.AddClassHandler(x => x.OnPointerPressed); + PointerReleasedEvent.AddClassHandler(x => x.OnPointerReleased); + PointerWheelChangedEvent.AddClassHandler(x => x.OnPointerWheelChanged); } public event EventHandler GotFocus diff --git a/Perspex.Interactivity/Interactive.cs b/Perspex.Interactivity/Interactive.cs index c4bf1762e5..5a6426ddba 100644 --- a/Perspex.Interactivity/Interactive.cs +++ b/Perspex.Interactivity/Interactive.cs @@ -116,6 +116,8 @@ namespace Perspex.Interactivity List delegates; + e.RoutedEvent.InvokeRaised(this, e); + if (this.eventHandlers.TryGetValue(e.RoutedEvent, out delegates)) { foreach (Delegate handler in delegates) diff --git a/Perspex.Interactivity/RoutedEvent.cs b/Perspex.Interactivity/RoutedEvent.cs index e74a7369b9..7696a512f6 100644 --- a/Perspex.Interactivity/RoutedEvent.cs +++ b/Perspex.Interactivity/RoutedEvent.cs @@ -7,6 +7,7 @@ namespace Perspex.Interactivity { using System; + using System.Linq.Expressions; using System.Reflection; public enum RoutingStrategy @@ -60,6 +61,8 @@ namespace Perspex.Interactivity private set; } + public event EventHandler Raised; + public static RoutedEvent Register( string name, RoutingStrategy routingStrategy) @@ -81,6 +84,14 @@ namespace Perspex.Interactivity return new RoutedEvent(name, routingStrategy, ownerType); } + + internal void InvokeRaised(object sender, RoutedEventArgs e) + { + if (this.Raised != null) + { + this.Raised(sender, e); + } + } } public class RoutedEvent : RoutedEvent @@ -93,5 +104,19 @@ namespace Perspex.Interactivity Contract.Requires(ownerType != null); Contract.Requires(typeof(IInteractive).GetTypeInfo().IsAssignableFrom(ownerType.GetTypeInfo())); } + + public void AddClassHandler(Func> handler) where TTarget : class + { + this.Raised += (s, e) => + { + var target = s as TTarget; + var args = e as TEventArgs; + + if (target != null) + { + handler(target)(args); + } + }; + } } }