diff --git a/src/Avalonia.Controls/ISelectionModel.cs b/src/Avalonia.Controls/ISelectionModel.cs index f7283d9d79..6a8e469a8f 100644 --- a/src/Avalonia.Controls/ISelectionModel.cs +++ b/src/Avalonia.Controls/ISelectionModel.cs @@ -25,26 +25,20 @@ namespace Avalonia.Controls void ClearSelection(); void Deselect(int index); - void Deselect(int groupIndex, int itemIndex); - void DeselectAt(IndexPath index); + void Deselect(IndexPath index); void DeselectRange(IndexPath start, IndexPath end); void DeselectRangeFromAnchor(int index); - void DeselectRangeFromAnchor(int endGroupIndex, int endItemIndex); - void DeselectRangeFromAnchorTo(IndexPath index); + void DeselectRangeFromAnchor(IndexPath index); void Dispose(); - bool? IsSelected(int index); - bool? IsSelected(int groupIndex, int itemIndex); - bool? IsSelectedAt(IndexPath index); + bool IsSelected(int index); + bool IsSelected(IndexPath index); + bool? IsTreeSelected(IndexPath index); void Select(int index); - void Select(int groupIndex, int itemIndex); + void Select(IndexPath index); void SelectAll(); - void SelectAt(IndexPath index); void SelectRange(IndexPath start, IndexPath end); void SelectRangeFromAnchor(int index); - void SelectRangeFromAnchor(int endGroupIndex, int endItemIndex); - void SelectRangeFromAnchorTo(IndexPath index); - void SetAnchorIndex(int index); - void SetAnchorIndex(int groupIndex, int index); + void SelectRangeFromAnchor(IndexPath index); IDisposable Update(); } } diff --git a/src/Avalonia.Controls/SelectionModel.cs b/src/Avalonia.Controls/SelectionModel.cs index de33f08c1e..09431b356c 100644 --- a/src/Avalonia.Controls/SelectionModel.cs +++ b/src/Avalonia.Controls/SelectionModel.cs @@ -174,9 +174,7 @@ namespace Avalonia.Controls } set { - var isSelected = IsSelectedAt(value); - - if (isSelected != true || SelectedItems.Count > 1) + if (!IsSelected(value) || SelectedItems.Count > 1) { using var operation = new Operation(this); ClearSelection(resetAnchor: true); @@ -351,23 +349,13 @@ namespace Avalonia.Controls _selectedItemsCached = null; } - public void SetAnchorIndex(int index) => AnchorIndex = new IndexPath(index); - - public void SetAnchorIndex(int groupIndex, int index) => AnchorIndex = new IndexPath(groupIndex, index); - public void Select(int index) { using var operation = new Operation(this); SelectImpl(index, select: true); } - public void Select(int groupIndex, int itemIndex) - { - using var operation = new Operation(this); - SelectWithGroupImpl(groupIndex, itemIndex, select: true); - } - - public void SelectAt(IndexPath index) + public void Select(IndexPath index) { using var operation = new Operation(this); SelectWithPathImpl(index, select: true); @@ -380,55 +368,35 @@ namespace Avalonia.Controls ApplyAutoSelect(); } - public void Deselect(int groupIndex, int itemIndex) - { - using var operation = new Operation(this); - SelectWithGroupImpl(groupIndex, itemIndex, select: false); - ApplyAutoSelect(); - } - - public void DeselectAt(IndexPath index) + public void Deselect(IndexPath index) { using var operation = new Operation(this); SelectWithPathImpl(index, select: false); ApplyAutoSelect(); } - public bool? IsSelected(int index) - { - if (index < 0) - { - throw new ArgumentException("Index must be >= 0", nameof(index)); - } + public bool IsSelected(int index) => _rootNode.IsSelected(index); - var isSelected = _rootNode.IsSelectedWithPartial(index); - return isSelected; - } - - public bool? IsSelected(int groupIndex, int itemIndex) + public bool IsSelected(IndexPath index) { - if (groupIndex < 0) - { - throw new ArgumentException("Group index must be >= 0", nameof(groupIndex)); - } + var path = index; + SelectionNode? node = _rootNode; - if (itemIndex < 0) + for (int i = 0; i < path.GetSize() - 1; i++) { - throw new ArgumentException("Item index must be >= 0", nameof(itemIndex)); - } - - var isSelected = (bool?)false; - var childNode = _rootNode.GetAt(groupIndex, realizeChild: false); + var childIndex = path.GetAt(i); + node = node.GetAt(childIndex, realizeChild: false); - if (childNode != null) - { - isSelected = childNode.IsSelectedWithPartial(itemIndex); + if (node == null) + { + return false; + } } - return isSelected; + return node.IsSelected(index.GetAt(index.GetSize() - 1)); } - public bool? IsSelectedAt(IndexPath index) + public bool? IsTreeSelected(IndexPath index) { var path = index; var isRealized = true; @@ -470,13 +438,7 @@ namespace Avalonia.Controls SelectRangeFromAnchorImpl(index, select: true); } - public void SelectRangeFromAnchor(int endGroupIndex, int endItemIndex) - { - using var operation = new Operation(this); - SelectRangeFromAnchorWithGroupImpl(endGroupIndex, endItemIndex, select: true); - } - - public void SelectRangeFromAnchorTo(IndexPath index) + public void SelectRangeFromAnchor(IndexPath index) { using var operation = new Operation(this); SelectRangeImpl(AnchorIndex, index, select: true); @@ -487,14 +449,8 @@ namespace Avalonia.Controls using var operation = new Operation(this); SelectRangeFromAnchorImpl(index, select: false); } - - public void DeselectRangeFromAnchor(int endGroupIndex, int endItemIndex) - { - using var operation = new Operation(this); - SelectRangeFromAnchorWithGroupImpl(endGroupIndex, endItemIndex, false /* select */); - } - - public void DeselectRangeFromAnchorTo(IndexPath index) + + public void DeselectRangeFromAnchor(IndexPath index) { using var operation = new Operation(this); SelectRangeImpl(AnchorIndex, index, select: false); @@ -650,22 +606,6 @@ namespace Avalonia.Controls } } - private void SelectWithGroupImpl(int groupIndex, int itemIndex, bool select) - { - if (_singleSelect) - { - ClearSelection(resetAnchor: true); - } - - var childNode = _rootNode.GetAt(groupIndex, realizeChild: true); - var selected = childNode!.Select(itemIndex, select); - - if (selected) - { - AnchorIndex = new IndexPath(groupIndex, itemIndex); - } - } - private void SelectWithPathImpl(IndexPath index, bool select) { bool selected = false; @@ -707,39 +647,6 @@ namespace Avalonia.Controls _rootNode.SelectRange(new IndexRange(anchorIndex, index), select); } - private void SelectRangeFromAnchorWithGroupImpl(int endGroupIndex, int endItemIndex, bool select) - { - var startGroupIndex = 0; - var startItemIndex = 0; - var anchorIndex = AnchorIndex; - - if (anchorIndex != null) - { - startGroupIndex = anchorIndex.GetAt(0); - startItemIndex = anchorIndex.GetAt(1); - } - - // Make sure start > end - if (startGroupIndex > endGroupIndex || - (startGroupIndex == endGroupIndex && startItemIndex > endItemIndex)) - { - int temp = startGroupIndex; - startGroupIndex = endGroupIndex; - endGroupIndex = temp; - temp = startItemIndex; - startItemIndex = endItemIndex; - endItemIndex = temp; - } - - for (int groupIdx = startGroupIndex; groupIdx <= endGroupIndex; groupIdx++) - { - var groupNode = _rootNode.GetAt(groupIdx, realizeChild: true)!; - int startIndex = groupIdx == startGroupIndex ? startItemIndex : 0; - int endIndex = groupIdx == endGroupIndex ? endItemIndex : groupNode.DataCount - 1; - groupNode.SelectRange(new IndexRange(startIndex, endIndex), select); - } - } - private void SelectRangeImpl(IndexPath start, IndexPath end, bool select) { var winrtStart = start; diff --git a/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs b/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs index fa193466ae..94e8100634 100644 --- a/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs +++ b/tests/Avalonia.Controls.UnitTests/SelectionModelTests.cs @@ -476,7 +476,7 @@ namespace Avalonia.Controls.UnitTests var selectionModel = new SelectionModel(); selectionModel.Source = data; - selectionModel.Select(1, 1); + selectionModel.Select(new IndexPath(1, 1)); ValidateSelection(selectionModel, new List() { @@ -593,8 +593,8 @@ namespace Avalonia.Controls.UnitTests var selectionModel = new SelectionModel(); selectionModel.Source = data; - selectionModel.Select(1, 1); - selectionModel.Select(1, 2); + selectionModel.Select(new IndexPath(1, 1)); + selectionModel.Select(new IndexPath(1, 2)); ValidateSelection(selectionModel, new List() { @@ -688,7 +688,7 @@ namespace Avalonia.Controls.UnitTests var selectionModel = new SelectionModel(); selectionModel.Source = data; - selectionModel.Select(1, 1); + selectionModel.Select(new IndexPath(1, 1)); ValidateSelection(selectionModel, new List() { @@ -743,7 +743,7 @@ namespace Avalonia.Controls.UnitTests var selectionModel = new SelectionModel(); selectionModel.Source = data; - selectionModel.Select(1, 1); + selectionModel.Select(new IndexPath(1, 1)); ValidateSelection(selectionModel, new List() { @@ -776,9 +776,9 @@ namespace Avalonia.Controls.UnitTests selectionModel.Source = data; selectionModel.SelectionChanged += (sender, args) => { selectionChangedRaised = true; }; - selectionModel.Select(1, 0); - selectionModel.Select(1, 1); - selectionModel.Select(1, 2); + selectionModel.Select(new IndexPath(1, 0)); + selectionModel.Select(new IndexPath(1, 1)); + selectionModel.Select(new IndexPath(1, 2)); ValidateSelection(selectionModel, new List() { @@ -1034,13 +1034,13 @@ namespace Avalonia.Controls.UnitTests ++raised; }; - target.Select(1, 1); + target.Select(new IndexPath(1, 1)); Assert.Equal(1, raised); } [Fact] - public void SelectAt_Raises_SelectionChanged() + public void Select_Path_Raises_SelectionChanged() { var target = new SelectionModel(); var raised = 0; @@ -1055,7 +1055,7 @@ namespace Avalonia.Controls.UnitTests ++raised; }; - target.SelectAt(new IndexPath(1, 1)); + target.Select(new IndexPath(1, 1)); Assert.Equal(1, raised); } @@ -1147,7 +1147,7 @@ namespace Avalonia.Controls.UnitTests }; target.AnchorIndex = new IndexPath(1, 1); - target.SelectRangeFromAnchor(1, 6); + target.SelectRangeFromAnchor(new IndexPath(1, 6)); Assert.Equal(1, raised); } @@ -1170,7 +1170,7 @@ namespace Avalonia.Controls.UnitTests }; target.AnchorIndex = new IndexPath(1, 1); - target.SelectRangeFromAnchorTo(new IndexPath(1, 6)); + target.SelectRangeFromAnchor(new IndexPath(1, 6)); Assert.Equal(1, raised); } @@ -1207,7 +1207,7 @@ namespace Avalonia.Controls.UnitTests var raised = 0; target.Source = CreateNestedData(1, 2, 3); - target.Select(1, 1); + target.Select(new IndexPath(1, 1)); target.SelectionChanged += (s, e) => { @@ -1958,11 +1958,11 @@ namespace Avalonia.Controls.UnitTests Log.Comment((select ? "Selecting " : "DeSelecting ") + groupIndex + "." + itemIndex); if (select) { - manager.Select(groupIndex, itemIndex); + manager.Select(new IndexPath(groupIndex, itemIndex)); } else { - manager.Deselect(groupIndex, itemIndex); + manager.Deselect(new IndexPath(groupIndex, itemIndex)); } } @@ -1971,11 +1971,11 @@ namespace Avalonia.Controls.UnitTests Log.Comment((select ? "Selecting " : "DeSelecting ") + index); if (select) { - manager.SelectAt(index); + manager.Select(index); } else { - manager.DeselectAt(index); + manager.Deselect(index); } } @@ -1997,11 +1997,11 @@ namespace Avalonia.Controls.UnitTests Log.Comment("SelectRangeFromAnchor " + groupIndex + "." + itemIndex + " select:" + select.ToString()); if (select) { - manager.SelectRangeFromAnchor(groupIndex, itemIndex); + manager.SelectRangeFromAnchor(new IndexPath(groupIndex, itemIndex)); } else { - manager.DeselectRangeFromAnchor(groupIndex, itemIndex); + manager.DeselectRangeFromAnchor(new IndexPath(groupIndex, itemIndex)); } } @@ -2010,11 +2010,11 @@ namespace Avalonia.Controls.UnitTests Log.Comment("SelectRangeFromAnchor " + index + " select: " + select.ToString()); if (select) { - manager.SelectRangeFromAnchorTo(index); + manager.SelectRangeFromAnchor(index); } else { - manager.DeselectRangeFromAnchorTo(index); + manager.DeselectRangeFromAnchor(index); } } @@ -2027,13 +2027,13 @@ namespace Avalonia.Controls.UnitTests private void SetAnchorIndex(SelectionModel manager, int index) { Log.Comment("SetAnchorIndex " + index); - manager.SetAnchorIndex(index); + manager.AnchorIndex = new IndexPath(index); } private void SetAnchorIndex(SelectionModel manager, int groupIndex, int itemIndex) { Log.Comment("SetAnchor " + groupIndex + "." + itemIndex); - manager.SetAnchorIndex(groupIndex, itemIndex); + manager.AnchorIndex = new IndexPath(groupIndex, itemIndex); } private void SetAnchorIndex(SelectionModel manager, IndexPath index) @@ -2067,7 +2067,7 @@ namespace Avalonia.Controls.UnitTests List allIndices = GetIndexPathsInSource(selectionModel.Source); foreach (var index in allIndices) { - bool? isSelected = selectionModel.IsSelectedAt(index); + bool? isSelected = selectionModel.IsTreeSelected(index); if (Contains(expectedSelected, index)) { Assert.True(isSelected.Value, index + " is Selected"); @@ -2094,7 +2094,7 @@ namespace Avalonia.Controls.UnitTests { foreach (var index in expectedSelected) { - Assert.True(selectionModel.IsSelectedAt(index).Value, index + " is Selected"); + Assert.True(selectionModel.IsTreeSelected(index).Value, index + " is Selected"); } } if (expectedSelected.Count > 0)