From fd935259aafa01e584801cbf84903f8767349eb3 Mon Sep 17 00:00:00 2001 From: leo Date: Fri, 16 May 2025 12:22:37 +0800 Subject: [PATCH] refactor: build tags view data in viewmodels instead of views Signed-off-by: leo --- src/ViewModels/Preferences.cs | 7 +- src/ViewModels/Repository.cs | 28 ++++- src/ViewModels/SubmoduleCollection.cs | 10 +- src/ViewModels/TagCollection.cs | 72 ++++++++++++- src/Views/Repository.axaml | 5 +- src/Views/TagsView.axaml | 53 +++++---- src/Views/TagsView.axaml.cs | 148 +++++--------------------- 7 files changed, 151 insertions(+), 172 deletions(-) diff --git a/src/ViewModels/Preferences.cs b/src/ViewModels/Preferences.cs index 5ce6f769..2698067e 100644 --- a/src/ViewModels/Preferences.cs +++ b/src/ViewModels/Preferences.cs @@ -178,9 +178,9 @@ namespace SourceGit.ViewModels public bool ShowTagsAsTree { - get => _showTagsAsTree; - set => SetProperty(ref _showTagsAsTree, value); - } + get; + set; + } = false; public bool ShowTagsInGraph { @@ -677,7 +677,6 @@ namespace SourceGit.ViewModels private double _lastCheckUpdateTime = 0; private string _ignoreUpdateTag = string.Empty; - private bool _showTagsAsTree = false; private bool _showTagsInGraph = true; private bool _useTwoColumnsLayoutInHistories = false; private bool _displayTimeAsPeriodInHistories = false; diff --git a/src/ViewModels/Repository.cs b/src/ViewModels/Repository.cs index c3e7c478..d24f6fbf 100644 --- a/src/ViewModels/Repository.cs +++ b/src/ViewModels/Repository.cs @@ -198,7 +198,21 @@ namespace SourceGit.ViewModels private set => SetProperty(ref _tags, value); } - public List VisibleTags + public bool ShowTagsAsTree + { + get => Preferences.Instance.ShowTagsAsTree; + set + { + if (value != Preferences.Instance.ShowTagsAsTree) + { + Preferences.Instance.ShowTagsAsTree = value; + VisibleTags = BuildVisibleTags(); + OnPropertyChanged(); + } + } + } + + public object VisibleTags { get => _visibleTags; private set => SetProperty(ref _visibleTags, value); @@ -548,7 +562,7 @@ namespace SourceGit.ViewModels _localBranchTrees.Clear(); _remoteBranchTrees.Clear(); _tags.Clear(); - _visibleTags.Clear(); + _visibleTags = null; _submodules.Clear(); _visibleSubmodules = null; _searchedCommits.Clear(); @@ -2492,7 +2506,7 @@ namespace SourceGit.ViewModels return builder; } - private List BuildVisibleTags() + private object BuildVisibleTags() { switch (_settings.TagSortMode) { @@ -2523,7 +2537,11 @@ namespace SourceGit.ViewModels var historiesFilters = _settings.CollectHistoriesFilters(); UpdateTagFilterMode(historiesFilters); - return visible; + + if (Preferences.Instance.ShowTagsAsTree) + return TagCollectionAsTree.Build(visible, _visibleTags as TagCollectionAsTree); + else + return new TagCollectionAsList() { Tags = visible }; } private object BuildVisibleSubmodules() @@ -2775,7 +2793,7 @@ namespace SourceGit.ViewModels private List _remoteBranchTrees = new List(); private List _worktrees = new List(); private List _tags = new List(); - private List _visibleTags = new List(); + private object _visibleTags = null; private List _submodules = new List(); private object _visibleSubmodules = null; diff --git a/src/ViewModels/SubmoduleCollection.cs b/src/ViewModels/SubmoduleCollection.cs index e2ebf634..4600496e 100644 --- a/src/ViewModels/SubmoduleCollection.cs +++ b/src/ViewModels/SubmoduleCollection.cs @@ -150,18 +150,12 @@ namespace SourceGit.ViewModels collection.Tree = SubmoduleTreeNode.Build(submodules, oldExpanded); var rows = new List(); - collection.MakeTreeRows(rows, collection.Tree); + MakeTreeRows(rows, collection.Tree); collection.Rows.AddRange(rows); return collection; } - public void Clear() - { - Tree.Clear(); - Rows.Clear(); - } - public void ToggleExpand(SubmoduleTreeNode node) { node.IsExpanded = !node.IsExpanded; @@ -193,7 +187,7 @@ namespace SourceGit.ViewModels } } - private void MakeTreeRows(List rows, List nodes) + private static void MakeTreeRows(List rows, List nodes) { foreach (var node in nodes) { diff --git a/src/ViewModels/TagCollection.cs b/src/ViewModels/TagCollection.cs index f05a727e..ce9c9508 100644 --- a/src/ViewModels/TagCollection.cs +++ b/src/ViewModels/TagCollection.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; + using Avalonia.Collections; + using CommunityToolkit.Mvvm.ComponentModel; namespace SourceGit.ViewModels @@ -61,7 +63,7 @@ namespace SourceGit.ViewModels Counter = 1; } - public static List Build(IList tags, HashSet expaneded) + public static List Build(List tags, HashSet expaneded) { var nodes = new List(); var folders = new Dictionary(); @@ -131,7 +133,7 @@ namespace SourceGit.ViewModels public class TagCollectionAsList { - public AvaloniaList Tags + public List Tags { get; set; @@ -151,5 +153,71 @@ namespace SourceGit.ViewModels get; set; } = []; + + public static TagCollectionAsTree Build(List tags, TagCollectionAsTree old) + { + var oldExpanded = new HashSet(); + if (old != null) + { + foreach (var row in old.Rows) + { + if (row.IsFolder && row.IsExpanded) + oldExpanded.Add(row.FullPath); + } + } + + var collection = new TagCollectionAsTree(); + collection.Tree = TagTreeNode.Build(tags, oldExpanded); + + var rows = new List(); + MakeTreeRows(rows, collection.Tree); + collection.Rows.AddRange(rows); + + return collection; + } + + public void ToggleExpand(TagTreeNode node) + { + node.IsExpanded = !node.IsExpanded; + + var rows = Rows; + var depth = node.Depth; + var idx = rows.IndexOf(node); + if (idx == -1) + return; + + if (node.IsExpanded) + { + var subrows = new List(); + MakeTreeRows(subrows, node.Children); + rows.InsertRange(idx + 1, subrows); + } + else + { + var removeCount = 0; + for (int i = idx + 1; i < rows.Count; i++) + { + var row = rows[i]; + if (row.Depth <= depth) + break; + + removeCount++; + } + rows.RemoveRange(idx + 1, removeCount); + } + } + + private static void MakeTreeRows(List rows, List nodes) + { + foreach (var node in nodes) + { + rows.Add(node); + + if (!node.IsExpanded || !node.IsFolder) + continue; + + MakeTreeRows(rows, node.Children); + } + } } } diff --git a/src/Views/Repository.axaml b/src/Views/Repository.axaml index 99bdd6ab..4eb303fe 100644 --- a/src/Views/Repository.axaml +++ b/src/Views/Repository.axaml @@ -271,7 +271,7 @@