diff --git a/Perspex/Controls/Control.cs b/Perspex/Controls/Control.cs index 69f97047bd..4f0c7e09ff 100644 --- a/Perspex/Controls/Control.cs +++ b/Perspex/Controls/Control.cs @@ -80,6 +80,12 @@ namespace Perspex.Controls public static readonly PerspexProperty WidthProperty = PerspexProperty.Register("Width", double.NaN); + public static readonly RoutedEvent PointerEnterEvent = + RoutedEvent.Register("PointerEnter", RoutingStrategy.Direct); + + public static readonly RoutedEvent PointerLeaveEvent = + RoutedEvent.Register("PointerLeave", RoutingStrategy.Direct); + public static readonly RoutedEvent PointerPressedEvent = RoutedEvent.Register("PointerPressed", RoutingStrategy.Bubble); @@ -96,6 +102,16 @@ namespace Perspex.Controls { this.classes = new Classes(); + this.PointerEnter += (s, e) => + { + this.IsPointerOver = true; + }; + + this.PointerLeave += (s, e) => + { + this.IsPointerOver = false; + }; + this.GetObservable(IsPointerOverProperty).Subscribe(x => { if (x) @@ -112,33 +128,28 @@ namespace Perspex.Controls this.GetObservable(BackgroundProperty).Skip(1).Subscribe(_ => this.InvalidateMeasure()); } - public event EventHandler PointerPressed + public event EventHandler PointerEnter { - add - { - Contract.Requires(value != null); - this.AddHandler(PointerPressedEvent, value); - } + add { this.AddHandler(PointerEnterEvent, value); } + remove { this.RemoveHandler(PointerEnterEvent, value); } + } - remove - { - Contract.Requires(value != null); - this.RemoveHandler(PointerPressedEvent, value); - } + public event EventHandler PointerLeave + { + add { this.AddHandler(PointerLeaveEvent, value); } + remove { this.RemoveHandler(PointerLeaveEvent, value); } + } + + public event EventHandler PointerPressed + { + add { this.AddHandler(PointerPressedEvent, value); } + remove { this.RemoveHandler(PointerPressedEvent, value); } } public event EventHandler PointerReleased { - add - { - Contract.Requires(value != null); - this.AddHandler(PointerReleasedEvent, value); - } - remove - { - Contract.Requires(value != null); - this.RemoveHandler(PointerReleasedEvent, value); - } + add { this.AddHandler(PointerReleasedEvent, value); } + remove { this.RemoveHandler(PointerReleasedEvent, value); } } public Brush Background diff --git a/Perspex/Input/InputManager.cs b/Perspex/Input/InputManager.cs index 9ab04b8e63..9e30515bb9 100644 --- a/Perspex/Input/InputManager.cs +++ b/Perspex/Input/InputManager.cs @@ -30,7 +30,7 @@ namespace Perspex.Input switch (e.Type) { case RawMouseEventType.Move: - this.MouseMove((IVisual)e.Root, e.Position); + this.MouseMove((IMouseDevice)e.Device, (IVisual)e.Root, e.Position); break; case RawMouseEventType.LeftButtonDown: this.MouseDown((IMouseDevice)e.Device, (IVisual)e.Root, e.Position); @@ -41,20 +41,36 @@ namespace Perspex.Input } } - private void MouseMove(IVisual visual, Point p) + private void MouseMove(IMouseDevice device, IVisual visual, Point p) { IEnumerable hits = visual.GetVisualsAt(p); foreach (var control in this.pointerOvers.ToList().Except(hits).Cast()) { + PointerEventArgs e = new PointerEventArgs + { + RoutedEvent = Control.PointerLeaveEvent, + Device = device, + OriginalSource = control, + Source = control, + }; + this.pointerOvers.Remove(control); - control.IsPointerOver = false; + control.RaiseEvent(e); } foreach (var control in hits.Except(this.pointerOvers).Cast()) { + PointerEventArgs e = new PointerEventArgs + { + RoutedEvent = Control.PointerEnterEvent, + Device = device, + OriginalSource = control, + Source = control, + }; + this.pointerOvers.Add(control); - control.IsPointerOver = true; + control.RaiseEvent(e); } }