diff --git a/Perspex.Windows/Input/MouseDevice.cs b/Perspex.Windows/Input/MouseDevice.cs
deleted file mode 100644
index 75ba5846d5..0000000000
--- a/Perspex.Windows/Input/MouseDevice.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-// -----------------------------------------------------------------------
-//
-// Copyright 2014 MIT Licence. See licence.md for more information.
-//
-// -----------------------------------------------------------------------
-
-namespace Perspex.Windows.Input
-{
- using System;
- using System.Reactive.Disposables;
- using Perspex.Input;
- using Perspex.Input.Raw;
- using Splat;
-
- public class MouseDevice : IMouseDevice
- {
- private static MouseDevice instance = new MouseDevice();
-
- public static MouseDevice Instance
- {
- get { return instance; }
- }
-
- public Interactive Captured
- {
- get;
- private set;
- }
-
- public Window CurrentWindow
- {
- get;
- set;
- }
-
- public Point Position
- {
- get;
- set;
- }
-
- public void Capture(Interactive visual)
- {
- this.Captured = visual;
-
- if (visual == null)
- {
- RawMouseEventArgs e = new RawMouseEventArgs(
- this,
- this.CurrentWindow,
- RawMouseEventType.Move,
- this.Position);
-
- IInputManager inputManager = Locator.Current.GetService();
- inputManager.Process(e);
- }
- }
- }
-}
diff --git a/Perspex.Windows/Input/WindowsMouseDevice.cs b/Perspex.Windows/Input/WindowsMouseDevice.cs
new file mode 100644
index 0000000000..c14dbc0742
--- /dev/null
+++ b/Perspex.Windows/Input/WindowsMouseDevice.cs
@@ -0,0 +1,34 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2014 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Windows.Input
+{
+ using Perspex.Input;
+ using Perspex.Input.Raw;
+ using Splat;
+
+ public class WindowsMouseDevice : MouseDevice
+ {
+ private static WindowsMouseDevice instance = new WindowsMouseDevice();
+
+ public static WindowsMouseDevice Instance
+ {
+ get { return instance; }
+ }
+
+ public Window CurrentWindow
+ {
+ get;
+ set;
+ }
+
+ public new Point Position
+ {
+ get { return base.Position; }
+ internal set { base.Position = value; }
+ }
+ }
+}
diff --git a/Perspex.Windows/Perspex.Windows.csproj b/Perspex.Windows/Perspex.Windows.csproj
index 7eacbfc990..243df648e7 100644
--- a/Perspex.Windows/Perspex.Windows.csproj
+++ b/Perspex.Windows/Perspex.Windows.csproj
@@ -56,7 +56,7 @@
-
+
diff --git a/Perspex.Windows/Window.cs b/Perspex.Windows/Window.cs
index efd5c5cfa6..089382e2b8 100644
--- a/Perspex.Windows/Window.cs
+++ b/Perspex.Windows/Window.cs
@@ -167,7 +167,7 @@ namespace Perspex.Windows
{
RawMouseEventArgs e = null;
- MouseDevice.Instance.CurrentWindow = this;
+ WindowsMouseDevice.Instance.CurrentWindow = this;
switch ((UnmanagedMethods.WindowsMessage)msg)
{
@@ -185,7 +185,7 @@ namespace Perspex.Windows
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
e = new RawMouseEventArgs(
- MouseDevice.Instance,
+ WindowsMouseDevice.Instance,
this,
RawMouseEventType.LeftButtonDown,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
@@ -193,7 +193,7 @@ namespace Perspex.Windows
case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP:
e = new RawMouseEventArgs(
- MouseDevice.Instance,
+ WindowsMouseDevice.Instance,
this,
RawMouseEventType.LeftButtonUp,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
@@ -201,7 +201,7 @@ namespace Perspex.Windows
case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE:
e = new RawMouseEventArgs(
- MouseDevice.Instance,
+ WindowsMouseDevice.Instance,
this,
RawMouseEventType.Move,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
@@ -215,7 +215,7 @@ namespace Perspex.Windows
if (e != null)
{
- MouseDevice.Instance.Position = e.Position;
+ WindowsMouseDevice.Instance.Position = e.Position;
this.inputManager.Process(e);
}
diff --git a/Perspex/Input/IInputManager.cs b/Perspex/Input/IInputManager.cs
index d7df6a0bf8..0cddac4e33 100644
--- a/Perspex/Input/IInputManager.cs
+++ b/Perspex/Input/IInputManager.cs
@@ -6,11 +6,16 @@
namespace Perspex.Input
{
+ using System;
using Perspex.Input.Raw;
using Perspex.Layout;
public interface IInputManager
{
+ IObservable RawEventReceived { get; }
+
void Process(RawInputEventArgs e);
+
+ void SetPointerOver(IPointerDevice device, IVisual visual, Point p);
}
}
diff --git a/Perspex/Input/IMouseDevice.cs b/Perspex/Input/IMouseDevice.cs
index 6a51c65eb0..b4b30ee65b 100644
--- a/Perspex/Input/IMouseDevice.cs
+++ b/Perspex/Input/IMouseDevice.cs
@@ -6,9 +6,8 @@
namespace Perspex.Input
{
- using System;
-
public interface IMouseDevice : IPointerDevice
{
+ Point Position { get; }
}
}
diff --git a/Perspex/Input/InputManager.cs b/Perspex/Input/InputManager.cs
index 1d203c1002..7f967e7cea 100644
--- a/Perspex/Input/InputManager.cs
+++ b/Perspex/Input/InputManager.cs
@@ -6,8 +6,10 @@
namespace Perspex.Input
{
+ using System;
using System.Collections.Generic;
using System.Linq;
+ using System.Reactive.Subjects;
using Perspex.Controls;
using Perspex.Input.Raw;
@@ -15,104 +17,19 @@ namespace Perspex.Input
{
private List pointerOvers = new List();
- public void Process(RawInputEventArgs e)
- {
- RawMouseEventArgs mouse = e as RawMouseEventArgs;
-
- if (mouse != null)
- {
- this.ProcessMouse(mouse);
- }
- }
-
- private void ProcessMouse(RawMouseEventArgs e)
- {
- switch (e.Type)
- {
- case RawMouseEventType.Move:
- this.MouseMove((IMouseDevice)e.Device, (IVisual)e.Root, e.Position);
- break;
- case RawMouseEventType.LeftButtonDown:
- this.MouseDown((IMouseDevice)e.Device, (IVisual)e.Root, e.Position);
- break;
- case RawMouseEventType.LeftButtonUp:
- this.MouseUp((IMouseDevice)e.Device, (IVisual)e.Root, e.Position);
- break;
- }
- }
-
- private void MouseMove(IMouseDevice device, IVisual visual, Point p)
- {
- if (device.Captured == null)
- {
- this.UpdatePointerOver(device, visual, p);
- }
- else
- {
- Point offset = new Point();
-
- foreach (IVisual ancestor in device.Captured.GetVisualAncestors())
- {
- offset += ancestor.Bounds.Position;
- }
+ private Subject rawEventReceived = new Subject();
- this.UpdatePointerOver(device, device.Captured, p - offset);
- }
- }
-
- private void MouseDown(IMouseDevice device, IVisual visual, Point p)
+ public IObservable RawEventReceived
{
- IVisual hit = visual.GetVisualAt(p);
-
- if (hit != null)
- {
- Interactive interactive = device.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor();
- IFocusable focusable =
- device.Captured as IFocusable ??
- hit.GetVisualAncestorsAndSelf()
- .OfType()
- .FirstOrDefault(x => x.Focusable);
-
- if (interactive != null)
- {
- interactive.RaiseEvent(new PointerEventArgs
- {
- Device = device,
- RoutedEvent = Control.PointerPressedEvent,
- OriginalSource = interactive,
- Source = interactive,
- });
- }
-
- if (focusable != null && focusable.Focusable)
- {
- focusable.Focus();
- }
- }
+ get { return this.rawEventReceived; }
}
- private void MouseUp(IMouseDevice device, IVisual visual, Point p)
+ public void Process(RawInputEventArgs e)
{
- IVisual hit = visual.GetVisualAt(p);
-
- if (hit != null)
- {
- Interactive source = device.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor();
-
- if (source != null)
- {
- source.RaiseEvent(new PointerEventArgs
- {
- Device = device,
- RoutedEvent = Control.PointerReleasedEvent,
- OriginalSource = source,
- Source = source,
- });
- }
- }
+ this.rawEventReceived.OnNext(e);
}
- private void UpdatePointerOver(IPointerDevice device, IVisual visual, Point p)
+ public void SetPointerOver(IPointerDevice device, IVisual visual, Point p)
{
IEnumerable hits = visual.GetVisualsAt(p);
diff --git a/Perspex/Input/MouseDevice.cs b/Perspex/Input/MouseDevice.cs
new file mode 100644
index 0000000000..502a392f7a
--- /dev/null
+++ b/Perspex/Input/MouseDevice.cs
@@ -0,0 +1,135 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2014 Tricycle. All rights reserved.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Input
+{
+ using System;
+ using System.Linq;
+ using System.Reactive.Linq;
+ using Perspex.Controls;
+ using Perspex.Input.Raw;
+ using Splat;
+
+ public abstract class MouseDevice : IMouseDevice
+ {
+ public MouseDevice()
+ {
+ this.InputManager.RawEventReceived
+ .OfType()
+ .Where(x => x.Device == this)
+ .Subscribe(this.ProcessMouse);
+ }
+
+ public Interactive Captured
+ {
+ get;
+ protected set;
+ }
+
+ public IInputManager InputManager
+ {
+ get { return Locator.Current.GetService(); }
+ }
+
+ public Point Position
+ {
+ get;
+ protected set;
+ }
+
+ public virtual void Capture(Interactive visual)
+ {
+ this.Captured = visual;
+ }
+
+ private void ProcessMouse(RawMouseEventArgs e)
+ {
+ switch (e.Type)
+ {
+ case RawMouseEventType.Move:
+ this.MouseMove((IMouseDevice)e.Device, (IVisual)e.Root, e.Position);
+ break;
+ case RawMouseEventType.LeftButtonDown:
+ this.MouseDown((IMouseDevice)e.Device, (IVisual)e.Root, e.Position);
+ break;
+ case RawMouseEventType.LeftButtonUp:
+ this.MouseUp((IMouseDevice)e.Device, (IVisual)e.Root, e.Position);
+ break;
+ }
+ }
+
+ private void MouseMove(IMouseDevice device, IVisual visual, Point p)
+ {
+ if (this.Captured == null)
+ {
+ this.InputManager.SetPointerOver(this, visual, p);
+ }
+ else
+ {
+ Point offset = new Point();
+
+ foreach (IVisual ancestor in this.Captured.GetVisualAncestors())
+ {
+ offset += ancestor.Bounds.Position;
+ }
+
+ this.InputManager.SetPointerOver(this, this.Captured, p - offset);
+ }
+ }
+
+ private void MouseDown(IMouseDevice device, IVisual visual, Point p)
+ {
+ IVisual hit = visual.GetVisualAt(p);
+
+ if (hit != null)
+ {
+ Interactive interactive = this.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor();
+ IFocusable focusable =
+ this.Captured as IFocusable ??
+ hit.GetVisualAncestorsAndSelf()
+ .OfType()
+ .FirstOrDefault(x => x.Focusable);
+
+ if (interactive != null)
+ {
+ interactive.RaiseEvent(new PointerEventArgs
+ {
+ Device = this,
+ RoutedEvent = Control.PointerPressedEvent,
+ OriginalSource = interactive,
+ Source = interactive,
+ });
+ }
+
+ if (focusable != null && focusable.Focusable)
+ {
+ focusable.Focus();
+ }
+ }
+ }
+
+ private void MouseUp(IMouseDevice device, IVisual visual, Point p)
+ {
+ IVisual hit = visual.GetVisualAt(p);
+
+ if (hit != null)
+ {
+ Interactive source = this.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor();
+
+ if (source != null)
+ {
+ source.RaiseEvent(new PointerEventArgs
+ {
+ Device = this,
+ RoutedEvent = Control.PointerReleasedEvent,
+ OriginalSource = source,
+ Source = source,
+ });
+ }
+ }
+ }
+ }
+}
diff --git a/Perspex/Perspex.csproj b/Perspex/Perspex.csproj
index beee983b6c..0fdefe0219 100644
--- a/Perspex/Perspex.csproj
+++ b/Perspex/Perspex.csproj
@@ -93,6 +93,7 @@
+