Browse Source

Fix the 4rd hardest problem in computer science.

Off by one errors.
pull/11519/head
Steven Kirk 3 years ago
committed by Steven Kirk
parent
commit
a8b14fd29c
  1. 2
      src/Avalonia.Controls/Automation/Peers/TextBoxAutomationPeer.cs
  2. 8
      src/Avalonia.Controls/Automation/Provider/TextRange.cs
  3. 38
      src/Windows/Avalonia.Win32/Automation/AutomationTextRange.cs

2
src/Avalonia.Controls/Automation/Peers/TextBoxAutomationPeer.cs

@ -63,7 +63,7 @@ namespace Avalonia.Automation.Peers
public IReadOnlyList<TextRange> GetSelection() public IReadOnlyList<TextRange> GetSelection()
{ {
var range = TextRange.FromInclusiveStartEnd(Owner.SelectionStart, Owner.SelectionEnd); var range = TextRange.FromStartEnd(Owner.SelectionStart, Owner.SelectionEnd);
return new[] { range }; return new[] { range };
} }

8
src/Avalonia.Controls/Automation/Provider/TextRange.cs

@ -45,12 +45,12 @@ namespace Avalonia.Automation.Provider
public static TextRange Empty => new(0, 0); public static TextRange Empty => new(0, 0);
/// <summary> /// <summary>
/// Creates a new <see cref="TextRange"/> from an inclusive start and end index. /// Creates a new <see cref="TextRange"/> from an exclusive start and end index.
/// </summary> /// </summary>
/// <param name="start">The inclusive start index of the range.</param> /// <param name="start">The exclusive start index of the range.</param>
/// <param name="end">The inclusive end index of the range.</param> /// <param name="end">The exclusive end index of the range.</param>
/// <returns></returns> /// <returns></returns>
public static TextRange FromInclusiveStartEnd(int start, int end) public static TextRange FromStartEnd(int start, int end)
{ {
var s = Math.Min(start, end); var s = Math.Min(start, end);
var e = Math.Max(start, end); var e = Math.Max(start, end);

38
src/Windows/Avalonia.Win32/Automation/AutomationTextRange.cs

@ -12,6 +12,8 @@ namespace Avalonia.Win32.Automation
internal class AutomationTextRange : ITextRangeProvider internal class AutomationTextRange : ITextRangeProvider
{ {
private readonly AutomationNode _owner; private readonly AutomationNode _owner;
private int _start;
private int _end;
public AutomationTextRange(AutomationNode owner, TextRange range) public AutomationTextRange(AutomationNode owner, TextRange range)
: this(owner, range.Start, range.End) : this(owner, range.Start, range.End)
@ -21,13 +23,37 @@ namespace Avalonia.Win32.Automation
public AutomationTextRange(AutomationNode owner, int start, int end) public AutomationTextRange(AutomationNode owner, int start, int end)
{ {
_owner = owner; _owner = owner;
Start = start; _start = start;
End = end; _end = end;
}
public int Start
{
get => _start;
private set
{
if (value < 0)
throw new InvalidOperationException();
if (value > _end)
_end = value;
_start = value;
}
}
public int End
{
get => _end;
private set
{
if (value < 0)
throw new InvalidOperationException();
if (value < _start)
_start = value;
_end = value;
}
} }
public int Start { get; private set; } public TextRange Range => new(Start, End);
public int End { get; private set; }
public TextRange Range => TextRange.FromInclusiveStartEnd(Start, End);
private AAP.ITextProvider InnerProvider => (AAP.ITextProvider)_owner.Peer; private AAP.ITextProvider InnerProvider => (AAP.ITextProvider)_owner.Peer;
@ -410,7 +436,7 @@ namespace Avalonia.Win32.Automation
case TextUnit.Word: case TextUnit.Word:
for (moved = 0; moved > count && index > 0; moved--) for (moved = 0; moved > count && index > 0; moved--)
{ {
for (index--; index < text.Length && IsWordBreak(text[index]); index--) for (index--; index >= 0 && IsWordBreak(text[index]); index--)
; ;
for (index--; !AtWordBoundary(text, index); index--) for (index--; !AtWordBoundary(text, index); index--)
; ;

Loading…
Cancel
Save