Browse Source
Merge branch 'master' into fixes/2003-treeview-autoscroll
pull/2782/head
Steven Kirk
7 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with
59 additions and
6 deletions
-
src/Avalonia.Controls/Generators/ItemContainerGenerator.cs
-
src/Avalonia.Controls/Primitives/SelectingItemsControl.cs
-
src/Avalonia.Controls/TopLevel.cs
-
src/Avalonia.Input/IMouseDevice.cs
-
src/Avalonia.Input/InputExtensions.cs
-
src/Avalonia.Input/MouseDevice.cs
-
src/Avalonia.Visuals/Rect.cs
-
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests_AutoSelect.cs
-
tests/Avalonia.Controls.UnitTests/TopLevelTests.cs
|
|
|
@ -128,6 +128,12 @@ namespace Avalonia.Controls.Generators |
|
|
|
} |
|
|
|
|
|
|
|
Dematerialized?.Invoke(this, new ItemContainerEventArgs(startingIndex, result)); |
|
|
|
|
|
|
|
if (toMove.Count > 0) |
|
|
|
{ |
|
|
|
var containers = toMove.Select(x => x.Value).ToList(); |
|
|
|
Recycled?.Invoke(this, new ItemContainerEventArgs(containers[0].Index, containers)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
|
|
|
|
@ -979,13 +979,14 @@ namespace Avalonia.Controls.Primitives |
|
|
|
} |
|
|
|
|
|
|
|
var item = ElementAt(Items, index); |
|
|
|
var itemChanged = !Equals(item, oldItem); |
|
|
|
var added = -1; |
|
|
|
HashSet<int> removed = null; |
|
|
|
|
|
|
|
_selectedIndex = index; |
|
|
|
_selectedItem = item; |
|
|
|
|
|
|
|
if (oldIndex != index || _selection.HasMultiple) |
|
|
|
if (oldIndex != index || itemChanged || _selection.HasMultiple) |
|
|
|
{ |
|
|
|
if (clear) |
|
|
|
{ |
|
|
|
@ -1022,7 +1023,7 @@ namespace Avalonia.Controls.Primitives |
|
|
|
index); |
|
|
|
} |
|
|
|
|
|
|
|
if (!Equals(item, oldItem)) |
|
|
|
if (itemChanged) |
|
|
|
{ |
|
|
|
RaisePropertyChanged( |
|
|
|
SelectedItemProperty, |
|
|
|
|
|
|
|
@ -269,8 +269,8 @@ namespace Avalonia.Controls |
|
|
|
/// </summary>
|
|
|
|
protected virtual void HandleClosed() |
|
|
|
{ |
|
|
|
(this as IInputRoot).MouseDevice?.TopLevelClosed(this); |
|
|
|
PlatformImpl = null; |
|
|
|
|
|
|
|
Closed?.Invoke(this, EventArgs.Empty); |
|
|
|
Renderer?.Dispose(); |
|
|
|
Renderer = null; |
|
|
|
|
|
|
|
@ -16,6 +16,8 @@ namespace Avalonia.Input |
|
|
|
[Obsolete("Use PointerEventArgs.GetPosition")] |
|
|
|
PixelPoint Position { get; } |
|
|
|
|
|
|
|
void TopLevelClosed(IInputRoot root); |
|
|
|
|
|
|
|
void SceneInvalidated(IInputRoot root, Rect rect); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@ -13,6 +13,8 @@ namespace Avalonia.Input |
|
|
|
/// </summary>
|
|
|
|
public static class InputExtensions |
|
|
|
{ |
|
|
|
private static readonly Func<IVisual, bool> s_hitTestDelegate = IsHitTestVisible; |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Returns the active input elements at a point on an <see cref="IInputElement"/>.
|
|
|
|
/// </summary>
|
|
|
|
@ -25,7 +27,7 @@ namespace Avalonia.Input |
|
|
|
{ |
|
|
|
Contract.Requires<ArgumentNullException>(element != null); |
|
|
|
|
|
|
|
return element.GetVisualsAt(p, IsHitTestVisible).Cast<IInputElement>(); |
|
|
|
return element.GetVisualsAt(p, s_hitTestDelegate).Cast<IInputElement>(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
|
|
@ -86,6 +86,11 @@ namespace Avalonia.Input |
|
|
|
ProcessRawEvent(margs); |
|
|
|
} |
|
|
|
|
|
|
|
public void TopLevelClosed(IInputRoot root) |
|
|
|
{ |
|
|
|
ClearPointerOver(this, 0, root, PointerPointProperties.None, KeyModifiers.None); |
|
|
|
} |
|
|
|
|
|
|
|
public void SceneInvalidated(IInputRoot root, Rect rect) |
|
|
|
{ |
|
|
|
var clientPoint = root.PointToClient(Position); |
|
|
|
|
|
|
|
@ -371,12 +371,12 @@ namespace Avalonia |
|
|
|
/// <returns>The bounding box</returns>
|
|
|
|
public Rect TransformToAABB(Matrix matrix) |
|
|
|
{ |
|
|
|
var points = new[] |
|
|
|
ReadOnlySpan<Point> points = stackalloc Point[4] |
|
|
|
{ |
|
|
|
TopLeft.Transform(matrix), |
|
|
|
TopRight.Transform(matrix), |
|
|
|
BottomRight.Transform(matrix), |
|
|
|
BottomLeft.Transform(matrix), |
|
|
|
BottomLeft.Transform(matrix) |
|
|
|
}; |
|
|
|
|
|
|
|
var left = double.MaxValue; |
|
|
|
|
|
|
|
@ -102,6 +102,25 @@ namespace Avalonia.Controls.UnitTests.Primitives |
|
|
|
Assert.Null(target.SelectedItem); |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void Removing_Selected_First_Item_Should_Select_Next_Item() |
|
|
|
{ |
|
|
|
var items = new AvaloniaList<string>(new[] { "foo", "bar" }); |
|
|
|
var target = new TestSelector |
|
|
|
{ |
|
|
|
Items = items, |
|
|
|
Template = Template(), |
|
|
|
}; |
|
|
|
|
|
|
|
target.ApplyTemplate(); |
|
|
|
target.Presenter.ApplyTemplate(); |
|
|
|
items.RemoveAt(0); |
|
|
|
|
|
|
|
Assert.Equal(0, target.SelectedIndex); |
|
|
|
Assert.Equal("bar", target.SelectedItem); |
|
|
|
Assert.Equal(new[] { ":selected" }, target.Presenter.Panel.Children[0].Classes); |
|
|
|
} |
|
|
|
|
|
|
|
private FuncControlTemplate Template() |
|
|
|
{ |
|
|
|
return new FuncControlTemplate<SelectingItemsControl>((control, scope) => |
|
|
|
|
|
|
|
@ -224,6 +224,24 @@ namespace Avalonia.Controls.UnitTests |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void Close_Should_Notify_MouseDevice() |
|
|
|
{ |
|
|
|
using (UnitTestApplication.Start(TestServices.StyledWindow)) |
|
|
|
{ |
|
|
|
var impl = new Mock<ITopLevelImpl>(); |
|
|
|
var mouseDevice = new Mock<IMouseDevice>(); |
|
|
|
impl.SetupAllProperties(); |
|
|
|
impl.Setup(x => x.MouseDevice).Returns(mouseDevice.Object); |
|
|
|
|
|
|
|
var target = new TestTopLevel(impl.Object); |
|
|
|
|
|
|
|
impl.Object.Closed(); |
|
|
|
|
|
|
|
mouseDevice.Verify(x => x.TopLevelClosed(target)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private FuncControlTemplate<TestTopLevel> CreateTemplate() |
|
|
|
{ |
|
|
|
return new FuncControlTemplate<TestTopLevel>((x, scope) => |
|
|
|
|