Browse Source

Draw selected TextBox text white.

pull/12/head
Steven Kirk 12 years ago
parent
commit
aef071ec8d
  1. 5
      Cairo/Perspex.Cairo/Media/FormattedTextImpl.cs
  2. 35
      Perspex.Controls/TextBlock.cs
  3. 17
      Perspex.Controls/TextBoxView.cs
  4. 5
      Perspex.SceneGraph/Media/FormattedText.cs
  5. 2
      Perspex.SceneGraph/Platform/IFormattedTextImpl.cs
  6. 15
      Windows/Perspex.Direct2D1/Media/BrushWrapper.cs
  7. 8
      Windows/Perspex.Direct2D1/Media/DrawingContext.cs
  8. 7
      Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs
  9. 97
      Windows/Perspex.Direct2D1/Media/PerspexTextRenderer.cs
  10. 2
      Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj

5
Cairo/Perspex.Cairo/Media/FormattedTextImpl.cs

@ -98,5 +98,10 @@ namespace Perspex.Cairo.Media
this.Layout.GetPixelSize(out width, out height);
return new Size(width, height);
}
public void SetForegroundBrush(Brush brush, int startIndex, int count)
{
// TODO: Implement.
}
}
}

35
Perspex.Controls/TextBlock.cs

@ -43,13 +43,7 @@ namespace Perspex.Controls
this.GetObservable(FontStyleProperty).Select(_ => Unit.Default))
.Subscribe(_ =>
{
if (this.formattedText != null)
{
this.formattedText.Dispose();
this.formattedText = null;
}
this.InvalidateMeasure();
this.InvalidateFormattedText();
});
}
@ -89,18 +83,13 @@ namespace Perspex.Controls
{
if (this.formattedText == null)
{
this.formattedText = new FormattedText(
this.Text,
this.FontFamily,
this.FontSize,
this.FontStyle);
this.formattedText = this.CreateFormattedText();
}
return this.formattedText;
}
}
public override void Render(IDrawingContext context)
{
Brush background = this.Background;
@ -113,6 +102,26 @@ namespace Perspex.Controls
context.DrawText(this.Foreground, new Point(), this.FormattedText);
}
protected virtual FormattedText CreateFormattedText()
{
return new FormattedText(
this.Text,
this.FontFamily,
this.FontSize,
this.FontStyle);
}
protected void InvalidateFormattedText()
{
if (this.formattedText != null)
{
this.formattedText.Dispose();
this.formattedText = null;
}
this.InvalidateMeasure();
}
protected override Size MeasureOverride(Size availableSize)
{
if (!string.IsNullOrEmpty(this.Text))

17
Perspex.Controls/TextBoxView.cs

@ -31,7 +31,7 @@ namespace Perspex.Controls
Observable.Merge(
this.parent.GetObservable(TextBox.SelectionStartProperty),
this.parent.GetObservable(TextBox.SelectionEndProperty))
.Subscribe(_ => this.InvalidateVisual());
.Subscribe(_ => this.InvalidateFormattedText());
parent.GetObservable(TextBox.CaretIndexProperty).Subscribe(_ => this.CaretMoved());
}
@ -95,6 +95,21 @@ namespace Perspex.Controls
}
}
protected override FormattedText CreateFormattedText()
{
var result = base.CreateFormattedText();
var selectionStart = this.parent.SelectionStart;
var selectionEnd = this.parent.SelectionEnd;
var start = Math.Min(selectionStart, selectionEnd);
var length = Math.Max(selectionStart, selectionEnd) - start;
if (length > 0)
{
result.SetForegroundBrush(Brushes.White, start, length);
}
return result;
}
internal void CaretMoved()
{
this.caretBlink = true;

5
Perspex.SceneGraph/Media/FormattedText.cs

@ -93,5 +93,10 @@ namespace Perspex.Media
{
return this.PlatformImpl.Measure();
}
public void SetForegroundBrush(Brush brush, int startIndex, int count)
{
this.PlatformImpl.SetForegroundBrush(brush, startIndex, count);
}
}
}

2
Perspex.SceneGraph/Platform/IFormattedTextImpl.cs

@ -23,5 +23,7 @@ namespace Perspex.Platform
IEnumerable<Rect> HitTestTextRange(int index, int length, Point origin);
Size Measure();
void SetForegroundBrush(Brush brush, int startIndex, int count);
}
}

15
Windows/Perspex.Direct2D1/Media/BrushWrapper.cs

@ -0,0 +1,15 @@
namespace Perspex.Direct2D1.Media
{
using Perspex.Media;
using SharpDX;
internal class BrushWrapper : ComObject
{
public BrushWrapper(Brush brush)
{
this.Brush = brush;
}
public Brush Brush { get; private set; }
}
}

8
Windows/Perspex.Direct2D1/Media/DrawingContext.cs

@ -8,7 +8,6 @@ namespace Perspex.Direct2D1.Media
{
using System;
using System.Reactive.Disposables;
using Perspex.Direct2D1.Media;
using Perspex.Media;
using SharpDX;
using SharpDX.Direct2D1;
@ -142,12 +141,9 @@ namespace Perspex.Direct2D1.Media
{
var impl = (FormattedTextImpl)text.PlatformImpl;
using (var brush = foreground.ToDirect2D(this.renderTarget))
using (var renderer = new PerspexTextRenderer(this.renderTarget, foreground.ToDirect2D(this.renderTarget)))
{
this.renderTarget.DrawTextLayout(
origin.ToSharpDX(),
impl.TextLayout,
brush);
impl.TextLayout.Draw(renderer, (float)origin.X, (float)origin.Y);
}
}
}

7
Windows/Perspex.Direct2D1/Media/FormattedTextImpl.cs

@ -113,5 +113,12 @@ namespace Perspex.Direct2D1.Media
this.TextLayout.Metrics.WidthIncludingTrailingWhitespace,
this.TextLayout.Metrics.Height);
}
public void SetForegroundBrush(Brush brush, int startIndex, int count)
{
this.TextLayout.SetDrawingEffect(
new BrushWrapper(brush),
new DWrite.TextRange(startIndex, count));
}
}
}

97
Windows/Perspex.Direct2D1/Media/PerspexTextRenderer.cs

@ -0,0 +1,97 @@
// -----------------------------------------------------------------------
// <copyright file="PerspexTextRenderer.cs" company="Steven Kirk">
// Copyright 2013 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Direct2D1.Media
{
using System;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.DirectWrite;
internal class PerspexTextRenderer : TextRenderer
{
private RenderTarget renderTarget;
private Brush foreground;
public PerspexTextRenderer(
RenderTarget target,
Brush foreground)
{
this.renderTarget = target;
this.foreground = foreground;
}
public IDisposable Shadow
{
get;
set;
}
public void Dispose()
{
this.foreground.Dispose();
}
public Result DrawGlyphRun(
object clientDrawingContext,
float baselineOriginX,
float baselineOriginY,
MeasuringMode measuringMode,
GlyphRun glyphRun,
GlyphRunDescription glyphRunDescription,
ComObject clientDrawingEffect)
{
var wrapper = clientDrawingEffect as BrushWrapper;
var brush = (wrapper == null) ?
this.foreground :
wrapper.Brush.ToDirect2D(this.renderTarget);
this.renderTarget.DrawGlyphRun(
new Vector2(baselineOriginX, baselineOriginY),
glyphRun,
brush,
measuringMode);
if (wrapper != null)
{
brush.Dispose();
}
return Result.Ok;
}
public Result DrawInlineObject(object clientDrawingContext, float originX, float originY, InlineObject inlineObject, bool isSideways, bool isRightToLeft, ComObject clientDrawingEffect)
{
throw new NotImplementedException();
}
public Result DrawStrikethrough(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref Strikethrough strikethrough, ComObject clientDrawingEffect)
{
throw new NotImplementedException();
}
public Result DrawUnderline(object clientDrawingContext, float baselineOriginX, float baselineOriginY, ref Underline underline, ComObject clientDrawingEffect)
{
throw new NotImplementedException();
}
public Matrix3x2 GetCurrentTransform(object clientDrawingContext)
{
return this.renderTarget.Transform;
}
public float GetPixelsPerDip(object clientDrawingContext)
{
return this.renderTarget.DotsPerInch.Width / 96;
}
public bool IsPixelSnappingDisabled(object clientDrawingContext)
{
return false;
}
}
}

2
Windows/Perspex.Direct2D1/Perspex.Direct2D1.csproj

@ -67,9 +67,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Direct2D1Platform.cs" />
<Compile Include="Media\BrushWrapper.cs" />
<Compile Include="Media\DrawingContext.cs" />
<Compile Include="Media\Imaging\RenderTargetBitmapImpl.cs" />
<Compile Include="Media\Imaging\BitmapImpl.cs" />
<Compile Include="Media\PerspexTextRenderer.cs" />
<Compile Include="Media\StreamGeometryContextImpl.cs" />
<Compile Include="Media\GeometryImpl.cs" />
<Compile Include="Media\StreamGeometryImpl.cs" />

Loading…
Cancel
Save