Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[UI] Export app SVG #12305

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion Directory.Packages.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<AvaloniaVersion>11.0.999-cibuild0044755-beta</AvaloniaVersion>
<AvaloniaVersion>11.1.999-cibuild0045038-beta</AvaloniaVersion>
</PropertyGroup>
<ItemGroup>
<!-- AspNetCore. -->
Expand Down
2,256 changes: 220 additions & 2,036 deletions WalletWasabi.Fluent.Desktop/packages.lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions WalletWasabi.Fluent/Controls/FadeOutTextBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@ protected override void RenderTextLayout(DrawingContext context, Point origin)
var hasCollapsed = TrimmedTextBlock.TextLayout.TextLines[0].HasCollapsed;
if (hasCollapsed)
{
// NOTE: Disable OpacityMask for making screenshots
using var _ = context.PushOpacityMask(FadeoutOpacityMask, Bounds);
TextLayout.Draw(context, origin + new Point(TextLayout.OverhangLeading, 0));
}
else
{
// NOTE: Disable OpacityMask for making screenshots
using var _ = context.PushOpacityMask(OpacityMask, Bounds);
TextLayout.Draw(context, origin + new Point(TextLayout.OverhangLeading, 0));
}
Expand Down
12 changes: 12 additions & 0 deletions WalletWasabi.Fluent/Helpers/FileDialogHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@
MimeTypes = new[] { "image/png" }
};

public static FilePickerFileType Svg { get; } = new("SVG Files")
{
Patterns = new[] {"*.svg"},
AppleUniformTypeIdentifiers = new[] {"public.svg-image"},
MimeTypes = new[] {"image/svg+xml"}
};

private static IStorageProvider? GetStorageProvider()
{
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime { MainWindow: { } window })
Expand Down Expand Up @@ -109,6 +116,11 @@
fileTypeFilters.Add(Png);
break;
}
case "svg":
{
fileTypeFilters.Add(Svg);
break;
}

Check warning on line 123 in WalletWasabi.Fluent/Helpers/FileDialogHelper.cs

View check run for this annotation

CodeScene Delta Analysis / CodeScene Cloud Delta Analysis (master)

❌ New issue: Complex Method

GetFilePickerFileTypes has a cyclomatic complexity of 9, threshold = 9. This function has many conditional statements (e.g. if, for, while), leading to lower code health. Avoid adding more conditionals and code to it without refactoring.
}
}

Expand Down
52 changes: 37 additions & 15 deletions WalletWasabi.Fluent/Screenshot/Capture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media.Imaging;
using Avalonia.Skia.Helpers;
using Avalonia.Threading;
using SkiaSharp;
using WalletWasabi.Fluent.Helpers;

namespace WalletWasabi.Fluent.Screenshot;
Expand Down Expand Up @@ -33,16 +36,35 @@ private static async Task SaveAsync(TopLevel root)
{
var file = await FileDialogHelper.SaveFileAsync(
"Save screenshot...",
new[] { "png", "*" },
"WalletWasabi.png",
["svg", "png", "*"],
"WalletWasabi.svg",
Environment.GetFolderPath(Environment.SpecialFolder.MyPictures));
if (file is not null)
{
Save(root, root.Bounds.Size, file.Path.AbsolutePath);
await SaveAsync(root, root.Bounds.Size, file.Path.AbsolutePath);
}
}

private static void Save(Control? target, Size size, string path)
private static void RenderAsPng(Control target, Size size, FileStream stream)
{
var pixelSize = new PixelSize((int) size.Width, (int) size.Height);
var dpiVector = new Vector(96d, 96d);
using var bitmap = new RenderTargetBitmap(pixelSize, dpiVector);
target.Measure(size);
target.Arrange(new Rect(size));
bitmap.Render(target);
bitmap.Save(stream);
}

private static async Task RenderAsSvgAsync(Stream stream, Size size, Visual visual)
{
using var managedWStream = new SKManagedWStream(stream);
var bounds = SKRect.Create(new SKSize((float) size.Width, (float) size.Height));
using var canvas = SKSvgCanvas.Create(bounds, managedWStream);
await DrawingContextHelper.RenderAsync(canvas, visual);
}

private static async Task SaveAsync(Control? target, Size size, string path)
{
if (target is null)
{
Expand All @@ -53,17 +75,17 @@ private static void Save(Control? target, Size size, string path)
switch (extension.ToLower())
{
case ".png":
{
using var stream = File.Create(path);
var pixelSize = new PixelSize((int)size.Width, (int)size.Height);
var dpiVector = new Vector(96d, 96d);
using var bitmap = new RenderTargetBitmap(pixelSize, dpiVector);
target.Measure(size);
target.Arrange(new Rect(size));
bitmap.Render(target);
bitmap.Save(stream);
break;
}
{
await using var stream = File.Create(path);
RenderAsPng(target, size, stream);
break;
}
case ".svg":
{
await using var stream = File.Create(path);
await RenderAsSvgAsync(stream, size, target);
break;
}
}
}
}
5 changes: 5 additions & 0 deletions WalletWasabi.Fluent/Views/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
RenderOptions.TextRenderingMode="SubpixelAntialias"
RenderOptions.RequiresFullOpacityHandling="True">
<Window.Styles>
<!-- NOTE: Uncomment ClipToBounds for making screenshots -->
<!-- <Style Selector=":is(Control):not(:is(ScrollViewer))"> -->
<!-- <Setter Property="ClipToBounds" Value="False" /> -->
<!-- </Style> -->
<Style Selector="TitleBar">
<Setter Property="Foreground" Value="{DynamicResource AcrylicTrimForeground}" />
</Style>
Expand All @@ -38,6 +42,7 @@
Do not remove as the OpacityMask is needed for RenderOptions.TextRenderingMode="SubpixelAntialias"
to work without artifacts until the https://github.com/AvaloniaUI/Avalonia/issues/13265 issue is fixed in Avalonia
-->
<!-- NOTE: Disable OpacityMask for making screenshots -->
<Panel.OpacityMask>
<LinearGradientBrush StartPoint="0%,0%"
EndPoint="100%,0%">
Expand Down