mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
feature<TextDiffView>: do NOT reset scroll offset after recompute diff with same change
This commit is contained in:
parent
096fd6cb22
commit
2b97d7c599
5 changed files with 38 additions and 12 deletions
|
@ -1,4 +1,5 @@
|
||||||
using Avalonia.Threading;
|
using Avalonia;
|
||||||
|
using Avalonia.Threading;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
@ -49,6 +50,11 @@ namespace SourceGit.ViewModels {
|
||||||
private set => SetProperty(ref _content, value);
|
private set => SetProperty(ref _content, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector SyncScrollOffset {
|
||||||
|
get => _syncScrollOffset;
|
||||||
|
set => SetProperty(ref _syncScrollOffset, value);
|
||||||
|
}
|
||||||
|
|
||||||
public DiffContext(string repo, Models.DiffOption option) {
|
public DiffContext(string repo, Models.DiffOption option) {
|
||||||
_repo = repo;
|
_repo = repo;
|
||||||
_option = option;
|
_option = option;
|
||||||
|
@ -113,5 +119,6 @@ namespace SourceGit.ViewModels {
|
||||||
private bool _isNoChange = false;
|
private bool _isNoChange = false;
|
||||||
private bool _isTextDiff = false;
|
private bool _isTextDiff = false;
|
||||||
private object _content = null;
|
private object _content = null;
|
||||||
|
private Vector _syncScrollOffset = Vector.Zero;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,6 @@ using System.Collections.Generic;
|
||||||
|
|
||||||
namespace SourceGit.ViewModels {
|
namespace SourceGit.ViewModels {
|
||||||
public class TwoSideTextDiff : ObservableObject {
|
public class TwoSideTextDiff : ObservableObject {
|
||||||
public Vector SyncScrollOffset {
|
|
||||||
get => _syncScrollOffset;
|
|
||||||
set => SetProperty(ref _syncScrollOffset, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public string File { get; set; } = string.Empty;
|
public string File { get; set; } = string.Empty;
|
||||||
public List<Models.TextDiffLine> Old { get; set; } = new List<Models.TextDiffLine>();
|
public List<Models.TextDiffLine> Old { get; set; } = new List<Models.TextDiffLine>();
|
||||||
public List<Models.TextDiffLine> New { get; set; } = new List<Models.TextDiffLine>();
|
public List<Models.TextDiffLine> New { get; set; } = new List<Models.TextDiffLine>();
|
||||||
|
@ -46,7 +41,5 @@ namespace SourceGit.ViewModels {
|
||||||
for (int i = 0; i < diff; i++) New.Add(new Models.TextDiffLine());
|
for (int i = 0; i < diff; i++) New.Add(new Models.TextDiffLine());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector _syncScrollOffset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using Avalonia.Controls;
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
using Avalonia.Platform.Storage;
|
using Avalonia.Platform.Storage;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
@ -194,6 +195,9 @@ namespace SourceGit.ViewModels {
|
||||||
|
|
||||||
// Restore last selection states.
|
// Restore last selection states.
|
||||||
if (viewChange != null) {
|
if (viewChange != null) {
|
||||||
|
var scrollOffset = Vector.Zero;
|
||||||
|
if (_detailContext is DiffContext old) scrollOffset = old.SyncScrollOffset;
|
||||||
|
|
||||||
if (lastSelectedIsUnstaged) {
|
if (lastSelectedIsUnstaged) {
|
||||||
SelectedUnstagedChange = viewChange;
|
SelectedUnstagedChange = viewChange;
|
||||||
SelectedUnstagedTreeNode = FileTreeNode.SelectByPath(_unstagedTree, viewFile);
|
SelectedUnstagedTreeNode = FileTreeNode.SelectByPath(_unstagedTree, viewFile);
|
||||||
|
@ -201,6 +205,8 @@ namespace SourceGit.ViewModels {
|
||||||
SelectedStagedChange = viewChange;
|
SelectedStagedChange = viewChange;
|
||||||
SelectedStagedTreeNode = FileTreeNode.SelectByPath(_stagedTree, viewFile);
|
SelectedStagedTreeNode = FileTreeNode.SelectByPath(_stagedTree, viewFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_detailContext is DiffContext cur) cur.SyncScrollOffset = scrollOffset;
|
||||||
} else {
|
} else {
|
||||||
SelectedUnstagedChange = null;
|
SelectedUnstagedChange = null;
|
||||||
SelectedUnstagedTreeNode = null;
|
SelectedUnstagedTreeNode = null;
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
SecondaryFG="{DynamicResource Brush.FG2}"
|
SecondaryFG="{DynamicResource Brush.FG2}"
|
||||||
FontFamily="{StaticResource JetBrainsMono}"
|
FontFamily="{StaticResource JetBrainsMono}"
|
||||||
FontSize="12"
|
FontSize="12"
|
||||||
DiffData="{Binding}"/>
|
DiffData="{Binding}"
|
||||||
|
SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
|
|
||||||
<DataTemplate DataType="vm:TwoSideTextDiff">
|
<DataTemplate DataType="vm:TwoSideTextDiff">
|
||||||
<Grid ColumnDefinitions="*,1,*">
|
<Grid ColumnDefinitions="*,1,*">
|
||||||
<v:SingleSideTextDiffPresenter Grid.Column="0"
|
<v:SingleSideTextDiffPresenter Grid.Column="0"
|
||||||
SyncScrollOffset="{Binding SyncScrollOffset, Mode=TwoWay}"
|
SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"
|
||||||
IsOld="True"
|
IsOld="True"
|
||||||
HorizontalScrollBarVisibility="Auto"
|
HorizontalScrollBarVisibility="Auto"
|
||||||
VerticalScrollBarVisibility="Auto"
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
@ -39,7 +40,7 @@
|
||||||
<Rectangle Grid.Column="1" Fill="{DynamicResource Brush.Border2}" Width="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
|
<Rectangle Grid.Column="1" Fill="{DynamicResource Brush.Border2}" Width="1" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
|
||||||
|
|
||||||
<v:SingleSideTextDiffPresenter Grid.Column="2"
|
<v:SingleSideTextDiffPresenter Grid.Column="2"
|
||||||
SyncScrollOffset="{Binding SyncScrollOffset, Mode=TwoWay}"
|
SyncScrollOffset="{Binding $parent[v:DiffView].DataContext.(vm:DiffContext).SyncScrollOffset, Mode=TwoWay}"
|
||||||
IsOld="False"
|
IsOld="False"
|
||||||
HorizontalScrollBarVisibility="Auto"
|
HorizontalScrollBarVisibility="Auto"
|
||||||
VerticalScrollBarVisibility="Auto"
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
|
|
@ -188,6 +188,14 @@ namespace SourceGit.Views {
|
||||||
set => SetValue(SecondaryFGProperty, value);
|
set => SetValue(SecondaryFGProperty, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<Vector> SyncScrollOffsetProperty =
|
||||||
|
AvaloniaProperty.Register<SingleSideTextDiffPresenter, Vector>(nameof(SyncScrollOffset));
|
||||||
|
|
||||||
|
public Vector SyncScrollOffset {
|
||||||
|
get => GetValue(SyncScrollOffsetProperty);
|
||||||
|
set => SetValue(SyncScrollOffsetProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
protected override Type StyleKeyOverride => typeof(TextEditor);
|
protected override Type StyleKeyOverride => typeof(TextEditor);
|
||||||
|
|
||||||
public CombinedTextDiffPresenter() : base(new TextArea(), new TextDocument()) {
|
public CombinedTextDiffPresenter() : base(new TextArea(), new TextDocument()) {
|
||||||
|
@ -208,6 +216,7 @@ namespace SourceGit.Views {
|
||||||
TextArea.TextView.BackgroundRenderers.Add(new LineBackgroundRenderer(this));
|
TextArea.TextView.BackgroundRenderers.Add(new LineBackgroundRenderer(this));
|
||||||
TextArea.TextView.LineTransformers.Add(new LineStyleTransformer(this, SecondaryFG));
|
TextArea.TextView.LineTransformers.Add(new LineStyleTransformer(this, SecondaryFG));
|
||||||
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
|
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
|
||||||
|
TextArea.TextView.ScrollOffsetChanged += OnTextViewScrollOffsetChanged;
|
||||||
|
|
||||||
if (App.Current?.ActualThemeVariant == ThemeVariant.Dark) {
|
if (App.Current?.ActualThemeVariant == ThemeVariant.Dark) {
|
||||||
_registryOptions = new RegistryOptions(ThemeName.DarkPlus);
|
_registryOptions = new RegistryOptions(ThemeName.DarkPlus);
|
||||||
|
@ -226,6 +235,7 @@ namespace SourceGit.Views {
|
||||||
TextArea.TextView.BackgroundRenderers.Clear();
|
TextArea.TextView.BackgroundRenderers.Clear();
|
||||||
TextArea.TextView.LineTransformers.Clear();
|
TextArea.TextView.LineTransformers.Clear();
|
||||||
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
|
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
|
||||||
|
TextArea.TextView.ScrollOffsetChanged -= OnTextViewScrollOffsetChanged;
|
||||||
_registryOptions = null;
|
_registryOptions = null;
|
||||||
_textMate.Dispose();
|
_textMate.Dispose();
|
||||||
_textMate = null;
|
_textMate = null;
|
||||||
|
@ -255,6 +265,10 @@ namespace SourceGit.Views {
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnTextViewScrollOffsetChanged(object sender, EventArgs e) {
|
||||||
|
SyncScrollOffset = TextArea.TextView.ScrollOffset;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) {
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) {
|
||||||
base.OnPropertyChanged(change);
|
base.OnPropertyChanged(change);
|
||||||
|
|
||||||
|
@ -270,6 +284,11 @@ namespace SourceGit.Views {
|
||||||
} else {
|
} else {
|
||||||
Text = string.Empty;
|
Text = string.Empty;
|
||||||
}
|
}
|
||||||
|
} else if (change.Property == SyncScrollOffsetProperty) {
|
||||||
|
if (TextArea.TextView.ScrollOffset != SyncScrollOffset) {
|
||||||
|
IScrollable scrollable = TextArea.TextView;
|
||||||
|
scrollable.Offset = SyncScrollOffset;
|
||||||
|
}
|
||||||
} else if (change.Property.Name == "ActualThemeVariant" && change.NewValue != null && _textMate != null) {
|
} else if (change.Property.Name == "ActualThemeVariant" && change.NewValue != null && _textMate != null) {
|
||||||
if (App.Current?.ActualThemeVariant == ThemeVariant.Dark) {
|
if (App.Current?.ActualThemeVariant == ThemeVariant.Dark) {
|
||||||
_textMate.SetTheme(_registryOptions.LoadTheme(ThemeName.DarkPlus));
|
_textMate.SetTheme(_registryOptions.LoadTheme(ThemeName.DarkPlus));
|
||||||
|
|
Loading…
Reference in a new issue