Skip to content

Commit e0d48bb

Browse files
committed
fix: arrows work
1 parent e1c9cd9 commit e0d48bb

File tree

1 file changed

+102
-35
lines changed

1 file changed

+102
-35
lines changed

src/Views/MergeConflictEditor.axaml.cs

Lines changed: 102 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
using Avalonia;
88
using Avalonia.Controls;
9+
using Avalonia.Data;
910
using Avalonia.Input;
1011
using Avalonia.Interactivity;
1112
using Avalonia.Media;
@@ -184,11 +185,6 @@ public int CurrentConflictEndLine
184185
TextArea.TextView.LineTransformers.Add(new MergeDiffIndicatorTransformer(this));
185186
}
186187

187-
public ScrollViewer GetScrollViewer()
188-
{
189-
return _scrollViewer;
190-
}
191-
192188
protected override void OnLoaded(RoutedEventArgs e)
193189
{
194190
base.OnLoaded(e);
@@ -198,36 +194,17 @@ protected override void OnLoaded(RoutedEventArgs e)
198194
Models.TextMateHelper.SetGrammarByFileName(_textMate, FileName);
199195

200196
TextArea.TextView.ContextRequested += OnTextViewContextRequested;
201-
202-
_scrollViewer = this.FindDescendantOfType<ScrollViewer>();
203-
if (_scrollViewer != null)
204-
{
205-
_scrollViewer.ScrollChanged += OnScrollViewerScrollChanged;
206-
_scrollViewer.Bind(ScrollViewer.OffsetProperty, new Avalonia.Data.Binding("ScrollOffset", Avalonia.Data.BindingMode.OneWay));
207-
}
208197
}
209198

210-
private void OnScrollViewerScrollChanged(object sender, ScrollChangedEventArgs e)
199+
public ScrollViewer GetScrollViewer()
211200
{
212-
if (_scrollViewer == null || DataContext is not ViewModels.MergeConflictEditor vm)
213-
return;
214-
215-
if (vm.ScrollOffset.NearlyEquals(_scrollViewer.Offset))
216-
return;
217-
218-
if (IsPointerOver || e.OffsetDelta.SquaredLength > 1.0f)
219-
{
220-
vm.ScrollOffset = _scrollViewer.Offset;
221-
}
201+
_scrollViewer ??= this.FindDescendantOfType<ScrollViewer>();
202+
return _scrollViewer;
222203
}
223204

224205
protected override void OnUnloaded(RoutedEventArgs e)
225206
{
226-
if (_scrollViewer != null)
227-
{
228-
_scrollViewer.ScrollChanged -= OnScrollViewerScrollChanged;
229-
_scrollViewer = null;
230-
}
207+
_scrollViewer = null;
231208

232209
TextArea.TextView.ContextRequested -= OnTextViewContextRequested;
233210

@@ -606,12 +583,68 @@ protected override void OnOpened(EventArgs e)
606583
_theirsPresenter = this.FindControl<MergeDiffPresenter>("TheirsPresenter");
607584
_resultPresenter = this.FindControl<MergeDiffPresenter>("ResultPresenter");
608585

586+
// Set up scroll synchronization
587+
SetupScrollSync();
588+
609589
if (DataContext is ViewModels.MergeConflictEditor vm)
610590
{
611591
vm.PropertyChanged += OnViewModelPropertyChanged;
612592
}
613593
}
614594

595+
private void SetupScrollSync()
596+
{
597+
var oursScroll = _oursPresenter?.GetScrollViewer();
598+
var theirsScroll = _theirsPresenter?.GetScrollViewer();
599+
var resultScroll = _resultPresenter?.GetScrollViewer();
600+
601+
if (oursScroll != null)
602+
oursScroll.ScrollChanged += OnPanelScrollChanged;
603+
if (theirsScroll != null)
604+
theirsScroll.ScrollChanged += OnPanelScrollChanged;
605+
if (resultScroll != null)
606+
resultScroll.ScrollChanged += OnPanelScrollChanged;
607+
}
608+
609+
private void OnPanelScrollChanged(object sender, ScrollChangedEventArgs e)
610+
{
611+
if (_isSyncingScroll || sender is not ScrollViewer source)
612+
return;
613+
614+
// Only sync if this panel initiated the scroll (pointer is over it or significant delta)
615+
var presenter = source.FindAncestorOfType<MergeDiffPresenter>();
616+
if (presenter == null)
617+
return;
618+
619+
if (!presenter.IsPointerOver && e.OffsetDelta.SquaredLength <= 1.0f)
620+
return;
621+
622+
_isSyncingScroll = true;
623+
try
624+
{
625+
var offset = source.Offset;
626+
627+
var oursScroll = _oursPresenter?.GetScrollViewer();
628+
var theirsScroll = _theirsPresenter?.GetScrollViewer();
629+
var resultScroll = _resultPresenter?.GetScrollViewer();
630+
631+
if (oursScroll != null && oursScroll != source)
632+
oursScroll.Offset = offset;
633+
if (theirsScroll != null && theirsScroll != source)
634+
theirsScroll.Offset = offset;
635+
if (resultScroll != null && resultScroll != source)
636+
resultScroll.Offset = offset;
637+
638+
// Update ViewModel
639+
if (DataContext is ViewModels.MergeConflictEditor vm)
640+
vm.ScrollOffset = offset;
641+
}
642+
finally
643+
{
644+
_isSyncingScroll = false;
645+
}
646+
}
647+
615648
private void OnViewModelPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
616649
{
617650
if (e.PropertyName == nameof(ViewModels.MergeConflictEditor.IsLoading))
@@ -694,12 +727,6 @@ protected override async void OnClosing(WindowClosingEventArgs e)
694727
}
695728
}
696729

697-
protected override void OnClosed(EventArgs e)
698-
{
699-
base.OnClosed(e);
700-
GC.Collect();
701-
}
702-
703730
protected override void OnKeyDown(KeyEventArgs e)
704731
{
705732
base.OnKeyDown(e);
@@ -855,12 +882,52 @@ private void ScrollToCurrentConflict()
855882
var lineHeight = _oursPresenter.TextArea.TextView.DefaultLineHeight;
856883
var vOffset = lineHeight * vm.CurrentConflictLine;
857884
var targetOffset = new Vector(0, Math.Max(0, vOffset - _oursPresenter.Bounds.Height * 0.3));
858-
vm.ScrollOffset = targetOffset;
885+
886+
// Sync all panels to this offset
887+
_isSyncingScroll = true;
888+
try
889+
{
890+
var oursScroll = _oursPresenter?.GetScrollViewer();
891+
var theirsScroll = _theirsPresenter?.GetScrollViewer();
892+
var resultScroll = _resultPresenter?.GetScrollViewer();
893+
894+
if (oursScroll != null)
895+
oursScroll.Offset = targetOffset;
896+
if (theirsScroll != null)
897+
theirsScroll.Offset = targetOffset;
898+
if (resultScroll != null)
899+
resultScroll.Offset = targetOffset;
900+
901+
vm.ScrollOffset = targetOffset;
902+
}
903+
finally
904+
{
905+
_isSyncingScroll = false;
906+
}
859907
}
860908
}
861909
}
862910

911+
protected override void OnClosed(EventArgs e)
912+
{
913+
// Clean up scroll handlers
914+
var oursScroll = _oursPresenter?.GetScrollViewer();
915+
var theirsScroll = _theirsPresenter?.GetScrollViewer();
916+
var resultScroll = _resultPresenter?.GetScrollViewer();
917+
918+
if (oursScroll != null)
919+
oursScroll.ScrollChanged -= OnPanelScrollChanged;
920+
if (theirsScroll != null)
921+
theirsScroll.ScrollChanged -= OnPanelScrollChanged;
922+
if (resultScroll != null)
923+
resultScroll.ScrollChanged -= OnPanelScrollChanged;
924+
925+
base.OnClosed(e);
926+
GC.Collect();
927+
}
928+
863929
private bool _forceClose = false;
930+
private bool _isSyncingScroll = false;
864931
private MergeDiffPresenter _oursPresenter;
865932
private MergeDiffPresenter _theirsPresenter;
866933
private MergeDiffPresenter _resultPresenter;

0 commit comments

Comments
 (0)