style<Blame>: rewrite MeasureOverride to fit content with for CommitInfoMargin; always show commit info for the first visual line

This commit is contained in:
leo 2024-03-01 15:09:17 +08:00
parent 7b70951c93
commit 59052d8e1f
2 changed files with 73 additions and 29 deletions

View file

@ -1,5 +1,4 @@
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
@ -50,35 +49,25 @@ namespace SourceGit.Commands {
_content.AppendLine(match.Groups[4].Value);
var commit = match.Groups[1].Value;
if (commit == _lastSHA) {
var info = new Models.BlameLineInfo() {
CommitSHA = commit,
Author = string.Empty,
Time = string.Empty,
};
var commit = match.Groups[1].Value;
var author = match.Groups[2].Value;
var timestamp = int.Parse(match.Groups[3].Value);
var when = UTC_START.AddSeconds(timestamp).ToString("yyyy/MM/dd");
_result.LineInfos.Add(info);
} else {
var author = match.Groups[2].Value;
var timestamp = int.Parse(match.Groups[3].Value);
var when = UTC_START.AddSeconds(timestamp).ToString("yyyy/MM/dd");
var info = new Models.BlameLineInfo() {
IsFirstInGroup = commit != _lastSHA,
CommitSHA = commit,
Author = author,
Time = when,
};
var blameLine = new Models.BlameLineInfo() {
IsFirstInGroup = true,
CommitSHA = commit,
Author = author,
Time = when,
};
_lastSHA = commit;
_result.LineInfos.Add(blameLine);
}
_result.LineInfos.Add(info);
_lastSHA = commit;
if (line[0] == '^') {
_needUnifyCommitSHA = true;
_minSHALen = Math.Min(_minSHALen, commit.Length);
}
}
}
private Models.BlameData _result = new Models.BlameData();

View file

@ -15,6 +15,7 @@ using System;
using System.Globalization;
using System.IO;
using TextMateSharp.Grammars;
using System.Collections.Generic;
namespace SourceGit.Views {
public class BlameTextEditor : TextEditor {
@ -37,10 +38,9 @@ namespace SourceGit.Views {
if (lineNumber > _editor.BlameData.LineInfos.Count) break;
var info = _editor.BlameData.LineInfos[lineNumber - 1];
if (!info.IsFirstInGroup) continue;
var x = 0.0;
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - view.VerticalOffset;
if (!info.IsFirstInGroup && y > view.DefaultLineHeight * 0.6) continue;
var shaLink = new FormattedText(
info.CommitSHA,
@ -76,7 +76,53 @@ namespace SourceGit.Views {
}
protected override Size MeasureOverride(Size availableSize) {
return new Size(250, 0);
var view = TextView;
var maxWidth = 0.0;
if (view != null && view.VisualLinesValid && _editor.BlameData != null) {
var typeface = view.CreateTypeface();
var calculated = new HashSet<string>();
foreach (var line in view.VisualLines) {
var lineNumber = line.FirstDocumentLine.LineNumber;
if (lineNumber > _editor.BlameData.LineInfos.Count) break;
var info = _editor.BlameData.LineInfos[lineNumber - 1];
if (calculated.Contains(info.CommitSHA)) continue;
calculated.Add(info.CommitSHA);
var x = 0.0;
var shaLink = new FormattedText(
info.CommitSHA,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
_editor.FontSize,
Brushes.DarkOrange);
x += shaLink.Width + 8;
var time = new FormattedText(
info.Time,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
_editor.FontSize,
_editor.Foreground);
x += time.Width + 8;
var author = new FormattedText(
info.Author,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
typeface,
_editor.FontSize,
_editor.Foreground);
x += author.Width;
if (maxWidth < x) maxWidth = x;
}
}
return new Size(maxWidth, 0);
}
protected override void OnPointerPressed(PointerPressedEventArgs e) {
@ -92,8 +138,6 @@ namespace SourceGit.Views {
if (lineNumber >= _editor.BlameData.LineInfos.Count) break;
var info = _editor.BlameData.LineInfos[lineNumber - 1];
if (!info.IsFirstInGroup) continue;
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - view.VerticalOffset;
var shaLink = new FormattedText(
info.CommitSHA,
@ -163,6 +207,7 @@ namespace SourceGit.Views {
TextArea.LeftMargins.Add(new CommitInfoMargin(this) { Margin = new Thickness(8, 0) });
TextArea.LeftMargins.Add(new VerticalSeperatorMargin(this));
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged;
TextArea.TextView.Margin = new Thickness(4, 0);
if (App.Current?.ActualThemeVariant == ThemeVariant.Dark) {
@ -180,6 +225,7 @@ namespace SourceGit.Views {
TextArea.LeftMargins.Clear();
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged -= OnTextViewVisualLinesChanged;
_registryOptions = null;
_textMate.Dispose();
@ -229,6 +275,15 @@ namespace SourceGit.Views {
e.Handled = true;
}
private void OnTextViewVisualLinesChanged(object sender, EventArgs e) {
foreach (var margin in TextArea.LeftMargins) {
if (margin is CommitInfoMargin commitInfo) {
commitInfo.InvalidateMeasure();
break;
}
}
}
private void UpdateGrammar() {
if (_textMate == null || BlameData == null) return;