refactor: implementation of synchronous scrolling in side-by-side diff view

This commit is contained in:
leo 2024-04-28 16:46:39 +08:00
parent 32e685622b
commit d9911b3447
2 changed files with 14 additions and 30 deletions

View file

@ -388,11 +388,11 @@ namespace SourceGit.Models
} }
[GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")] [GeneratedRegex(@"^@@ \-(\d+),?\d* \+(\d+),?\d* @@")]
private static partial Regex indicatorRegex(); private static partial Regex REG_INDICATOR();
private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed) private bool ProcessIndicatorForPatch(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool tailed)
{ {
var match = indicatorRegex().Match(indicator.Content); var match = REG_INDICATOR().Match(indicator.Content);
var oldStart = int.Parse(match.Groups[1].Value); var oldStart = int.Parse(match.Groups[1].Value);
var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds; var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds;
var oldCount = 0; var oldCount = 0;
@ -461,7 +461,7 @@ namespace SourceGit.Models
private bool ProcessIndicatorForPatchSingleSide(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool isOldSide, bool tailed) private bool ProcessIndicatorForPatchSingleSide(StringBuilder builder, TextDiffLine indicator, int idx, int start, int end, int ignoreRemoves, int ignoreAdds, bool revert, bool isOldSide, bool tailed)
{ {
var match = indicatorRegex().Match(indicator.Content); var match = REG_INDICATOR().Match(indicator.Content);
var oldStart = int.Parse(match.Groups[1].Value); var oldStart = int.Parse(match.Groups[1].Value);
var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds; var newStart = int.Parse(match.Groups[2].Value) + ignoreRemoves - ignoreAdds;
var oldCount = 0; var oldCount = 0;

View file

@ -7,6 +7,7 @@ using System.Text;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.VisualTree; using Avalonia.VisualTree;
@ -657,6 +658,7 @@ namespace SourceGit.Views
UpdateTextMate(); UpdateTextMate();
TextArea.PointerWheelChanged += OnTextAreaPointerWheelChanged;
TextArea.TextView.ContextRequested += OnTextViewContextRequested; TextArea.TextView.ContextRequested += OnTextViewContextRequested;
} }
@ -676,21 +678,20 @@ namespace SourceGit.Views
_textMate = null; _textMate = null;
} }
TextArea.PointerWheelChanged -= OnTextAreaPointerWheelChanged;
TextArea.TextView.ContextRequested -= OnTextViewContextRequested; TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
GC.Collect(); GC.Collect();
} }
private void OnTextAreaPointerWheelChanged(object sender, PointerWheelEventArgs e)
{
if (!TextArea.IsFocused) Focus();
}
private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e) private void OnTextViewScrollChanged(object sender, ScrollChangedEventArgs e)
{ {
if (_syncScrollingByOthers) if (TextArea.IsFocused) SetCurrentValue(SyncScrollOffsetProperty, _scrollViewer.Offset);
{
_syncScrollingByOthers = false;
}
else
{
SetCurrentValue(SyncScrollOffsetProperty, _scrollViewer.Offset);
}
} }
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e) private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
@ -754,25 +755,9 @@ namespace SourceGit.Views
} }
else if (change.Property == SyncScrollOffsetProperty) else if (change.Property == SyncScrollOffsetProperty)
{ {
if (_scrollViewer == null) if (_scrollViewer != null)
return;
var curOffset = _scrollViewer.Offset;
if (!curOffset.Equals(SyncScrollOffset))
{
_syncScrollingByOthers = true;
if (curOffset.X != SyncScrollOffset.X)
{
var offset = new Vector(Math.Min(_scrollViewer.ScrollBarMaximum.X, SyncScrollOffset.X), SyncScrollOffset.Y);
_scrollViewer.Offset = offset;
}
else
{
_scrollViewer.Offset = SyncScrollOffset; _scrollViewer.Offset = SyncScrollOffset;
} }
}
}
else if (change.Property == UseSyntaxHighlightingProperty) else if (change.Property == UseSyntaxHighlightingProperty)
{ {
UpdateTextMate(); UpdateTextMate();
@ -813,7 +798,6 @@ namespace SourceGit.Views
private TextMate.Installation _textMate; private TextMate.Installation _textMate;
private readonly LineStyleTransformer _lineStyleTransformer = null; private readonly LineStyleTransformer _lineStyleTransformer = null;
private ScrollViewer _scrollViewer = null; private ScrollViewer _scrollViewer = null;
private bool _syncScrollingByOthers = false;
} }
public partial class TextDiffView : UserControl public partial class TextDiffView : UserControl