From a2254ae578b5b4ca964aa99cb2ec30d9eb44b5a9 Mon Sep 17 00:00:00 2001 From: leo Date: Mon, 7 Dec 2020 18:03:05 +0800 Subject: [PATCH] feature: change style of tabs in title bar; bookmark color for repository --- src/Converters/IntToRepoColor.cs | 52 +++++++++ src/Git/Repository.cs | 4 + src/Resources/Styles/ContextMenu.xaml | 2 +- src/UI/Launcher.xaml | 113 +++++++++++++------- src/UI/Launcher.xaml.cs | 148 +++++++++++++++++--------- 5 files changed, 232 insertions(+), 87 deletions(-) create mode 100644 src/Converters/IntToRepoColor.cs diff --git a/src/Converters/IntToRepoColor.cs b/src/Converters/IntToRepoColor.cs new file mode 100644 index 00000000..8a328224 --- /dev/null +++ b/src/Converters/IntToRepoColor.cs @@ -0,0 +1,52 @@ +using System; +using System.Globalization; +using System.Windows; +using System.Windows.Data; +using System.Windows.Media; + +namespace SourceGit.Converters { + + /// + /// Integer to color. + /// + public class IntToRepoColor : IValueConverter { + + /// + /// All supported colors. + /// + public static Brush[] Colors = new Brush[] { + Brushes.White, + Brushes.Red, + Brushes.Orange, + Brushes.Yellow, + Brushes.ForestGreen, + Brushes.Purple, + Brushes.DeepSkyBlue, + Brushes.Magenta, + }; + + /// + /// Implement IValueConverter.Convert + /// + /// + /// + /// + /// + /// + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { + return Colors[((int)value) % Colors.Length]; + } + + /// + /// Implement IValueConverter.ConvertBack + /// + /// + /// + /// + /// + /// + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { + return ((Thickness)value).Left; + } + } +} diff --git a/src/Git/Repository.cs b/src/Git/Repository.cs index 4078935e..b2ca87d2 100644 --- a/src/Git/Repository.cs +++ b/src/Git/Repository.cs @@ -39,6 +39,10 @@ namespace SourceGit.Git { /// public string GroupId { get; set; } /// + /// Custom color. + /// + public int Color { get; set; } = 0; + /// /// Last open time(File time format). /// public long LastOpenTime { get; set; } diff --git a/src/Resources/Styles/ContextMenu.xaml b/src/Resources/Styles/ContextMenu.xaml index d0cf2b2c..8568041b 100644 --- a/src/Resources/Styles/ContextMenu.xaml +++ b/src/Resources/Styles/ContextMenu.xaml @@ -57,7 +57,7 @@ - + diff --git a/src/UI/Launcher.xaml b/src/UI/Launcher.xaml index 8f1ef01c..e9a81106 100644 --- a/src/UI/Launcher.xaml +++ b/src/UI/Launcher.xaml @@ -5,6 +5,8 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:source="clr-namespace:SourceGit" + xmlns:local="clr-namespace:SourceGit.UI" + xmlns:converters="clr-namespace:SourceGit.Converters" mc:Ignorable="d" MinWidth="800" MinHeight="600" Title="Source Git" @@ -62,41 +64,82 @@ - + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - diff --git a/src/UI/Launcher.xaml.cs b/src/UI/Launcher.xaml.cs index a050f2c3..f3acfe70 100644 --- a/src/UI/Launcher.xaml.cs +++ b/src/UI/Launcher.xaml.cs @@ -1,5 +1,5 @@ -using System; using System.Collections.ObjectModel; +using System.ComponentModel; using System.Net; using System.Reflection; using System.Text.Json; @@ -8,6 +8,7 @@ using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Input; +using System.Windows.Media; namespace SourceGit.UI { @@ -19,13 +20,48 @@ namespace SourceGit.UI { /// /// Tab data. /// - public class Tab { + public class Tab : INotifyPropertyChanged { public string Title { get; set; } public string Tooltip { get; set; } - public bool AllowDragDrop { get; set; } public bool IsActive { get; set; } public Git.Repository Repo { get; set; } public object Page { get; set; } + public bool IsRepo => Repo != null; + public int Color { + get { return Repo == null ? 0 : Repo.Color; } + set { + if (Repo == null || Repo.Color == value) return; + Repo.Color = value; + PropertyChanged.Invoke(this, new PropertyChangedEventArgs("Color")); + } + } + + public event PropertyChangedEventHandler PropertyChanged; + } + + /// + /// Manager tab + /// + public class ManagerTab : Tab { + public ManagerTab() { + Title = "HOME"; + Tooltip = "Repositories Manager"; + IsActive = true; + Page = new Manager(); + } + } + + /// + /// Repository tab. + /// + public class RepoTab : Tab { + public RepoTab(Git.Repository repo, Dashboard page) { + Title = repo.Parent == null ? repo.Name : $"{repo.Parent.Name} : {repo.Name}"; + Tooltip = repo.Path; + Repo = repo; + IsActive = false; + Page = page; + } } /// @@ -42,16 +78,9 @@ namespace SourceGit.UI { /// Constructor /// public Launcher() { - Tabs.Add(new Tab() { - Title = "HOME", - Tooltip = "Repositories Manager", - AllowDragDrop = false, - Page = new Manager(), - }); - + Tabs.Add(new ManagerTab()); InitializeComponent(); openedTabs.SelectedItem = Tabs[0]; - if (App.Preference.CheckUpdate) Task.Run(CheckUpdate); } @@ -69,16 +98,8 @@ namespace SourceGit.UI { } repo.Open(); - var page = new Dashboard(repo); - var tab = new Tab() { - Title = repo.Parent == null ? repo.Name : $"{repo.Parent.Name} : {repo.Name}", - Tooltip = repo.Path, - AllowDragDrop = true, - Repo = repo, - Page = page, - }; - + var tab = new RepoTab(repo, page); repo.SetPopupManager(page.popupManager); Tabs.Add(tab); openedTabs.SelectedItem = tab; @@ -112,6 +133,26 @@ namespace SourceGit.UI { } #region LAYOUT_CONTENT + /// + /// Close repository. + /// + /// + /// + private void CloseRepo(object sender, RoutedEventArgs e) { + var tab = (sender as Button).DataContext as Tab; + if (tab == null || tab.Repo == null) { + e.Handled = true; + return; + } + + Tabs.Remove(tab); + + tab.Page = null; + tab.Repo.RemovePopup(); + tab.Repo.Close(); + tab.Repo = null; + } + /// /// Context menu for tab items. /// @@ -119,34 +160,12 @@ namespace SourceGit.UI { /// private void TabsContextMenuOpening(object sender, ContextMenuEventArgs ev) { var tab = (sender as TabItem).DataContext as Tab; - if (tab == null) { + if (tab == null || tab.Repo == null) { ev.Handled = true; return; } var repo = tab.Repo; - if (repo == null) { - ev.Handled = true; - return; - } - - var close = new MenuItem(); - close.Header = "Close"; - close.Click += (o, e) => { - Tabs.Remove(tab); - - tab.Page = null; - tab.Repo.RemovePopup(); - tab.Repo.Close(); - tab.Repo = null; - }; - - var copyPath = new MenuItem(); - copyPath.Header = "Copy Path"; - copyPath.Click += (o, e) => { - Clipboard.SetText(repo.Path); - e.Handled = true; - }; var refresh = new MenuItem(); refresh.Header = "Refresh"; @@ -155,11 +174,39 @@ namespace SourceGit.UI { e.Handled = true; }; + var bookmark = new MenuItem(); + bookmark.Header = "Bookmark"; + for (int i = 0; i < Converters.IntToRepoColor.Colors.Length; i++) { + var icon = new System.Windows.Shapes.Path(); + icon.Style = FindResource("Style.Icon") as Style; + icon.Data = Geometry.Parse("M 0,0 A 180,180 180 1 1 1,1 Z"); + icon.Fill = Converters.IntToRepoColor.Colors[i]; + icon.Width = 12; + + var mark = new MenuItem(); + mark.Icon = icon; + mark.Header = $"{i + 1}"; + + var refIdx = i; + mark.Click += (o, e) => { + tab.Color = refIdx; + e.Handled = true; + }; + + bookmark.Items.Add(mark); + } + + var copyPath = new MenuItem(); + copyPath.Header = "Copy path"; + copyPath.Click += (o, e) => { + Clipboard.SetText(repo.Path); + e.Handled = true; + }; + var menu = new ContextMenu(); - menu.Items.Add(close); - menu.Items.Add(new Separator()); - menu.Items.Add(copyPath); menu.Items.Add(refresh); + menu.Items.Add(bookmark); + menu.Items.Add(copyPath); menu.IsOpen = true; ev.Handled = true; @@ -227,11 +274,14 @@ namespace SourceGit.UI { #region DRAG_DROP private void TabsMouseMove(object sender, MouseEventArgs e) { - var tab = e.Source as TabItem; - if (tab == null || (tab.DataContext as Tab).Repo == null) return; + var item = e.Source as TabItem; + if (item == null) return; + + var tab = item.DataContext as Tab; + if (tab == null || tab.Repo == null) return; if (Mouse.LeftButton == MouseButtonState.Pressed) { - DragDrop.DoDragDrop(tab, tab, DragDropEffects.All); + DragDrop.DoDragDrop(item, item, DragDropEffects.All); e.Handled = true; } }