Browse Source

Merge pull request #9861 from Mikolaytis/TextDoubleClickSelect

[Text] [Selection] fix double click selection on word end position
pull/9879/head
Max Katz 4 years ago
committed by GitHub
parent
commit
3257f5fc50
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      src/Avalonia.Controls/SelectableTextBlock.cs
  2. 6
      src/Avalonia.Controls/TextBox.cs
  3. 49
      src/Avalonia.Controls/Utils/StringUtils.cs

6
src/Avalonia.Controls/SelectableTextBlock.cs

@ -300,7 +300,11 @@ namespace Avalonia.Controls
_wordSelectionStart = SelectionStart;
SelectionEnd = StringUtils.NextWord(text, index);
if (!StringUtils.IsEndOfWord(text, index))
{
SelectionEnd = StringUtils.NextWord(text, index);
}
break;
case 3:
_wordSelectionStart = -1;

6
src/Avalonia.Controls/TextBox.cs

@ -1475,7 +1475,11 @@ namespace Avalonia.Controls
_wordSelectionStart = SelectionStart;
SelectionEnd = StringUtils.NextWord(text, index);
if (!StringUtils.IsEndOfWord(text, index))
{
SelectionEnd = StringUtils.NextWord(text, index);
}
break;
case 3:
_wordSelectionStart = -1;

49
src/Avalonia.Controls/Utils/StringUtils.cs

@ -67,6 +67,55 @@ namespace Avalonia.Controls.Utils
}
}
public static bool IsEndOfWord(string text, int index)
{
if (index >= text.Length)
{
return true;
}
var codepoint = new Codepoint(text[index]);
if (!codepoint.IsWhiteSpace)
{
return false;
}
// A 'word' starts with an AlphaNumeric or some punctuation symbols immediately
// preceeded by lwsp.
if (index > 0)
{
var nextCodePoint = new Codepoint(text[index + 1]);
if (nextCodePoint.IsBreakChar)
{
return true;
}
}
switch (codepoint.GeneralCategory)
{
case GeneralCategory.LowercaseLetter:
case GeneralCategory.TitlecaseLetter:
case GeneralCategory.UppercaseLetter:
case GeneralCategory.DecimalNumber:
case GeneralCategory.LetterNumber:
case GeneralCategory.OtherNumber:
case GeneralCategory.DashPunctuation:
case GeneralCategory.InitialPunctuation:
case GeneralCategory.OpenPunctuation:
case GeneralCategory.CurrencySymbol:
case GeneralCategory.MathSymbol:
return false;
// TODO: How do you do this in .NET?
// case UnicodeCategory.OtherPunctuation:
// // words cannot start with '.', but they can start with '&' or '*' (for example)
// return g_unichar_break_type(buffer->text[index]) == G_UNICODE_BREAK_ALPHABETIC;
default:
return true;
}
}
public static int PreviousWord(string text, int cursor)
{
if (string.IsNullOrEmpty(text))

Loading…
Cancel
Save