Browse Source

Add IsUndoEnabled to TextBox

pull/6023/head
Deadpikle 5 years ago
parent
commit
6763337e25
  1. 87
      src/Avalonia.Controls/TextBox.cs

87
src/Avalonia.Controls/TextBox.cs

@ -119,9 +119,9 @@ namespace Avalonia.Controls
AvaloniaProperty.Register<TextBox, bool>(nameof(RevealPassword)); AvaloniaProperty.Register<TextBox, bool>(nameof(RevealPassword));
public static readonly DirectProperty<TextBox, bool> CanCutProperty = public static readonly DirectProperty<TextBox, bool> CanCutProperty =
AvaloniaProperty.RegisterDirect<TextBox, bool>( AvaloniaProperty.RegisterDirect<TextBox, bool>(
nameof(CanCut), nameof(CanCut),
o => o.CanCut); o => o.CanCut);
public static readonly DirectProperty<TextBox, bool> CanCopyProperty = public static readonly DirectProperty<TextBox, bool> CanCopyProperty =
AvaloniaProperty.RegisterDirect<TextBox, bool>( AvaloniaProperty.RegisterDirect<TextBox, bool>(
@ -129,9 +129,14 @@ namespace Avalonia.Controls
o => o.CanCopy); o => o.CanCopy);
public static readonly DirectProperty<TextBox, bool> CanPasteProperty = public static readonly DirectProperty<TextBox, bool> CanPasteProperty =
AvaloniaProperty.RegisterDirect<TextBox, bool>( AvaloniaProperty.RegisterDirect<TextBox, bool>(
nameof(CanPaste), nameof(CanPaste),
o => o.CanPaste); o => o.CanPaste);
public static readonly StyledProperty<bool> IsUndoEnabledProperty =
AvaloniaProperty.Register<TextBox, bool>(
nameof(IsUndoEnabled),
defaultValue: true);
struct UndoRedoState : IEquatable<UndoRedoState> struct UndoRedoState : IEquatable<UndoRedoState>
{ {
@ -218,7 +223,7 @@ namespace Avalonia.Controls
value = CoerceCaretIndex(value); value = CoerceCaretIndex(value);
SetAndRaise(CaretIndexProperty, ref _caretIndex, value); SetAndRaise(CaretIndexProperty, ref _caretIndex, value);
UndoRedoState state; UndoRedoState state;
if (_undoRedoHelper.TryGetLastState(out state) && state.Text == Text) if (IsUndoEnabled && _undoRedoHelper.TryGetLastState(out state) && state.Text == Text)
_undoRedoHelper.UpdateLastState(); _undoRedoHelper.UpdateLastState();
} }
} }
@ -316,7 +321,7 @@ namespace Avalonia.Controls
SelectionEnd = CoerceCaretIndex(SelectionEnd, value); SelectionEnd = CoerceCaretIndex(SelectionEnd, value);
CaretIndex = CoerceCaretIndex(caretIndex, value); CaretIndex = CoerceCaretIndex(caretIndex, value);
if (SetAndRaise(TextProperty, ref _text, value) && !_isUndoingRedoing) if (SetAndRaise(TextProperty, ref _text, value) && IsUndoEnabled && !_isUndoingRedoing)
{ {
_undoRedoHelper.Clear(); _undoRedoHelper.Clear();
} }
@ -329,7 +334,7 @@ namespace Avalonia.Controls
get { return GetSelection(); } get { return GetSelection(); }
set set
{ {
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))
{ {
DeleteSelection(); DeleteSelection();
@ -338,7 +343,7 @@ namespace Avalonia.Controls
{ {
HandleTextInput(value); HandleTextInput(value);
} }
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
} }
} }
@ -446,6 +451,27 @@ namespace Avalonia.Controls
private set { SetAndRaise(CanPasteProperty, ref _canPaste, value); } private set { SetAndRaise(CanPasteProperty, ref _canPaste, value); }
} }
/// <summary>
/// Property for determining whether undo/redo is enabled
/// </summary>
public bool IsUndoEnabled
{
get { return GetValue(IsUndoEnabledProperty); }
set
{
SetValue(IsUndoEnabledProperty, value);
if (value == false)
{
// from docs at
// https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.primitives.textboxbase.isundoenabled:
// "Setting this property to false clears the undo stack.
// Therefore, if you disable undo and then re-enable it, undo commands still do not work
// because the undo stack was emptied when you disabled undo."
_undoRedoHelper.Clear();
}
}
}
protected override void OnApplyTemplate(TemplateAppliedEventArgs e) protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{ {
_presenter = e.NameScope.Get<TextPresenter>("PART_TextPresenter"); _presenter = e.NameScope.Get<TextPresenter>("PART_TextPresenter");
@ -551,7 +577,10 @@ namespace Avalonia.Controls
SetTextInternal(text.Substring(0, caretIndex) + input + text.Substring(caretIndex)); SetTextInternal(text.Substring(0, caretIndex) + input + text.Substring(caretIndex));
CaretIndex += input.Length; CaretIndex += input.Length;
ClearSelection(); ClearSelection();
_undoRedoHelper.DiscardRedo(); if (IsUndoEnabled)
{
_undoRedoHelper.DiscardRedo();
}
} }
} }
@ -570,10 +599,10 @@ namespace Avalonia.Controls
var text = GetSelection(); var text = GetSelection();
if (text is null) return; if (text is null) return;
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
Copy(); Copy();
DeleteSelection(); DeleteSelection();
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
} }
public async void Copy() public async void Copy()
@ -591,9 +620,9 @@ namespace Avalonia.Controls
if (text is null) return; if (text is null) return;
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
HandleTextInput(text); HandleTextInput(text);
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
} }
protected override void OnKeyDown(KeyEventArgs e) protected override void OnKeyDown(KeyEventArgs e)
@ -638,7 +667,7 @@ namespace Avalonia.Controls
Paste(); Paste();
handled = true; handled = true;
} }
else if (Match(keymap.Undo)) else if (Match(keymap.Undo) && IsUndoEnabled)
{ {
try try
{ {
@ -652,7 +681,7 @@ namespace Avalonia.Controls
handled = true; handled = true;
} }
else if (Match(keymap.Redo)) else if (Match(keymap.Redo) && IsUndoEnabled)
{ {
try try
{ {
@ -752,7 +781,7 @@ namespace Avalonia.Controls
break; break;
case Key.Back: case Key.Back:
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
if (hasWholeWordModifiers && SelectionStart == SelectionEnd) if (hasWholeWordModifiers && SelectionStart == SelectionEnd)
{ {
SetSelectionForControlBackspace(); SetSelectionForControlBackspace();
@ -776,13 +805,13 @@ namespace Avalonia.Controls
CaretIndex -= removedCharacters; CaretIndex -= removedCharacters;
ClearSelection(); ClearSelection();
} }
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
handled = true; handled = true;
break; break;
case Key.Delete: case Key.Delete:
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
if (hasWholeWordModifiers && SelectionStart == SelectionEnd) if (hasWholeWordModifiers && SelectionStart == SelectionEnd)
{ {
SetSelectionForControlDelete(); SetSelectionForControlDelete();
@ -804,7 +833,7 @@ namespace Avalonia.Controls
SetTextInternal(text.Substring(0, caretIndex) + SetTextInternal(text.Substring(0, caretIndex) +
text.Substring(caretIndex + removedCharacters)); text.Substring(caretIndex + removedCharacters));
} }
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
handled = true; handled = true;
break; break;
@ -812,9 +841,9 @@ namespace Avalonia.Controls
case Key.Enter: case Key.Enter:
if (AcceptsReturn) if (AcceptsReturn)
{ {
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
HandleTextInput(NewLine); HandleTextInput(NewLine);
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
handled = true; handled = true;
} }
@ -823,9 +852,9 @@ namespace Avalonia.Controls
case Key.Tab: case Key.Tab:
if (AcceptsTab) if (AcceptsTab)
{ {
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
HandleTextInput("\t"); HandleTextInput("\t");
_undoRedoHelper.Snapshot(); SnapshotUndoRedo();
handled = true; handled = true;
} }
else else
@ -1251,5 +1280,13 @@ namespace Avalonia.Controls
ClearSelection(); ClearSelection();
} }
} }
private void SnapshotUndoRedo()
{
if (IsUndoEnabled)
{
_undoRedoHelper.Snapshot();
}
}
} }
} }

Loading…
Cancel
Save