refactor: new tooltip for change

Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
leo 2025-06-01 10:34:24 +08:00
parent db5bb0aec9
commit 26307e2343
No known key found for this signature in database
4 changed files with 60 additions and 30 deletions

View file

@ -54,6 +54,9 @@ namespace SourceGit.Models
public string ConflictMarker => CONFLICT_MARKERS[(int)ConflictReason];
public string ConflictDesc => CONFLICT_DESCS[(int)ConflictReason];
public string WorkTreeDesc => TYPE_DESCS[(int)WorkTree];
public string IndexDesc => TYPE_DESCS[(int)Index];
public void Set(ChangeState index, ChangeState workTree = ChangeState.None)
{
Index = index;
@ -85,6 +88,18 @@ namespace SourceGit.Models
OriginalPath = OriginalPath.Substring(1, OriginalPath.Length - 2);
}
private static readonly string[] TYPE_DESCS =
[
"Unknown",
"Modified",
"Type Changed",
"Added",
"Deleted",
"Renamed",
"Copied",
"Untracked",
"Conflict"
];
private static readonly string[] CONFLICT_MARKERS =
[
string.Empty,

View file

@ -41,7 +41,7 @@
Margin="{Binding Depth, Converter={x:Static c:IntConverters.ToTreeMargin}}"
Background="Transparent"
DoubleTapped="OnRowDoubleTapped"
ToolTip.Tip="{Binding FullPath}">
DataContextChanged="OnRowDataContextChanged">
<v:ChangeTreeNodeToggleButton Grid.Column="0"
Classes="tree_expander"
Focusable="False"
@ -85,7 +85,7 @@
<Grid ColumnDefinitions="Auto,Auto,Auto,*"
Background="Transparent"
DoubleTapped="OnRowDoubleTapped"
ToolTip.Tip="{Binding Path}">
DataContextChanged="OnRowDataContextChanged">
<v:ChangeStatusIcon Grid.Column="0"
Width="14" Height="14"
Margin="4,0,0,0"
@ -118,7 +118,7 @@
<Grid ColumnDefinitions="Auto,Auto,*"
Background="Transparent"
DoubleTapped="OnRowDoubleTapped"
ToolTip.Tip="{Binding Path}">
DataContextChanged="OnRowDataContextChanged">
<v:ChangeStatusIcon Grid.Column="0"
Width="14" Height="14"
Margin="4,0,0,0"

View file

@ -3,9 +3,11 @@ using System.Collections.Generic;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.Documents;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.VisualTree;
namespace SourceGit.Views
@ -86,7 +88,7 @@ namespace SourceGit.Views
}
public static readonly StyledProperty<bool> AutoSelectFirstChangeProperty =
AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(AutoSelectFirstChange), false);
AvaloniaProperty.Register<ChangeCollectionView, bool>(nameof(AutoSelectFirstChange));
public bool AutoSelectFirstChange
{
@ -229,6 +231,28 @@ namespace SourceGit.Views
UpdateSelection();
}
private void OnRowDataContextChanged(object sender, EventArgs e)
{
if (sender is not Control control)
return;
if (control.DataContext is ViewModels.ChangeTreeNode node)
{
if (node.Change is {} c)
UpdateRowTips(control, c);
else
ToolTip.SetTip(control, node.FullPath);
}
else if (control.DataContext is Models.Change change)
{
UpdateRowTips(control, change);
}
else
{
ToolTip.SetTip(control, null);
}
}
private void OnRowDoubleTapped(object sender, TappedEventArgs e)
{
var grid = sender as Grid;
@ -466,6 +490,21 @@ namespace SourceGit.Views
}
}
private void UpdateRowTips(Control control, Models.Change change)
{
var tip = new TextBlock() { TextWrapping = TextWrapping.Wrap };
tip.Inlines!.Add(new Run(change.Path));
tip.Inlines!.Add(new Run(" • ") { Foreground = Brushes.Gray });
tip.Inlines!.Add(new Run(IsUnstagedChange ? change.WorkTreeDesc : change.IndexDesc) { Foreground = Brushes.Gray });
if (change.IsConflicted)
{
tip.Inlines!.Add(new Run(" • ") { Foreground = Brushes.Gray });
tip.Inlines!.Add(new Run(change.ConflictDesc) { Foreground = Brushes.Gray });
}
ToolTip.SetTip(control, tip);
}
private bool _disableSelectionChangingEvent = false;
}
}

View file

@ -9,6 +9,7 @@ namespace SourceGit.Views
{
public class ChangeStatusIcon : Control
{
private static readonly string[] INDICATOR = ["?", "±", "T", "+", "", "➜", "❏", "★", "!"];
private static readonly IBrush[] BACKGROUNDS = [
Brushes.Transparent,
new LinearGradientBrush
@ -56,9 +57,6 @@ namespace SourceGit.Views
Brushes.OrangeRed,
];
private static readonly string[] INDICATOR = ["?", "±", "T", "+", "", "➜", "❏", "★", "!"];
private static readonly string[] TIPS = ["Unknown", "Modified", "Type Changed", "Added", "Deleted", "Renamed", "Copied", "Untracked", "Conflict"];
public static readonly StyledProperty<bool> IsUnstagedChangeProperty =
AvaloniaProperty.Register<ChangeStatusIcon, bool>(nameof(IsUnstagedChange));
@ -116,29 +114,7 @@ namespace SourceGit.Views
base.OnPropertyChanged(change);
if (change.Property == IsUnstagedChangeProperty || change.Property == ChangeProperty)
{
var isUnstaged = IsUnstagedChange;
var c = Change;
if (c == null)
{
ToolTip.SetTip(this, null);
return;
}
if (isUnstaged)
{
if (c.IsConflicted)
ToolTip.SetTip(this, $"Conflict ({c.ConflictDesc})");
else
ToolTip.SetTip(this, TIPS[(int)c.WorkTree]);
}
else
{
ToolTip.SetTip(this, TIPS[(int)c.Index]);
}
InvalidateVisual();
}
}
}
}