From d4302b4faa713f3ca045e34302586a62fed9aec0 Mon Sep 17 00:00:00 2001 From: leo Date: Wed, 23 Oct 2024 15:19:59 +0800 Subject: [PATCH] refactor: render `+`/`-` marks after line number Signed-off-by: leo --- src/Views/TextDiffView.axaml.cs | 121 ++++++++++++++++++++++++-------- 1 file changed, 91 insertions(+), 30 deletions(-) diff --git a/src/Views/TextDiffView.axaml.cs b/src/Views/TextDiffView.axaml.cs index 4a450e0a..7a2725d2 100644 --- a/src/Views/TextDiffView.axaml.cs +++ b/src/Views/TextDiffView.axaml.cs @@ -72,6 +72,8 @@ namespace SourceGit.Views { _usePresenter = usePresenter; _isOld = isOld; + + Margin = new Thickness(8, 0); ClipToBounds = true; } @@ -105,32 +107,6 @@ namespace SourceGit.Views continue; var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineMiddle) - view.VerticalOffset; - - var prefix = null as FormattedText; - if (info.Type == Models.TextDiffLineType.Added) - { - prefix = new FormattedText( - "+", - CultureInfo.CurrentCulture, - FlowDirection.LeftToRight, - typeface, - presenter.FontSize, - Brushes.Green); - } - else if (info.Type == Models.TextDiffLineType.Deleted) - { - prefix = new FormattedText( - "-", - CultureInfo.CurrentCulture, - FlowDirection.LeftToRight, - typeface, - presenter.FontSize, - Brushes.Red); - } - - if (prefix != null) - context.DrawText(prefix, new Point(0, y - prefix.Height * 0.5)); - var txt = new FormattedText( lineNumber, CultureInfo.CurrentCulture, @@ -152,7 +128,7 @@ namespace SourceGit.Views var maxLineNumber = presenter.GetMaxLineNumber(); var typeface = TextView.CreateTypeface(); var test = new FormattedText( - $"- {maxLineNumber}", + $"{maxLineNumber}", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, @@ -171,6 +147,89 @@ namespace SourceGit.Views private bool _isOld = false; } + public class LineModifyTypeMargin : AbstractMargin + { + public LineModifyTypeMargin() + { + Margin = new Thickness(1, 0); + ClipToBounds = true; + } + + public override void Render(DrawingContext context) + { + var presenter = this.FindAncestorOfType(); + if (presenter == null) + return; + + var lines = presenter.GetLines(); + var view = TextView; + if (view != null && view.VisualLinesValid) + { + var typeface = view.CreateTypeface(); + foreach (var line in view.VisualLines) + { + if (line.IsDisposed || line.FirstDocumentLine == null || line.FirstDocumentLine.IsDeleted) + continue; + + var index = line.FirstDocumentLine.LineNumber; + if (index > lines.Count) + break; + + var info = lines[index - 1]; + var y = line.GetTextLineVisualYPosition(line.TextLines[0], VisualYPosition.LineMiddle) - view.VerticalOffset; + var indicator = null as FormattedText; + if (info.Type == Models.TextDiffLineType.Added) + { + indicator = new FormattedText( + "+", + CultureInfo.CurrentCulture, + FlowDirection.LeftToRight, + typeface, + presenter.FontSize, + Brushes.Green); + } + else if (info.Type == Models.TextDiffLineType.Deleted) + { + indicator = new FormattedText( + "-", + CultureInfo.CurrentCulture, + FlowDirection.LeftToRight, + typeface, + presenter.FontSize, + Brushes.Red); + } + + if (indicator != null) + context.DrawText(indicator, new Point(0, y - indicator.Height * 0.5)); + } + } + } + + protected override Size MeasureOverride(Size availableSize) + { + var presenter = this.FindAncestorOfType(); + if (presenter == null) + return new Size(0, 0); + + var maxLineNumber = presenter.GetMaxLineNumber(); + var typeface = TextView.CreateTypeface(); + var test = new FormattedText( + $"-", + CultureInfo.CurrentCulture, + FlowDirection.LeftToRight, + typeface, + presenter.FontSize, + Brushes.White); + return new Size(test.Width, 0); + } + + protected override void OnDataContextChanged(EventArgs e) + { + base.OnDataContextChanged(e); + InvalidateMeasure(); + } + } + public class LineBackgroundRenderer : IBackgroundRenderer { public KnownLayer Layer => KnownLayer.Background; @@ -700,10 +759,11 @@ namespace SourceGit.Views { public CombinedTextDiffPresenter() : base(new TextArea(), new TextDocument()) { - TextArea.LeftMargins.Add(new LineNumberMargin(false, true) { Margin = new Thickness(8, 0) }); + TextArea.LeftMargins.Add(new LineNumberMargin(false, true)); TextArea.LeftMargins.Add(new VerticalSeperatorMargin()); - TextArea.LeftMargins.Add(new LineNumberMargin(false, false) { Margin = new Thickness(8, 0) }); + TextArea.LeftMargins.Add(new LineNumberMargin(false, false)); TextArea.LeftMargins.Add(new VerticalSeperatorMargin()); + TextArea.LeftMargins.Add(new LineModifyTypeMargin()); } public override List GetLines() @@ -904,8 +964,9 @@ namespace SourceGit.Views { public SingleSideTextDiffPresenter() : base(new TextArea(), new TextDocument()) { - TextArea.LeftMargins.Add(new LineNumberMargin(true, false) { Margin = new Thickness(8, 0) }); + TextArea.LeftMargins.Add(new LineNumberMargin(true, false)); TextArea.LeftMargins.Add(new VerticalSeperatorMargin()); + TextArea.LeftMargins.Add(new LineModifyTypeMargin()); } public override List GetLines()