From 5d3088d520449254c8045a2e208d8b261230b2b3 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 21 Aug 2023 17:38:36 +0800 Subject: [PATCH] feature: supports set bookmark of selected repository from context menu. --- src/Models/Watcher.cs | 14 +++++++ src/Views/Controls/BindableBase.cs | 54 ------------------------ src/Views/Launcher.xaml.cs | 8 ---- src/Views/Widgets/PageTabBar.xaml.cs | 35 ++++++++++------ src/Views/Widgets/Welcome.xaml | 2 +- src/Views/Widgets/Welcome.xaml.cs | 62 +++++++++++++++++++++++++++- 6 files changed, 97 insertions(+), 78 deletions(-) delete mode 100644 src/Views/Controls/BindableBase.cs diff --git a/src/Models/Watcher.cs b/src/Models/Watcher.cs index f2234a97..c9bb6787 100644 --- a/src/Models/Watcher.cs +++ b/src/Models/Watcher.cs @@ -14,6 +14,11 @@ namespace SourceGit.Models { /// public static event Action Opened; + /// + /// 仓库的书签变化了 + /// + public static event Action BookmarkChanged; + /// /// 跳转到指定提交的事件 /// @@ -97,6 +102,15 @@ namespace SourceGit.Models { } } + /// + /// 设置仓库标签变化 + /// + /// + /// + public static void SetBookmark(string repo, int bookmark) { + BookmarkChanged?.Invoke(repo, bookmark); + } + /// /// 跳转到指定的提交 /// diff --git a/src/Views/Controls/BindableBase.cs b/src/Views/Controls/BindableBase.cs deleted file mode 100644 index 6570a8fe..00000000 --- a/src/Views/Controls/BindableBase.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.ComponentModel; -using System.Runtime.CompilerServices; - -namespace SourceGit.Views.Controls { - - /// - /// Implementation of to simplify models. - /// - public abstract class BindableBase : INotifyPropertyChanged { - /// - /// Multicast event for property change notifications. - /// - public event PropertyChangedEventHandler PropertyChanged; - - /// - /// Checks if a property already matches a desired value. Sets the property and - /// notifies listeners only when necessary. - /// - /// Type of the property. - /// Reference to a property with both getter and setter. - /// Desired value for the property. - /// - /// Name of the property used to notify listeners. This - /// value is optional and can be provided automatically when invoked from compilers that - /// support CallerMemberName. - /// - /// - /// True if the value was changed, false if the existing value matched the - /// desired value. - /// - protected bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) { - if (Equals(storage, value)) { - return false; - } - - storage = value; - this.OnPropertyChanged(propertyName); - return true; - } - - /// - /// Notifies listeners that a property value has changed. - /// - /// - /// Name of the property used to notify listeners. This - /// value is optional and can be provided automatically when invoked from compilers - /// that support . - /// - protected void OnPropertyChanged([CallerMemberName] string propertyName = null) { - this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - } - -} diff --git a/src/Views/Launcher.xaml.cs b/src/Views/Launcher.xaml.cs index 43b937f4..0e3cee7e 100644 --- a/src/Views/Launcher.xaml.cs +++ b/src/Views/Launcher.xaml.cs @@ -19,14 +19,6 @@ namespace SourceGit.Views { Models.Watcher.Opened += OpenRepository; InitializeComponent(); tabs.Add(); - - tabs.OnTabEdited += (t) => { - foreach (var tab in tabs.Tabs) { - if (tab.IsRepository) continue; - var page = container.Get(tab.Id) as Widgets.Welcome; - if (page != null) page.UpdateVisibles(); - } - }; } private void OnClosing(object sender, CancelEventArgs e) { diff --git a/src/Views/Widgets/PageTabBar.xaml.cs b/src/Views/Widgets/PageTabBar.xaml.cs index 681019fc..0df9afc0 100644 --- a/src/Views/Widgets/PageTabBar.xaml.cs +++ b/src/Views/Widgets/PageTabBar.xaml.cs @@ -1,6 +1,8 @@ using System; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Linq; +using System.Runtime.CompilerServices; using System.Windows; using System.Windows.Controls; using System.Windows.Input; @@ -16,10 +18,12 @@ namespace SourceGit.Views.Widgets { /// /// 标签数据 /// - public class Tab : Controls.BindableBase { + public class Tab : INotifyPropertyChanged { + public event PropertyChangedEventHandler PropertyChanged; + public string Id { get; set; } public bool IsRepository { get; set; } - + private string title; public string Title { get => title; @@ -39,12 +43,13 @@ namespace SourceGit.Views.Widgets { get => isSeperatorVisible; set => SetProperty(ref isSeperatorVisible, value); } - } - /// - /// 仓库标签页编辑事件参数 - /// - public event Action OnTabEdited; + public void SetProperty(ref T storage, T value, [CallerMemberName] string propName = null) { + if (Equals(storage, value)) return; + storage = value; + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); + } + } /// /// 标签相关事件参数 @@ -99,6 +104,15 @@ namespace SourceGit.Views.Widgets { public PageTabBar() { Tabs = new ObservableCollection(); InitializeComponent(); + + Models.Watcher.BookmarkChanged += (repoPath, bookmark) => { + foreach (var tab in Tabs) { + if (tab.Id == repoPath) { + tab.Bookmark = bookmark; + break; + } + } + }; } public void Add() { @@ -350,12 +364,7 @@ namespace SourceGit.Views.Widgets { var refIdx = i; mark.Click += (o, ev) => { - var repo = Models.Preference.Instance.FindRepository(tab.Id); - if (repo != null) { - repo.Bookmark = refIdx; - tab.Bookmark = refIdx; - OnTabEdited?.Invoke(tab); - } + Models.Watcher.SetBookmark(tab.Id, refIdx); ev.Handled = true; }; bookmark.Items.Add(mark); diff --git a/src/Views/Widgets/Welcome.xaml b/src/Views/Widgets/Welcome.xaml index 29229d7a..d69edfda 100644 --- a/src/Views/Widgets/Welcome.xaml +++ b/src/Views/Widgets/Welcome.xaml @@ -107,7 +107,7 @@ - + diff --git a/src/Views/Widgets/Welcome.xaml.cs b/src/Views/Widgets/Welcome.xaml.cs index 7a3b3ade..d5c9e376 100644 --- a/src/Views/Widgets/Welcome.xaml.cs +++ b/src/Views/Widgets/Welcome.xaml.cs @@ -19,6 +19,14 @@ namespace SourceGit.Views.Widgets { InitializeComponent(); UpdateVisibles(); Models.Theme.AddListener(this, UpdateVisibles); + + Models.Watcher.BookmarkChanged += (repoPath, bookmark) => { + var repo = Models.Preference.Instance.FindRepository(repoPath); + if (repo != null) { + repo.Bookmark = bookmark; + UpdateVisibles(); + } + }; } #region FUNC_EVENTS @@ -89,7 +97,7 @@ namespace SourceGit.Views.Widgets { } private void OnRemoveRepository(object sender, RoutedEventArgs e) { - var repo = (sender as Button).DataContext as Models.Repository; + var repo = (sender as Control).DataContext as Models.Repository; if (repo == null) return; var confirmDialog = new ConfirmDialog( @@ -108,6 +116,56 @@ namespace SourceGit.Views.Widgets { OnOpenRepository(sender, e); } + private void OnRepositoryContextMenuOpening(object sender, ContextMenuEventArgs e) { + var control = sender as Control; + if (control == null) return; + + var repo = control.DataContext as Models.Repository; + if (repo == null) return; + + var menu = new ContextMenu(); + menu.Placement = PlacementMode.MousePoint; + menu.PlacementTarget = control; + menu.StaysOpen = false; + menu.Focusable = true; + + var open = new MenuItem(); + open.Header = App.Text("RepoCM.Open"); + open.Click += OnOpenRepository; + menu.Items.Add(open); + menu.Items.Add(new Separator()); + + var bookmark = new MenuItem(); + bookmark.Header = App.Text("PageTabBar.Tab.Bookmark"); + for (int i = 0; i < Converters.IntToBookmarkBrush.COLORS.Length; i++) { + var icon = new System.Windows.Shapes.Path(); + icon.Data = new EllipseGeometry(new Point(0, 0), 12, 12); + icon.Fill = Converters.IntToBookmarkBrush.COLORS[i]; + icon.Width = 12; + + var mark = new MenuItem(); + mark.Icon = icon; + mark.Header = $"{i}"; + + var refIdx = i; + mark.Click += (o, ev) => { + Models.Watcher.SetBookmark(repo.Path, refIdx); + ev.Handled = true; + }; + bookmark.Items.Add(mark); + } + menu.Items.Add(bookmark); + menu.Items.Add(new Separator()); + + var remove = new MenuItem(); + remove.Header = App.Text("Welcome.Delete"); + remove.Click += OnRemoveRepository; + menu.Items.Add(remove); + + menu.IsOpen = true; + e.Handled = true; + } + private void OnOpenRepository(object sender, RoutedEventArgs e) { var repo = (sender as Control).DataContext as Models.Repository; if (repo == null) return; @@ -125,7 +183,7 @@ namespace SourceGit.Views.Widgets { } private void OnOpenRepositoryTerminal(object sender, RoutedEventArgs e) { - var repo = (sender as Button).DataContext as Models.Repository; + var repo = (sender as Control).DataContext as Models.Repository; if (repo == null) return; var bash = Path.Combine(Models.Preference.Instance.Git.Path, "..", "bash.exe");