feature<PageTabBar>: apply repository configuration updates (bookmarks, titles, etc.)

This commit is contained in:
Jai 2021-08-13 18:28:07 +08:00
parent 1845fbbbc8
commit fbb59823bf
4 changed files with 120 additions and 17 deletions

View file

@ -0,0 +1,54 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace SourceGit.Views.Controls {
/// <summary>
/// Implementation of <see cref="INotifyPropertyChanged" /> to simplify models.
/// </summary>
public abstract class BindableBase : INotifyPropertyChanged {
/// <summary>
/// Multicast event for property change notifications.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Checks if a property already matches a desired value. Sets the property and
/// notifies listeners only when necessary.
/// </summary>
/// <typeparam name="T">Type of the property.</typeparam>
/// <param name="storage">Reference to a property with both getter and setter.</param>
/// <param name="value">Desired value for the property.</param>
/// <param name="propertyName">
/// Name of the property used to notify listeners. This
/// value is optional and can be provided automatically when invoked from compilers that
/// support CallerMemberName.
/// </param>
/// <returns>
/// True if the value was changed, false if the existing value matched the
/// desired value.
/// </returns>
protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null) {
if (Equals(storage, value)) {
return false;
}
storage = value;
this.OnPropertyChanged(propertyName);
return true;
}
/// <summary>
/// Notifies listeners that a property value has changed.
/// </summary>
/// <param name="propertyName">
/// Name of the property used to notify listeners. This
/// value is optional and can be provided automatically when invoked from compilers
/// that support <see cref="CallerMemberNameAttribute" />.
/// </param>
protected void OnPropertyChanged([CallerMemberName] string propertyName = null) {
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View file

@ -14,12 +14,23 @@ namespace SourceGit.Views.Widgets {
/// <summary> /// <summary>
/// 标签数据 /// 标签数据
/// </summary> /// </summary>
public class Tab { public class Tab : Controls.BindableBase {
public string Id { get; set; } public string Id { get; set; }
public bool IsWelcomePage { get; set; } public bool IsWelcomePage { get; set; }
public string Title { get; set; }
private string title;
public string Title {
get => title;
set => SetProperty(ref title, value);
}
public string Tooltip { get; set; } public string Tooltip { get; set; }
public int Bookmark { get; set; }
private int bookmark = 0;
public int Bookmark {
get => bookmark;
set => SetProperty(ref bookmark, value);
}
} }
/// <summary> /// <summary>
@ -123,6 +134,16 @@ namespace SourceGit.Views.Widgets {
if (curTab.Id == id) container.SelectedItem = replaced; if (curTab.Id == id) container.SelectedItem = replaced;
} }
public void Update(string id, int bookmark, string title) {
foreach (var one in Tabs) {
if (one.Id == id) {
one.Bookmark = bookmark;
one.Title = title;
break;
}
}
}
public bool Goto(string id) { public bool Goto(string id) {
foreach (var tab in Tabs) { foreach (var tab in Tabs) {
if (tab.Id == id) { if (tab.Id == id) {

View file

@ -127,6 +127,16 @@
<Path Grid.Column="0" Margin="2,0,0,0" x:Name="Icon" Width="16" Height="16" Data="{StaticResource Icon.Git}"/> <Path Grid.Column="0" Margin="2,0,0,0" x:Name="Icon" Width="16" Height="16" Data="{StaticResource Icon.Git}"/>
<controls:Bookmark
Grid.Column="0"
Margin="2,0,0,0"
x:Name="BookmarkIcon"
Width="16" Height="16"
Color="{Binding Bookmark}"
IsNewPage="False"
HideOnZero="False"
Visibility="Collapsed"/>
<StackPanel Grid.Column="1" x:Name="Contents" Orientation="Horizontal"> <StackPanel Grid.Column="1" x:Name="Contents" Orientation="Horizontal">
<TextBlock Margin="8,0" Text="{Binding Name}"/> <TextBlock Margin="8,0" Text="{Binding Name}"/>
<TextBlock x:Name="Path" Text="{Binding Id}" Foreground="{DynamicResource Brush.FG2}"/> <TextBlock x:Name="Path" Text="{Binding Id}" Foreground="{DynamicResource Brush.FG2}"/>
@ -145,12 +155,6 @@
IsHitTestVisible="True" IsHitTestVisible="True"
Visibility="Collapsed"/> Visibility="Collapsed"/>
<controls:Bookmark
Grid.Column="2"
Width="14" Height="14"
Color="{Binding Bookmark}"
IsNewPage="False"
HideOnZero="True"/>
</Grid> </Grid>
</Border> </Border>
@ -158,6 +162,10 @@
<DataTrigger Binding="{Binding IsGroup}" Value="True"> <DataTrigger Binding="{Binding IsGroup}" Value="True">
<Setter TargetName="Path" Property="Visibility" Value="Collapsed"/> <Setter TargetName="Path" Property="Visibility" Value="Collapsed"/>
</DataTrigger> </DataTrigger>
<DataTrigger Binding="{Binding IsGroup}" Value="False">
<Setter TargetName="Icon" Property="Visibility" Value="Collapsed"></Setter>
<Setter TargetName="BookmarkIcon" Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
<MultiDataTrigger> <MultiDataTrigger>
<MultiDataTrigger.Conditions> <MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsGroup}" Value="True"/> <Condition Binding="{Binding IsGroup}" Value="True"/>

View file

@ -15,14 +15,32 @@ namespace SourceGit.Views.Widgets {
/// <summary> /// <summary>
/// 树节点数据 /// 树节点数据
/// </summary> /// </summary>
public class Node { public class Node : Controls.BindableBase {
public string Id { get; set; } public string Id { get; set; }
public string ParentId { get; set; } public string ParentId { get; set; }
public string Name { get; set; }
private string name;
public string Name {
get => name;
set => SetProperty(ref name, value);
}
public bool IsGroup { get; set; } public bool IsGroup { get; set; }
public bool IsEditing { get; set; }
private bool isEditing = false;
public bool IsEditing {
get => isEditing;
set => SetProperty(ref isEditing, value);
}
public bool IsExpanded { get; set; } public bool IsExpanded { get; set; }
public int Bookmark { get; set; }
private int bookmark = 0;
public int Bookmark {
get => bookmark;
set => SetProperty(ref bookmark, value);
}
public List<Node> Children { get; set; } public List<Node> Children { get; set; }
} }
@ -125,7 +143,8 @@ namespace SourceGit.Views.Widgets {
var repo = Models.Preference.Instance.FindRepository(node.Id); var repo = Models.Preference.Instance.FindRepository(node.Id);
if (repo != null) { if (repo != null) {
repo.Bookmark = refIdx; repo.Bookmark = refIdx;
UpdateTree(); node.Bookmark = refIdx;
(Application.Current.MainWindow as Launcher)?.tabs.Update(node.Id, refIdx, node.Name);
} }
ev.Handled = true; ev.Handled = true;
}; };
@ -375,13 +394,14 @@ namespace SourceGit.Views.Widgets {
var node = edit.DataContext as Node; var node = edit.DataContext as Node;
if (node != null) { if (node != null) {
node.Name = edit.Text;
node.IsEditing = false;
if (node.IsGroup) { if (node.IsGroup) {
Models.Preference.Instance.RenameGroup(node.Id, edit.Text); Models.Preference.Instance.RenameGroup(node.Id, edit.Text);
} else { } else {
Models.Preference.Instance.RenameRepository(node.Id, edit.Text); Models.Preference.Instance.RenameRepository(node.Id, node.Name);
(Application.Current.MainWindow as Launcher)?.tabs.Update(node.Id, node.Bookmark, edit.Text);
} }
UpdateTree();
e.Handled = false; e.Handled = false;
} }
} }