From 8eea7fb4bc0e185a58506c92b044d40c4b125d85 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Mon, 3 Oct 2016 16:54:13 +0300 Subject: [PATCH 1/4] fixes #686: "End" key works incorrectly in TextBox. --- src/Avalonia.Controls/TextBox.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index ed92899cc69..0ae73da96f7 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -718,6 +718,10 @@ private void MoveEnd(InputModifiers modifiers) if (pos < text.Length) { --pos; + if (pos > 0 && Text[pos - 1] == '\r' && Text[pos] == '\n') + { + --pos; + } } break; From f940456d3e4587690db28cced85a61a791f67010 Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Wed, 5 Oct 2016 18:40:56 +0300 Subject: [PATCH 2/4] gtkMode = true by default in NextWord and PreviousWord methods. --- src/Avalonia.Controls/TextBox.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 0ae73da96f7..60ac1b5e3b9 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -495,10 +495,10 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) case 2: if (!StringUtils.IsStartOfWord(text, index)) { - SelectionStart = StringUtils.PreviousWord(text, index, false); + SelectionStart = StringUtils.PreviousWord(text, index, true); } - SelectionEnd = StringUtils.NextWord(text, index, false); + SelectionEnd = StringUtils.NextWord(text, index, true); break; case 3: SelectionStart = 0; @@ -638,11 +638,11 @@ private void MoveHorizontal(int direction, InputModifiers modifiers) { if (direction > 0) { - CaretIndex += StringUtils.NextWord(text, caretIndex, false) - caretIndex; + CaretIndex += StringUtils.NextWord(text, caretIndex, true) - caretIndex; } else { - CaretIndex += StringUtils.PreviousWord(text, caretIndex, false) - caretIndex; + CaretIndex += StringUtils.PreviousWord(text, caretIndex, true) - caretIndex; } } } From af696acc697eb74bdc26377891927e437f58190d Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 14 Oct 2016 17:51:59 +0200 Subject: [PATCH 3/4] Removed gtkMode from Next/PreviousWord. As we always want this behaviour. --- src/Avalonia.Controls/TextBox.cs | 8 +- src/Avalonia.Controls/Utils/StringUtils.cs | 118 +++++---------------- 2 files changed, 28 insertions(+), 98 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 60ac1b5e3b9..cd3dd0d0988 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -495,10 +495,10 @@ protected override void OnPointerPressed(PointerPressedEventArgs e) case 2: if (!StringUtils.IsStartOfWord(text, index)) { - SelectionStart = StringUtils.PreviousWord(text, index, true); + SelectionStart = StringUtils.PreviousWord(text, index); } - SelectionEnd = StringUtils.NextWord(text, index, true); + SelectionEnd = StringUtils.NextWord(text, index); break; case 3: SelectionStart = 0; @@ -638,11 +638,11 @@ private void MoveHorizontal(int direction, InputModifiers modifiers) { if (direction > 0) { - CaretIndex += StringUtils.NextWord(text, caretIndex, true) - caretIndex; + CaretIndex += StringUtils.NextWord(text, caretIndex) - caretIndex; } else { - CaretIndex += StringUtils.PreviousWord(text, caretIndex, true) - caretIndex; + CaretIndex += StringUtils.PreviousWord(text, caretIndex) - caretIndex; } } } diff --git a/src/Avalonia.Controls/Utils/StringUtils.cs b/src/Avalonia.Controls/Utils/StringUtils.cs index 8571d663f5c..2304866a85e 100644 --- a/src/Avalonia.Controls/Utils/StringUtils.cs +++ b/src/Avalonia.Controls/Utils/StringUtils.cs @@ -57,7 +57,7 @@ public static bool IsStartOfWord(string text, int index) } } - public static int PreviousWord(string text, int cursor, bool gtkMode) + public static int PreviousWord(string text, int cursor) { int begin; int i; @@ -81,60 +81,21 @@ public static int PreviousWord(string text, int cursor, bool gtkMode) return (cr > 0) ? cr : 0; } - if (gtkMode) - { - CharClass cc = GetCharClass(text[cursor - 1]); - begin = lf + 1; - i = cursor; - - // skip over the word, punctuation, or run of whitespace - while (i > begin && GetCharClass(text[i - 1]) == cc) - { - i--; - } + CharClass cc = GetCharClass(text[cursor - 1]); + begin = lf + 1; + i = cursor; - // if the cursor was at whitespace, skip back a word too - if (cc == CharClass.CharClassWhitespace && i > begin) - { - cc = GetCharClass(text[i - 1]); - while (i > begin && GetCharClass(text[i - 1]) == cc) - { - i--; - } - } - } - else + // skip over the word, punctuation, or run of whitespace + while (i > begin && GetCharClass(text[i - 1]) == cc) { - begin = lf + 1; - i = cursor; - - if (cursor < text.Length) - { - // skip to the beginning of this word - while (i > begin && !char.IsWhiteSpace(text[i - 1])) - { - i--; - } - - if (i < cursor && IsStartOfWord(text, i)) - { - return i; - } - } - - // skip to the start of the lwsp - while (i > begin && char.IsWhiteSpace(text[i - 1])) - { - i--; - } - - if (i > begin) - { - i--; - } + i--; + } - // skip to the beginning of the word - while (i > begin && !IsStartOfWord(text, i)) + // if the cursor was at whitespace, skip back a word too + if (cc == CharClass.CharClassWhitespace && i > begin) + { + cc = GetCharClass(text[i - 1]); + while (i > begin && GetCharClass(text[i - 1]) == cc) { i--; } @@ -143,7 +104,7 @@ public static int PreviousWord(string text, int cursor, bool gtkMode) return i; } - public static int NextWord(string text, int cursor, bool gtkMode) + public static int NextWord(string text, int cursor) { int i, lf, cr; @@ -169,50 +130,19 @@ public static int NextWord(string text, int cursor, bool gtkMode) return cursor; } - if (gtkMode) - { - CharClass cc = GetCharClass(text[cursor]); - i = cursor; - - // skip over the word, punctuation, or run of whitespace - while (i < cr && GetCharClass(text[i]) == cc) - { - i++; - } + CharClass cc = GetCharClass(text[cursor]); + i = cursor; - // skip any whitespace after the word/punct - while (i < cr && char.IsWhiteSpace(text[i])) - { - i++; - } - } - else + // skip over the word, punctuation, or run of whitespace + while (i < cr && GetCharClass(text[i]) == cc) { - i = cursor; - - // skip any whitespace before the word - while (i < cr && char.IsWhiteSpace(text[i])) - { - i++; - } - - // skip to the end of the current word - while (i < cr && !char.IsWhiteSpace(text[i])) - { - i++; - } - - // skip any whitespace after the word - while (i < cr && char.IsWhiteSpace(text[i])) - { - i++; - } + i++; + } - // find the start of the next word - while (i < cr && !IsStartOfWord(text, i)) - { - i++; - } + // skip any whitespace after the word/punct + while (i < cr && char.IsWhiteSpace(text[i])) + { + i++; } return i; From 85f07274d434b11d9aa722a491c2286fcf0791d7 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Fri, 14 Oct 2016 18:18:04 +0200 Subject: [PATCH 4/4] Fixed failing test. --- src/Avalonia.Controls/TextBox.cs | 6 ------ tests/Avalonia.Controls.UnitTests/TextBoxTests.cs | 9 +++++---- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index ea4d6b1f227..7a271e8615d 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -824,12 +824,6 @@ private void SetSelectionForControlDelete(InputModifiers modifiers) SelectionStart = CaretIndex; MoveHorizontal(1, modifiers); SelectionEnd = CaretIndex; - - string selection = GetSelection(); - if (selection != " " && selection.EndsWith(" ")) - { - SelectionEnd = CaretIndex - 1; - } } UndoRedoState UndoRedoHelper.IUndoRedoHost.UndoRedoState diff --git a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs index 851657ab6c4..cff49bc32e4 100644 --- a/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TextBoxTests.cs @@ -175,24 +175,25 @@ public void Control_Delete_Should_Remove_The_Word_After_The_Caret_If_There_Is_No RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); Assert.Equal("First Second Third ", textBox.Text); - // (First Second| Third ) - textBox.CaretIndex = 12; + // (First Second |Third ) + textBox.CaretIndex = 13; RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); Assert.Equal("First Second ", textBox.Text); // (First Sec|ond ) textBox.CaretIndex = 9; RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); - Assert.Equal("First Sec ", textBox.Text); + Assert.Equal("First Sec", textBox.Text); // (Fi[rs]t Sec ) textBox.SelectionStart = 2; textBox.SelectionEnd = 4; RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); - Assert.Equal("Fit Sec ", textBox.Text); + Assert.Equal("Fit Sec", textBox.Text); // (Fit Sec| ) + textBox.Text += " "; textBox.CaretIndex = 7; RaiseKeyEvent(textBox, Key.Delete, InputModifiers.Control); Assert.Equal("Fit Sec", textBox.Text);