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

View file

@ -15,6 +15,7 @@ using System;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using TextMateSharp.Grammars; using TextMateSharp.Grammars;
using System.Collections.Generic;
namespace SourceGit.Views { namespace SourceGit.Views {
public class BlameTextEditor : TextEditor { public class BlameTextEditor : TextEditor {
@ -37,10 +38,9 @@ namespace SourceGit.Views {
if (lineNumber > _editor.BlameData.LineInfos.Count) break; if (lineNumber > _editor.BlameData.LineInfos.Count) break;
var info = _editor.BlameData.LineInfos[lineNumber - 1]; var info = _editor.BlameData.LineInfos[lineNumber - 1];
if (!info.IsFirstInGroup) continue;
var x = 0.0; var x = 0.0;
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - view.VerticalOffset; var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - view.VerticalOffset;
if (!info.IsFirstInGroup && y > view.DefaultLineHeight * 0.6) continue;
var shaLink = new FormattedText( var shaLink = new FormattedText(
info.CommitSHA, info.CommitSHA,
@ -76,7 +76,53 @@ namespace SourceGit.Views {
} }
protected override Size MeasureOverride(Size availableSize) { 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) { protected override void OnPointerPressed(PointerPressedEventArgs e) {
@ -92,8 +138,6 @@ namespace SourceGit.Views {
if (lineNumber >= _editor.BlameData.LineInfos.Count) break; if (lineNumber >= _editor.BlameData.LineInfos.Count) break;
var info = _editor.BlameData.LineInfos[lineNumber - 1]; var info = _editor.BlameData.LineInfos[lineNumber - 1];
if (!info.IsFirstInGroup) continue;
var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - view.VerticalOffset; var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.TextTop) - view.VerticalOffset;
var shaLink = new FormattedText( var shaLink = new FormattedText(
info.CommitSHA, info.CommitSHA,
@ -163,6 +207,7 @@ namespace SourceGit.Views {
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.TextView.ContextRequested += OnTextViewContextRequested; TextArea.TextView.ContextRequested += OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged += OnTextViewVisualLinesChanged;
TextArea.TextView.Margin = new Thickness(4, 0); TextArea.TextView.Margin = new Thickness(4, 0);
if (App.Current?.ActualThemeVariant == ThemeVariant.Dark) { if (App.Current?.ActualThemeVariant == ThemeVariant.Dark) {
@ -180,6 +225,7 @@ namespace SourceGit.Views {
TextArea.LeftMargins.Clear(); TextArea.LeftMargins.Clear();
TextArea.TextView.ContextRequested -= OnTextViewContextRequested; TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
TextArea.TextView.VisualLinesChanged -= OnTextViewVisualLinesChanged;
_registryOptions = null; _registryOptions = null;
_textMate.Dispose(); _textMate.Dispose();
@ -229,6 +275,15 @@ namespace SourceGit.Views {
e.Handled = true; 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() { private void UpdateGrammar() {
if (_textMate == null || BlameData == null) return; if (_textMate == null || BlameData == null) return;