Skip to content

Commit eb8ee36

Browse files
authored
Added screenshot/svg (#2556)
1 parent 84434cd commit eb8ee36

8 files changed

Lines changed: 111 additions & 10 deletions

File tree

.claude/skills/gum-cli/SKILL.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: gum-cli
3-
description: Reference guide for GumCli — the headless command-line tool for Gum projects. Load this when working on gumcli commands (new, check, codegen, codegen-init), Gum.ProjectServices, HeadlessErrorChecker, ProjectLoader, HeadlessCodeGenerationService, CodeGenerationAutoSetupService, or the FormsTemplateCreator.
3+
description: Reference guide for GumCli — the headless command-line tool for Gum projects. Load this when working on gumcli commands (new, check, codegen, codegen-init, fonts, screenshot, svg), Gum.ProjectServices, HeadlessErrorChecker, ProjectLoader, HeadlessCodeGenerationService, CodeGenerationAutoSetupService, or the FormsTemplateCreator.
44
---
55

66
# GumCli Reference
@@ -21,6 +21,8 @@ description: Reference guide for GumCli — the headless command-line tool for G
2121
| `gumcli codegen <project.gumx> [--element <name>...]` | Generate C# code. Requires `ProjectCodeSettings.codsj`. Per-element error check gates generation. |
2222
| `gumcli codegen-init <project.gumx> [--force] [--csproj <path>]` | Auto-detect `.csproj`, derive namespace and output library, write `ProjectCodeSettings.codsj`. Use `--csproj` when the Gum project is not inside the MonoGame project directory. |
2323
| `gumcli fonts <project.gumx>` | Generate missing bitmap font files (.fnt + .png). Windows-only (bmfont.exe). |
24+
| `gumcli screenshot <project.gumx> <element> [--output] [--width] [--height]` | Render a Screen or Component to a PNG via MonoGame DesktopGL. Pixel-accurate; cross-platform. |
25+
| `gumcli svg <project.gumx> <element> [--output] [--width] [--height]` | Render a Screen or Component to a vector SVG via SkiaGum's `SKSvgCanvas`. Bitmaps embed as base64. |
2426

2527
**Exit codes:** 0 = success, 1 = errors found / generation blocked, 2 = load failure, bad args, or non-Windows (fonts).
2628

@@ -32,7 +34,9 @@ Program.cs
3234
├── CheckCommand → ProjectLoader → HeadlessErrorChecker
3335
├── CodegenCommand → ProjectLoader → HeadlessErrorChecker (gates) → HeadlessCodeGenerationService
3436
├── CodegenInitCommand → CodeGenerationAutoSetupService
35-
└── FontsCommand → ProjectLoader → HeadlessFontGenerationService (Windows-gated)
37+
├── FontsCommand → ProjectLoader → HeadlessFontGenerationService (Windows-gated)
38+
├── ScreenshotCommand → MonoGameScreenshotService (Gum.ProjectServices.MonoGame)
39+
└── SvgCommand → SkiaGumSvgExportService (Gum.ProjectServices.SkiaGum)
3640
```
3741

3842
Each command class has a static `Create()` returning a `System.CommandLine` `Command` with handler, then a static `Execute()` doing the work.

Tools/Gum.Cli/Commands/SvgCommand.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
using System.CommandLine;
33
using System.CommandLine.Invocation;
44
using System.IO;
5-
using System.Reflection;
65
using Gum.ProjectServices.SkiaGum;
76
using Gum.ProjectServices.SvgExport;
87

@@ -69,13 +68,6 @@ public static Command Create()
6968

7069
private static int Execute(string projectPath, string elementName, string outputPath, int? width, int? height)
7170
{
72-
string version = Assembly.GetExecutingAssembly()
73-
.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion
74-
?? Assembly.GetExecutingAssembly().GetName().Version?.ToString()
75-
?? "unknown";
76-
77-
Console.WriteLine($"gumcli v{version}");
78-
7971
string fullProjectPath = Path.GetFullPath(projectPath);
8072

8173
if (!File.Exists(fullProjectPath))

Tools/Gum.Cli/HeadlessNameVerifier.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,13 @@ public bool IsBehaviorNameValid(string behaviorName, BehaviorSave behaviorSave,
9999
/// <inheritdoc/>
100100
public bool IsComponentNameAlreadyUsed(string name) => false;
101101

102+
/// <inheritdoc/>
103+
public bool IsNameValidTopLevel(string name, ElementSave element, object? objectToIgnore, out string? whyNotValid)
104+
{
105+
whyNotValid = null;
106+
return true;
107+
}
108+
102109
/// <inheritdoc/>
103110
public bool IsNameValidAndroidFile(string name, out string whyNotValid)
104111
{

Tools/Gum.Cli/Program.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ public static int Main(string[] args)
1616
?? Assembly.GetExecutingAssembly().GetName().Version?.ToString()
1717
?? "unknown";
1818

19+
System.Console.WriteLine($"gumcli v{version}");
20+
1921
var rootCommand = new RootCommand($"gumcli v{version} - create projects, check for errors, and generate code.");
2022

2123
rootCommand.AddCommand(NewCommand.Create());

docs/SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,5 @@
387387
* [codegen-init](cli/codegen-init.md)
388388
* [codegen](cli/codegen.md)
389389
* [fonts](cli/fonts.md)
390+
* [screenshot](cli/screenshot.md)
391+
* [svg](cli/svg.md)

docs/cli/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Once installed, invoke it as `gumcli` from any terminal.
3434
| `codegen-init` | Initialize code generation settings |
3535
| `codegen` | Generate C# code for project elements |
3636
| `fonts` | Generate missing bitmap font files |
37+
| `screenshot` | Render a Screen or Component to a PNG file |
38+
| `svg` | Render a Screen or Component to an SVG file |
3739

3840
## Exit Codes
3941

docs/cli/screenshot.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# screenshot
2+
3+
```
4+
gumcli screenshot <project.gumx> <element> [--output <path>] [--width <px>] [--height <px>]
5+
```
6+
7+
Renders a Gum Screen or Component to a PNG file. The element is laid out and drawn using the same MonoGame (DesktopGL) backend a shipped game would use, so the output is pixel-accurate and suitable for visual regression testing, documentation screenshots, or asset pipelines.
8+
9+
## Arguments
10+
11+
- `<project.gumx>` — Path to the `.gumx` project file.
12+
- `<element>` — Name of the Screen or Component to render (for example, `MainMenu` or `Controls/Button`).
13+
14+
## Options
15+
16+
- `--output` — Path for the output PNG file. Defaults to `<element>.png` in the current directory.
17+
- `--width` — Width of the output image in pixels. Defaults to the project canvas width.
18+
- `--height` — Height of the output image in pixels. Defaults to the project canvas height.
19+
20+
## Examples
21+
22+
```
23+
gumcli screenshot MyProject/MyProject.gumx MainMenu
24+
gumcli screenshot MyProject/MyProject.gumx Controls/Button --output button.png
25+
gumcli screenshot MyProject/MyProject.gumx MainMenu --width 1920 --height 1080
26+
```
27+
28+
Output on success:
29+
30+
```
31+
Screenshot written to: /full/path/to/MainMenu.png
32+
```
33+
34+
## Notes
35+
36+
- Works cross-platform — uses DesktopGL, not a Windows-specific rendering path.
37+
- Any fonts referenced by the element must already exist in the project's `FontCache/` folder. Run [`gumcli fonts`](fonts.md) first if fonts are missing.
38+
- Bitmap content (sprites, nine-slices, text) is rasterized into the PNG at the requested resolution.
39+
40+
## Exit Codes
41+
42+
| Code | Meaning |
43+
|------|---------|
44+
| 0 | Screenshot written successfully |
45+
| 1 | Rendering failed (for example, the named element does not exist) |
46+
| 2 | Project file not found |

docs/cli/svg.md

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# svg
2+
3+
```
4+
gumcli svg <project.gumx> <element> [--output <path>] [--width <px>] [--height <px>]
5+
```
6+
7+
Renders a Gum Screen or Component to a vector SVG file. Useful when you need scalable output for documentation, print, or design tooling rather than a fixed-resolution bitmap.
8+
9+
## Arguments
10+
11+
- `<project.gumx>` — Path to the `.gumx` project file.
12+
- `<element>` — Name of the Screen or Component to render.
13+
14+
## Options
15+
16+
- `--output` — Path for the output SVG file. Defaults to `<element>.svg` in the current directory.
17+
- `--width` — Width of the output SVG in pixels. Defaults to the project canvas width.
18+
- `--height` — Height of the output SVG in pixels. Defaults to the project canvas height.
19+
20+
## Examples
21+
22+
```
23+
gumcli svg MyProject/MyProject.gumx MainMenu
24+
gumcli svg MyProject/MyProject.gumx Controls/Button --output button.svg
25+
gumcli svg MyProject/MyProject.gumx MainMenu --width 1920 --height 1080
26+
```
27+
28+
Output on success:
29+
30+
```
31+
SVG written to: /full/path/to/MainMenu.svg
32+
```
33+
34+
## Notes
35+
36+
- Uses SkiaGum's `SKSvgCanvas` to produce the SVG, so shapes and text are emitted as vector elements.
37+
- Bitmap content (sprites, textures) is embedded as base64-encoded images inside the SVG. The file is self-contained but can be significantly larger than the equivalent PNG when the element contains many bitmaps.
38+
- If you need a rasterized PNG instead, use [`gumcli screenshot`](screenshot.md).
39+
40+
## Exit Codes
41+
42+
| Code | Meaning |
43+
|------|---------|
44+
| 0 | SVG written successfully |
45+
| 1 | Export failed (for example, the named element does not exist) |
46+
| 2 | Project file not found |

0 commit comments

Comments
 (0)