Skip to content

Add MAUI and Blazor WASM gallery sample apps; retire all legacy gallery platforms#3578

Draft
Copilot wants to merge 22 commits intomainfrom
copilot/review-gallery-samples-blazor
Draft

Add MAUI and Blazor WASM gallery sample apps; retire all legacy gallery platforms#3578
Copilot wants to merge 22 commits intomainfrom
copilot/review-gallery-samples-blazor

Conversation

Copy link
Contributor

Copilot AI commented Mar 25, 2026

Replaces the Xamarin.Forms-based gallery (deprecated, targeting netstandard2.0) with two new gallery apps — one for .NET MAUI and one for Blazor WebAssembly — sharing the same 44 sample implementations via file links. All legacy gallery platform directories have been removed.

Description of Change

Sample audit (shared Samples/)

  • Removed BitmapScalerSample — already [Obsolete], uses retired SKBitmapResizeMethod API
  • Renamed "Xamagon""Complex Paths" with a description — drawing code intact, Xamarin brand gone
  • Kept all 44 remaining samples — all demonstrate valid, current SkiaSharp APIs
  • CreateXpsSample remains Windows-only via SupportedPlatform = AllWindows; excluded from MAUI/Blazor automatically

Shared infrastructure changes

  • SamplePlatforms: added MAUI = 1 << 6, Blazor = 1 << 7; All updated to include both; added AllModern = MAUI | Blazor
  • SampleBase: added public ResetMatrix() — allows gallery UIs to reset pan/zoom without accessing the protected Matrix field

Legacy gallery platforms removed

All old platform-specific gallery directories have been deleted: Desktop/, WPF/, macOS/, tvOS/, UWP/, Xamarin.Forms/, Uno/, Uno.WinUI/, and PlatformShared/. Only Shared/, Maui/, and Blazor/ remain under samples/Gallery/.

samples/Gallery/Maui/ — .NET MAUI app (iOS, macOS Catalyst, Android, Windows)

  • Shell flyout navigation; CollectionView with category grouping + live search
  • "▶ Play" mode cycles all samples on a 3-second timer
  • SKCanvasView (CPU) and SKGLView (GPU) with a two-button CPU (Raster) / GPU (OpenGL) toggle bar at the bottom of the canvas; GPU button is disabled when the current sample's SupportedBackends does not include OpenGL
  • Pan/pinch/tap gestures and InvalidateSurface are routed to whichever view is active
  • Uses [QueryProperty] for typed Shell route parameters

samples/Gallery/Blazor/ — Blazor WebAssembly app

  • Fixed sidebar with category-grouped nav and search; route: /sample/{title}
  • CPU (Raster) / GPU (OpenGL) toggle button group below the canvas; only one view is mounted at a time (SKCanvasView or SKGLView); EnableRenderLoop enabled on SKGLView only for AnimatedSampleBase samples
  • Unsupported backends are automatically disabled per sample.SupportedBackends
  • Pointer-based pan, click-to-tap; all navigation strings go through Uri.EscapeDataString/UnescapeDataString

Bugs Fixed

None.

API Changes

Added:

  • void SampleBase.ResetMatrix()

Behavioral Changes

None.

Required skia PR

None.

PR Checklist

  • Has tests (if omitted, state reason in description)
  • Rebased on top of main at time of PR
  • Merged related skia PRs
  • Changes adhere to coding standard
  • Updated documentation
Original prompt

Please review the gallery samples and help me create a new sample that is just maui and Blazor wasm. Look at all the features that exist and come up with a detailed plan on how we can do this as well as the lisylt of samples and what they demonstrate and if it is worth keeping. Those samples are very old so we actually need to see what there is that is worth keeping.


⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS or Windows machine with Raycast.

- Add MAUI and Blazor platform flags to SamplePlatforms
- Add ResetMatrix() to SampleBase for public access
- Remove obsolete BitmapScalerSample (deprecated API)
- Update XamagonSample: rename to 'Complex Paths', add description
- Create new MAUI gallery: Shell navigation, CollectionView list,
  SKCanvasView detail page with gestures, cycle mode, info overlay
- Create new Blazor WASM gallery: sidebar with category navigation,
  search, SKCanvasView (raster) and SKGLView (GPU) rendering

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Agent-Logs-Url: https://github.com/mono/SkiaSharp/sessions/ff83b618-88ef-4ebb-96db-4e405c1cccaa
Copilot AI changed the title [WIP] Review and plan new Maui and Blazor Wasm sample Add MAUI and Blazor WASM gallery sample apps; retire obsolete samples Mar 25, 2026
Copilot AI requested a review from mattleibow March 25, 2026 02:40
@mattleibow
Copy link
Contributor

@copilot please delete all the other samples. Also, the sample page needs to have a toggle for CPU and GPU. Can you also categorize the samples and group on the UI

- Remove all old gallery platform directories (Desktop, WPF, macOS,
  tvOS, UWP, Xamarin.Forms, Uno, Uno.WinUI, PlatformShared)
- MAUI SampleDetailPage: add SKGLView + CPU/GPU toggle buttons,
  disable GPU if sample.SupportedBackends lacks OpenGL, route all
  gestures and InvalidateSurface to the active view
- Blazor SamplePage: replace AnimatedSampleBase auto-select with
  explicit CPU/GPU toggle buttons, disable unsupported backends,
  fix backend switch to invalidate newly-mounted view after state change
- Category grouping already present in both UIs (MAUI CollectionView
  IsGrouped, Blazor sidebar category headers)

Co-authored-by: mattleibow <1096616+mattleibow@users.noreply.github.com>
Agent-Logs-Url: https://github.com/mono/SkiaSharp/sessions/8aa083e9-ce0f-45e5-be84-7c1e1ec7b287
Copy link
Contributor Author

Copilot AI commented Mar 25, 2026

@copilot please delete all the other samples. Also, the sample page needs to have a toggle for CPU and GPU. Can you also categorize the samples and group on the UI

Done in commit 66ec982:

Old gallery apps deleted — removed Desktop, WPF, macOS, tvOS, UWP, Xamarin.Forms, Uno, and Uno.WinUI from samples/Gallery/. Only Shared/, Maui/, and Blazor/ remain.

CPU/GPU toggle added to both platforms:

  • MAUI (SampleDetailPage): A two-button bar at the bottom of the canvas lets you switch between CPU (Raster) using SKCanvasView and GPU (OpenGL) using SKGLView. The GPU button is disabled for any sample whose SupportedBackends doesn't include OpenGL.

  • Blazor (SamplePage): A toggle button group above the canvas lets you pick CPU (Raster) or GPU (OpenGL). Both views are rendered inline (only one is mounted at a time); EnableRenderLoop is enabled on SKGLView only for animated samples. Buttons that aren't supported by the current sample are disabled.

Category grouping is already present in both UIs:

  • MAUI uses CollectionView with IsGrouped="True" and a GroupHeaderTemplate showing category labels (uppercase, accent colour)
  • Blazor's sidebar NavMenu renders a section header for each category, with samples nested beneath it, plus a live search box

Copilot AI changed the title Add MAUI and Blazor WASM gallery sample apps; retire obsolete samples Add MAUI and Blazor WASM gallery sample apps; retire all legacy gallery platforms Mar 25, 2026
mattleibow and others added 15 commits March 25, 2026 16:10
- Move Blazor and Maui project files up one level, eliminating the
  redundant SkiaSharpSample/ subdirectory in each
- Remove per-project .sln files (Blazor/SkiaSharpSample.sln,
  Maui/SkiaSharpSample.sln) in favor of the existing Gallery.sln
- Update relative paths in both .csproj files to account for the
  reduced directory depth

New structure:
  samples/Gallery/
    Gallery.sln          (single solution, both projects)
    Blazor/              (csproj + sources directly here)
    Maui/                (csproj + sources directly here)
    Shared/              (shared samples and media)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Rename csproj files to SkiaSharpSample.Blazor.csproj and
  SkiaSharpSample.Maui.csproj for clarity in the shared solution
- Add RootNamespace=SkiaSharpSample to both so namespaces stay unchanged
- Update Gallery.sln project references to match

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Create Shared/SkiaSharpSample.Shared.csproj targeting net10.0 with
  RootNamespace=SkiaSharpSample
- Replace file-level Compile/EmbeddedResource includes in Blazor and
  Maui projects with a ProjectReference to the shared library
- Remove duplicate SkiaSharp/HarfBuzz/Skottie project references from
  app projects (now transitive via Shared)
- Add Gallery.sln entry for the new Shared project
- Fix pre-existing build errors in samples:
  - Remove ThreeDSamplePerspective.cs (uses removed SK3dView API)
  - Update CreateMagnifier calls to match current 4-arg signature
  - Fix SKMatrix.Concat calls (ref removed from value args)
  - Add missing Microsoft.Maui.Graphics using in SampleDetailPage

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace SkiaSharpSample.sln with SkiaSharpSample.slnx (net10 format)
- Add all SkiaSharp dependency projects so the solution is self-contained:
  - Bindings: SkiaSharp, HarfBuzzSharp, Skottie, SceneGraph, Resources
  - NativeAssets: macOS, Win32, WebAssembly (both SkiaSharp and HarfBuzz)
  - Source: SkiaSharp.HarfBuzz, Views.Blazor, Views.Maui.Controls/Core
- Organize into solution folders: Samples, Bindings, NativeAssets, Source

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- build.cake: Add *.slnx to solution discovery globs alongside *.sln
  and *.slnf, both for building and platform variant detection
- scripts/cake/samples.cake: Add .slnx handler that strips external
  project references (outside samples dir) using XML parsing, and
  removes empty solution folders after cleanup

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Both Blazor and Maui projects were missing the
IncludeNativeAssets.HarfBuzzSharp.targets import, which was previously
pulled in transitively when HarfBuzzSharp was a direct ProjectReference.
Now that it flows through the Shared project, the import must be explicit.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
XamlParseException at startup: 'Cannot assign property LetterSpacing'
on a Label inside a DataTemplate. Remove the cosmetic property to fix
the crash on net10.0-maccatalyst.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- MainLayout.razor.css: Add missing .page flex layout, .sidebar width
  (280px), sticky positioning, and responsive breakpoints matching the
  standard Blazor WASM template
- NavMenu.razor.css: Add responsive media query to keep sidebar
  expanded on desktop, with scrollable nav area
- SamplePage.razor: Change canvas height from fixed 500px to responsive
  60vh with 300px minimum
- index.html: Fix scoped CSS filename to match renamed assembly
  (SkiaSharpSample.Blazor.styles.css)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The flyout just showed a single 'Samples' entry which was redundant with
the SamplesListPage already serving as the main navigation. Disable the
flyout so the samples list is the direct root content.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the separate SamplesListPage with a dynamically populated
Shell flyout. Each sample category becomes a FlyoutItem header, and
each sample is a ShellContent entry that lazily creates a
SampleDetailPage via DataTemplate.

The flyout now IS the sample browser — swipe or tap the hamburger to
see all samples grouped by category, tap one to navigate directly to
the rendering page.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace custom layout/CSS with the standard Blazor WASM template
styles, fixing:
- Missing hamburger button on narrow viewports
- Double header issue when sidebar collapses
- Sidebar not expanding/collapsing properly
- Ugly custom styles that didn't match the template

Files reset to template defaults:
- MainLayout.razor.css: Standard .page flex layout with responsive
  breakpoints, 280px sidebar, sticky positioning
- NavMenu.razor.css: Template navbar-toggler, nav-item styles, and
  media queries for collapse behavior, plus sample category/link styles
- app.css: Template defaults (loading progress, error UI, validation)
  plus minimal canvas-wrapper and backend-bar styles

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SKCanvasView/SKGLView already have a built-in ResizeObserver via
SizeWatcher that invalidates on resize. Removing IgnorePixelScaling
lets the canvas render at native DPI resolution and properly respond
to container size changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace all layout and CSS files with byte-for-byte copies from
'dotnet new blazorwasm' (.NET 10), with only minimal customizations:
- MainLayout.razor: SkiaSharp GitHub link instead of ASP.NET docs
- NavMenu.razor: Sample list with categories instead of template pages
- index.html: SkiaSharp title, correct styles.css filename
- Bootstrap upgraded from css/bootstrap/ to lib/bootstrap/dist/css/

Layout CSS (MainLayout.razor.css, NavMenu.razor.css) and app.css are
identical to the template — no custom overrides. This ensures the
responsive layout, hamburger toggle, and sidebar collapse work exactly
as the standard Blazor WASM template.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
mattleibow and others added 4 commits March 25, 2026 20:46
- Replace SampleCategories [Flags] enum with string constants for
  clean UI display ('Bitmap Decoding', 'Color Filters', etc.)
- Remove SamplePlatforms enum; add virtual bool IsSupported property
  (only CreateXpsSample overrides with OperatingSystem.IsWindows())
- Remove SampleBackends enum (all samples support all backends)
- Create DocumentSampleBase for PDF/XPS document samples
- Remove PreserveAttribute (Xamarin iOS linker artifact)
- Update SamplesManager.GetSamples() to filter by IsSupported
- Update Blazor NavMenu and MAUI AppShell grouping to use strings
- Simplify backend toggle UI (always enabled)

56 files changed, -338/+209 lines — net reduction in complexity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove .NET 10 template fingerprint syntax that doesn't work with
the current build output (blazor.webassembly.js, not fingerprinted).
Remove unused preload and importmap tags.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace __WASM__ preprocessor directives with a runtime check for
SynchronizationContext.Current. The old #if !__WASM__ was from Uno
and is not defined in Blazor WASM builds, causing
TaskScheduler.FromCurrentSynchronizationContext() to throw.

Now falls back to TaskScheduler.Default when no sync context exists.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Fixes:
- ColorTableColorFilter: Use identity alpha table instead of null
- DocumentSampleBase: Hide document samples on WASM (no temp dir),
  guard OnInit against null TempDataPath
- Re-add ThreeDSamplePerspective using SKMatrix44 (was removed with
  SK3dView)
- AnimatedSampleBase already fixed (previous commit)

Blazor UI:
- Move CPU/GPU toggle from per-sample page to global header bar
  in MainLayout, persisted across page navigation via CascadingValue
- Default to GPU mode so animated samples use requestAnimationFrame
- Remove per-sample backend bar
- SamplePage consumes UseGpu cascading parameter

Co-authored-by: Copilot <223556219+Copilot@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

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants