Skip to content

Commit 4074f75

Browse files
committed
Add PanAndZoom and headless testing docs content
1 parent a15360c commit 4074f75

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1377
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
title: "Custom Bounds, Resize, and Rotation"
3+
---
4+
5+
# Custom Bounds, Resize, and Rotation
6+
7+
If the built-in behavior is close but not exact, `ZoomBorder` exposes virtual hooks for custom policy.
8+
9+
## Extensibility Points
10+
11+
- `GetContentBounds()`: return the effective content bounds used for custom constraints
12+
- `ValidateTransform(Matrix newMatrix)`: veto proposed transforms
13+
- `OnResized(Size oldSize, Size newSize)`: apply custom resize policy
14+
15+
Example:
16+
17+
```csharp
18+
public class CustomZoomBorder : ZoomBorder
19+
{
20+
protected override Rect GetContentBounds() => base.GetContentBounds();
21+
22+
protected override bool ValidateTransform(Matrix newMatrix)
23+
{
24+
return base.ValidateTransform(newMatrix);
25+
}
26+
27+
protected override void OnResized(Size oldSize, Size newSize)
28+
{
29+
base.OnResized(oldSize, newSize);
30+
}
31+
}
32+
```
33+
34+
## When To Override
35+
36+
- content bounds depend on domain data rather than only the child's measured bounds
37+
- certain zoom or pan regions must be blocked
38+
- resize behavior needs to preserve a custom anchor or workflow-specific invariant
39+
40+
## Rotation Considerations
41+
42+
Rotation state is configurable, but advanced rotation-heavy surfaces should validate how rotation interacts with bounds, serialization, and any custom overlay math before relying on it as a full scene-graph feature.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
title: "Diagnostics and Testing"
3+
---
4+
5+
# Diagnostics and Testing
6+
7+
This repository is already test-heavy, which makes the codebase a good reference for both usage and expected behavior.
8+
9+
## PanAndZoom Test Coverage Areas
10+
11+
The main test project covers:
12+
13+
- pointer, wheel, keyboard, and gesture interaction
14+
- bounds modes and dynamic zoom limits
15+
- view history, saved views, and state serialization
16+
- rotation, scale indicator, viewport culling, and `ILogicalScrollable`
17+
- Appium-style APIs and recording workflows
18+
19+
## HeadlessTestingFramework Test Coverage Areas
20+
21+
The second test project focuses on:
22+
23+
- touch simulation and gesture recognizer helpers
24+
- tree validation, tree comparison, and XPath helpers
25+
- recording infrastructure and multi-touch helper construction
26+
27+
## Useful Debug Artifacts
28+
29+
- generated Lunet API docs under `site/.lunet/build/www/api`
30+
- recording output from `HeadlessScreenRecorder` or `RecordingSession`
31+
- tree and template comparison summaries from `TreeComparer` and `TemplateComparer`
32+
33+
## Documentation Validation
34+
35+
Validate docs locally with:
36+
37+
```bash
38+
./check-docs.sh
39+
```
40+
41+
That rebuilds the Lunet site and API reference from the same sources used by CI.

site/articles/advanced/menu.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
advanced:
2+
- {path: readme.md, title: "Advanced"}
3+
- {path: custom-bounds-resize-and-rotation.md, title: "Custom Bounds, Resize, and Rotation"}
4+
- {path: scrollviewer-and-logical-scroll.md, title: "ScrollViewer and Logical Scroll"}
5+
- {path: diagnostics-and-testing.md, title: "Diagnostics and Testing"}

site/articles/advanced/readme.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: "Advanced"
3+
---
4+
5+
# Advanced
6+
7+
- [Custom Bounds, Resize, and Rotation](custom-bounds-resize-and-rotation.md)
8+
- [ScrollViewer and Logical Scroll](scrollviewer-and-logical-scroll.md)
9+
- [Diagnostics and Testing](diagnostics-and-testing.md)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
title: "ScrollViewer and Logical Scroll"
3+
---
4+
5+
# ScrollViewer and Logical Scroll
6+
7+
`ZoomBorder` implements `ILogicalScrollable` so it can participate in Avalonia scrolling infrastructure instead of fighting it.
8+
9+
## Why This Matters
10+
11+
Embedding zoomable content inside a `ScrollViewer` is common, but naive implementations can create feedback loops between viewport transforms and host scroll offsets.
12+
13+
`ZoomBorder` addresses that through:
14+
15+
- the `ILogicalScrollable` implementation in `ZoomBorder.ILogicalScrollable.cs`
16+
- `CalculateScrollable(...)` for computing extent, viewport, and offset from source bounds and the active matrix
17+
18+
## Practical Guidance
19+
20+
- Put a `ScrollViewer` around the control only when you want scrollbars or host-level scrolling semantics.
21+
- Review wheel configuration carefully; wheel input may need to pan instead of zoom in some host layouts.
22+
- Use the existing unit tests around logical scrolling as the baseline behavior contract when modifying this area.
23+
24+
## Related APIs
25+
26+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.CalculateScrollable(Avalonia.Rect,Avalonia.Size,Avalonia.Media.Transformation.Matrix,Avalonia.Size@,Avalonia.Size@,Avalonia.Vector@)`
27+
- `BringIntoView(...)` behavior through the scrollable contract
28+
- [Bounds, Wheel, and Resize](../guides/bounds-wheel-and-resize.md)

site/articles/build-and-package.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
title: "Build and Package"
3+
---
4+
5+
# Build and Package
6+
7+
Build, test, and pack from repository root:
8+
9+
```bash
10+
dotnet restore
11+
dotnet build -c Release --no-restore
12+
dotnet test -c Release --no-build
13+
dotnet pack -c Release --no-build -o artifacts/packages
14+
```
15+
16+
Packages are written to `artifacts/packages` as `.nupkg` and `.snupkg` files.
17+
18+
## Build The Sample App
19+
20+
```bash
21+
dotnet build samples/AvaloniaDemo.Desktop/AvaloniaDemo.Desktop.csproj -c Release
22+
```
23+
24+
## Build Documentation
25+
26+
```bash
27+
./build-docs.sh
28+
./check-docs.sh
29+
./serve-docs.sh
30+
```
31+
32+
PowerShell:
33+
34+
```powershell
35+
./build-docs.ps1
36+
./serve-docs.ps1
37+
```
38+
39+
Documentation output is written to `site/.lunet/build/www`.
40+
41+
## CI
42+
43+
- `build.yml` builds, tests, and packs the repository
44+
- `docs.yml` builds the Lunet site and publishes it to GitHub Pages
45+
- `release.yml` builds release packages and publishes NuGet artifacts
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
title: "Interaction Model"
3+
---
4+
5+
# Interaction Model
6+
7+
`ZoomBorder` combines several input paths, each with its own enable flags and behavior settings.
8+
9+
## Pointer And Wheel
10+
11+
- dragging pans the content using the configured `PanButton`
12+
- wheel input is controlled by `WheelBehavior`, `WheelWithCtrl`, `WheelWithShift`, `WheelZoomSensitivity`, and `WheelPanSensitivity`
13+
- `EnablePan` and `EnableZoom` are the first-level switches
14+
15+
## Gestures
16+
17+
When `EnableGestures` is `true`, the control attaches pinch and scroll recognizers. Additional flags refine what a gesture is allowed to do:
18+
19+
- `EnableGestureZoom`
20+
- `EnableGestureTranslation`
21+
- `EnableGestureRotation`
22+
- `EnableSimultaneousPanZoom`
23+
24+
The gesture path is useful on touch devices and in headless tests that use gesture recognizers rather than just pointer emulation.
25+
26+
## Keyboard
27+
28+
With `EnableKeyboardNavigation`, the control listens for built-in navigation and zoom shortcuts. That makes the control usable without custom command wiring, but the command properties are still available for toolbar and MVVM scenarios.
29+
30+
## Commands
31+
32+
`ZoomBorder` exposes `ICommand` properties such as `ZoomInCommand`, `ResetCommand`, `FitCommand`, and history navigation commands. These commands reflect control state and are the preferred way to surface interaction in view models.
33+
34+
## Animation
35+
36+
Most high-level methods accept an `animate` or `skipTransitions` argument. `EnableAnimations` and `AnimationDuration` determine whether transitions should be applied by default for command-driven view changes.

site/articles/concepts/menu.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
concepts:
2+
- {path: readme.md, title: "Concepts"}
3+
- {path: transform-and-coordinate-spaces.md, title: "Transform and Coordinate Spaces"}
4+
- {path: interaction-model.md, title: "Interaction Model"}
5+
- {path: view-state-and-persistence.md, title: "View State and Persistence"}

site/articles/concepts/readme.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: "Concepts"
3+
---
4+
5+
# Concepts
6+
7+
- [Transform and Coordinate Spaces](transform-and-coordinate-spaces.md)
8+
- [Interaction Model](interaction-model.md)
9+
- [View State and Persistence](view-state-and-persistence.md)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
title: "Transform and Coordinate Spaces"
3+
---
4+
5+
# Transform and Coordinate Spaces
6+
7+
`ZoomBorder` maintains a transform matrix that maps content coordinates into viewport coordinates. Most higher-level APIs are thin wrappers over that model.
8+
9+
## The Three Views Of Space
10+
11+
- content space: the original coordinate system of the child control
12+
- viewport space: the visible region inside the `ZoomBorder`
13+
- screen-like vectors and sizes: transformed measurements derived from the active matrix
14+
15+
## Core Conversion APIs
16+
17+
Use these methods instead of manually duplicating matrix math:
18+
19+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.ViewportToContent(Avalonia.Point)`
20+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.ContentToViewport(Avalonia.Point)`
21+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.ViewportToContent(Avalonia.Rect)`
22+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.ContentToViewport(Avalonia.Rect)`
23+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.GetContentToScreenMatrix`
24+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.GetScreenToContentMatrix`
25+
26+
These become important when:
27+
28+
- zooming to a region selected in viewport space
29+
- showing overlays aligned with content coordinates
30+
- translating pointer positions into domain coordinates on a diagram or image
31+
32+
## Matrix Helpers
33+
34+
`Avalonia.Controls.PanAndZoom.MatrixHelper` contains reusable helpers such as:
35+
36+
- `Translate(...)`
37+
- `ScaleAt(...)`
38+
- `Rotation(...)`
39+
- `TransformPoint(...)`
40+
41+
It is useful when you build custom overlays or test matrix calculations separately from the control.
42+
43+
## Visible Area Queries
44+
45+
Two methods are especially important for viewport-aware logic:
46+
47+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.GetVisibleContentBounds`
48+
- `Avalonia.Controls.PanAndZoom.ZoomBorder.GetViewportBounds`
49+
50+
They allow item culling, overlay rendering, and "jump to region" UX without duplicating coordinate conversion code.

0 commit comments

Comments
 (0)