feature: highlight lines those come from the same change with current line (#448)

This commit is contained in:
leo 2024-09-09 11:45:02 +08:00
parent 0d7999027b
commit 4be7710336
No known key found for this signature in database
2 changed files with 61 additions and 6 deletions

View file

@ -50,14 +50,14 @@
</Border> </Border>
<!-- Body --> <!-- Body -->
<Grid Grid.Row="2"> <Grid Grid.Row="2" Background="{DynamicResource Brush.Contents}">
<!-- Blame View --> <!-- Blame View -->
<v:BlameTextEditor HorizontalScrollBarVisibility="Auto" <v:BlameTextEditor HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
Margin="4,0,4,4" Margin="4,0,4,4"
BorderBrush="{DynamicResource Brush.Border2}" BorderBrush="{DynamicResource Brush.Border2}"
BorderThickness="1" BorderThickness="1"
Background="{DynamicResource Brush.Contents}" Background="Transparent"
Foreground="{DynamicResource Brush.FG1}" Foreground="{DynamicResource Brush.FG1}"
FontFamily="{DynamicResource Fonts.Monospace}" FontFamily="{DynamicResource Fonts.Monospace}"
BlameData="{Binding Data}"/> BlameData="{Binding Data}"/>

View file

@ -174,7 +174,11 @@ namespace SourceGit.Views
var rect = new Rect(0, y, shaLink.Width, shaLink.Height); var rect = new Rect(0, y, shaLink.Width, shaLink.Height);
if (rect.Contains(pos)) if (rect.Contains(pos))
{ {
_editor.OnCommitSHAClicked(info.CommitSHA); if (DataContext is ViewModels.Blame blame)
{
blame.NavigateToCommit(info.CommitSHA);
}
e.Handled = true; e.Handled = true;
break; break;
} }
@ -229,6 +233,8 @@ namespace SourceGit.Views
TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this)); TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this));
TextArea.LeftMargins.Add(new CommitInfoMargin(this) { Margin = new Thickness(8, 0) }); TextArea.LeftMargins.Add(new CommitInfoMargin(this) { Margin = new Thickness(8, 0) });
TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this)); TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this));
TextArea.LayoutUpdated += OnTextAreaLayoutUpdated;
TextArea.Caret.PositionChanged += OnCaretPositionChanged;
TextArea.TextView.ContextRequested += OnTextViewContextRequested; TextArea.TextView.ContextRequested += OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged; TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged;
TextArea.TextView.Margin = new Thickness(4, 0); TextArea.TextView.Margin = new Thickness(4, 0);
@ -236,11 +242,35 @@ namespace SourceGit.Views
TextArea.TextView.Options.EnableEmailHyperlinks = false; TextArea.TextView.Options.EnableEmailHyperlinks = false;
} }
public void OnCommitSHAClicked(string sha) public override void Render(DrawingContext context)
{ {
if (DataContext is ViewModels.Blame blame) base.Render(context);
if (string.IsNullOrEmpty(_highlight))
return;
var view = TextArea.TextView;
if (view == null || !view.VisualLinesValid)
return;
var color = (Color)this.FindResource("SystemAccentColor")!;
var brush = new SolidColorBrush(color, 0.4);
foreach (var line in view.VisualLines)
{ {
blame.NavigateToCommit(sha); if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted)
continue;
var lineNumber = line.FirstDocumentLine.LineNumber;
if (lineNumber >= BlameData.LineInfos.Count)
break;
var info = BlameData.LineInfos[lineNumber - 1];
if (info.CommitSHA != _highlight)
continue;
var startY = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineTop) - view.VerticalOffset;
var endY = line.GetTextLineVisualYPosition(line.TextLines[^1], VisualYPosition.LineBottom) - view.VerticalOffset;
context.FillRectangle(brush, new Rect(0, startY, Bounds.Width, endY - startY));
} }
} }
@ -249,6 +279,8 @@ namespace SourceGit.Views
base.OnUnloaded(e); base.OnUnloaded(e);
TextArea.LeftMargins.Clear(); TextArea.LeftMargins.Clear();
TextArea.LayoutUpdated += OnTextAreaLayoutUpdated;
TextArea.Caret.PositionChanged -= OnCaretPositionChanged;
TextArea.TextView.ContextRequested -= OnTextViewContextRequested; TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged -= OnTextViewVisualLinesChanged; TextArea.TextView.VisualLinesChanged -= OnTextViewVisualLinesChanged;
@ -281,6 +313,28 @@ namespace SourceGit.Views
} }
} }
private void OnTextAreaLayoutUpdated(object sender, EventArgs e)
{
InvalidateVisual();
}
private void OnCaretPositionChanged(object sender, EventArgs e)
{
if (!TextArea.IsFocused)
return;
var caret = TextArea.Caret;
if (caret.Line >= BlameData.LineInfos.Count)
return;
var info = BlameData.LineInfos[caret.Line - 1];
if (_highlight != info.CommitSHA)
{
_highlight = info.CommitSHA;
InvalidateVisual();
}
}
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e) private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
{ {
var selected = SelectedText; var selected = SelectedText;
@ -325,6 +379,7 @@ namespace SourceGit.Views
} }
private TextMate.Installation _textMate = null; private TextMate.Installation _textMate = null;
private string _highlight = string.Empty;
} }
public partial class Blame : ChromelessWindow public partial class Blame : ChromelessWindow