diff --git a/Cairo/Perspex.Cairo/Media/TextService.cs b/Cairo/Perspex.Cairo/Media/TextService.cs
index 3032786190..f37ae9ecf2 100644
--- a/Cairo/Perspex.Cairo/Media/TextService.cs
+++ b/Cairo/Perspex.Cairo/Media/TextService.cs
@@ -49,15 +49,20 @@ namespace Perspex.Cairo.Media
var layout = this.CreateLayout(text);
int result;
int trailing;
- layout.XyToIndex((int)point.X, (int)point.Y, out result, out trailing);
- return result;
+ return layout.XyToIndex(
+ Pango.Units.FromDouble(point.X),
+ Pango.Units.FromDouble(point.Y),
+ out result,
+ out trailing) ? result : text.Text.Length;
}
public Point GetCaretPosition(FormattedText text, int caretIndex, Size constraint)
{
+ // TODO: Rather than have this and GetLineHeights, might be best to just return
+ // the rect if that's also possible in Direct2D backend.
var layout = this.CreateLayout(text);
var rect = layout.IndexToPos(caretIndex);
- return new Point(rect.X, rect.Y);
+ return new Point(Pango.Units.ToDouble(rect.X), Pango.Units.ToDouble(rect.Y));
}
public double[] GetLineHeights(FormattedText text, Size constraint)
diff --git a/Gtk/Perspex.Gtk/GtkPlatform.cs b/Gtk/Perspex.Gtk/GtkPlatform.cs
index 34023ff732..70c0342ea0 100644
--- a/Gtk/Perspex.Gtk/GtkPlatform.cs
+++ b/Gtk/Perspex.Gtk/GtkPlatform.cs
@@ -8,6 +8,7 @@ namespace Perspex.Gtk
{
using System;
using System.Reactive.Disposables;
+ using Perspex.Input;
using Perspex.Platform;
using Splat;
using Gtk = global::Gtk;
@@ -25,7 +26,7 @@ namespace Perspex.Gtk
{
var locator = Locator.CurrentMutable;
locator.Register(() => new WindowImpl(), typeof(IWindowImpl));
- //locator.Register(() => WindowsKeyboardDevice.Instance, typeof(IKeyboardDevice));
+ locator.Register(() => GtkKeyboardDevice.Instance, typeof(IKeyboardDevice));
locator.Register(() => instance, typeof(IPlatformThreadingInterface));
}
diff --git a/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs b/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
index 2329d3acc2..fb42e5e817 100644
--- a/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
+++ b/Gtk/Perspex.Gtk/Input/GtkKeyboardDevice.cs
@@ -3,8 +3,10 @@
// Copyright 2014 MIT Licence. See licence.md for more information.
//
// -----------------------------------------------------------------------
+
namespace Perspex.Gtk
{
+ using System;
using Perspex.Input;
public class GtkKeyboardDevice : KeyboardDevice
@@ -32,7 +34,25 @@ namespace Perspex.Gtk
public static Perspex.Input.Key ConvertKey(Gdk.Key key)
{
- return Key.X;
+ // TODO: Don't use reflection for this! My eyes!!!
+ if (key == Gdk.Key.BackSpace)
+ {
+ return Perspex.Input.Key.Back;
+ }
+ else
+ {
+ var s = Enum.GetName(typeof(Gdk.Key), key);
+ Perspex.Input.Key result;
+
+ if (Enum.TryParse(s, true, out result))
+ {
+ return result;
+ }
+ else
+ {
+ return Perspex.Input.Key.None;
+ }
+ }
}
}
}
diff --git a/Gtk/Perspex.Gtk/WindowImpl.cs b/Gtk/Perspex.Gtk/WindowImpl.cs
index 01598bd482..9a78fc78fb 100644
--- a/Gtk/Perspex.Gtk/WindowImpl.cs
+++ b/Gtk/Perspex.Gtk/WindowImpl.cs
@@ -111,7 +111,7 @@ namespace Perspex.Gtk
GtkKeyboardDevice.Instance,
RawKeyEventType.KeyDown,
GtkKeyboardDevice.ConvertKey(evnt.Key),
- "X");
+ new string((char)Gdk.Keyval.ToUnicode((uint)evnt.Key), 1));
this.Input(e);
return true;
}
diff --git a/Perspex.Controls/TextBoxView.cs b/Perspex.Controls/TextBoxView.cs
index 2a3a443939..a723395476 100644
--- a/Perspex.Controls/TextBoxView.cs
+++ b/Perspex.Controls/TextBoxView.cs
@@ -1,126 +1,126 @@
-// -----------------------------------------------------------------------
-//
-// Copyright 2013 MIT Licence. See licence.md for more information.
-//
-// -----------------------------------------------------------------------
-
-namespace Perspex.Controls
-{
- using System;
- using Perspex.Media;
- using Perspex.Platform;
- using Perspex.Threading;
- using Splat;
-
- internal class TextBoxView : Control
- {
- private TextBox parent;
-
- private FormattedText formattedText;
-
- private DispatcherTimer caretTimer;
-
- private bool caretBlink;
-
- public TextBoxView(TextBox parent)
- {
- this.caretTimer = new DispatcherTimer();
- this.caretTimer.Interval = TimeSpan.FromMilliseconds(500);
- this.caretTimer.Tick += this.CaretTimerTick;
- this.parent = parent;
- }
-
- public FormattedText FormattedText
- {
- get
- {
- if (this.formattedText == null)
- {
- this.formattedText = this.CreateFormattedText();
- }
-
- return this.formattedText;
- }
- }
-
- public new void GotFocus()
- {
- this.caretBlink = true;
- this.caretTimer.Start();
- }
-
- public new void LostFocus()
- {
- this.caretTimer.Stop();
- this.InvalidateVisual();
- }
-
- public void InvalidateText()
- {
- this.formattedText = null;
- this.InvalidateMeasure();
- }
-
- internal void CaretMoved()
- {
- this.caretBlink = true;
- this.caretTimer.Stop();
- this.caretTimer.Start();
- this.InvalidateVisual();
- }
-
- public override void Render(IDrawingContext context)
- {
- Rect rect = new Rect(this.ActualSize);
-
- context.DrawText(Brushes.Black, rect, this.FormattedText);
-
- if (this.parent.IsFocused)
- {
- ITextService textService = Locator.Current.GetService();
- Point caretPos = textService.GetCaretPosition(
- this.formattedText,
- this.parent.CaretIndex,
- this.ActualSize);
- double[] lineHeights = textService.GetLineHeights(this.formattedText, this.ActualSize);
- Brush caretBrush = Brushes.Black;
-
- if (this.caretBlink)
- {
- context.DrawLine(
- new Pen(caretBrush, 1),
- caretPos,
- new Point(caretPos.X, caretPos.Y + lineHeights[0]));
- }
- }
- }
-
- protected override Size MeasureOverride(Size constraint)
- {
- if (!string.IsNullOrEmpty(this.parent.Text))
- {
- ITextService textService = Locator.Current.GetService();
- return textService.Measure(this.FormattedText, constraint);
- }
-
- return new Size();
- }
-
- private FormattedText CreateFormattedText()
- {
- return new FormattedText
- {
- FontFamilyName = "Segoe UI",
- FontSize = this.GetValue(TextBlock.FontSizeProperty),
- FontStyle = this.GetValue(TextBlock.FontStyleProperty),
- Text = this.parent.Text,
- };
- }
-
- private void CaretTimerTick(object sender, EventArgs e)
- {
- this.caretBlink = !this.caretBlink;
- this.InvalidateVisual();
- }
- }
-}
+// -----------------------------------------------------------------------
+//
+// Copyright 2013 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Controls
+{
+ using System;
+ using Perspex.Media;
+ using Perspex.Platform;
+ using Perspex.Threading;
+ using Splat;
+
+ internal class TextBoxView : Control
+ {
+ private TextBox parent;
+
+ private FormattedText formattedText;
+
+ private DispatcherTimer caretTimer;
+
+ private bool caretBlink;
+
+ public TextBoxView(TextBox parent)
+ {
+ this.caretTimer = new DispatcherTimer();
+ this.caretTimer.Interval = TimeSpan.FromMilliseconds(500);
+ this.caretTimer.Tick += this.CaretTimerTick;
+ this.parent = parent;
+ }
+
+ public FormattedText FormattedText
+ {
+ get
+ {
+ if (this.formattedText == null)
+ {
+ this.formattedText = this.CreateFormattedText();
+ }
+
+ return this.formattedText;
+ }
+ }
+
+ public new void GotFocus()
+ {
+ this.caretBlink = true;
+ this.caretTimer.Start();
+ }
+
+ public new void LostFocus()
+ {
+ this.caretTimer.Stop();
+ this.InvalidateVisual();
+ }
+
+ public void InvalidateText()
+ {
+ this.formattedText = null;
+ this.InvalidateMeasure();
+ }
+
+ internal void CaretMoved()
+ {
+ this.caretBlink = true;
+ this.caretTimer.Stop();
+ this.caretTimer.Start();
+ this.InvalidateVisual();
+ }
+
+ public override void Render(IDrawingContext context)
+ {
+ Rect rect = new Rect(this.ActualSize);
+
+ context.DrawText(Brushes.Black, rect, this.FormattedText);
+
+ if (this.parent.IsFocused)
+ {
+ ITextService textService = Locator.Current.GetService();
+ Point caretPos = textService.GetCaretPosition(
+ this.formattedText,
+ this.parent.CaretIndex,
+ this.ActualSize);
+ double[] lineHeights = textService.GetLineHeights(this.formattedText, this.ActualSize);
+ Brush caretBrush = Brushes.Black;
+
+ if (this.caretBlink)
+ {
+ context.DrawLine(
+ new Pen(caretBrush, 1),
+ caretPos,
+ new Point(caretPos.X, caretPos.Y + lineHeights[0]));
+ }
+ }
+ }
+
+ protected override Size MeasureOverride(Size constraint)
+ {
+ if (!string.IsNullOrEmpty(this.parent.Text))
+ {
+ ITextService textService = Locator.Current.GetService();
+ return textService.Measure(this.FormattedText, constraint);
+ }
+
+ return new Size();
+ }
+
+ private FormattedText CreateFormattedText()
+ {
+ return new FormattedText
+ {
+ FontFamilyName = "Segoe UI",
+ FontSize = this.GetValue(TextBlock.FontSizeProperty),
+ FontStyle = this.GetValue(TextBlock.FontStyleProperty),
+ Text = this.parent.Text,
+ };
+ }
+
+ private void CaretTimerTick(object sender, EventArgs e)
+ {
+ this.caretBlink = !this.caretBlink;
+ this.InvalidateVisual();
+ }
+ }
+}
diff --git a/Perspex.SceneGraph/Platform/ITextService.cs b/Perspex.SceneGraph/Platform/ITextService.cs
index d4eadd7b91..9422f1c392 100644
--- a/Perspex.SceneGraph/Platform/ITextService.cs
+++ b/Perspex.SceneGraph/Platform/ITextService.cs
@@ -1,21 +1,21 @@
-// -----------------------------------------------------------------------
-//
-// Copyright 2014 MIT Licence. See licence.md for more information.
-//
-// -----------------------------------------------------------------------
-
-namespace Perspex.Platform
-{
- using Perspex.Media;
-
- public interface ITextService
- {
- int GetCaretIndex(FormattedText text, Point point, Size constraint);
-
- Point GetCaretPosition(FormattedText text, int caretIndex, Size constraint);
-
- double[] GetLineHeights(FormattedText text, Size constraint);
-
- Size Measure(FormattedText text, Size constraint);
- }
-}
+// -----------------------------------------------------------------------
+//
+// Copyright 2014 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Platform
+{
+ using Perspex.Media;
+
+ public interface ITextService
+ {
+ int GetCaretIndex(FormattedText text, Point point, Size constraint);
+
+ Point GetCaretPosition(FormattedText text, int caretIndex, Size constraint);
+
+ double[] GetLineHeights(FormattedText text, Size constraint);
+
+ Size Measure(FormattedText text, Size constraint);
+ }
+}