feat(studio): headless --screenshot mode (render panel to PNG + exit)
Add `--screenshot <path>` to the UI Studio: when set the window is created hidden (WindowOptions.IsVisible = false), the panel is loaded and rendered into PanelFbo on the first OnRender tick, pixels are read back with the new PanelFbo.ReadColorRgba(), rows are flipped (GL bottom-left → PNG top-left), and the result is saved via ImageSharp SaveAsPng before calling _window.Close(). Render size is derived from the loaded root's Width/Height (clamped 256–2048 px); falls back to 1280×720 when the root has no explicit size. In headless mode ImGui, the inspector, and input wiring are all skipped — only PanelFbo is created. Interactive path is unchanged. SixLabors.ImageSharp 3.1.12 was already a direct dep of AcDream.App (Phase O-T7); no new PackageReference needed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
e3de7f0dab
commit
f778b100b7
3 changed files with 133 additions and 24 deletions
|
|
@ -9,8 +9,9 @@ public sealed record StudioOptions(
|
|||
string DatDir,
|
||||
uint? LayoutId,
|
||||
string? MarkupPath,
|
||||
string? DumpSlug = null,
|
||||
string? DumpFile = null)
|
||||
string? DumpSlug = null,
|
||||
string? DumpFile = null,
|
||||
string? ScreenshotPath = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse studio options from the args that come AFTER the <c>ui-studio</c> token.
|
||||
|
|
@ -24,16 +25,20 @@ public sealed record StudioOptions(
|
|||
/// <para><c>--dump-file <path></c>: override the default dump file path
|
||||
/// (<c>docs/research/2026-06-25-retail-ui-layout-dump.json</c> from the solution root).
|
||||
/// Only meaningful when <c>--dump</c> is also given.</para>
|
||||
/// <para><c>--screenshot <path></c>: headless mode — render the loaded panel to a PNG
|
||||
/// at <paramref name="path"/> and exit without showing an interactive window.
|
||||
/// Combines with <c>--dump</c> or <c>--layout</c>.</para>
|
||||
/// <para>When neither <c>--layout</c>, <c>--markup</c>, nor <c>--dump</c> is given the
|
||||
/// default layout <c>0x2100006C</c> (vitals) is used.</para>
|
||||
/// </summary>
|
||||
public static StudioOptions Parse(string[] args)
|
||||
{
|
||||
string? datDir = null;
|
||||
uint? layoutId = null;
|
||||
string? markupPath = null;
|
||||
string? dumpSlug = null;
|
||||
string? dumpFile = null;
|
||||
string? datDir = null;
|
||||
uint? layoutId = null;
|
||||
string? markupPath = null;
|
||||
string? dumpSlug = null;
|
||||
string? dumpFile = null;
|
||||
string? screenshotPath = null;
|
||||
|
||||
for (int i = 0; i < args.Length; i++)
|
||||
{
|
||||
|
|
@ -58,6 +63,10 @@ public sealed record StudioOptions(
|
|||
{
|
||||
dumpFile = args[++i];
|
||||
}
|
||||
else if (args[i] == "--screenshot" && i + 1 < args.Length)
|
||||
{
|
||||
screenshotPath = args[++i];
|
||||
}
|
||||
else if (!args[i].StartsWith('-'))
|
||||
{
|
||||
datDir ??= args[i];
|
||||
|
|
@ -75,7 +84,7 @@ public sealed record StudioOptions(
|
|||
if (layoutId is null && markupPath is null && dumpSlug is null)
|
||||
layoutId = 0x2100006Cu;
|
||||
|
||||
return new StudioOptions(datDir, layoutId, markupPath, dumpSlug, dumpFile);
|
||||
return new StudioOptions(datDir, layoutId, markupPath, dumpSlug, dumpFile, screenshotPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue