Browse Source

Refactored input a bit.

pull/4/head
Steven Kirk 12 years ago
parent
commit
96401affdd
  1. 59
      Perspex.Windows/Input/MouseDevice.cs
  2. 34
      Perspex.Windows/Input/WindowsMouseDevice.cs
  3. 2
      Perspex.Windows/Perspex.Windows.csproj
  4. 10
      Perspex.Windows/Window.cs
  5. 5
      Perspex/Input/IInputManager.cs
  6. 3
      Perspex/Input/IMouseDevice.cs
  7. 99
      Perspex/Input/InputManager.cs
  8. 135
      Perspex/Input/MouseDevice.cs
  9. 1
      Perspex/Perspex.csproj

59
Perspex.Windows/Input/MouseDevice.cs

@ -1,59 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="MouseDevice.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
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<IInputManager>();
inputManager.Process(e);
}
}
}
}

34
Perspex.Windows/Input/WindowsMouseDevice.cs

@ -0,0 +1,34 @@
// -----------------------------------------------------------------------
// <copyright file="MouseDevice.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
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; }
}
}
}

2
Perspex.Windows/Perspex.Windows.csproj

@ -56,7 +56,7 @@
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Input\MouseDevice.cs" /> <Compile Include="Input\WindowsMouseDevice.cs" />
<Compile Include="Threading\Dispatcher.cs" /> <Compile Include="Threading\Dispatcher.cs" />
<Compile Include="Threading\DispatcherFrame.cs" /> <Compile Include="Threading\DispatcherFrame.cs" />
<Compile Include="Threading\DispatcherOperation.cs" /> <Compile Include="Threading\DispatcherOperation.cs" />

10
Perspex.Windows/Window.cs

@ -167,7 +167,7 @@ namespace Perspex.Windows
{ {
RawMouseEventArgs e = null; RawMouseEventArgs e = null;
MouseDevice.Instance.CurrentWindow = this; WindowsMouseDevice.Instance.CurrentWindow = this;
switch ((UnmanagedMethods.WindowsMessage)msg) switch ((UnmanagedMethods.WindowsMessage)msg)
{ {
@ -185,7 +185,7 @@ namespace Perspex.Windows
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN: case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
e = new RawMouseEventArgs( e = new RawMouseEventArgs(
MouseDevice.Instance, WindowsMouseDevice.Instance,
this, this,
RawMouseEventType.LeftButtonDown, RawMouseEventType.LeftButtonDown,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16)); new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
@ -193,7 +193,7 @@ namespace Perspex.Windows
case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP:
e = new RawMouseEventArgs( e = new RawMouseEventArgs(
MouseDevice.Instance, WindowsMouseDevice.Instance,
this, this,
RawMouseEventType.LeftButtonUp, RawMouseEventType.LeftButtonUp,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16)); new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
@ -201,7 +201,7 @@ namespace Perspex.Windows
case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE: case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE:
e = new RawMouseEventArgs( e = new RawMouseEventArgs(
MouseDevice.Instance, WindowsMouseDevice.Instance,
this, this,
RawMouseEventType.Move, RawMouseEventType.Move,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16)); new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
@ -215,7 +215,7 @@ namespace Perspex.Windows
if (e != null) if (e != null)
{ {
MouseDevice.Instance.Position = e.Position; WindowsMouseDevice.Instance.Position = e.Position;
this.inputManager.Process(e); this.inputManager.Process(e);
} }

5
Perspex/Input/IInputManager.cs

@ -6,11 +6,16 @@
namespace Perspex.Input namespace Perspex.Input
{ {
using System;
using Perspex.Input.Raw; using Perspex.Input.Raw;
using Perspex.Layout; using Perspex.Layout;
public interface IInputManager public interface IInputManager
{ {
IObservable<RawInputEventArgs> RawEventReceived { get; }
void Process(RawInputEventArgs e); void Process(RawInputEventArgs e);
void SetPointerOver(IPointerDevice device, IVisual visual, Point p);
} }
} }

3
Perspex/Input/IMouseDevice.cs

@ -6,9 +6,8 @@
namespace Perspex.Input namespace Perspex.Input
{ {
using System;
public interface IMouseDevice : IPointerDevice public interface IMouseDevice : IPointerDevice
{ {
Point Position { get; }
} }
} }

99
Perspex/Input/InputManager.cs

@ -6,8 +6,10 @@
namespace Perspex.Input namespace Perspex.Input
{ {
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Subjects;
using Perspex.Controls; using Perspex.Controls;
using Perspex.Input.Raw; using Perspex.Input.Raw;
@ -15,104 +17,19 @@ namespace Perspex.Input
{ {
private List<Control> pointerOvers = new List<Control>(); private List<Control> pointerOvers = new List<Control>();
public void Process(RawInputEventArgs e) private Subject<RawInputEventArgs> rawEventReceived = new Subject<RawInputEventArgs>();
{
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;
}
this.UpdatePointerOver(device, device.Captured, p - offset); public IObservable<RawInputEventArgs> RawEventReceived
}
}
private void MouseDown(IMouseDevice device, IVisual visual, Point p)
{ {
IVisual hit = visual.GetVisualAt(p); get { return this.rawEventReceived; }
if (hit != null)
{
Interactive interactive = device.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>();
IFocusable focusable =
device.Captured as IFocusable ??
hit.GetVisualAncestorsAndSelf()
.OfType<IFocusable>()
.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();
}
}
} }
private void MouseUp(IMouseDevice device, IVisual visual, Point p) public void Process(RawInputEventArgs e)
{ {
IVisual hit = visual.GetVisualAt(p); this.rawEventReceived.OnNext(e);
if (hit != null)
{
Interactive source = device.Captured ?? (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>();
if (source != null)
{
source.RaiseEvent(new PointerEventArgs
{
Device = device,
RoutedEvent = Control.PointerReleasedEvent,
OriginalSource = source,
Source = source,
});
}
}
} }
private void UpdatePointerOver(IPointerDevice device, IVisual visual, Point p) public void SetPointerOver(IPointerDevice device, IVisual visual, Point p)
{ {
IEnumerable<IVisual> hits = visual.GetVisualsAt(p); IEnumerable<IVisual> hits = visual.GetVisualsAt(p);

135
Perspex/Input/MouseDevice.cs

@ -0,0 +1,135 @@
// -----------------------------------------------------------------------
// <copyright file="MouseDevice.cs" company="Tricycle">
// Copyright 2014 Tricycle. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
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<RawMouseEventArgs>()
.Where(x => x.Device == this)
.Subscribe(this.ProcessMouse);
}
public Interactive Captured
{
get;
protected set;
}
public IInputManager InputManager
{
get { return Locator.Current.GetService<IInputManager>(); }
}
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<Interactive>();
IFocusable focusable =
this.Captured as IFocusable ??
hit.GetVisualAncestorsAndSelf()
.OfType<IFocusable>()
.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<Interactive>();
if (source != null)
{
source.RaiseEvent(new PointerEventArgs
{
Device = this,
RoutedEvent = Control.PointerReleasedEvent,
OriginalSource = source,
Source = source,
});
}
}
}
}
}

1
Perspex/Perspex.csproj

@ -93,6 +93,7 @@
<Compile Include="Input\IInputManager.cs" /> <Compile Include="Input\IInputManager.cs" />
<Compile Include="Input\InputManager.cs" /> <Compile Include="Input\InputManager.cs" />
<Compile Include="Input\FocusEventArgs.cs" /> <Compile Include="Input\FocusEventArgs.cs" />
<Compile Include="Input\MouseDevice.cs" />
<Compile Include="Input\Raw\RawInputEventArgs.cs" /> <Compile Include="Input\Raw\RawInputEventArgs.cs" />
<Compile Include="Input\Raw\RawMouseEventArgs.cs" /> <Compile Include="Input\Raw\RawMouseEventArgs.cs" />
<Compile Include="Layout\LayoutHelper.cs" /> <Compile Include="Layout\LayoutHelper.cs" />

Loading…
Cancel
Save