Skip to content

Callback-based zoom/offset workaround for Avalonia PanAndZoom#4

Draft
Copilot wants to merge 1 commit intodevelopfrom
copilot/implement-zoom-offset-workaround
Draft

Callback-based zoom/offset workaround for Avalonia PanAndZoom#4
Copilot wants to merge 1 commit intodevelopfrom
copilot/implement-zoom-offset-workaround

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 12, 2026

Avalonia's PanAndZoom ZoomBorder only exposes zoom and offset as read-only (unlike WPF's two-way bindable ZoomPanel), and the absolute offset values are unreliable. This makes the existing ViewTabViewModel binding-driven approach non-functional for Avalonia.

Approach

Adds a readOnlyZoomAndOffsets constructor parameter to ViewTabViewModel (default false, WPF untouched). When true, programmatic view changes (Fill, Fit, Zoom100, scrolling) use registered callbacks that directly manipulate ZoomBorder.SetMatrix() instead of pushing values through bindings.

Changes

  • ViewTabViewModel — new bool readOnlyZoomAndOffsets ctor param; ApplyTransformCallback(zoom, tx, ty) for absolute transforms; PanStepCallback(dx, dy) for incremental panning. All mutating methods (Fill, Fit, Zoom100, DefferedFill, StartScrollingAsync) branch on the flag.
  • MainWindow.Methods.axaml.csRegisterZoomBorderCallbacks() wires callbacks to ZoomBorder.SetMatrix() via Dispatcher.UIThread.Post
  • MainWindow.axaml.cs — registers callbacks on Opened for both source/target panels
  • MainWindow.axaml — removed PanelAttributesAP.* and OffsetX/OffsetY bindings from both ZoomBorders (replaced by callbacks); retained ZoomX/ZoomY OneWayToSource so the VM still reads gesture zoom
  • App.DI.axaml.cs — passes readOnlyZoomAndOffsets: true for both ViewTabViewModel registrations

WPF project: zero files changed.

// Avalonia view registration
viewTab.ApplyTransformCallback = (zoom, tx, ty) =>
{
    Dispatcher.UIThread.Post(() =>
    {
        panel.SetMatrix(Matrix.CreateScale(zoom, zoom) *
                        Matrix.CreateTranslation(tx, ty));
    });
};

viewTab.PanStepCallback = (dx, dy) =>
{
    Dispatcher.UIThread.Post(() =>
    {
        panel.SetMatrix(panel.Matrix * Matrix.CreateTranslation(dx, dy));
    });
};

Scrolling in read-only mode uses a 1-second step interval per the issue requirements rather than the WPF 3ms continuous loop.

…backs

- Add readOnlyZoomAndOffsets parameter to ViewTabViewModel constructor (default false)
- Add ApplyTransformCallback and PanStepCallback callback properties
- Modify Fill, Fit, Zoom100, DefferedFill to use callbacks in read-only mode
- Modify StartScrollingAsync to use step-per-second translation via callback
- Pass readOnlyZoomAndOffsets=true in Avalonia DI registration
- Remove PanelAttributesAP bindings from Avalonia ZoomBorder XAML
- Register ZoomBorder matrix callbacks in MainWindow.Methods.axaml.cs
- WPF version remains completely unaffected

Agent-Logs-Url: https://github.com/JohnnyJF10/TgaBuilder/sessions/dd11e2f8-35b2-4466-9eed-5693e68e6e9b

Co-authored-by: JohnnyJF10 <83164789+JohnnyJF10@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants