Browse Source

Started on TextBox.

Can type but not much else.
pull/4/head
Steven Kirk 12 years ago
parent
commit
6d31e7d865
  1. 4
      Perspex.Direct2D1/Direct2D1Platform.cs
  2. 381
      Perspex.Windows/Input/KeyInterop.cs
  3. 96
      Perspex.Windows/Input/WindowsKeyboardDevice.cs
  4. 3
      Perspex.Windows/Input/WindowsMouseDevice.cs
  5. 2
      Perspex.Windows/Perspex.Windows.csproj
  6. 20
      Perspex.Windows/Window.cs
  7. 84
      Perspex/Controls/Control.cs
  8. 61
      Perspex/Controls/TextBox.cs
  9. 13
      Perspex/Controls/ToggleButton.cs
  10. 26
      Perspex/Input/FocusManager.cs
  11. 2
      Perspex/Input/IFocusable.cs
  12. 33
      Perspex/Input/IKeyboardDevice.cs
  13. 214
      Perspex/Input/Key.cs
  14. 9
      Perspex/Input/KeyEventArgs.cs
  15. 61
      Perspex/Input/KeyboardDevice.cs
  16. 6
      Perspex/Input/MouseDevice.cs
  17. 31
      Perspex/Input/Raw/RawKeyEventArgs.cs
  18. 2
      Perspex/Media/FormattedText.cs
  19. 2
      Perspex/Media/Imaging/Bitmap.cs
  20. 2
      Perspex/Media/Imaging/RenderTargetBitmap.cs
  21. 2
      Perspex/Media/RectangleGeometry.cs
  22. 2
      Perspex/Media/StreamGeometry.cs
  23. 8
      Perspex/Perspex.csproj
  24. 2
      Perspex/Platform/IPlatformInterface.cs

4
Perspex.Direct2D1/Direct2D1Platform.cs

@ -11,7 +11,7 @@ namespace Perspex.Direct2D1
using Perspex.Platform;
using Splat;
public class Direct2D1Platform : IPlatformFactory
public class Direct2D1Platform : IPlatformInterface
{
private static Direct2D1Platform instance = new Direct2D1Platform();
@ -26,7 +26,7 @@ namespace Perspex.Direct2D1
public static void Initialize()
{
var locator = Locator.CurrentMutable;
locator.Register(() => instance, typeof(IPlatformFactory));
locator.Register(() => instance, typeof(IPlatformInterface));
locator.Register(() => d2d1Factory, typeof(SharpDX.Direct2D1.Factory));
locator.Register(() => dwFactory, typeof(SharpDX.DirectWrite.Factory));
locator.Register(() => imagingFactory, typeof(SharpDX.WIC.ImagingFactory));

381
Perspex.Windows/Input/KeyInterop.cs

@ -0,0 +1,381 @@
// -----------------------------------------------------------------------
// <copyright file="KeyInterop.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Windows.Input
{
using System.Collections.Generic;
using System.Text;
using Perspex.Input;
using Perspex.Windows.Interop;
public static class KeyInterop
{
private static Dictionary<Key, int> virtualKeyFromKey = new Dictionary<Key, int>
{
{ Key.None, 0 },
{ Key.Cancel, 3 },
{ Key.Back, 8 },
{ Key.Tab, 9 },
{ Key.LineFeed, 0 },
{ Key.Clear, 12 },
{ Key.Return, 13 },
{ Key.Pause, 19 },
{ Key.Capital, 20 },
{ Key.KanaMode, 21 },
{ Key.JunjaMode, 23 },
{ Key.FinalMode, 24 },
{ Key.HanjaMode, 25 },
{ Key.Escape, 27 },
{ Key.ImeConvert, 28 },
{ Key.ImeNonConvert, 29 },
{ Key.ImeAccept, 30 },
{ Key.ImeModeChange, 31 },
{ Key.Space, 32 },
{ Key.PageUp, 33 },
{ Key.Next, 34 },
{ Key.End, 35 },
{ Key.Home, 36 },
{ Key.Left, 37 },
{ Key.Up, 38 },
{ Key.Right, 39 },
{ Key.Down, 40 },
{ Key.Select, 41 },
{ Key.Print, 42 },
{ Key.Execute, 43 },
{ Key.Snapshot, 44 },
{ Key.Insert, 45 },
{ Key.Delete, 46 },
{ Key.Help, 47 },
{ Key.D0, 48 },
{ Key.D1, 49 },
{ Key.D2, 50 },
{ Key.D3, 51 },
{ Key.D4, 52 },
{ Key.D5, 53 },
{ Key.D6, 54 },
{ Key.D7, 55 },
{ Key.D8, 56 },
{ Key.D9, 57 },
{ Key.A, 65 },
{ Key.B, 66 },
{ Key.C, 67 },
{ Key.D, 68 },
{ Key.E, 69 },
{ Key.F, 70 },
{ Key.G, 71 },
{ Key.H, 72 },
{ Key.I, 73 },
{ Key.J, 74 },
{ Key.K, 75 },
{ Key.L, 76 },
{ Key.M, 77 },
{ Key.N, 78 },
{ Key.O, 79 },
{ Key.P, 80 },
{ Key.Q, 81 },
{ Key.R, 82 },
{ Key.S, 83 },
{ Key.T, 84 },
{ Key.U, 85 },
{ Key.V, 86 },
{ Key.W, 87 },
{ Key.X, 88 },
{ Key.Y, 89 },
{ Key.Z, 90 },
{ Key.LWin, 91 },
{ Key.RWin, 92 },
{ Key.Apps, 93 },
{ Key.Sleep, 95 },
{ Key.NumPad0, 96 },
{ Key.NumPad1, 97 },
{ Key.NumPad2, 98 },
{ Key.NumPad3, 99 },
{ Key.NumPad4, 100 },
{ Key.NumPad5, 101 },
{ Key.NumPad6, 102 },
{ Key.NumPad7, 103 },
{ Key.NumPad8, 104 },
{ Key.NumPad9, 105 },
{ Key.Multiply, 106 },
{ Key.Add, 107 },
{ Key.Separator, 108 },
{ Key.Subtract, 109 },
{ Key.Decimal, 110 },
{ Key.Divide, 111 },
{ Key.F1, 112 },
{ Key.F2, 113 },
{ Key.F3, 114 },
{ Key.F4, 115 },
{ Key.F5, 116 },
{ Key.F6, 117 },
{ Key.F7, 118 },
{ Key.F8, 119 },
{ Key.F9, 120 },
{ Key.F10, 121 },
{ Key.F11, 122 },
{ Key.F12, 123 },
{ Key.F13, 124 },
{ Key.F14, 125 },
{ Key.F15, 126 },
{ Key.F16, 127 },
{ Key.F17, 128 },
{ Key.F18, 129 },
{ Key.F19, 130 },
{ Key.F20, 131 },
{ Key.F21, 132 },
{ Key.F22, 133 },
{ Key.F23, 134 },
{ Key.F24, 135 },
{ Key.NumLock, 144 },
{ Key.Scroll, 145 },
{ Key.LeftShift, 160 },
{ Key.RightShift, 161 },
{ Key.LeftCtrl, 162 },
{ Key.RightCtrl, 163 },
{ Key.LeftAlt, 164 },
{ Key.RightAlt, 165 },
{ Key.BrowserBack, 166 },
{ Key.BrowserForward, 167 },
{ Key.BrowserRefresh, 168 },
{ Key.BrowserStop, 169 },
{ Key.BrowserSearch, 170 },
{ Key.BrowserFavorites, 171 },
{ Key.BrowserHome, 172 },
{ Key.VolumeMute, 173 },
{ Key.VolumeDown, 174 },
{ Key.VolumeUp, 175 },
{ Key.MediaNextTrack, 176 },
{ Key.MediaPreviousTrack, 177 },
{ Key.MediaStop, 178 },
{ Key.MediaPlayPause, 179 },
{ Key.LaunchMail, 180 },
{ Key.SelectMedia, 181 },
{ Key.LaunchApplication1, 182 },
{ Key.LaunchApplication2, 183 },
{ Key.Oem1, 186 },
{ Key.OemPlus, 187 },
{ Key.OemComma, 188 },
{ Key.OemMinus, 189 },
{ Key.OemPeriod, 190 },
{ Key.OemQuestion, 191 },
{ Key.Oem3, 192 },
{ Key.AbntC1, 193 },
{ Key.AbntC2, 194 },
{ Key.OemOpenBrackets, 219 },
{ Key.Oem5, 220 },
{ Key.Oem6, 221 },
{ Key.OemQuotes, 222 },
{ Key.Oem8, 223 },
{ Key.OemBackslash, 226 },
{ Key.ImeProcessed, 229 },
{ Key.System, 0 },
{ Key.OemAttn, 240 },
{ Key.OemFinish, 241 },
{ Key.OemCopy, 242 },
{ Key.DbeSbcsChar, 243 },
{ Key.OemEnlw, 244 },
{ Key.OemBackTab, 245 },
{ Key.DbeNoRoman, 246 },
{ Key.DbeEnterWordRegisterMode, 247 },
{ Key.DbeEnterImeConfigureMode, 248 },
{ Key.EraseEof, 249 },
{ Key.Play, 250 },
{ Key.DbeNoCodeInput, 251 },
{ Key.NoName, 252 },
{ Key.Pa1, 253 },
{ Key.OemClear, 254 },
{ Key.DeadCharProcessed, 0 },
};
private static Dictionary<int, Key> keyFromVirtualKey = new Dictionary<int, Key>
{
{ 0, Key.None },
{ 3, Key.Cancel },
{ 8, Key.Back },
{ 9, Key.Tab },
{ 12, Key.Clear },
{ 13, Key.Return },
{ 19, Key.Pause },
{ 20, Key.Capital },
{ 21, Key.KanaMode },
{ 23, Key.JunjaMode },
{ 24, Key.FinalMode },
{ 25, Key.HanjaMode },
{ 27, Key.Escape },
{ 28, Key.ImeConvert },
{ 29, Key.ImeNonConvert },
{ 30, Key.ImeAccept },
{ 31, Key.ImeModeChange },
{ 32, Key.Space },
{ 33, Key.PageUp },
{ 34, Key.Next },
{ 35, Key.End },
{ 36, Key.Home },
{ 37, Key.Left },
{ 38, Key.Up },
{ 39, Key.Right },
{ 40, Key.Down },
{ 41, Key.Select },
{ 42, Key.Print },
{ 43, Key.Execute },
{ 44, Key.Snapshot },
{ 45, Key.Insert },
{ 46, Key.Delete },
{ 47, Key.Help },
{ 48, Key.D0 },
{ 49, Key.D1 },
{ 50, Key.D2 },
{ 51, Key.D3 },
{ 52, Key.D4 },
{ 53, Key.D5 },
{ 54, Key.D6 },
{ 55, Key.D7 },
{ 56, Key.D8 },
{ 57, Key.D9 },
{ 65, Key.A },
{ 66, Key.B },
{ 67, Key.C },
{ 68, Key.D },
{ 69, Key.E },
{ 70, Key.F },
{ 71, Key.G },
{ 72, Key.H },
{ 73, Key.I },
{ 74, Key.J },
{ 75, Key.K },
{ 76, Key.L },
{ 77, Key.M },
{ 78, Key.N },
{ 79, Key.O },
{ 80, Key.P },
{ 81, Key.Q },
{ 82, Key.R },
{ 83, Key.S },
{ 84, Key.T },
{ 85, Key.U },
{ 86, Key.V },
{ 87, Key.W },
{ 88, Key.X },
{ 89, Key.Y },
{ 90, Key.Z },
{ 91, Key.LWin },
{ 92, Key.RWin },
{ 93, Key.Apps },
{ 95, Key.Sleep },
{ 96, Key.NumPad0 },
{ 97, Key.NumPad1 },
{ 98, Key.NumPad2 },
{ 99, Key.NumPad3 },
{ 100, Key.NumPad4 },
{ 101, Key.NumPad5 },
{ 102, Key.NumPad6 },
{ 103, Key.NumPad7 },
{ 104, Key.NumPad8 },
{ 105, Key.NumPad9 },
{ 106, Key.Multiply },
{ 107, Key.Add },
{ 108, Key.Separator },
{ 109, Key.Subtract },
{ 110, Key.Decimal },
{ 111, Key.Divide },
{ 112, Key.F1 },
{ 113, Key.F2 },
{ 114, Key.F3 },
{ 115, Key.F4 },
{ 116, Key.F5 },
{ 117, Key.F6 },
{ 118, Key.F7 },
{ 119, Key.F8 },
{ 120, Key.F9 },
{ 121, Key.F10 },
{ 122, Key.F11 },
{ 123, Key.F12 },
{ 124, Key.F13 },
{ 125, Key.F14 },
{ 126, Key.F15 },
{ 127, Key.F16 },
{ 128, Key.F17 },
{ 129, Key.F18 },
{ 130, Key.F19 },
{ 131, Key.F20 },
{ 132, Key.F21 },
{ 133, Key.F22 },
{ 134, Key.F23 },
{ 135, Key.F24 },
{ 144, Key.NumLock },
{ 145, Key.Scroll },
{ 160, Key.LeftShift },
{ 161, Key.RightShift },
{ 162, Key.LeftCtrl },
{ 163, Key.RightCtrl },
{ 164, Key.LeftAlt },
{ 165, Key.RightAlt },
{ 166, Key.BrowserBack },
{ 167, Key.BrowserForward },
{ 168, Key.BrowserRefresh },
{ 169, Key.BrowserStop },
{ 170, Key.BrowserSearch },
{ 171, Key.BrowserFavorites },
{ 172, Key.BrowserHome },
{ 173, Key.VolumeMute },
{ 174, Key.VolumeDown },
{ 175, Key.VolumeUp },
{ 176, Key.MediaNextTrack },
{ 177, Key.MediaPreviousTrack },
{ 178, Key.MediaStop },
{ 179, Key.MediaPlayPause },
{ 180, Key.LaunchMail },
{ 181, Key.SelectMedia },
{ 182, Key.LaunchApplication1 },
{ 183, Key.LaunchApplication2 },
{ 186, Key.Oem1 },
{ 187, Key.OemPlus },
{ 188, Key.OemComma },
{ 189, Key.OemMinus },
{ 190, Key.OemPeriod },
{ 191, Key.OemQuestion },
{ 192, Key.Oem3 },
{ 193, Key.AbntC1 },
{ 194, Key.AbntC2 },
{ 219, Key.OemOpenBrackets },
{ 220, Key.Oem5 },
{ 221, Key.Oem6 },
{ 222, Key.OemQuotes },
{ 223, Key.Oem8 },
{ 226, Key.OemBackslash },
{ 229, Key.ImeProcessed },
{ 240, Key.OemAttn },
{ 241, Key.OemFinish },
{ 242, Key.OemCopy },
{ 243, Key.DbeSbcsChar },
{ 244, Key.OemEnlw },
{ 245, Key.OemBackTab },
{ 246, Key.DbeNoRoman },
{ 247, Key.DbeEnterWordRegisterMode },
{ 248, Key.DbeEnterImeConfigureMode },
{ 249, Key.EraseEof },
{ 250, Key.Play },
{ 251, Key.DbeNoCodeInput },
{ 252, Key.NoName },
{ 253, Key.Pa1 },
{ 254, Key.OemClear },
};
public static Key KeyFromVirtualKey(int virtualKey)
{
Key result;
keyFromVirtualKey.TryGetValue(virtualKey, out result);
return result;
}
public static int VirtualKeyFromKey(Key key)
{
int result;
virtualKeyFromKey.TryGetValue(key, out result);
return result;
}
}
}

96
Perspex.Windows/Input/WindowsKeyboardDevice.cs

@ -0,0 +1,96 @@
// -----------------------------------------------------------------------
// <copyright file="WindowsKeyboardDevice.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Windows.Input
{
using System.Text;
using Perspex.Input;
using Perspex.Windows.Interop;
public class WindowsKeyboardDevice : KeyboardDevice
{
private static WindowsKeyboardDevice instance = new WindowsKeyboardDevice();
private byte[] keyStates = new byte[256];
public static WindowsKeyboardDevice Instance
{
get { return instance; }
}
public override ModifierKeys Modifiers
{
get
{
ModifierKeys result = 0;
if (this.GetKeyStates(Key.LeftAlt) == KeyStates.Down ||
this.GetKeyStates(Key.RightAlt) == KeyStates.Down)
{
result |= ModifierKeys.Alt;
}
if (this.GetKeyStates(Key.LeftCtrl) == KeyStates.Down ||
this.GetKeyStates(Key.RightCtrl) == KeyStates.Down)
{
result |= ModifierKeys.Control;
}
if (this.GetKeyStates(Key.LeftShift) == KeyStates.Down ||
this.GetKeyStates(Key.RightShift) == KeyStates.Down)
{
result |= ModifierKeys.Shift;
}
if (this.GetKeyStates(Key.LWin) == KeyStates.Down ||
this.GetKeyStates(Key.RWin) == KeyStates.Down)
{
result |= ModifierKeys.Windows;
}
return result;
}
}
public string StringFromVirtualKey(uint virtualKey)
{
StringBuilder result = new StringBuilder(256);
int length = UnmanagedMethods.ToUnicode(
virtualKey,
0,
this.keyStates,
result,
256,
0);
return result.ToString();
}
internal void UpdateKeyStates()
{
UnmanagedMethods.GetKeyboardState(this.keyStates);
}
private KeyStates GetKeyStates(Key key)
{
int vk = KeyInterop.VirtualKeyFromKey(key);
byte state = this.keyStates[vk];
KeyStates result = 0;
if ((state & 0x80) != 0)
{
result |= KeyStates.Down;
}
if ((state & 0x01) != 0)
{
result |= KeyStates.Toggled;
}
return result;
}
}
}

3
Perspex.Windows/Input/WindowsMouseDevice.cs

@ -7,8 +7,6 @@
namespace Perspex.Windows.Input
{
using Perspex.Input;
using Perspex.Input.Raw;
using Splat;
public class WindowsMouseDevice : MouseDevice
{
@ -32,3 +30,4 @@ namespace Perspex.Windows.Input
}
}
}

2
Perspex.Windows/Perspex.Windows.csproj

@ -56,6 +56,8 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Input\KeyInterop.cs" />
<Compile Include="Input\WindowsKeyboardDevice.cs" />
<Compile Include="Input\WindowsMouseDevice.cs" />
<Compile Include="Threading\Dispatcher.cs" />
<Compile Include="Threading\DispatcherFrame.cs" />

20
Perspex.Windows/Window.cs

@ -39,7 +39,7 @@ namespace Perspex.Windows
public Window()
{
IPlatformFactory factory = Locator.Current.GetService<IPlatformFactory>();
IPlatformInterface factory = Locator.Current.GetService<IPlatformInterface>();
this.CreateWindow();
Size clientSize = this.ClientSize;
@ -165,7 +165,7 @@ namespace Perspex.Windows
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")]
private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
{
RawMouseEventArgs e = null;
RawInputEventArgs e = null;
WindowsMouseDevice.Instance.CurrentWindow = this;
@ -175,13 +175,14 @@ namespace Perspex.Windows
//// this.OnClosed();
//// break;
////case UnmanagedMethods.WindowsMessage.WM_KEYDOWN:
//// InputManager.Current.ProcessInput(
//// new RawKeyEventArgs(
//// keyboard,
//// RawKeyEventType.KeyDown,
//// KeyInterop.KeyFromVirtualKey((int)wParam)));
//// break;
case UnmanagedMethods.WindowsMessage.WM_KEYDOWN:
WindowsKeyboardDevice.Instance.UpdateKeyStates();
e = new RawKeyEventArgs(
WindowsKeyboardDevice.Instance,
RawKeyEventType.KeyDown,
KeyInterop.KeyFromVirtualKey((int)wParam),
WindowsKeyboardDevice.Instance.StringFromVirtualKey((uint)wParam));
break;
case UnmanagedMethods.WindowsMessage.WM_LBUTTONDOWN:
e = new RawMouseEventArgs(
@ -215,7 +216,6 @@ namespace Perspex.Windows
if (e != null)
{
WindowsMouseDevice.Instance.Position = e.Position;
this.inputManager.Process(e);
}

84
Perspex/Controls/Control.cs

@ -92,6 +92,15 @@ namespace Perspex.Controls
public static readonly PerspexProperty<double> WidthProperty =
PerspexProperty.Register<Control, double>("Width", double.NaN);
public static readonly RoutedEvent<RoutedEventArgs> GotFocusEvent =
RoutedEvent.Register<Control, RoutedEventArgs>("GotFocus", RoutingStrategy.Bubble);
public static readonly RoutedEvent<RoutedEventArgs> LostFocusEvent =
RoutedEvent.Register<Control, RoutedEventArgs>("LostFocus", RoutingStrategy.Bubble);
public static readonly RoutedEvent<KeyEventArgs> KeyDownEvent =
RoutedEvent.Register<Control, KeyEventArgs>("KeyDown", RoutingStrategy.Bubble);
public static readonly RoutedEvent<PointerEventArgs> PointerEnterEvent =
RoutedEvent.Register<Control, PointerEventArgs>("PointerEnter", RoutingStrategy.Direct);
@ -113,40 +122,30 @@ namespace Perspex.Controls
public Control()
{
this.classes = new Classes();
this.GotFocus += (s, e) => this.IsFocused = true;
this.LostFocus += (s, e) => this.IsFocused = false;
this.PointerEnter += (s, e) => this.IsPointerOver = true;
this.PointerLeave += (s, e) => this.IsPointerOver = false;
this.AddPseudoClass(IsPointerOverProperty, ":pointerover");
this.AddPseudoClass(IsFocusedProperty, ":focus");
}
this.PointerEnter += (s, e) =>
{
this.IsPointerOver = true;
};
this.PointerLeave += (s, e) =>
{
this.IsPointerOver = false;
};
public event EventHandler<RoutedEventArgs> GotFocus
{
add { this.AddHandler(GotFocusEvent, value); }
remove { this.RemoveHandler(GotFocusEvent, value); }
}
this.GetObservable(IsPointerOverProperty).Subscribe(x =>
{
if (x)
{
this.Classes.Add(":pointerover");
}
else
{
this.Classes.Remove(":pointerover");
}
});
public event EventHandler<RoutedEventArgs> LostFocus
{
add { this.AddHandler(LostFocusEvent, value); }
remove { this.RemoveHandler(LostFocusEvent, value); }
}
this.GetObservable(IsFocusedProperty).Subscribe(x =>
{
if (x)
{
this.Classes.Add(":focus");
}
else
{
this.Classes.Remove(":focus");
}
});
public event EventHandler<KeyEventArgs> KeyDown
{
add { this.AddHandler(KeyDownEvent, value); }
remove { this.RemoveHandler(KeyDownEvent, value); }
}
public event EventHandler<PointerEventArgs> PointerEnter
@ -246,7 +245,7 @@ namespace Perspex.Controls
public bool IsFocused
{
get { return this.GetValue(IsFocusedProperty); }
internal set { this.SetValue(IsFocusedProperty, value); }
private set { this.SetValue(IsFocusedProperty, value); }
}
public string Id
@ -356,12 +355,6 @@ namespace Perspex.Controls
set { this.SetValue(WidthProperty, value); }
}
bool IFocusable.IsFocused
{
get { return this.GetValue(IsFocusedProperty); }
set { this.SetValue(IsFocusedProperty, value); }
}
ILogical ILogical.LogicalParent
{
get { return this.Parent; }
@ -414,6 +407,21 @@ namespace Perspex.Controls
}
}
protected void AddPseudoClass(PerspexProperty<bool> property, string className)
{
this.GetObservable(property).Subscribe(x =>
{
if (x)
{
this.classes.Add(className);
}
else
{
this.classes.Remove(className);
}
});
}
protected virtual void ArrangeCore(Rect finalRect)
{
double originX = finalRect.X + this.Margin.Left;

61
Perspex/Controls/TextBox.cs

@ -8,7 +8,10 @@ namespace Perspex.Controls
{
using System;
using System.Linq;
using Perspex.Input;
using Perspex.Platform;
using Perspex.Styling;
using Splat;
public class TextBox : TemplatedControl
{
@ -26,7 +29,10 @@ namespace Perspex.Controls
public TextBox()
{
this.GetObservable(TextProperty).Subscribe(_ => this.InvalidateVisual());
this.GotFocus += (s, e) => this.textBoxView.GotFocus();
this.LostFocus += (s, e) => this.textBoxView.LostFocus();
this.KeyDown += this.OnKeyDown;
this.PointerPressed += this.OnPointerPressed;
}
public int CaretIndex
@ -68,6 +74,59 @@ namespace Perspex.Controls
}
textContainer.Content = this.textBoxView = new TextBoxView(this);
this.GetObservable(TextProperty).Subscribe(_ => this.textBoxView.InvalidateText());
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
string text = this.Text;
switch (e.Key)
{
case Key.Left:
--this.CaretIndex;
break;
case Key.Right:
++this.CaretIndex;
break;
case Key.Back:
if (this.caretIndex > 0)
{
this.Text = text.Substring(0, this.caretIndex - 1) + text.Substring(this.caretIndex);
--this.CaretIndex;
}
break;
case Key.Delete:
if (this.caretIndex < text.Length)
{
this.Text = text.Substring(0, this.caretIndex) + text.Substring(this.caretIndex + 1);
}
break;
default:
if (!string.IsNullOrEmpty(e.Text))
{
this.Text = text.Substring(0, this.caretIndex) + e.Text + text.Substring(this.caretIndex);
++this.CaretIndex;
}
break;
}
e.Handled = true;
}
private void OnPointerPressed(object sender, PointerEventArgs e)
{
//IPlatformInterface platform = Locator.Current.GetService<IPlatformInterface>();
//this.CaretIndex = platform.GetTextService().GetCaretIndex(
// this.textBoxView.FormattedText,
// e.GetPosition(this.textBoxView));
}
}
}

13
Perspex/Controls/ToggleButton.cs

@ -16,18 +16,7 @@ namespace Perspex.Controls
public ToggleButton()
{
this.Click += (s, e) => this.IsChecked = !this.IsChecked;
this.GetObservable(IsCheckedProperty).Subscribe(x =>
{
if (x)
{
this.Classes.Add(":checked");
}
else
{
this.Classes.Remove(":checked");
}
});
this.AddPseudoClass(IsCheckedProperty, ":checked");
}
public bool IsChecked

26
Perspex/Input/FocusManager.cs

@ -4,6 +4,8 @@
// </copyright>
// -----------------------------------------------------------------------
using Perspex.Controls;
namespace Perspex.Input
{
public class FocusManager : IFocusManager
@ -16,15 +18,29 @@ namespace Perspex.Input
public void Focus(IFocusable control)
{
if (this.Current != null)
Interactive current = this.Current as Interactive;
Interactive next = control as Interactive;
if (current != null)
{
this.Current.IsFocused = false;
current.RaiseEvent(new RoutedEventArgs
{
RoutedEvent = Control.GotFocusEvent,
Source = current,
OriginalSource = current,
});
}
if (control != null)
this.Current = control;
if (next != null)
{
control.IsFocused = true;
this.Current = control;
next.RaiseEvent(new RoutedEventArgs
{
RoutedEvent = Control.GotFocusEvent,
Source = next,
OriginalSource = next,
});
}
}
}

2
Perspex/Input/IFocusable.cs

@ -10,7 +10,7 @@ namespace Perspex.Input
{
bool Focusable { get; }
bool IsFocused { get; set; }
bool IsFocused { get; }
void Focus();
}

33
Perspex/Input/IKeyboardDevice.cs

@ -0,0 +1,33 @@
// -----------------------------------------------------------------------
// <copyright file="IKeyboardDevice.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input
{
using System;
[Flags]
public enum ModifierKeys
{
None = 0,
Alt = 1,
Control = 2,
Shift = 4,
Windows = 8,
}
[Flags]
public enum KeyStates
{
None = 0,
Down = 1,
Toggled = 2,
}
public interface IKeyboardDevice : IInputDevice
{
ModifierKeys Modifiers { get; }
}
}

214
Perspex/Input/Key.cs

@ -0,0 +1,214 @@
// -----------------------------------------------------------------------
// <copyright file="Key.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input
{
public enum Key
{
None = 0,
Cancel = 1,
Back = 2,
Tab = 3,
LineFeed = 4,
Clear = 5,
Return = 6,
Enter = 6,
Pause = 7,
CapsLock = 8,
Capital = 8,
HangulMode = 9,
KanaMode = 9,
JunjaMode = 10,
FinalMode = 11,
KanjiMode = 12,
HanjaMode = 12,
Escape = 13,
ImeConvert = 14,
ImeNonConvert = 15,
ImeAccept = 16,
ImeModeChange = 17,
Space = 18,
PageUp = 19,
Prior = 19,
PageDown = 20,
Next = 20,
End = 21,
Home = 22,
Left = 23,
Up = 24,
Right = 25,
Down = 26,
Select = 27,
Print = 28,
Execute = 29,
Snapshot = 30,
PrintScreen = 30,
Insert = 31,
Delete = 32,
Help = 33,
D0 = 34,
D1 = 35,
D2 = 36,
D3 = 37,
D4 = 38,
D5 = 39,
D6 = 40,
D7 = 41,
D8 = 42,
D9 = 43,
A = 44,
B = 45,
C = 46,
D = 47,
E = 48,
F = 49,
G = 50,
H = 51,
I = 52,
J = 53,
K = 54,
L = 55,
M = 56,
N = 57,
O = 58,
P = 59,
Q = 60,
R = 61,
S = 62,
T = 63,
U = 64,
V = 65,
W = 66,
X = 67,
Y = 68,
Z = 69,
LWin = 70,
RWin = 71,
Apps = 72,
Sleep = 73,
NumPad0 = 74,
NumPad1 = 75,
NumPad2 = 76,
NumPad3 = 77,
NumPad4 = 78,
NumPad5 = 79,
NumPad6 = 80,
NumPad7 = 81,
NumPad8 = 82,
NumPad9 = 83,
Multiply = 84,
Add = 85,
Separator = 86,
Subtract = 87,
Decimal = 88,
Divide = 89,
F1 = 90,
F2 = 91,
F3 = 92,
F4 = 93,
F5 = 94,
F6 = 95,
F7 = 96,
F8 = 97,
F9 = 98,
F10 = 99,
F11 = 100,
F12 = 101,
F13 = 102,
F14 = 103,
F15 = 104,
F16 = 105,
F17 = 106,
F18 = 107,
F19 = 108,
F20 = 109,
F21 = 110,
F22 = 111,
F23 = 112,
F24 = 113,
NumLock = 114,
Scroll = 115,
LeftShift = 116,
RightShift = 117,
LeftCtrl = 118,
RightCtrl = 119,
LeftAlt = 120,
RightAlt = 121,
BrowserBack = 122,
BrowserForward = 123,
BrowserRefresh = 124,
BrowserStop = 125,
BrowserSearch = 126,
BrowserFavorites = 127,
BrowserHome = 128,
VolumeMute = 129,
VolumeDown = 130,
VolumeUp = 131,
MediaNextTrack = 132,
MediaPreviousTrack = 133,
MediaStop = 134,
MediaPlayPause = 135,
LaunchMail = 136,
SelectMedia = 137,
LaunchApplication1 = 138,
LaunchApplication2 = 139,
OemSemicolon = 140,
Oem1 = 140,
OemPlus = 141,
OemComma = 142,
OemMinus = 143,
OemPeriod = 144,
OemQuestion = 145,
Oem2 = 145,
OemTilde = 146,
Oem3 = 146,
AbntC1 = 147,
AbntC2 = 148,
OemOpenBrackets = 149,
Oem4 = 149,
OemPipe = 150,
Oem5 = 150,
OemCloseBrackets = 151,
Oem6 = 151,
OemQuotes = 152,
Oem7 = 152,
Oem8 = 153,
OemBackslash = 154,
Oem102 = 154,
ImeProcessed = 155,
System = 156,
OemAttn = 157,
DbeAlphanumeric = 157,
OemFinish = 158,
DbeKatakana = 158,
DbeHiragana = 159,
OemCopy = 159,
DbeSbcsChar = 160,
OemAuto = 160,
DbeDbcsChar = 161,
OemEnlw = 161,
OemBackTab = 162,
DbeRoman = 162,
DbeNoRoman = 163,
Attn = 163,
CrSel = 164,
DbeEnterWordRegisterMode = 164,
ExSel = 165,
DbeEnterImeConfigureMode = 165,
EraseEof = 166,
DbeFlushString = 166,
Play = 167,
DbeCodeInput = 167,
DbeNoCodeInput = 168,
Zoom = 168,
NoName = 169,
DbeDetermineString = 169,
DbeEnterDialogConversionMode = 170,
Pa1 = 170,
OemClear = 171,
DeadCharProcessed = 172,
}
}

9
Perspex/Input/FocusEventArgs.cs → Perspex/Input/KeyEventArgs.cs

@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="FocusEventArgs.cs" company="Steven Kirk">
// <copyright file="PointerEventArgs.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
@ -8,7 +8,12 @@ namespace Perspex.Input
{
using System;
public class FocusEventArgs : RoutedEventArgs
public class KeyEventArgs : RoutedEventArgs
{
public IKeyboardDevice Device { get; set; }
public Key Key { get; set; }
public string Text { get; set; }
}
}

61
Perspex/Input/KeyboardDevice.cs

@ -0,0 +1,61 @@
// -----------------------------------------------------------------------
// <copyright file="KeyboardDevice.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </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 KeyboardDevice : IKeyboardDevice
{
public KeyboardDevice()
{
this.InputManager.RawEventReceived
.OfType<RawKeyEventArgs>()
.Where(x => x.Device == this)
.Subscribe(this.ProcessRawEvent);
}
public IInputManager InputManager
{
get { return Locator.Current.GetService<IInputManager>(); }
}
public IFocusManager FocusManager
{
get { return Locator.Current.GetService<IFocusManager>(); }
}
public abstract ModifierKeys Modifiers { get; }
private void ProcessRawEvent(RawKeyEventArgs e)
{
Interactive interactive = FocusManager.Current as Interactive;
if (interactive != null)
{
switch (e.Type)
{
case RawKeyEventType.KeyDown:
interactive.RaiseEvent(new KeyEventArgs
{
RoutedEvent = Control.KeyDownEvent,
Device = this,
Key = e.Key,
Text = e.Text,
Source = interactive,
OriginalSource = interactive,
});
break;
}
}
}
}
}

6
Perspex/Input/MouseDevice.cs

@ -20,7 +20,7 @@ namespace Perspex.Input
this.InputManager.RawEventReceived
.OfType<RawMouseEventArgs>()
.Where(x => x.Device == this)
.Subscribe(this.ProcessMouse);
.Subscribe(this.ProcessRawEvent);
}
public Interactive Captured
@ -45,8 +45,10 @@ namespace Perspex.Input
this.Captured = visual;
}
private void ProcessMouse(RawMouseEventArgs e)
private void ProcessRawEvent(RawMouseEventArgs e)
{
this.Position = e.Position;
switch (e.Type)
{
case RawMouseEventType.Move:

31
Perspex/Input/Raw/RawKeyEventArgs.cs

@ -0,0 +1,31 @@
// -----------------------------------------------------------------------
// <copyright file="RawKeyEventArgs.cs" company="Tricycle">
// Copyright 2014 Tricycle. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Input.Raw
{
public enum RawKeyEventType
{
KeyDown,
KeyUp
}
public class RawKeyEventArgs : RawInputEventArgs
{
public RawKeyEventArgs(KeyboardDevice device, RawKeyEventType type, Key key, string text)
: base(device)
{
this.Key = key;
this.Type = type;
this.Text = text;
}
public Key Key { get; set; }
public string Text { get; set; }
public RawKeyEventType Type { get; set; }
}
}

2
Perspex/Media/FormattedText.cs

@ -21,7 +21,7 @@ namespace Perspex.Media
{
get
{
IPlatformFactory factory = Locator.Current.GetService<IPlatformFactory>();
IPlatformInterface factory = Locator.Current.GetService<IPlatformInterface>();
ITextService service = factory.GetTextService();
return service.Measure(this);
}

2
Perspex/Media/Imaging/Bitmap.cs

@ -13,7 +13,7 @@ namespace Perspex.Media
{
public Bitmap(int width, int height)
{
IPlatformFactory factory = Locator.Current.GetService<IPlatformFactory>();
IPlatformInterface factory = Locator.Current.GetService<IPlatformInterface>();
this.PlatformImpl = factory.CreateBitmap(width, height);
}

2
Perspex/Media/Imaging/RenderTargetBitmap.cs

@ -28,7 +28,7 @@ namespace Perspex.Media
private static IBitmapImpl CreateImpl(int width, int height)
{
IPlatformFactory factory = Locator.Current.GetService<IPlatformFactory>();
IPlatformInterface factory = Locator.Current.GetService<IPlatformInterface>();
return factory.CreateRenderTargetBitmap(width, height);
}
}

2
Perspex/Media/RectangleGeometry.cs

@ -13,7 +13,7 @@ namespace Perspex.Media
{
public RectangleGeometry(Rect rect)
{
IPlatformFactory factory = Locator.Current.GetService<IPlatformFactory>();
IPlatformInterface factory = Locator.Current.GetService<IPlatformInterface>();
IStreamGeometryImpl impl = factory.CreateStreamGeometry();
using (IStreamGeometryContextImpl context = impl.Open())

2
Perspex/Media/StreamGeometry.cs

@ -13,7 +13,7 @@ namespace Perspex.Media
{
public StreamGeometry()
{
IPlatformFactory factory = Locator.Current.GetService<IPlatformFactory>();
IPlatformInterface factory = Locator.Current.GetService<IPlatformInterface>();
this.PlatformImpl = factory.CreateStreamGeometry();
}

8
Perspex/Perspex.csproj

@ -87,14 +87,18 @@
<Compile Include="Input\IFocusManager.cs" />
<Compile Include="Input\FocusManager.cs" />
<Compile Include="Input\IFocusable.cs" />
<Compile Include="Input\Key.cs" />
<Compile Include="Input\KeyboardDevice.cs" />
<Compile Include="Input\IKeyboardDevice.cs" />
<Compile Include="Input\IMouseDevice.cs" />
<Compile Include="Input\IPointerDevice.cs" />
<Compile Include="Input\IInputDevice.cs" />
<Compile Include="Input\IInputManager.cs" />
<Compile Include="Input\InputManager.cs" />
<Compile Include="Input\FocusEventArgs.cs" />
<Compile Include="Input\MouseDevice.cs" />
<Compile Include="Input\KeyEventArgs.cs" />
<Compile Include="Input\Raw\RawInputEventArgs.cs" />
<Compile Include="Input\Raw\RawKeyEventArgs.cs" />
<Compile Include="Input\Raw\RawMouseEventArgs.cs" />
<Compile Include="Layout\LayoutHelper.cs" />
<Compile Include="Media\Brushes.cs" />
@ -102,7 +106,7 @@
<Compile Include="Media\Imaging\RenderTargetBitmap.cs" />
<Compile Include="Platform\IRenderTargetBitmapImpl.cs" />
<Compile Include="Platform\IBitmapImpl.cs" />
<Compile Include="Platform\IPlatformFactory.cs" />
<Compile Include="Platform\IPlatformInterface.cs" />
<Compile Include="Platform\IStreamGeometryContextImpl.cs" />
<Compile Include="Platform\IGeometryImpl.cs" />
<Compile Include="Platform\IStreamGeometryImpl.cs" />

2
Perspex/Platform/IPlatformFactory.cs → Perspex/Platform/IPlatformInterface.cs

@ -8,7 +8,7 @@ namespace Perspex.Platform
{
using System;
public interface IPlatformFactory
public interface IPlatformInterface
{
IBitmapImpl CreateBitmap(int width, int height);
Loading…
Cancel
Save