Browse Source

Merge branch 'master' into fixes/702_textbox_tab_focus_select_all_text

pull/745/head
Steven Kirk 10 years ago
parent
commit
d5e220279f
  1. 5
      src/Avalonia.Controls/TextBox.cs
  2. 59
      src/Avalonia.Controls/Utils/UndoRedoHelper.cs
  3. 4
      src/Skia/Avalonia.Skia/FormattedTextImpl.cs
  4. 52
      tests/Avalonia.Controls.UnitTests/TextBoxTests.cs

5
src/Avalonia.Controls/TextBox.cs

@ -148,7 +148,8 @@ namespace Avalonia.Controls
{
value = CoerceCaretIndex(value);
SetAndRaise(CaretIndexProperty, ref _caretIndex, value);
if (_undoRedoHelper.IsLastState && _undoRedoHelper.LastState.Text == Text)
UndoRedoState state;
if (_undoRedoHelper.TryGetLastState(out state) && state.Text == Text)
_undoRedoHelper.UpdateLastState();
}
}
@ -732,7 +733,7 @@ namespace Avalonia.Controls
private void SelectAll()
{
SelectionStart = 0;
SelectionEnd = Text.Length;
SelectionEnd = Text?.Length ?? 0;
}
private bool DeleteSelection()

59
src/Avalonia.Controls/Utils/UndoRedoHelper.cs

@ -8,20 +8,19 @@ using Avalonia.Utilities;
namespace Avalonia.Controls.Utils
{
class UndoRedoHelper<TState> : WeakTimer.IWeakTimerSubscriber where TState : IEquatable<TState>
class UndoRedoHelper<TState> : WeakTimer.IWeakTimerSubscriber where TState : struct, IEquatable<TState>
{
private readonly IUndoRedoHost _host;
public interface IUndoRedoHost
{
TState UndoRedoState { get; set; }
TState UndoRedoState { get; set; }
}
private readonly LinkedList<TState> _states = new LinkedList<TState>();
[NotNull]
private LinkedListNode<TState> _currentNode;
public int Limit { get; set; } = 10;
@ -29,24 +28,31 @@ namespace Avalonia.Controls.Utils
public UndoRedoHelper(IUndoRedoHost host)
{
_host = host;
_states.AddFirst(_host.UndoRedoState);
_currentNode = _states.First;
WeakTimer.StartWeakTimer(this, new TimeSpan(0, 0, 1));
WeakTimer.StartWeakTimer(this, TimeSpan.FromSeconds(1));
}
public void Undo()
{
if (_currentNode?.Previous != null)
{
_currentNode = _currentNode.Previous;
}
_host.UndoRedoState = _currentNode.Value;
if (_currentNode?.Previous != null)
{
_currentNode = _currentNode.Previous;
_host.UndoRedoState = _currentNode.Value;
}
}
public bool IsLastState => _currentNode.Next == null;
public bool IsLastState => _currentNode != null && _currentNode.Next == null;
public bool TryGetLastState(out TState _state)
{
_state = default(TState);
if (!IsLastState)
return false;
_state = _currentNode.Value;
return true;
}
public bool HasState => _currentNode != null;
public void UpdateLastState(TState state)
{
_states.Last.Value = state;
@ -57,34 +63,31 @@ namespace Avalonia.Controls.Utils
_states.Last.Value = _host.UndoRedoState;
}
public TState LastState => _currentNode.Value;
public void DiscardRedo()
{
//Linked list sucks, so we are doing this
while (_currentNode.Next != null)
while (_currentNode?.Next != null)
_states.Remove(_currentNode.Next);
}
public void Redo()
{
if (_currentNode?.Next != null) {
_currentNode = _currentNode.Next;
}
_host.UndoRedoState = _currentNode.Value;
{
if (_currentNode?.Next != null)
{
_currentNode = _currentNode.Next;
_host.UndoRedoState = _currentNode.Value;
}
}
public void Snapshot()
{
var current = _host.UndoRedoState;
if (!_currentNode.Value.Equals(current))
if (_currentNode == null || !_currentNode.Value.Equals(current))
{
if(_currentNode.Next != null)
if (_currentNode?.Next != null)
DiscardRedo();
_states.AddLast(current);
_currentNode = _states.Last;
if(_states.Count > Limit)
if (_states.Count > Limit)
_states.RemoveFirst();
}
}

4
src/Skia/Avalonia.Skia/FormattedTextImpl.cs

@ -28,7 +28,9 @@ namespace Avalonia.Skia
//Paint.TextEncoding = SKTextEncoding.Utf8;
_paint.TextEncoding = SKTextEncoding.Utf16;
_paint.IsStroke = false;
_paint.IsAntialias = true;
_paint.IsAntialias = true;
_paint.LcdRenderText = true;
_paint.SubpixelText = true;
_paint.Typeface = typeface;
_paint.TextSize = (float)fontSize;
_paint.TextAlign = textAlignment.ToSKTextAlign();

52
tests/Avalonia.Controls.UnitTests/TextBoxTests.cs

@ -41,6 +41,58 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Press_Ctrl_A_Select_All_Text()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
Template = CreateTemplate(),
Text = "1234"
};
RaiseKeyEvent(target, Key.A, InputModifiers.Control);
Assert.Equal(0, target.SelectionStart);
Assert.Equal(4, target.SelectionEnd);
}
}
[Fact]
public void Press_Ctrl_A_Select_All_Null_Text()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
Template = CreateTemplate()
};
RaiseKeyEvent(target, Key.A, InputModifiers.Control);
Assert.Equal(0, target.SelectionStart);
Assert.Equal(0, target.SelectionEnd);
}
}
[Fact]
public void Press_Ctrl_Z_Will_Not_Modify_Text()
{
using (UnitTestApplication.Start(Services))
{
var target = new TextBox
{
Template = CreateTemplate(),
Text = "1234"
};
RaiseKeyEvent(target, Key.Z, InputModifiers.Control);
Assert.Equal("1234", target.Text);
}
}
[Fact]
public void Typing_Beginning_With_0_Should_Not_Modify_Text_When_Bound_To_Int()
{

Loading…
Cancel
Save