A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

186 lines
6.9 KiB

using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Headless;
using Avalonia.LinuxFramebuffer;
using Avalonia.LinuxFramebuffer.Output;
using Avalonia.LogicalTree;
using Avalonia.Platform;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
using Avalonia.Vulkan;
using ControlCatalog.Pages;
namespace ControlCatalog.Desktop
{
static class Program
{
[STAThread]
static int Main(string[] args)
{
if (args.Contains("--wait-for-attach"))
{
Console.WriteLine("Attach debugger and use 'Set next statement'");
while (true)
{
Thread.Sleep(100);
if (Debugger.IsAttached)
break;
}
}
var builder = BuildAvaloniaApp();
double GetScaling()
{
var idx = Array.IndexOf(args, "--scaling");
if (idx >= 0 && args.Length > idx + 1 &&
double.TryParse(args[idx + 1], NumberStyles.Any, CultureInfo.InvariantCulture, out var scaling))
return scaling;
return 1;
}
SurfaceOrientation GetOrientation()
{
var idx = Array.IndexOf(args, "--orientation");
if (idx >= 0 && args.Length > idx + 1 &&
Enum.TryParse<SurfaceOrientation>(args[idx + 1], true, out var orientation))
return orientation;
return SurfaceOrientation.Rotation0;
}
string? GetCard()
{
var idx = Array.IndexOf(args, "--card");
if (idx >= 0 && args.Length > idx + 1)
return args[idx + 1];
return null;
}
if (args.Contains("--fbdev"))
{
SilenceConsole();
return builder.StartLinuxFbDev(args, new FbDevOutputOptions()
{
Scaling = GetScaling()
});
}
else if (args.Contains("--vnc"))
{
return builder.StartWithHeadlessVncPlatform(null, 5901, args, ShutdownMode.OnMainWindowClose);
}
else if (args.Contains("--full-headless"))
{
return builder
.UseHeadless(new AvaloniaHeadlessPlatformOptions
{
UseHeadlessDrawing = true
})
.AfterSetup(_ =>
{
DispatcherTimer.RunOnce(async () =>
{
var window = ((IClassicDesktopStyleApplicationLifetime)Application.Current!.ApplicationLifetime!)
.MainWindow!;
var tc = window.GetLogicalDescendants().OfType<TabControl>().First();
foreach (var page in tc.Items.Cast<TabItem>().ToList())
{
if (page.Header?.ToString() is "DatePicker" or "TreeView")
continue;
Console.WriteLine("Selecting " + page.Header);
tc.SelectedItem = page;
await Task.Delay(50);
}
Console.WriteLine("Selecting the first page");
tc.SelectedItem = tc.Items.OfType<object>().First();
await Task.Delay(500);
Console.WriteLine("Clicked through all pages, triggering GC");
for (var c = 0; c < 3; c++)
{
GC.Collect(2, GCCollectionMode.Forced);
await Task.Delay(50);
}
void FormatMem(string metric, long bytes)
{
Console.WriteLine(metric + ": " + bytes / 1024 / 1024 + "MB");
}
FormatMem("GC allocated bytes", GC.GetTotalMemory(true));
FormatMem("WorkingSet64", Process.GetCurrentProcess().WorkingSet64);
}, TimeSpan.FromSeconds(1));
})
.StartWithClassicDesktopLifetime(args);
}
else if (args.Contains("--drm"))
{
SilenceConsole();
return builder.StartLinuxDrm(args, card: GetCard(), options: new DrmOutputOptions()
{
Scaling = GetScaling(),
Orientation = GetOrientation(),
});
}
else if (args.Contains("--dxgi"))
{
builder.With(new Win32PlatformOptions()
{
CompositionMode = [Win32CompositionMode.LowLatencyDxgiSwapChain]
});
return builder.StartWithClassicDesktopLifetime(args);
}
else
return builder.StartWithClassicDesktopLifetime(args);
}
/// <summary>
/// This method is needed for IDE previewer infrastructure
/// </summary>
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.With(new X11PlatformOptions
{
EnableMultiTouch = true,
UseDBusMenu = true,
EnableIme = true,
})
.With(new VulkanOptions
{
VulkanInstanceCreationOptions = new ()
{
UseDebug = true
}
})
.With(new CompositionOptions()
{
UseRegionDirtyRectClipping = true
})
.UseSkia()
.WithInterFont()
.WithDeveloperTools()
.AfterSetup(builder =>
{
EmbedSample.Implementation = OperatingSystem.IsWindows() ? new EmbedSampleWin()
: OperatingSystem.IsMacOS() ? new EmbedSampleMac()
: OperatingSystem.IsLinux() ? new EmbedSampleGtk()
: null;
})
.LogToTrace();
private static void SilenceConsole()
{
new Thread(() =>
{
Console.CursorVisible = false;
while (true)
Console.ReadKey(true);
})
{ IsBackground = true }.Start();
}
}
}