Verify Views files against decompiled, extract embedded types

Fixed files:
- SkiaImageButton.cs: Added SVG support with multi-path search
- SkiaNavigationPage.cs: Added LinuxApplication.IsGtkMode check
- SkiaRefreshView.cs: Added ICommand support (Command, CommandParameter)
- SkiaTemplatedView.cs: Added missing using statements

Extracted embedded types to separate files (matching decompiled pattern):
- From SkiaMenuBar.cs: MenuBarItem, MenuItem, SkiaMenuFlyout, MenuItemClickedEventArgs
- From SkiaNavigationPage.cs: NavigationEventArgs
- From SkiaTabbedPage.cs: TabItem
- From SkiaVisualStateManager.cs: SkiaVisualStateGroupList, SkiaVisualStateGroup, SkiaVisualState, SkiaVisualStateSetter
- From SkiaSwipeView.cs: SwipeItem, SwipeStartedEventArgs, SwipeEndedEventArgs
- From SkiaFlyoutPage.cs: FlyoutLayoutBehavior (already separate)
- From SkiaIndicatorView.cs: IndicatorShape (already separate)
- From SkiaBorder.cs: SkiaFrame
- From SkiaCarouselView.cs: PositionChangedEventArgs
- From SkiaCollectionView.cs: SkiaSelectionMode, ItemsLayoutOrientation
- From SkiaContentPresenter.cs: LayoutAlignment

Verified matching decompiled:
- SkiaContextMenu.cs, SkiaFlexLayout.cs, SkiaGraphicsView.cs

Build: 0 errors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-01 17:02:39 -05:00
parent 6007b84e7a
commit f6eadaad57
171 changed files with 4208 additions and 3913 deletions

View File

@@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.Globalization;
using System.IO;
using SkiaSharp;
using Svg.Skia;
namespace Microsoft.Maui.Platform.Linux.Services;
/// <summary>
/// Generates application icons from MAUI icon metadata.
/// Creates PNG icons suitable for use as window icons on Linux.
/// Note: SVG overlay support requires Svg.Skia package (optional).
/// Uses SVG overlay support via Svg.Skia package.
/// </summary>
public static class MauiIconGenerator
{
@@ -28,50 +28,52 @@ public static class MauiIconGenerator
string path = Path.GetDirectoryName(metaFilePath) ?? "";
var metadata = ParseMetadata(File.ReadAllText(metaFilePath));
// bg and fg paths (bg not currently used, but available for future)
Path.Combine(path, "appicon_bg.svg");
string fgPath = Path.Combine(path, "appicon_fg.svg");
string outputPath = Path.Combine(path, "appicon.png");
// Parse size from metadata or use default
int size = metadata.TryGetValue("Size", out var sizeStr) && int.TryParse(sizeStr, out var sizeVal)
? sizeVal
: DefaultIconSize;
// Parse color from metadata or use default purple
SKColor color = metadata.TryGetValue("Color", out var colorStr)
? ParseColor(colorStr)
: SKColors.Purple;
// Parse scale from metadata or use default 0.65
float scale = metadata.TryGetValue("Scale", out var scaleStr) && float.TryParse(scaleStr, out var scaleVal)
? scaleVal
: 0.65f;
Console.WriteLine($"[MauiIconGenerator] Generating {size}x{size} icon");
Console.WriteLine($"[MauiIconGenerator] Color: {color}");
Console.WriteLine($"[MauiIconGenerator] Scale: {scale}");
using var surface = SKSurface.Create(new SKImageInfo(size, size, SKColorType.Bgra8888, SKAlphaType.Premul));
var canvas = surface.Canvas;
// Draw background with rounded corners
canvas.Clear(SKColors.Transparent);
float cornerRadius = size * 0.2f;
using var paint = new SKPaint { Color = color, IsAntialias = true };
canvas.DrawRoundRect(new SKRoundRect(new SKRect(0, 0, size, size), cornerRadius), paint);
// Fill background with color
canvas.Clear(color);
// Try to load PNG foreground as fallback (appicon_fg.png)
string fgPngPath = Path.Combine(path, "appicon_fg.png");
if (File.Exists(fgPngPath))
// Load and draw SVG foreground if it exists
if (File.Exists(fgPath))
{
try
using var svg = new SKSvg();
if (svg.Load(fgPath) != null && svg.Picture != null)
{
using var fgBitmap = SKBitmap.Decode(fgPngPath);
if (fgBitmap != null)
{
float scale = size * 0.65f / Math.Max(fgBitmap.Width, fgBitmap.Height);
float fgWidth = fgBitmap.Width * scale;
float fgHeight = fgBitmap.Height * scale;
float offsetX = (size - fgWidth) / 2f;
float offsetY = (size - fgHeight) / 2f;
var cullRect = svg.Picture.CullRect;
float svgScale = size * scale / Math.Max(cullRect.Width, cullRect.Height);
float offsetX = (size - cullRect.Width * svgScale) / 2f;
float offsetY = (size - cullRect.Height * svgScale) / 2f;
var dstRect = new SKRect(offsetX, offsetY, offsetX + fgWidth, offsetY + fgHeight);
canvas.DrawBitmap(fgBitmap, dstRect);
}
}
catch (Exception ex)
{
Console.WriteLine("[MauiIconGenerator] Failed to load foreground PNG: " + ex.Message);
canvas.Save();
canvas.Translate(offsetX, offsetY);
canvas.Scale(svgScale);
canvas.DrawPicture(svg.Picture);
canvas.Restore();
}
}