Skip to content

Extract AvalonDraw into reusable Svg.Editor.* packages#470

Merged
wieslawsoltes merged 8 commits into
masterfrom
refactor/svg-editor-packages
Mar 11, 2026
Merged

Extract AvalonDraw into reusable Svg.Editor.* packages#470
wieslawsoltes merged 8 commits into
masterfrom
refactor/svg-editor-packages

Conversation

@wieslawsoltes
Copy link
Copy Markdown
Owner

PR Summary: Extract AvalonDraw into reusable Svg.Editor.* packages

Overview

This change turns samples/AvalonDraw into a thin demo host and moves reusable editor functionality into a new package family under src/Svg.Editor.*.

The extracted packages are intended to let consuming applications embed:

  • host-agnostic editor/session state
  • SVG mutation services and models
  • Skia editing and overlay behavior
  • reusable Avalonia editor panels and dialog content
  • a composed Avalonia + Skia editor surface/workspace

samples/AvalonDraw remains the sample application that wires desktop-specific behavior such as top-level hosting, preview chrome, and storage-provider integration.

Package layout

src/Svg.Editor.Core

Owns reusable editor state and session primitives, including:

  • editor session orchestration
  • settings/state models
  • artboard and node abstractions migrated out of the sample host

src/Svg.Editor.Svg

Owns SVG mutation and resource management concerns, including:

  • document open/save helpers
  • appearance/layer/property/resource services
  • public models used by the editor surface and property/resource panels

src/Svg.Editor.Skia

Owns rendering/editing behavior that is not Avalonia-specific, including:

  • path/selection/alignment services
  • overlay rendering abstraction
  • interaction controller abstraction

src/Svg.Editor.Avalonia

Owns reusable non-canvas Avalonia UI, including:

  • DocumentOutlineView
  • ResourceBrowserView
  • PropertyInspectorView
  • ToolPaletteView
  • StatusBarView
  • reusable dialog content views for insert/text/gradient/mesh/stroke/pattern/path/swatch/symbol/settings flows
  • dialog/file-dialog service abstractions for host-controlled modal and file-picker behavior

src/Svg.Editor.Skia.Avalonia

Owns the reusable Skia/Avalonia composition layer, including:

  • SvgEditorSurface
  • SvgEditorWorkspace

The workspace now exposes host-facing dialog/file-dialog seams so applications can embed the editor without inheriting sample-specific modal or storage logic.

Sample host changes

samples/AvalonDraw now behaves as a composition shell instead of the primary implementation site.

Key changes:

  • MainWindow hosts SvgEditorWorkspace instead of owning editor logic directly
  • modal editors were replaced by reusable view content hosted through the new dialog services
  • sample-only responsibilities remain in the host:
    • window composition
    • preview window integration
    • storage provider usage
    • demo app menu wiring

Large blocks of reusable code were removed from:

  • samples/AvalonDraw/Services
  • sample-local editor windows previously used as the only UI implementation

Public API and reuse improvements

This refactor establishes clear reusable seams for downstream applications:

  • session/state lives outside the sample app
  • SVG document/resource/property operations are available from library projects
  • surface interaction and overlay behavior can be reused independently from the sample window
  • non-canvas editor panels are reusable controls instead of MainWindow-local templates
  • modal/editor flows can be hosted through pluggable services rather than hardcoded sample window logic

Test coverage added

Three new test projects were added to the solution:

  • tests/Svg.Editor.Svg.UnitTests

    • document service coverage
    • appearance/layer service coverage
  • tests/Svg.Editor.Skia.UnitTests

    • path service coverage
    • selection service coverage
    • interaction controller coverage
    • overlay renderer coverage
  • tests/Svg.Editor.Skia.Avalonia.UnitTests

    • editor view coverage
    • panel control coverage
    • workspace interaction/wiring coverage

Solution integration

Svg.Skia.slnx now includes:

  • src/Svg.Editor.Core
  • src/Svg.Editor.Svg
  • src/Svg.Editor.Skia
  • src/Svg.Editor.Avalonia
  • src/Svg.Editor.Skia.Avalonia
  • tests/Svg.Editor.Svg.UnitTests
  • tests/Svg.Editor.Skia.UnitTests
  • tests/Svg.Editor.Skia.Avalonia.UnitTests

Documentation for package selection and consumer guidance was added in docs/editor-packages.md.

Commit breakdown

This branch is split into three commits:

  1. d78a550e Extract Svg.Editor core service libraries

    • creates Svg.Editor.Core, Svg.Editor.Svg, and Svg.Editor.Skia
    • moves reusable state/models/services out of the sample app
  2. 01294aaa Move AvalonDraw UI into reusable editor packages

    • creates Svg.Editor.Avalonia and Svg.Editor.Skia.Avalonia
    • extracts reusable panels, editor views, dialog/file-dialog services, surface/workspace composition
    • reduces samples/AvalonDraw to a thin host
  3. e85598b6 Add editor solution tests and docs

    • adds solution entries for the new packages and test projects
    • adds documentation for package consumers
    • adds the new unit and headless UI test coverage

Validation

Validated on branch refactor/svg-editor-packages with:

dotnet format --no-restore
dotnet build Svg.Skia.slnx -c Release
dotnet test Svg.Skia.slnx -c Release --no-build

Results:

  • dotnet format completed successfully
  • dotnet build completed successfully
  • dotnet test completed successfully

Warnings and follow-up notes

The branch is valid but the solution still emits pre-existing warnings outside the scope of this extraction, including:

  • NU1510 in samples/svgc
  • existing Avalonia obsolete API warnings in sample projects
  • existing nullability warnings in unrelated projects
  • strong-name warning for Svg.Editor.Skia.Avalonia on net461 because Svg.Controls.Skia.Avalonia is not strong-named

The extracted editor workspace still contains obsolete Avalonia drag/drop and container APIs that build successfully but should be modernized in a follow-up cleanup.

Working tree note

The externals/SVG submodule is dirty in the local workspace and was intentionally left untouched because it is unrelated to this refactor.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e85598b608

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Editor.Skia.Avalonia/SvgEditorWorkspace.axaml.cs Outdated
Comment thread src/Svg.Editor.Skia.Avalonia/SvgEditorWorkspace.axaml.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 502584ef46

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Editor.Skia.Avalonia/SvgEditorWorkspace.axaml.cs Outdated
Comment thread src/Svg.Editor.Skia.Avalonia/SvgEditorWorkspace.axaml.cs Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c9618fa93b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/Svg.Editor.Skia.Avalonia/SvgEditorWorkspace.axaml.cs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant