mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
ux: improve change list selection
This commit is contained in:
parent
2f5f98770f
commit
ef0c904e91
5 changed files with 132 additions and 88 deletions
|
@ -164,7 +164,7 @@ namespace SourceGit.Models
|
|||
|
||||
private void OnRepositoryChanged(object o, FileSystemEventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(e.Name))
|
||||
if (string.IsNullOrEmpty(e.Name) || e.Name.EndsWith(".lock", StringComparison.Ordinal))
|
||||
return;
|
||||
|
||||
var name = e.Name.Replace("\\", "/");
|
||||
|
|
|
@ -8,15 +8,18 @@ namespace SourceGit.ViewModels
|
|||
{
|
||||
public List<ChangeTreeNode> Tree { get; set; } = new List<ChangeTreeNode>();
|
||||
public AvaloniaList<ChangeTreeNode> Rows { get; set; } = new AvaloniaList<ChangeTreeNode>();
|
||||
public AvaloniaList<ChangeTreeNode> SelectedRows { get; set; } = new AvaloniaList<ChangeTreeNode>();
|
||||
}
|
||||
|
||||
public class ChangeCollectionAsGrid
|
||||
{
|
||||
public AvaloniaList<Models.Change> Changes { get; set; } = new AvaloniaList<Models.Change>();
|
||||
public AvaloniaList<Models.Change> SelectedChanges { get; set; } = new AvaloniaList<Models.Change>();
|
||||
}
|
||||
|
||||
public class ChangeCollectionAsList
|
||||
{
|
||||
public AvaloniaList<Models.Change> Changes { get; set; } = new AvaloniaList<Models.Change>();
|
||||
public AvaloniaList<Models.Change> SelectedChanges { get; set; } = new AvaloniaList<Models.Change>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -301,11 +301,13 @@ namespace SourceGit.ViewModels
|
|||
public void StageSelected()
|
||||
{
|
||||
StageChanges(_selectedUnstaged);
|
||||
SelectedUnstaged = [];
|
||||
}
|
||||
|
||||
public void StageAll()
|
||||
{
|
||||
StageChanges(_unstaged);
|
||||
SelectedUnstaged = [];
|
||||
}
|
||||
|
||||
public async void StageChanges(List<Models.Change> changes)
|
||||
|
@ -337,11 +339,13 @@ namespace SourceGit.ViewModels
|
|||
public void UnstageSelected()
|
||||
{
|
||||
UnstageChanges(_selectedStaged);
|
||||
SelectedStaged = [];
|
||||
}
|
||||
|
||||
public void UnstageAll()
|
||||
{
|
||||
UnstageChanges(_staged);
|
||||
SelectedStaged = [];
|
||||
}
|
||||
|
||||
public async void UnstageChanges(List<Models.Change> changes)
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<UserControl.DataTemplates>
|
||||
<DataTemplate DataType="vm:ChangeCollectionAsTree">
|
||||
<v:ChangeCollectionContainer ItemsSource="{Binding Rows}"
|
||||
SelectedItems="{Binding SelectedRows, Mode=TwoWay}"
|
||||
SelectionMode="{Binding #ThisControl.SelectionMode}"
|
||||
SelectionChanged="OnRowSelectionChanged">
|
||||
<ListBox.ItemTemplate>
|
||||
|
@ -65,6 +66,7 @@
|
|||
|
||||
<DataTemplate DataType="vm:ChangeCollectionAsGrid">
|
||||
<v:ChangeCollectionContainer ItemsSource="{Binding Changes}"
|
||||
SelectedItems="{Binding SelectedChanges, Mode=TwoWay}"
|
||||
SelectionMode="{Binding #ThisControl.SelectionMode}"
|
||||
SelectionChanged="OnRowSelectionChanged">
|
||||
<ListBox.ItemTemplate>
|
||||
|
@ -93,6 +95,7 @@
|
|||
|
||||
<DataTemplate DataType="vm:ChangeCollectionAsList">
|
||||
<v:ChangeCollectionContainer ItemsSource="{Binding Changes}"
|
||||
SelectedItems="{Binding SelectedChanges, Mode=TwoWay}"
|
||||
SelectionMode="{Binding #ThisControl.SelectionMode}"
|
||||
SelectionChanged="OnRowSelectionChanged">
|
||||
<ListBox.ItemTemplate>
|
||||
|
|
|
@ -6,6 +6,7 @@ using Avalonia.Controls;
|
|||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Threading;
|
||||
using Avalonia.VisualTree;
|
||||
|
||||
namespace SourceGit.Views
|
||||
|
@ -101,7 +102,7 @@ namespace SourceGit.Views
|
|||
|
||||
public void ToggleNodeIsExpanded(ViewModels.ChangeTreeNode node)
|
||||
{
|
||||
if (_displayContext is ViewModels.ChangeCollectionAsTree tree)
|
||||
if (Content is ViewModels.ChangeCollectionAsTree tree)
|
||||
{
|
||||
node.IsExpanded = !node.IsExpanded;
|
||||
|
||||
|
@ -136,92 +137,12 @@ namespace SourceGit.Views
|
|||
{
|
||||
base.OnPropertyChanged(change);
|
||||
|
||||
if (change.Property == ViewModeProperty || change.Property == ChangesProperty)
|
||||
{
|
||||
_disableSelectionChangingEvent = change.Property == ChangesProperty;
|
||||
var changes = Changes;
|
||||
if (changes == null || changes.Count == 0)
|
||||
{
|
||||
Content = null;
|
||||
_displayContext = null;
|
||||
_disableSelectionChangingEvent = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ViewMode == Models.ChangeViewMode.Tree)
|
||||
{
|
||||
HashSet<string> oldFolded = new HashSet<string>();
|
||||
if (_displayContext is ViewModels.ChangeCollectionAsTree oldTree)
|
||||
{
|
||||
foreach (var row in oldTree.Rows)
|
||||
{
|
||||
if (row.IsFolder && !row.IsExpanded)
|
||||
oldFolded.Add(row.FullPath);
|
||||
}
|
||||
}
|
||||
|
||||
var tree = new ViewModels.ChangeCollectionAsTree();
|
||||
tree.Tree = ViewModels.ChangeTreeNode.Build(changes, oldFolded);
|
||||
|
||||
var rows = new List<ViewModels.ChangeTreeNode>();
|
||||
MakeTreeRows(rows, tree.Tree);
|
||||
tree.Rows.AddRange(rows);
|
||||
_displayContext = tree;
|
||||
}
|
||||
else if (ViewMode == Models.ChangeViewMode.Grid)
|
||||
{
|
||||
var grid = new ViewModels.ChangeCollectionAsGrid();
|
||||
grid.Changes.AddRange(changes);
|
||||
_displayContext = grid;
|
||||
}
|
||||
else
|
||||
{
|
||||
var list = new ViewModels.ChangeCollectionAsList();
|
||||
list.Changes.AddRange(changes);
|
||||
_displayContext = list;
|
||||
}
|
||||
|
||||
Content = _displayContext;
|
||||
_disableSelectionChangingEvent = false;
|
||||
}
|
||||
if (change.Property == ViewModeProperty)
|
||||
UpdateDataSource(false);
|
||||
else if (change.Property == ChangesProperty)
|
||||
UpdateDataSource(true);
|
||||
else if (change.Property == SelectedChangesProperty)
|
||||
{
|
||||
if (_disableSelectionChangingEvent)
|
||||
return;
|
||||
|
||||
var list = this.FindDescendantOfType<ChangeCollectionContainer>();
|
||||
if (list == null)
|
||||
return;
|
||||
|
||||
_disableSelectionChangingEvent = true;
|
||||
|
||||
var selected = SelectedChanges;
|
||||
if (selected == null || selected.Count == 0)
|
||||
{
|
||||
list.SelectedItem = null;
|
||||
}
|
||||
else if (_displayContext is ViewModels.ChangeCollectionAsTree tree)
|
||||
{
|
||||
var sets = new HashSet<Models.Change>();
|
||||
foreach (var c in selected)
|
||||
sets.Add(c);
|
||||
|
||||
var nodes = new List<ViewModels.ChangeTreeNode>();
|
||||
foreach (var row in tree.Rows)
|
||||
{
|
||||
if (row.Change != null && sets.Contains(row.Change))
|
||||
nodes.Add(row);
|
||||
}
|
||||
|
||||
list.SelectedItems = nodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
list.SelectedItems = selected;
|
||||
}
|
||||
|
||||
_disableSelectionChangingEvent = false;
|
||||
}
|
||||
UpdateSelection();
|
||||
}
|
||||
|
||||
private void OnRowDoubleTapped(object sender, TappedEventArgs e)
|
||||
|
@ -283,6 +204,120 @@ namespace SourceGit.Views
|
|||
}
|
||||
}
|
||||
|
||||
private void UpdateDataSource(bool disableEvents)
|
||||
{
|
||||
_disableSelectionChangingEvent = disableEvents;
|
||||
|
||||
var changes = Changes;
|
||||
if (changes == null || changes.Count == 0)
|
||||
{
|
||||
Content = null;
|
||||
_disableSelectionChangingEvent = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var selected = SelectedChanges ?? [];
|
||||
if (ViewMode == Models.ChangeViewMode.Tree)
|
||||
{
|
||||
HashSet<string> oldFolded = new HashSet<string>();
|
||||
if (Content is ViewModels.ChangeCollectionAsTree oldTree)
|
||||
{
|
||||
foreach (var row in oldTree.Rows)
|
||||
{
|
||||
if (row.IsFolder && !row.IsExpanded)
|
||||
oldFolded.Add(row.FullPath);
|
||||
}
|
||||
}
|
||||
|
||||
var tree = new ViewModels.ChangeCollectionAsTree();
|
||||
tree.Tree = ViewModels.ChangeTreeNode.Build(changes, oldFolded);
|
||||
|
||||
var rows = new List<ViewModels.ChangeTreeNode>();
|
||||
MakeTreeRows(rows, tree.Tree);
|
||||
tree.Rows.AddRange(rows);
|
||||
|
||||
if (selected.Count > 0)
|
||||
{
|
||||
var sets = new HashSet<Models.Change>();
|
||||
foreach (var c in selected)
|
||||
sets.Add(c);
|
||||
|
||||
var nodes = new List<ViewModels.ChangeTreeNode>();
|
||||
foreach (var row in tree.Rows)
|
||||
{
|
||||
if (row.Change != null && sets.Contains(row.Change))
|
||||
nodes.Add(row);
|
||||
}
|
||||
|
||||
tree.SelectedRows.AddRange(nodes);
|
||||
}
|
||||
|
||||
Content = tree;
|
||||
}
|
||||
else if (ViewMode == Models.ChangeViewMode.Grid)
|
||||
{
|
||||
var grid = new ViewModels.ChangeCollectionAsGrid();
|
||||
grid.Changes.AddRange(changes);
|
||||
if (selected.Count > 0)
|
||||
grid.SelectedChanges.AddRange(selected);
|
||||
Content = grid;
|
||||
}
|
||||
else
|
||||
{
|
||||
var list = new ViewModels.ChangeCollectionAsList();
|
||||
list.Changes.AddRange(changes);
|
||||
if (selected.Count > 0)
|
||||
list.SelectedChanges.AddRange(selected);
|
||||
Content = list;
|
||||
}
|
||||
|
||||
_disableSelectionChangingEvent = false;
|
||||
}
|
||||
|
||||
private void UpdateSelection()
|
||||
{
|
||||
if (_disableSelectionChangingEvent)
|
||||
return;
|
||||
|
||||
_disableSelectionChangingEvent = true;
|
||||
|
||||
var selected = SelectedChanges ?? [];
|
||||
if (Content is ViewModels.ChangeCollectionAsTree tree)
|
||||
{
|
||||
tree.SelectedRows.Clear();
|
||||
|
||||
if (selected.Count > 0)
|
||||
{
|
||||
var sets = new HashSet<Models.Change>();
|
||||
foreach (var c in selected)
|
||||
sets.Add(c);
|
||||
|
||||
var nodes = new List<ViewModels.ChangeTreeNode>();
|
||||
foreach (var row in tree.Rows)
|
||||
{
|
||||
if (row.Change != null && sets.Contains(row.Change))
|
||||
nodes.Add(row);
|
||||
}
|
||||
|
||||
tree.SelectedRows.AddRange(nodes);
|
||||
}
|
||||
}
|
||||
else if (Content is ViewModels.ChangeCollectionAsGrid grid)
|
||||
{
|
||||
grid.SelectedChanges.Clear();
|
||||
if (selected.Count > 0)
|
||||
grid.SelectedChanges.AddRange(selected);
|
||||
}
|
||||
else if (Content is ViewModels.ChangeCollectionAsList list)
|
||||
{
|
||||
list.SelectedChanges.Clear();
|
||||
if (selected.Count > 0)
|
||||
list.SelectedChanges.AddRange(selected);
|
||||
}
|
||||
|
||||
_disableSelectionChangingEvent = false;
|
||||
}
|
||||
|
||||
private void CollectChangesInNode(List<Models.Change> outs, ViewModels.ChangeTreeNode node)
|
||||
{
|
||||
if (node.IsFolder)
|
||||
|
@ -324,6 +359,5 @@ namespace SourceGit.Views
|
|||
}
|
||||
|
||||
private bool _disableSelectionChangingEvent = false;
|
||||
private object _displayContext = null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue