Skip to content

Commit

Permalink
Improving TextBox behaviour on Ctrl+Backspace down event (#14138)
Browse files Browse the repository at this point in the history
* Test: TextBox Ctrl+Back caret position

* Fixed: TextBox Ctrl+Back caret position

* Test: TextBox Ctrl+Back remove double whitespace

* Fixed: TextBox Ctrl+Back remove double whitespace

* Test: TextBox Ctrl+Back undo return caret position

* Fixed: TextBox Ctrl+Back undo return caret position
  • Loading branch information
exGensImpl authored and maxkatz6 committed Jan 17, 2024
1 parent dd0da02 commit 6b5a9a7
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 9 deletions.
28 changes: 19 additions & 9 deletions src/Avalonia.Controls/TextBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1275,13 +1275,13 @@ protected override void OnKeyDown(KeyEventArgs e)
{
case Key.Left:
selection = DetectSelection();
MoveHorizontal(-1, hasWholeWordModifiers, selection);
MoveHorizontal(-1, hasWholeWordModifiers, selection, true);
movement = true;
break;

case Key.Right:
selection = DetectSelection();
MoveHorizontal(1, hasWholeWordModifiers, selection);
MoveHorizontal(1, hasWholeWordModifiers, selection, true);
movement = true;
break;

Expand Down Expand Up @@ -1672,7 +1672,7 @@ internal static int CoerceCaretIndex(AvaloniaObject sender, int value)
/// </summary>
public void Clear() => SetCurrentValue(TextProperty, string.Empty);

private void MoveHorizontal(int direction, bool wholeWord, bool isSelecting)
private void MoveHorizontal(int direction, bool wholeWord, bool isSelecting, bool moveCaretPosition)
{
if (_presenter == null)
{
Expand Down Expand Up @@ -1727,10 +1727,13 @@ private void MoveHorizontal(int direction, bool wholeWord, bool isSelecting)
}

SetCurrentValue(SelectionEndProperty, SelectionEnd + offset);

if (moveCaretPosition)
{
_presenter.MoveCaretToTextPosition(SelectionEnd);
}

_presenter.MoveCaretToTextPosition(SelectionEnd);

if (!isSelecting)
if (!isSelecting && moveCaretPosition)
{
SetCurrentValue(CaretIndexProperty, SelectionEnd);
}
Expand Down Expand Up @@ -1867,7 +1870,7 @@ internal bool DeleteSelection()

_presenter?.MoveCaretToTextPosition(start);

SetCurrentValue(CaretIndexProperty, start);
SetCurrentValue(SelectionStartProperty, start);

ClearSelection();

Expand Down Expand Up @@ -1957,9 +1960,16 @@ private void RaiseTextChangeEvents()

private void SetSelectionForControlBackspace()
{
var text = Text ?? string.Empty;
var selectionStart = CaretIndex;

MoveHorizontal(-1, true, false);
MoveHorizontal(-1, true, false, false);

if (SelectionEnd > 0 &&
selectionStart < text.Length && text[selectionStart] == ' ')
{
SetCurrentValue(SelectionEndProperty, SelectionEnd - 1);
}

SetCurrentValue(SelectionStartProperty, selectionStart);
}
Expand All @@ -1974,7 +1984,7 @@ private void SetSelectionForControlDelete()

SetCurrentValue(SelectionStartProperty, CaretIndex);

MoveHorizontal(1, true, true);
MoveHorizontal(1, true, true, false);

if (SelectionEnd < textLength && Text![SelectionEnd] == ' ')
{
Expand Down
73 changes: 73 additions & 0 deletions tests/Avalonia.Controls.UnitTests/TextBoxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,79 @@ public void CaretIndex_Can_Moved_To_Position_After_The_End_Of_Text_With_Arrow_Ke
Assert.Equal(4, target.CaretIndex);
}
}

[Fact]
public void Control_Backspace_Should_Set_Caret_Position_To_The_Start_Of_The_Deletion()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
Template = CreateTemplate(),
Text = "First Second Third",
SelectionStart = 13,
SelectionEnd = 13
};

target.CaretIndex = 10;
target.ApplyTemplate();

// (First Second |Third)
RaiseKeyEvent(target, Key.Back, KeyModifiers.Control);
// (First |Third)

Assert.Equal(6, target.CaretIndex);
}
}

[Fact]
public void Control_Backspace_Should_Remove_The_Double_Whitespace_If_Caret_Index_Was_At_The_End_Of_A_Word()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
Template = CreateTemplate(),
Text = "First Second Third",
SelectionStart = 12,
SelectionEnd = 12
};

target.ApplyTemplate();

// (First Second| Third)
RaiseKeyEvent(target, Key.Back, KeyModifiers.Control);
// (First| Third)

Assert.Equal("First Third", target.Text);
}
}

[Fact]
public void Control_Backspace_Undo_Should_Return_Caret_Position()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
Template = CreateTemplate(),
Text = "First Second Third",
SelectionStart = 9,
SelectionEnd = 9
};

target.ApplyTemplate();

// (First Second| Third)
RaiseKeyEvent(target, Key.Back, KeyModifiers.Control);
// (First| Third)

target.Undo();
// (First Second| Third)

Assert.Equal(9, target.CaretIndex);
}
}

[Fact]
public void Press_Ctrl_A_Select_All_Text()
Expand Down

0 comments on commit 6b5a9a7

Please sign in to comment.