From 4c4d8ae0312014e90c5edc1c601c29e85c7ff608 Mon Sep 17 00:00:00 2001 From: leo Date: Tue, 24 Jun 2025 18:08:35 +0800 Subject: [PATCH] feature: auto-select and scroll to current local branch when clicking `Navigate To HEAD` button in toolbar (#1022) Signed-off-by: leo --- src/Views/BranchTree.axaml.cs | 58 ++++++++++++++++++++++++++++ src/Views/RepositoryToolbar.axaml.cs | 3 ++ 2 files changed, 61 insertions(+) diff --git a/src/Views/BranchTree.axaml.cs b/src/Views/BranchTree.axaml.cs index 045e9d1b..321b48e7 100644 --- a/src/Views/BranchTree.axaml.cs +++ b/src/Views/BranchTree.axaml.cs @@ -241,6 +241,47 @@ namespace SourceGit.Views InitializeComponent(); } + public void Select(Models.Branch branch) + { + if (branch == null) + return; + + _disableSelectionChangingEvent = true; + + var treePath = new List(); + FindTreePath(treePath, Nodes, branch.Name, 0); + + if (treePath.Count == 0) + { + _disableSelectionChangingEvent = false; + return; + } + + var oldRowCount = Rows.Count; + var rows = Rows; + for (var i = 0; i < treePath.Count - 1; i++) + { + var node = treePath[i]; + if (!node.IsExpanded) + { + node.IsExpanded = true; + + var idx = rows.IndexOf(node); + var subtree = new List(); + MakeRows(subtree, node.Children, node.Depth + 1); + rows.InsertRange(idx + 1, subtree); + } + } + + var target = treePath[treePath.Count - 1]; + BranchesPresenter.SelectedItem = target; + BranchesPresenter.ScrollIntoView(target); + _disableSelectionChangingEvent = false; + + if (oldRowCount != rows.Count) + RaiseEvent(new RoutedEventArgs(RowsChangedEvent)); + } + public void UnselectAll() { BranchesPresenter.SelectedItem = null; @@ -534,6 +575,23 @@ namespace SourceGit.Views CollectBranchesInNode(outs, sub); } + private void FindTreePath(List outPath, List collection, string path, int start) + { + if (start >= path.Length - 1) + return; + + var sepIdx = path.IndexOf('/', start); + var name = sepIdx < 0 ? path.Substring(start) : path.Substring(start, sepIdx - start); + foreach (var node in collection) + { + if (node.Name.Equals(name, StringComparison.Ordinal)) + { + outPath.Add(node); + FindTreePath(outPath, node.Children, path, sepIdx + 1); + } + } + } + private bool _disableSelectionChangingEvent = false; } } diff --git a/src/Views/RepositoryToolbar.axaml.cs b/src/Views/RepositoryToolbar.axaml.cs index 4fe5c87b..ea1e3257 100644 --- a/src/Views/RepositoryToolbar.axaml.cs +++ b/src/Views/RepositoryToolbar.axaml.cs @@ -157,6 +157,9 @@ namespace SourceGit.Views { if (DataContext is ViewModels.Repository { CurrentBranch: not null } repo) { + var repoView = TopLevel.GetTopLevel(this)?.FindDescendantOfType(false); + repoView?.LocalBranchTree?.Select(repo.CurrentBranch); + repo.NavigateToCommit(repo.CurrentBranch.Head); e.Handled = true; }