sourcegit/src/Views/ChangeStatusIcon.cs
2024-10-15 09:39:01 +08:00

150 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Globalization;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Media;
namespace SourceGit.Views
{
public class ChangeStatusIcon : Control
{
private static readonly IBrush[] BACKGROUNDS = [
Brushes.Transparent,
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(238, 160, 14), 0), new GradientStop(Color.FromRgb(228, 172, 67), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(238, 160, 14), 0), new GradientStop(Color.FromRgb(228, 172, 67), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(47, 185, 47), 0), new GradientStop(Color.FromRgb(75, 189, 75), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Colors.Tomato, 0), new GradientStop(Color.FromRgb(252, 165, 150), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Colors.Orchid, 0), new GradientStop(Color.FromRgb(248, 161, 245), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(238, 160, 14), 0), new GradientStop(Color.FromRgb(228, 172, 67), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(238, 160, 14), 0), new GradientStop(Color.FromRgb(228, 172, 67), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
new LinearGradientBrush
{
GradientStops = new GradientStops() { new GradientStop(Color.FromRgb(47, 185, 47), 0), new GradientStop(Color.FromRgb(75, 189, 75), 1) },
StartPoint = new RelativePoint(0, 0, RelativeUnit.Relative),
EndPoint = new RelativePoint(0, 1, RelativeUnit.Relative),
},
];
private static readonly string[] INDICATOR = ["?", "±", "T", "+", "", "➜", "❏", "U", "★"];
private static readonly string[] TIPS = ["Unknown", "Modified", "Type Changed", "Added", "Deleted", "Renamed", "Copied", "Unmerged", "Untracked"];
public static readonly StyledProperty<bool> IsUnstagedChangeProperty =
AvaloniaProperty.Register<ChangeStatusIcon, bool>(nameof(IsUnstagedChange));
public bool IsUnstagedChange
{
get => GetValue(IsUnstagedChangeProperty);
set => SetValue(IsUnstagedChangeProperty, value);
}
public static readonly StyledProperty<Models.Change> ChangeProperty =
AvaloniaProperty.Register<ChangeStatusIcon, Models.Change>(nameof(Change));
public Models.Change Change
{
get => GetValue(ChangeProperty);
set => SetValue(ChangeProperty, value);
}
public override void Render(DrawingContext context)
{
if (Change == null || Bounds.Width <= 0)
return;
var typeface = new Typeface("fonts:SourceGit#JetBrains Mono");
IBrush background;
string indicator;
if (IsUnstagedChange)
{
if (Change.IsConflit)
{
background = Brushes.OrangeRed;
indicator = "!";
}
else
{
background = BACKGROUNDS[(int)Change.WorkTree];
indicator = INDICATOR[(int)Change.WorkTree];
}
}
else
{
background = BACKGROUNDS[(int)Change.Index];
indicator = INDICATOR[(int)Change.Index];
}
var txt = new FormattedText(
indicator,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
Bounds.Width * 0.8,
Brushes.White);
var corner = (float)Math.Max(2, Bounds.Width / 16);
var textOrigin = new Point((Bounds.Width - txt.Width) * 0.5, (Bounds.Height - txt.Height) * 0.5);
context.DrawRectangle(background, null, new Rect(0, 0, Bounds.Width, Bounds.Height), corner, corner);
context.DrawText(txt, textOrigin);
}
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
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)
ToolTip.SetTip(this, c.IsConflit ? "Conflict" : TIPS[(int)c.WorkTree]);
else
ToolTip.SetTip(this, TIPS[(int)c.Index]);
InvalidateVisual();
}
}
}
}