Browse Source

Route input events through InputManager.

pull/4/head
Steven Kirk 12 years ago
parent
commit
19d6236f46
  1. 14
      Perspex.Windows/Input/MouseDevice.cs
  2. 1
      Perspex.Windows/Perspex.Windows.csproj
  3. 88
      Perspex.Windows/Window.cs
  4. 18
      Perspex/Input/IInputDevice.cs
  5. 15
      Perspex/Input/IInputManager.cs
  6. 95
      Perspex/Input/InputManager.cs
  7. 27
      Perspex/Input/Raw/RawInputEventArgs.cs
  8. 42
      Perspex/Input/Raw/RawMouseEventArgs.cs
  9. 5
      Perspex/Perspex.csproj
  10. 3
      TestApplication/Program.cs

14
Perspex.Windows/Input/MouseDevice.cs

@ -0,0 +1,14 @@
// -----------------------------------------------------------------------
// <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;
public class MouseDevice : IInputDevice
{
}
}

1
Perspex.Windows/Perspex.Windows.csproj

@ -66,6 +66,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="DrawingContext.cs" /> <Compile Include="DrawingContext.cs" />
<Compile Include="Input\MouseDevice.cs" />
<Compile Include="Media\TextService.cs" /> <Compile Include="Media\TextService.cs" />
<Compile Include="Renderer.cs" /> <Compile Include="Renderer.cs" />
<Compile Include="Threading\Dispatcher.cs" /> <Compile Include="Threading\Dispatcher.cs" />

88
Perspex.Windows/Window.cs

@ -13,21 +13,28 @@ namespace Perspex.Windows
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Perspex.Controls; using Perspex.Controls;
using Perspex.Input; using Perspex.Input;
using Perspex.Input.Raw;
using Perspex.Layout; using Perspex.Layout;
using Perspex.Windows.Input;
using Perspex.Windows.Interop; using Perspex.Windows.Interop;
using Perspex.Windows.Threading; using Perspex.Windows.Threading;
using Splat;
public class Window : ContentControl, ILayoutRoot public class Window : ContentControl, ILayoutRoot
{ {
public static readonly PerspexProperty<double> FontSizeProperty = public static readonly PerspexProperty<double> FontSizeProperty =
TextBlock.FontSizeProperty.AddOwner<Window>(); TextBlock.FontSizeProperty.AddOwner<Window>();
private static readonly IInputDevice MouseDevice = new MouseDevice();
private UnmanagedMethods.WndProc wndProcDelegate; private UnmanagedMethods.WndProc wndProcDelegate;
private string className; private string className;
private Renderer renderer; private Renderer renderer;
private IInputManager inputManager;
static Window() static Window()
{ {
FontSizeProperty.OverrideDefaultValue(typeof(Window), 18.0); FontSizeProperty.OverrideDefaultValue(typeof(Window), 18.0);
@ -39,6 +46,7 @@ namespace Perspex.Windows
Size clientSize = this.ClientSize; Size clientSize = this.ClientSize;
this.LayoutManager = new LayoutManager(); this.LayoutManager = new LayoutManager();
this.renderer = new Renderer(this.Handle, (int)clientSize.Width, (int)clientSize.Height); this.renderer = new Renderer(this.Handle, (int)clientSize.Width, (int)clientSize.Height);
this.inputManager = Locator.Current.GetService<IInputManager>();
this.Template = ControlTemplate.Create<Window>(this.DefaultTemplate); this.Template = ControlTemplate.Create<Window>(this.DefaultTemplate);
this.LayoutManager.LayoutNeeded.Subscribe(x => this.LayoutManager.LayoutNeeded.Subscribe(x =>
@ -138,64 +146,11 @@ namespace Perspex.Windows
} }
} }
private void MouseDown(Visual visual, Point p)
{
IVisual hit = visual.GetVisualAt(p);
if (hit != null)
{
Interactive source = (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>();
if (source != null)
{
source.RaiseEvent(new PointerEventArgs
{
RoutedEvent = Control.PointerPressedEvent,
OriginalSource = source,
Source = source,
});
}
}
}
private void MouseMove(Visual visual, Point p)
{
Control control = visual as Control;
if (control != null)
{
control.IsPointerOver = visual.Bounds.Contains(p);
}
foreach (Visual child in ((IVisual)visual).VisualChildren)
{
this.MouseMove(child, p - visual.Bounds.Position);
}
}
private void MouseUp(Visual visual, Point p)
{
IVisual hit = visual.GetVisualAt(p);
if (hit != null)
{
Interactive source = (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>();
if (source != null)
{
source.RaiseEvent(new PointerEventArgs
{
RoutedEvent = Control.PointerReleasedEvent,
OriginalSource = source,
Source = source,
});
}
}
}
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")] [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")]
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{ {
RawInputEventArgs e = null;
switch ((UnmanagedMethods.WindowsMessage)msg) switch ((UnmanagedMethods.WindowsMessage)msg)
{ {
////case UnmanagedMethods.WindowsMessage.WM_DESTROY: ////case UnmanagedMethods.WindowsMessage.WM_DESTROY:
@ -211,15 +166,27 @@ namespace Perspex.Windows
//// break; //// break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN: case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
this.MouseDown(this, new Point((uint)lParam & 0xffff, (uint)lParam >> 16)); e = new RawMouseEventArgs(
MouseDevice,
this,
RawMouseEventType.LeftButtonDown,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break; break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP: case UnmanagedMethods.WindowsMessage.WM_LBUTTONUP:
this.MouseUp(this, new Point((uint)lParam & 0xffff, (uint)lParam >> 16)); e = new RawMouseEventArgs(
MouseDevice,
this,
RawMouseEventType.LeftButtonUp,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break; break;
case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE: case UnmanagedMethods.WindowsMessage.WM_MOUSEMOVE:
this.MouseMove(this, new Point((uint)lParam & 0xffff, (uint)lParam >> 16)); e = new RawMouseEventArgs(
MouseDevice,
this,
RawMouseEventType.Move,
new Point((uint)lParam & 0xffff, (uint)lParam >> 16));
break; break;
case UnmanagedMethods.WindowsMessage.WM_SIZE: case UnmanagedMethods.WindowsMessage.WM_SIZE:
@ -228,6 +195,11 @@ namespace Perspex.Windows
return IntPtr.Zero; return IntPtr.Zero;
} }
if (e != null)
{
this.inputManager.Process(e);
}
return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam); return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam);
} }
} }

18
Perspex/Input/IInputDevice.cs

@ -0,0 +1,18 @@
// -----------------------------------------------------------------------
// <copyright file="IInputDevice.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public interface IInputDevice
{
}
}

15
Perspex/Input/IInputManager.cs

@ -0,0 +1,15 @@
// -----------------------------------------------------------------------
// <copyright file="IInputManager.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input
{
using Perspex.Input.Raw;
public interface IInputManager
{
void Process(RawInputEventArgs e);
}
}

95
Perspex/Input/InputManager.cs

@ -0,0 +1,95 @@
// -----------------------------------------------------------------------
// <copyright file="InputManager.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input
{
using Perspex.Controls;
using Perspex.Input.Raw;
public class InputManager : IInputManager
{
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((IVisual)e.Root, e.Position);
break;
case RawMouseEventType.LeftButtonDown:
this.MouseDown((IVisual)e.Root, e.Position);
break;
case RawMouseEventType.LeftButtonUp:
this.MouseUp((IVisual)e.Root, e.Position);
break;
}
}
private void MouseMove(IVisual visual, Point p)
{
Control control = visual as Control;
if (control != null)
{
control.IsPointerOver = visual.Bounds.Contains(p);
}
foreach (IVisual child in visual.VisualChildren)
{
this.MouseMove(child, p - visual.Bounds.Position);
}
}
private void MouseDown(IVisual visual, Point p)
{
IVisual hit = visual.GetVisualAt(p);
if (hit != null)
{
Interactive source = (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>();
if (source != null)
{
source.RaiseEvent(new PointerEventArgs
{
RoutedEvent = Control.PointerPressedEvent,
OriginalSource = source,
Source = source,
});
}
}
}
private void MouseUp(IVisual visual, Point p)
{
IVisual hit = visual.GetVisualAt(p);
if (hit != null)
{
Interactive source = (hit as Interactive) ?? hit.GetVisualAncestor<Interactive>();
if (source != null)
{
source.RaiseEvent(new PointerEventArgs
{
RoutedEvent = Control.PointerReleasedEvent,
OriginalSource = source,
Source = source,
});
}
}
}
}
}

27
Perspex/Input/Raw/RawInputEventArgs.cs

@ -0,0 +1,27 @@
// -----------------------------------------------------------------------
// <copyright file="RawInputEventArgs.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input.Raw
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Perspex.Layout;
public class RawInputEventArgs : EventArgs
{
public RawInputEventArgs(IInputDevice device)
{
Contract.Requires<ArgumentNullException>(device != null);
this.Device = device;
}
public IInputDevice Device { get; private set; }
}
}

42
Perspex/Input/Raw/RawMouseEventArgs.cs

@ -0,0 +1,42 @@
// -----------------------------------------------------------------------
// <copyright file="RawMouseEventArgs.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input.Raw
{
using System;
using Perspex.Layout;
public enum RawMouseEventType
{
Move,
LeftButtonDown,
LeftButtonUp,
}
public class RawMouseEventArgs : RawInputEventArgs
{
public RawMouseEventArgs(
IInputDevice device,
ILayoutRoot root,
RawMouseEventType type,
Point position)
: base(device)
{
Contract.Requires<ArgumentNullException>(device != null);
Contract.Requires<ArgumentNullException>(root != null);
this.Root = root;
this.Position = position;
this.Type = type;
}
public ILayoutRoot Root { get; private set; }
public Point Position { get; private set; }
public RawMouseEventType Type { get; private set; }
}
}

5
Perspex/Perspex.csproj

@ -73,6 +73,11 @@
<Compile Include="Controls\LogicalChildren.cs" /> <Compile Include="Controls\LogicalChildren.cs" />
<Compile Include="Controls\Panel.cs" /> <Compile Include="Controls\Panel.cs" />
<Compile Include="Controls\StackPanel.cs" /> <Compile Include="Controls\StackPanel.cs" />
<Compile Include="Input\IInputDevice.cs" />
<Compile Include="Input\IInputManager.cs" />
<Compile Include="Input\InputManager.cs" />
<Compile Include="Input\Raw\RawInputEventArgs.cs" />
<Compile Include="Input\Raw\RawMouseEventArgs.cs" />
<Compile Include="Styling\StyleBinding.cs" /> <Compile Include="Styling\StyleBinding.cs" />
<Compile Include="Classes.cs" /> <Compile Include="Classes.cs" />
<Compile Include="Contract.cs" /> <Compile Include="Contract.cs" />

3
TestApplication/Program.cs

@ -7,6 +7,7 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Perspex; using Perspex;
using Perspex.Controls; using Perspex.Controls;
using Perspex.Input;
using Perspex.Media; using Perspex.Media;
using Perspex.Styling; using Perspex.Styling;
using Perspex.Themes.Default; using Perspex.Themes.Default;
@ -37,7 +38,9 @@ namespace TestApplication
static void Main(string[] args) static void Main(string[] args)
{ {
TextService textService = new TextService(new SharpDX.DirectWrite.Factory()); TextService textService = new TextService(new SharpDX.DirectWrite.Factory());
InputManager inputManager = new InputManager();
Locator.CurrentMutable.Register(() => inputManager, typeof(IInputManager));
Locator.CurrentMutable.Register(() => textService, typeof(ITextService)); Locator.CurrentMutable.Register(() => textService, typeof(ITextService));
Locator.CurrentMutable.Register(() => new Styler(), typeof(IStyler)); Locator.CurrentMutable.Register(() => new Styler(), typeof(IStyler));
Locator.CurrentMutable.Register(() => new TestLogger(), typeof(ILogger)); Locator.CurrentMutable.Register(() => new TestLogger(), typeof(ILogger));

Loading…
Cancel
Save