|
|
|
@ -1,5 +1,6 @@ |
|
|
|
using System; |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Data; |
|
|
|
using System.Linq; |
|
|
|
using Avalonia.Controls.Documents; |
|
|
|
using Avalonia.Controls.Utils; |
|
|
|
@ -32,6 +33,9 @@ namespace Avalonia.Controls |
|
|
|
public static readonly StyledProperty<IBrush?> SelectionBrushProperty = |
|
|
|
TextBox.SelectionBrushProperty.AddOwner<SelectableTextBlock>(); |
|
|
|
|
|
|
|
public static readonly StyledProperty<IBrush?> SelectionForegroundBrushProperty = |
|
|
|
TextBox.SelectionForegroundBrushProperty.AddOwner<SelectableTextBlock>(); |
|
|
|
|
|
|
|
public static readonly DirectProperty<SelectableTextBlock, bool> CanCopyProperty = |
|
|
|
TextBox.CanCopyProperty.AddOwner<SelectableTextBlock>(o => o.CanCopy); |
|
|
|
|
|
|
|
@ -63,6 +67,15 @@ namespace Avalonia.Controls |
|
|
|
set => SetValue(SelectionBrushProperty, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets a brush that is used for the foreground of selected text
|
|
|
|
/// </summary>
|
|
|
|
public IBrush? SelectionForegroundBrush |
|
|
|
{ |
|
|
|
get => GetValue(SelectionForegroundBrushProperty); |
|
|
|
set => SetValue(SelectionForegroundBrushProperty, value); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets a character index for the beginning of the current selection.
|
|
|
|
/// </summary>
|
|
|
|
@ -167,6 +180,58 @@ namespace Avalonia.Controls |
|
|
|
UpdateCommandStates(); |
|
|
|
} |
|
|
|
|
|
|
|
protected override TextLayout CreateTextLayout(string? text) |
|
|
|
{ |
|
|
|
var typeface = new Typeface(FontFamily, FontStyle, FontWeight, FontStretch); |
|
|
|
|
|
|
|
var defaultProperties = new GenericTextRunProperties( |
|
|
|
typeface, |
|
|
|
FontSize, |
|
|
|
TextDecorations, |
|
|
|
Foreground); |
|
|
|
|
|
|
|
var paragraphProperties = new GenericTextParagraphProperties(FlowDirection, TextAlignment, true, false, |
|
|
|
defaultProperties, TextWrapping, LineHeight, 0, LetterSpacing) |
|
|
|
{ |
|
|
|
LineSpacing = LineSpacing |
|
|
|
}; |
|
|
|
|
|
|
|
IReadOnlyList<ValueSpan<TextRunProperties>>? textStyleOverrides = null; |
|
|
|
var selectionStart = SelectionStart; |
|
|
|
var selectionEnd = SelectionEnd; |
|
|
|
var start = Math.Min(selectionStart, selectionEnd); |
|
|
|
var length = Math.Max(selectionStart, selectionEnd) - start; |
|
|
|
|
|
|
|
if (length > 0 && SelectionForegroundBrush != null) |
|
|
|
{ |
|
|
|
textStyleOverrides = new[] |
|
|
|
{ |
|
|
|
new ValueSpan<TextRunProperties>(start, length, |
|
|
|
new GenericTextRunProperties(typeface, FontSize, |
|
|
|
foregroundBrush: SelectionForegroundBrush)) |
|
|
|
}; |
|
|
|
} |
|
|
|
|
|
|
|
ITextSource textSource; |
|
|
|
|
|
|
|
if (_textRuns != null) |
|
|
|
{ |
|
|
|
textSource = new InlinesTextSource(_textRuns, textStyleOverrides); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
textSource = new FormattedTextSource(text ?? "", defaultProperties, textStyleOverrides); |
|
|
|
} |
|
|
|
|
|
|
|
return new TextLayout( |
|
|
|
textSource, |
|
|
|
paragraphProperties, |
|
|
|
TextTrimming, |
|
|
|
_constraint.Width, |
|
|
|
_constraint.Height, |
|
|
|
MaxLines); |
|
|
|
} |
|
|
|
|
|
|
|
protected override void RenderTextLayout(DrawingContext context, Point origin) |
|
|
|
{ |
|
|
|
var selectionStart = SelectionStart; |
|
|
|
@ -220,10 +285,17 @@ namespace Avalonia.Controls |
|
|
|
{ |
|
|
|
base.OnPropertyChanged(change); |
|
|
|
|
|
|
|
if (change.Property == SelectionStartProperty || change.Property == SelectionEndProperty) |
|
|
|
if (change.Property == SelectionStartProperty || |
|
|
|
change.Property == SelectionEndProperty) |
|
|
|
{ |
|
|
|
RaisePropertyChanged(SelectedTextProperty, "", ""); |
|
|
|
UpdateCommandStates(); |
|
|
|
InvalidateTextLayout(); |
|
|
|
} |
|
|
|
|
|
|
|
if(change.Property == SelectionForegroundBrushProperty) |
|
|
|
{ |
|
|
|
InvalidateTextLayout(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|