fix(diff): resolve themed brushes and stop recomputing alignment on layout toggle
This commit is contained in:
@@ -76,23 +76,34 @@ public partial class DiffTextView : UserControl
|
|||||||
_leftTm = LeftEditor.InstallTextMate(Registry);
|
_leftTm = LeftEditor.InstallTextMate(Registry);
|
||||||
_rightTm = RightEditor.InstallTextMate(Registry);
|
_rightTm = RightEditor.InstallTextMate(Registry);
|
||||||
InstallRenderers();
|
InstallRenderers();
|
||||||
Rebuild();
|
ReloadFile();
|
||||||
HookScrollSync();
|
HookScrollSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
|
||||||
{
|
{
|
||||||
base.OnPropertyChanged(change);
|
base.OnPropertyChanged(change);
|
||||||
if (change.Property == FileProperty || change.Property == IsSplitProperty)
|
if (change.Property == FileProperty)
|
||||||
Rebuild();
|
ReloadFile();
|
||||||
|
else if (change.Property == IsSplitProperty)
|
||||||
|
RefreshLayout();
|
||||||
else if (change.Property == WrapLinesProperty)
|
else if (change.Property == WrapLinesProperty)
|
||||||
ApplyWrap();
|
ApplyWrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Rebuild()
|
/// Recomputes the alignment (word-diff LCS) for the current <see cref="File"/> and then
|
||||||
|
/// refreshes everything downstream of it. Only ever needed when the file actually changes.
|
||||||
|
private void ReloadFile()
|
||||||
{
|
{
|
||||||
_aligned = DiffAlignment.Build(File?.Lines);
|
_aligned = DiffAlignment.Build(File?.Lines);
|
||||||
|
RefreshLayout();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Re-applies the current <see cref="_aligned"/> to the editors for the current layout
|
||||||
|
/// (split vs unified). A single <see cref="AlignedDiff"/> already carries both row sets,
|
||||||
|
/// so toggling <see cref="IsSplit"/> never needs to re-run the alignment.
|
||||||
|
private void RefreshLayout()
|
||||||
|
{
|
||||||
var split = IsSplit;
|
var split = IsSplit;
|
||||||
RightEditor.IsVisible = split;
|
RightEditor.IsVisible = split;
|
||||||
PaneDivider.IsVisible = split;
|
PaneDivider.IsVisible = split;
|
||||||
@@ -181,7 +192,7 @@ public partial class DiffTextView : UserControl
|
|||||||
}
|
}
|
||||||
|
|
||||||
private IBrush Brush(string key, Color fallback) =>
|
private IBrush Brush(string key, Color fallback) =>
|
||||||
this.TryGetResource(key, ActualThemeVariant, out var value) && value is IBrush brush
|
this.TryFindResource(key, out var value) && value is IBrush brush
|
||||||
? brush
|
? brush
|
||||||
: new SolidColorBrush(fallback);
|
: new SolidColorBrush(fallback);
|
||||||
|
|
||||||
@@ -235,11 +246,20 @@ public partial class DiffTextView : UserControl
|
|||||||
if (WrapLines)
|
if (WrapLines)
|
||||||
{
|
{
|
||||||
// Line heights differ once lines wrap, so anchor on the top visible line.
|
// Line heights differ once lines wrap, so anchor on the top visible line.
|
||||||
|
// ScrollToLine/ScrollTo are "bring into view" primitives (they park the line
|
||||||
|
// near mid-viewport past a hysteresis threshold) — top-align by computing the
|
||||||
|
// target's own vertical offset for that document line and assigning it
|
||||||
|
// directly, the same way the non-wrap branch assigns Offset below. That is
|
||||||
|
// synchronous, so the same offset-comparison guard makes the echo self-terminate.
|
||||||
var topLine = sourceEditor.TextArea.TextView.VisualLines is { Count: > 0 } visualLines
|
var topLine = sourceEditor.TextArea.TextView.VisualLines is { Count: > 0 } visualLines
|
||||||
? visualLines[0].FirstDocumentLine.LineNumber
|
? visualLines[0].FirstDocumentLine.LineNumber
|
||||||
: (int?)null;
|
: (int?)null;
|
||||||
if (topLine is { } line && line >= 1 && line <= targetEditor.Document.LineCount)
|
if (topLine is { } line && line >= 1 && line <= targetEditor.Document.LineCount)
|
||||||
targetEditor.ScrollToLine(line);
|
{
|
||||||
|
var targetTop = targetEditor.TextArea.TextView.GetVisualTopByDocumentLine(line);
|
||||||
|
if (Math.Abs(target.Offset.Y - targetTop) > 0.5)
|
||||||
|
target.Offset = new Vector(target.Offset.X, targetTop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (Math.Abs(target.Offset.Y - source.Offset.Y) > 0.5)
|
else if (Math.Abs(target.Offset.Y - source.Offset.Y) > 0.5)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user