Skip to content

Commit

Permalink
Merge pull request #767 from AvaloniaUI/kvantt-textbox-fixes
Browse files Browse the repository at this point in the history
TextBox fixes
  • Loading branch information
grokys authored Oct 14, 2016
2 parents 6be24be + 85f0727 commit 081f940
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 108 deletions.
18 changes: 8 additions & 10 deletions src/Avalonia.Controls/TextBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

SelectionEnd = StringUtils.NextWord(text, index, false);
SelectionEnd = StringUtils.NextWord(text, index);
break;
case 3:
SelectionStart = 0;
Expand Down Expand Up @@ -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) - caretIndex;
}
else
{
CaretIndex += StringUtils.PreviousWord(text, caretIndex, false) - caretIndex;
CaretIndex += StringUtils.PreviousWord(text, caretIndex) - caretIndex;
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -820,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<UndoRedoState>.IUndoRedoHost.UndoRedoState
Expand Down
118 changes: 24 additions & 94 deletions src/Avalonia.Controls/Utils/StringUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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--;
}
Expand All @@ -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;

Expand All @@ -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;
Expand Down
9 changes: 5 additions & 4 deletions tests/Avalonia.Controls.UnitTests/TextBoxTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 081f940

Please sign in to comment.