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;
}
}