@ -316,8 +316,13 @@ namespace Avalonia.Controls
private bool _ canRedo ;
private int _ wordSelectionStart = - 1 ;
private bool _ touchDragStarted ;
private bool _ inTouchDrag ;
private Point _ touchDragStartPoint ;
private int _ selectedTextChangesMadeSinceLastUndoSnapshot ;
private bool _ hasDoneSnapshotOnce ;
private static bool _ isHolding ;
private int _ currentClickCount ;
private const int _ maxCharsBeforeUndoSnapshot = 7 ;
static TextBox ( )
@ -821,6 +826,16 @@ namespace Avalonia.Controls
_ presenter . PropertyChanged + = PresenterPropertyChanged ;
}
AddHandler ( Gestures . HoldingEvent , OnHolding ) ;
}
private void OnHolding ( object? sender , HoldingRoutedEventArgs e )
{
if ( e . Handled | | e . HoldingState ! = HoldingState . Started )
return ;
_ isHolding = true ;
}
protected override void OnDetachedFromVisualTree ( VisualTreeAttachmentEventArgs e )
@ -835,6 +850,8 @@ namespace Avalonia.Controls
}
_ imClient . SetPresenter ( null , null ) ;
RemoveHandler ( Gestures . HoldingEvent , OnHolding ) ;
}
private void PresenterPropertyChanged ( object? sender , AvaloniaPropertyChangedEventArgs e )
@ -1456,8 +1473,21 @@ namespace Avalonia.Controls
if ( text ! = null & & clickInfo . Properties . IsLeftButtonPressed & &
! ( clickInfo . Pointer ? . Captured is Border ) )
{
var isTouch = e . Pointer . Type = = PointerType . Touch ;
_ currentClickCount = e . ClickCount ;
var point = e . GetPosition ( _ presenter ) ;
if ( isTouch & & e . ClickCount = = 1 )
{
_ wordSelectionStart = - 1 ;
_ touchDragStarted = true ;
_ touchDragStartPoint = point ;
e . Pointer . Capture ( _ presenter ) ;
e . Handled = true ;
return ;
}
_ presenter . MoveCaretToPoint ( point ) ;
var caretIndex = _ presenter . CaretIndex ;
@ -1491,7 +1521,6 @@ namespace Avalonia.Controls
break ;
case 2 :
if ( ! StringUtils . IsStartOfWord ( text , caretIndex ) )
{
selectionStart = StringUtils . PreviousWord ( text , caretIndex ) ;
@ -1525,7 +1554,7 @@ namespace Avalonia.Controls
protected override void OnPointerMoved ( PointerEventArgs e )
{
if ( _ presenter = = null )
if ( _ presenter = = null | | _ isHolding )
{
return ;
}
@ -1539,6 +1568,16 @@ namespace Avalonia.Controls
MathUtilities . Clamp ( point . X , 0 , Math . Max ( _ presenter . Bounds . Width - 1 , 0 ) ) ,
MathUtilities . Clamp ( point . Y , 0 , Math . Max ( _ presenter . Bounds . Height - 1 , 0 ) ) ) ;
if ( _ touchDragStarted )
{
_ touchDragStarted = false ;
_ inTouchDrag = true ;
_ presenter . MoveCaretToPoint ( _ touchDragStartPoint ) ;
_ touchDragStartPoint = default ;
SetCurrentValue ( SelectionStartProperty , _ presenter . CaretIndex ) ;
}
_ presenter . MoveCaretToPoint ( point ) ;
var caretIndex = _ presenter . CaretIndex ;
@ -1593,12 +1632,23 @@ namespace Avalonia.Controls
return ;
}
_ touchDragStarted = false ;
_ touchDragStartPoint = default ;
var isInTouchDrag = _ inTouchDrag ;
_ inTouchDrag = false ;
if ( e . Pointer . Captured ! = _ presenter )
{
return ;
}
if ( e . InitialPressMouseButton = = MouseButton . Right )
// Don't update selection if the pointer was held
if ( _ isHolding )
{
_ isHolding = false ;
}
else if ( e . InitialPressMouseButton = = MouseButton . Right )
{
var point = e . GetPosition ( _ presenter ) ;
@ -1619,6 +1669,24 @@ namespace Avalonia.Controls
SetCurrentValue ( SelectionStartProperty , caretIndex ) ;
}
}
else if ( e . Pointer . Type = = PointerType . Touch )
{
if ( _ currentClickCount = = 1 & & ! isInTouchDrag )
{
var point = e . GetPosition ( _ presenter ) ;
_ presenter . MoveCaretToPoint ( point ) ;
var caretIndex = _ presenter . CaretIndex ;
SetCurrentValue ( SelectionStartProperty , caretIndex ) ;
SetCurrentValue ( SelectionEndProperty , caretIndex ) ;
}
if ( SelectionStart ! = SelectionEnd )
{
RaiseEvent ( new ContextRequestedEventArgs ( e ) ) ;
}
}
e . Pointer . Capture ( null ) ;
}