Browse Source

Display (not-yet-blinking) caret in TextBox.

pull/4/head
Steven Kirk 12 years ago
parent
commit
cfbc5d19f6
  1. 10
      Perspex.Direct2D1/Direct2D1Platform.cs
  2. 19
      Perspex.Direct2D1/Media/DrawingContext.cs
  3. 5
      Perspex.Direct2D1/PrimitiveExtensions.cs
  4. 40
      Perspex.Direct2D1/TextService.cs
  5. 10
      Perspex.Windows/Input/WindowsMouseDevice.cs
  6. 8
      Perspex/Controls/TextBox.cs
  7. 42
      Perspex/Controls/TextBoxView.cs
  8. 2
      Perspex/Input/IPointerDevice.cs
  9. 16
      Perspex/Input/MouseDevice.cs
  10. 5
      Perspex/Input/PointerEventArgs.cs
  11. 3
      Perspex/Media/FormattedText.cs
  12. 8
      Perspex/Media/IDrawingContext.cs
  13. 4
      Perspex/Platform/IPlatformInterface.cs
  14. 4
      Perspex/Platform/ITextService.cs
  15. 1
      Perspex/Themes/Default/TextBoxStyle.cs

10
Perspex.Direct2D1/Direct2D1Platform.cs

@ -32,6 +32,11 @@ namespace Perspex.Direct2D1
locator.Register(() => imagingFactory, typeof(SharpDX.WIC.ImagingFactory));
}
public ITextService TextService
{
get { return textService; }
}
public IBitmapImpl CreateBitmap(int width, int height)
{
return new BitmapImpl(imagingFactory, width, height);
@ -51,10 +56,5 @@ namespace Perspex.Direct2D1
{
return new StreamGeometryImpl();
}
public ITextService GetTextService()
{
return textService;
}
}
}

19
Perspex.Direct2D1/Media/DrawingContext.cs

@ -51,6 +51,23 @@ namespace Perspex.Direct2D1.Media
this.renderTarget.EndDraw();
}
/// <summary>
/// Draws a line.
/// </summary>
/// <param name="pen">The stroke pen.</param>
/// <param name="p1">The first point of the line.</param>
/// <param name="p1">The second point of the line.</param>
public void DrawLine(Pen pen, Perspex.Point p1, Perspex.Point p2)
{
if (pen != null)
{
using (SharpDX.Direct2D1.SolidColorBrush d2dBrush = this.Convert(pen.Brush))
{
this.renderTarget.DrawLine(p1.ToSharpDX(), p2.ToSharpDX(), d2dBrush);
}
}
}
/// <summary>
/// Draws a geometry.
/// </summary>
@ -105,7 +122,7 @@ namespace Perspex.Direct2D1.Media
if (!string.IsNullOrEmpty(text.Text))
{
using (SharpDX.Direct2D1.SolidColorBrush brush = this.Convert(foreground))
using (SharpDX.DirectWrite.TextFormat format = TextService.Convert(this.directWriteFactory, text))
using (SharpDX.DirectWrite.TextFormat format = TextService.GetTextFormat(this.directWriteFactory, text))
{
this.renderTarget.DrawText(
text.Text,

5
Perspex.Direct2D1/PrimitiveExtensions.cs

@ -6,11 +6,6 @@
namespace Perspex.Direct2D1
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SharpDX;
public static class PrimitiveExtensions

40
Perspex.Direct2D1/TextService.cs

@ -6,6 +6,7 @@
namespace Perspex.Direct2D1
{
using System;
using Perspex.Media;
using Perspex.Platform;
using SharpDX.DirectWrite;
@ -19,7 +20,7 @@ namespace Perspex.Direct2D1
this.factory = factory;
}
public static TextFormat Convert(Factory factory, FormattedText text)
public static TextFormat GetTextFormat(Factory factory, FormattedText text)
{
return new TextFormat(
factory,
@ -27,10 +28,43 @@ namespace Perspex.Direct2D1
(float)text.FontSize);
}
public TextLayout GetTextLayout(Factory factory, FormattedText text)
{
return new TextLayout(
factory,
text.Text,
GetTextFormat(factory, text),
float.MaxValue,
float.MaxValue);
}
public int GetCaretIndex(FormattedText text, Point point)
{
TextLayout layout = GetTextLayout(this.factory, text);
SharpDX.Bool isTrailingHit;
SharpDX.Bool isInside;
HitTestMetrics result = layout.HitTestPoint(
(float)point.X,
(float)point.Y,
out isTrailingHit,
out isInside);
return result.TextPosition + (isTrailingHit ? 1 : 0);
}
public Point GetCaretPosition(FormattedText text, int caretIndex)
{
TextLayout layout = GetTextLayout(this.factory, text);
float x;
float y;
layout.HitTestTextPosition(caretIndex, false, out x, out y);
return new Point(x, y);
}
public Size Measure(FormattedText text)
{
TextFormat f = Convert(this.factory, text);
TextLayout layout = new TextLayout(this.factory, text.Text, f, float.MaxValue, float.MaxValue);
TextLayout layout = GetTextLayout(this.factory, text);
return new Size(
layout.Metrics.WidthIncludingTrailingWhitespace,
layout.Metrics.Height);

10
Perspex.Windows/Input/WindowsMouseDevice.cs

@ -6,7 +6,9 @@
namespace Perspex.Windows.Input
{
using System;
using Perspex.Input;
using Perspex.Windows.Interop;
public class WindowsMouseDevice : MouseDevice
{
@ -28,6 +30,14 @@ namespace Perspex.Windows.Input
get { return base.Position; }
internal set { base.Position = value; }
}
protected override Point GetClientPosition()
{
UnmanagedMethods.POINT p;
UnmanagedMethods.GetCursorPos(out p);
UnmanagedMethods.ScreenToClient(this.CurrentWindow.Handle, ref p);
return new Point(p.X, p.Y);
}
}
}

8
Perspex/Controls/TextBox.cs

@ -123,10 +123,10 @@ namespace Perspex.Controls
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));
IPlatformInterface platform = Locator.Current.GetService<IPlatformInterface>();
this.CaretIndex = platform.TextService.GetCaretIndex(
this.textBoxView.FormattedText,
e.GetPosition(this.textBoxView));
}
}
}

42
Perspex/Controls/TextBoxView.cs

@ -9,6 +9,8 @@ namespace Perspex.Controls
using System;
using System.Globalization;
using Perspex.Media;
using Perspex.Platform;
using Splat;
internal class TextBoxView : Control
{
@ -73,32 +75,20 @@ namespace Perspex.Controls
context.DrawText(Brushes.Black, rect, this.FormattedText);
//if (this.parent.IsKeyboardFocused)
//{
// Point caretPos = this.FormattedText.GetCaretPosition(this.parent.CaretIndex);
// Brush caretBrush = this.parent.CaretBrush;
// if (caretBrush == null)
// {
// Color color = Colors.Black;
// SolidColorBrush background = this.parent.Background as SolidColorBrush;
// if (background != null)
// {
// color = Color.FromUInt32(0x00ffffffu ^ background.Color.ToUint32());
// }
// caretBrush = new SolidColorBrush(color);
// }
// if (this.caretBlink)
// {
// drawingContext.DrawLine(
// new Pen(caretBrush, 1),
// caretPos,
// caretPos + new Vector(0, this.FormattedText.Height));
// }
//}
if (this.parent.IsFocused)
{
IPlatformInterface platform = Locator.Current.GetService<IPlatformInterface>();
Point caretPos = platform.TextService.GetCaretPosition(this.formattedText, this.parent.CaretIndex);
Brush caretBrush = Brushes.Black;
//if (!this.caretBlink)
{
context.DrawLine(
new Pen(caretBrush, 1),
caretPos,
new Point(caretPos.X, caretPos.Y + this.FormattedText.Size.Height));
}
}
}
protected override Size MeasureOverride(Size constraint)

2
Perspex/Input/IPointerDevice.cs

@ -13,5 +13,7 @@ namespace Perspex.Input
Interactive Captured { get; }
void Capture(Interactive visual);
Point GetPosition(IVisual relativeTo);
}
}

16
Perspex/Input/MouseDevice.cs

@ -45,6 +45,22 @@ namespace Perspex.Input
this.Captured = visual;
}
public Point GetPosition(IVisual relativeTo)
{
Point p = this.GetClientPosition();
IVisual v = relativeTo;
while (v != null)
{
p -= v.Bounds.Position;
v = v.VisualParent;
}
return p;
}
protected abstract Point GetClientPosition();
private void ProcessRawEvent(RawMouseEventArgs e)
{
this.Position = e.Position;

5
Perspex/Input/PointerEventArgs.cs

@ -11,5 +11,10 @@ namespace Perspex.Input
public class PointerEventArgs : RoutedEventArgs
{
public IPointerDevice Device { get; set; }
public Point GetPosition(IVisual relativeTo)
{
return this.Device.GetPosition(relativeTo);
}
}
}

3
Perspex/Media/FormattedText.cs

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

8
Perspex/Media/IDrawingContext.cs

@ -13,6 +13,14 @@ namespace Perspex.Media
/// </summary>
public interface IDrawingContext : IDisposable
{
/// <summary>
/// Draws a line.
/// </summary>
/// <param name="pen">The stroke pen.</param>
/// <param name="p1">The first point of the line.</param>
/// <param name="p1">The second point of the line.</param>
void DrawLine(Pen pen, Point p1, Point p2);
/// <summary>
/// Draws a geometry.
/// </summary>

4
Perspex/Platform/IPlatformInterface.cs

@ -10,6 +10,8 @@ namespace Perspex.Platform
public interface IPlatformInterface
{
ITextService TextService { get; }
IBitmapImpl CreateBitmap(int width, int height);
IStreamGeometryImpl CreateStreamGeometry();
@ -17,7 +19,5 @@ namespace Perspex.Platform
IRenderer CreateRenderer(IntPtr handle, double width, double height);
IRenderTargetBitmapImpl CreateRenderTargetBitmap(int width, int height);
ITextService GetTextService();
}
}

4
Perspex/Platform/ITextService.cs

@ -11,5 +11,9 @@ namespace Perspex.Platform
public interface ITextService
{
Size Measure(FormattedText text);
int GetCaretIndex(FormattedText text, Point point);
Point GetCaretPosition(FormattedText text, int caretIndex);
}
}

1
Perspex/Themes/Default/TextBoxStyle.cs

@ -43,6 +43,7 @@ namespace Perspex.Themes.Default
Border result = new Border
{
Id = "border",
Padding = new Thickness(2),
[~Border.BackgroundProperty] = control[~TextBox.BackgroundProperty],
[~Border.BorderBrushProperty] = control[~TextBox.BorderBrushProperty],
[~Border.BorderThicknessProperty] = control[~TextBox.BorderThicknessProperty],

Loading…
Cancel
Save