mirror of
https://fastgit.cc/github.com/sourcegit-scm/sourcegit
synced 2026-04-24 02:40:24 +08:00
Signed-off-by: leo <longshuang@msn.cn>
This commit is contained in:
@@ -7,7 +7,7 @@ namespace SourceGit.ViewModels
|
||||
{
|
||||
public record Block(int Start, int End)
|
||||
{
|
||||
public bool IsInRange(int line)
|
||||
public bool Contains(int line)
|
||||
{
|
||||
return line >= Start && line <= End;
|
||||
}
|
||||
@@ -27,7 +27,7 @@ namespace SourceGit.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public BlockNavigation(List<Models.TextDiffLine> lines)
|
||||
public BlockNavigation(List<Models.TextDiffLine> lines, bool gotoFirst)
|
||||
{
|
||||
_blocks.Clear();
|
||||
_current = -1;
|
||||
@@ -65,6 +65,9 @@ namespace SourceGit.ViewModels
|
||||
blocks.Add(new Block(blockStartIdx, lines.Count));
|
||||
|
||||
_blocks.AddRange(blocks);
|
||||
|
||||
if (gotoFirst)
|
||||
GotoFirst();
|
||||
}
|
||||
|
||||
public Block GetCurrentBlock()
|
||||
@@ -126,7 +129,7 @@ namespace SourceGit.ViewModels
|
||||
if (_current >= 0 && _current < _blocks.Count)
|
||||
{
|
||||
var block = _blocks[_current];
|
||||
if (block.IsInRange(caretLine))
|
||||
if (block.Contains(caretLine))
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
namespace SourceGit.ViewModels
|
||||
{
|
||||
public record TextDiffDisplayRange(int Start, int End);
|
||||
|
||||
public record TextDiffSelectedChunk(double Y, double Height, int StartIdx, int EndIdx, bool Combined, bool IsOldSide)
|
||||
{
|
||||
public static bool IsChanged(TextDiffSelectedChunk oldValue, TextDiffSelectedChunk newValue)
|
||||
@@ -24,10 +26,6 @@ namespace SourceGit.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public record TextDiffDisplayRange(int Start, int End)
|
||||
{
|
||||
}
|
||||
|
||||
public class TextDiffContext : ObservableObject
|
||||
{
|
||||
public Models.TextDiff Data => _data;
|
||||
@@ -147,10 +145,16 @@ namespace SourceGit.ViewModels
|
||||
public CombinedTextDiff(Models.TextDiff diff, CombinedTextDiff previous = null)
|
||||
{
|
||||
_data = diff;
|
||||
_blockNavigation = new BlockNavigation(_data.Lines);
|
||||
|
||||
if (previous != null && previous.File.Equals(File, StringComparison.Ordinal))
|
||||
_scrollOffset = previous.ScrollOffset;
|
||||
{
|
||||
_blockNavigation = new BlockNavigation(_data.Lines, false);
|
||||
_scrollOffset = previous._scrollOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
_blockNavigation = new BlockNavigation(_data.Lines, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override TextDiffContext SwitchMode()
|
||||
@@ -187,10 +191,16 @@ namespace SourceGit.ViewModels
|
||||
}
|
||||
|
||||
FillEmptyLines();
|
||||
_blockNavigation = new BlockNavigation(Old);
|
||||
|
||||
if (previous != null && previous.File.Equals(File, StringComparison.Ordinal))
|
||||
{
|
||||
_blockNavigation = new BlockNavigation(_data.Lines, false);
|
||||
_scrollOffset = previous._scrollOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
_blockNavigation = new BlockNavigation(_data.Lines, true);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsSideBySide()
|
||||
|
||||
@@ -221,7 +221,7 @@ namespace SourceGit.Views
|
||||
if (_presenter.Document == null || !textView.VisualLinesValid)
|
||||
return;
|
||||
|
||||
var changeBlock = _presenter.BlockNavigation?.GetCurrentBlock();
|
||||
var changeBlock = _presenter.BlockNavigation.GetCurrentBlock();
|
||||
var changeBlockBG = new SolidColorBrush(Colors.Gray, 0.25);
|
||||
var changeBlockFG = new Pen(Brushes.Gray);
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace SourceGit.Views
|
||||
}
|
||||
}
|
||||
|
||||
if (changeBlock != null && changeBlock.IsInRange(index))
|
||||
if (changeBlock != null && changeBlock.Contains(index))
|
||||
{
|
||||
drawingContext.DrawRectangle(changeBlockBG, null, new Rect(0, startY, width, endY - startY));
|
||||
if (index == changeBlock.Start)
|
||||
@@ -498,7 +498,7 @@ namespace SourceGit.Views
|
||||
|
||||
public virtual void GotoFirstChange()
|
||||
{
|
||||
var first = BlockNavigation?.GotoFirst();
|
||||
var first = BlockNavigation.GotoFirst();
|
||||
if (first != null)
|
||||
{
|
||||
TextArea.Caret.Line = first.Start;
|
||||
@@ -508,7 +508,7 @@ namespace SourceGit.Views
|
||||
|
||||
public virtual void GotoPrevChange()
|
||||
{
|
||||
var prev = BlockNavigation?.GotoPrev();
|
||||
var prev = BlockNavigation.GotoPrev();
|
||||
if (prev != null)
|
||||
{
|
||||
TextArea.Caret.Line = prev.Start;
|
||||
@@ -518,7 +518,7 @@ namespace SourceGit.Views
|
||||
|
||||
public virtual void GotoNextChange()
|
||||
{
|
||||
var next = BlockNavigation?.GotoNext();
|
||||
var next = BlockNavigation.GotoNext();
|
||||
if (next != null)
|
||||
{
|
||||
TextArea.Caret.Line = next.Start;
|
||||
@@ -528,7 +528,7 @@ namespace SourceGit.Views
|
||||
|
||||
public virtual void GotoLastChange()
|
||||
{
|
||||
var next = BlockNavigation?.GotoLast();
|
||||
var next = BlockNavigation.GotoLast();
|
||||
if (next != null)
|
||||
{
|
||||
TextArea.Caret.Line = next.Start;
|
||||
@@ -627,6 +627,23 @@ namespace SourceGit.Views
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnDataContextBeginUpdate()
|
||||
{
|
||||
base.OnDataContextBeginUpdate();
|
||||
AutoScrollToFirstChange();
|
||||
}
|
||||
|
||||
protected override void OnSizeChanged(SizeChangedEventArgs e)
|
||||
{
|
||||
base.OnSizeChanged(e);
|
||||
|
||||
if (!_execSizeChanged)
|
||||
{
|
||||
_execSizeChanged = true;
|
||||
AutoScrollToFirstChange();
|
||||
}
|
||||
}
|
||||
|
||||
private async void OnTextAreaKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.KeyModifiers.Equals(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control))
|
||||
@@ -644,7 +661,7 @@ namespace SourceGit.Views
|
||||
|
||||
private void OnTextAreaCaretPositionChanged(object sender, EventArgs e)
|
||||
{
|
||||
BlockNavigation?.UpdateByCaretPosition(TextArea?.Caret?.Line ?? 0);
|
||||
BlockNavigation.UpdateByCaretPosition(TextArea?.Caret?.Line ?? 0);
|
||||
}
|
||||
|
||||
private void OnTextViewContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
@@ -783,6 +800,34 @@ namespace SourceGit.Views
|
||||
}
|
||||
}
|
||||
|
||||
private void AutoScrollToFirstChange()
|
||||
{
|
||||
if (Bounds.Height < 0.1)
|
||||
return;
|
||||
|
||||
if (DataContext is not ViewModels.TextDiffContext ctx)
|
||||
return;
|
||||
|
||||
if (ctx.IsSideBySide() && !IsOld)
|
||||
return;
|
||||
|
||||
var curBlock = ctx.BlockNavigation.GetCurrentBlock();
|
||||
if (curBlock == null)
|
||||
return;
|
||||
|
||||
var lineHeight = TextArea.TextView.DefaultLineHeight;
|
||||
var vOffset = lineHeight * (curBlock.Start - 1) - Bounds.Height * 0.5;
|
||||
if (vOffset >= 0)
|
||||
{
|
||||
var scroller = this.FindDescendantOfType<ScrollViewer>();
|
||||
if (scroller != null)
|
||||
{
|
||||
ctx.ScrollOffset = new Vector(0, vOffset);
|
||||
scroller.Offset = ctx.ScrollOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task CopyWithoutIndicatorsAsync()
|
||||
{
|
||||
var selection = TextArea.Selection;
|
||||
@@ -852,6 +897,7 @@ namespace SourceGit.Views
|
||||
await App.CopyTextAsync(builder.ToString());
|
||||
}
|
||||
|
||||
private bool _execSizeChanged = false;
|
||||
private TextMate.Installation _textMate = null;
|
||||
private TextLocation _lastSelectStart = TextLocation.Empty;
|
||||
private TextLocation _lastSelectEnd = TextLocation.Empty;
|
||||
|
||||
Reference in New Issue
Block a user