name: gum-icons description: Umbrella for icons in Gum. Triggers: GumIcon, GumIconKind, GumFigmaIconRipper, GumIcons.xaml, FluentIcon usage in the tool, replacing/adding icons in WPF chrome, tree view, or Forms runtime. Read this first before adding an icon anywhere — it routes you to the right pipeline. type: skill
Gum Icons Reference
There are three independent icon pipelines in Gum. Pick the right one before authoring or adding code.
At a glance
| Where | Format on disk | Runtime form | Theming | Detail skill |
|---|---|---|---|---|
| Tool WPF chrome (variable grid, dock/anchor/alignment, toggle-button option displays) | SVG in Gum/Content/Svg/ |
PathGeometry resources in Gum/Themes/GumIcons.xaml, consumed via <controls:GumIcon Icon="…"/> |
Fill follows the control's Foreground (theme brush) |
this file |
| Tool tree view (Screens/Components/Behaviors panel, '!' overlay, sizing/origin badges) | PNG in Gum/Content/Icons/UpdatedTreeViewIcons/ |
Image cached in ElementTreeViewCreator._originalImages, indexed by ImageIndex constants |
White-on-transparent source, multiplicatively tinted from Frb.Colors.Icon.* per a key→color map |
gum-tool-tree-view |
| Forms runtime default visuals (in-game UI on the user's MonoGame/Skia/etc. surface — not the tool itself) | Sprite sheet (PNG atlas) shipped with Styling.ActiveStyle |
Sprite coords from Icons table, drawn through the runtime sprite system |
Style-driven (V2/V3 styling); no DynamicResource concept | gum-forms-default-visuals |
Don't mix them. A tree-view PNG is not a GumIcon. A GumIcon PathGeometry cannot be drawn into the MonoGame viewport. The Forms sprite sheet has nothing to do with the tool's WPF chrome.
Pipeline 1 — Tool WPF chrome (GumIcon)
The standard for any icon in the WPF tool outside the tree view. Replaces ad-hoc {wpf:FluentIcon …} usage from the FluentIcons.Wpf NuGet.
These icons live inside WPF displayer controls (e.g. the variable grid's origin/alignment/dock toggles). For how such a displayer gets attached to a variable, see gum-tool-variable-grid.
Components:
Gum/Content/Svg/*.svg— authored sources.Gum/GumFigmaIconRipper/Program.cs— console tool. Uses SharpVectors at build time only (no runtime dependency). Walks the SVG drawing tree; flattens into a primary geometry (≥95% opacity fills/strokes) and an optional.Secondarygeometry (lower-opacity detail). Clips to a 2px live area inside a 32×32 viewBox.Gum/Themes/GumIcons.xaml— generatedResourceDictionaryofPathGeometrykeyed by SVG filename. Merged inFrb.Styles.Defaults.xaml, so it's globally available.Gum/Themes/GumIconKind.g.cs— generated enum +GumIconKindMap.GetResourceKey, plus aTypeConverterthat acceptsIcon="folder-star"orIcon="FolderStar"in XAML.Gum/Controls/GumIcon.cs+ style/template inFrb.Styles.Defaults.xaml— templatedControlwithPART_Path/PART_PathSecondary/PART_Image/PART_Box. Both paths fill from{TemplateBinding Foreground}, so the icon inherits theme tint from its parent button/style.SecondaryOpacitydefaults to 0.32.
Adding a new icon:
- Author SVG following the format spec below. Drop into
Gum/Content/Svg/YourIconName.svg. - Run
GumFigmaIconRipperfrom its own directory (it computes input/output paths relative toDirectory.GetCurrentDirectory(), expecting cwd =Gum/GumFigmaIconRipper):
Do not usecd Gum/GumFigmaIconRipper && dotnet rundotnet run --project Gum/GumFigmaIconRipperfrom the repo root — the ripper will look in the wrong place. The ripper rewritesGum/Themes/GumIcons.xamlandGum/Themes/GumIconKind.g.csin full. - Commit the SVG, the regenerated
GumIcons.xaml, and the regeneratedGumIconKind.g.cstogether. - In XAML, use
<controls:GumIcon Icon="YourIconName"/>(wherecontrolsisclr-namespace:Gum.Controls).GumIconis aControl, not a markup extension — set the button's child element rather than itsContentattribute when you have other content:<Button Click="LeftButton_Click" ToolTip="Dock Left"> <controls:GumIcon Icon="DockLeft" /> </Button>
Migrating from FluentIcons.Wpf:
- Replace
Content="{wpf:FluentIcon Icon=Foo}"withContent="{controls2:GumIcon Icon=YourEquivalent}"(or a nested<controls:GumIcon Icon="…"/>element). - The icon library is yours, not Microsoft's — names are whatever the SVG filename was.
Author format (passable to a designer or icon-producing AI):
SVG, 32×32
viewBox="0 0 32 32". Keep all visible content within a 2px margin (live area 2..30; the ripper hard-clips outside this). Single solid color (any — color is replaced by themeForegroundat runtime). Usefill-opacity≥0.95 for the primary tone and<0.95for any secondary detail (the ripper auto-routes secondary geometry into a.Secondaryresource that draws at 0.32 opacity, giving free two-tone). Pure path geometry only — no gradients, filters, masks, or embedded raster; text must be converted to outlines.
Pipeline 2 — Tool tree view (PNG ImageList)
Used by the main element tree (MultiSelectTreeView) and the flat search list. Uses WinForms-era PNGs because the tree view itself is a WinForms-derived control. White/grayscale PNGs are runtime-tinted from theme colors.
To add a tree-view icon, see gum-tool-tree-view. The short version: drop a white-on-transparent PNG into Gum/Content/Icons/UpdatedTreeViewIcons/, append a TryInjectIcon call in InjectDynamicIcons() matching the next ImageIndex constant, and add a color-map entry in GetCurrentColorMap() if the icon should pick up a theme color other than Frb.Colors.Primary.
Do not migrate tree-view icons to GumIcon — the tree view's MultiSelectTreeView/ImageList model expects Image instances, not WPF Controls, and the index-based lookup is wired through ElementTreeViewManager.
Pipeline 3 — Forms runtime default visuals
In-game UI icons (Forms controls' check marks, arrows, etc.) come from a sprite sheet bundled with the active styling. This is a runtime concern (MonoGame/Skia/Raylib), not WPF chrome, and is handled by the Forms styling system rather than any of the above.
To add an in-game icon, see gum-forms-default-visuals. Coordinates live in the Icons table and are referenced by sprite name from styling.
Notable existing third-party usage to be aware of
wpf:FluentIcon(FluentIcons.Wpf NuGet) — still used inStateAnimationPlugin,AnchorControl.xaml,DockControl.xaml, and a few ToggleButtonOptionDisplay templates. Treat as legacy: preferGumIconfor any new chrome icon, and migrate existing ones opportunistically.MaterialDesignThemesPackIcon— used for tree-view collapse buttons (sized viaUpdateCollapseButtonSizes). Distinct from the tree's image-list icons; left as-is for now.gumcli svg <project> <element>— exports a Gum project element to an SVG file (via SkiaGum'sSKSvgCanvas). Unrelated to icon authoring; do not confuse with this pipeline.
Gotchas
- The ripper is not wired into MSBuild. If you edit an SVG and forget to run it (
cd Gum/GumFigmaIconRipper && dotnet run),GumIcons.xamlandGumIconKind.g.cswill be stale and the new icon won't appear. The CI build won't catch this — only a visual inspection will. - The ripper writes
GumIconKind.g.csandGumIcons.xamlexternally. Editors and agent file caches that don't re-stat after a sub-process write may show stale content. If a newGumIconKind.YourIconmember appears missing, re-read the file fresh (e.g. via shellgrep) before assuming the ripper failed. - Live-area clip is silent. Anything in the SVG outside
2..30on either axis is clipped without warning. Designers used to authoring at the full 32×32 will see edges chopped. - Two-tone is opacity-driven, not class- or layer-driven. SharpVectors flattens the SVG drawing tree; tone routing happens by the resolved fill/stroke alpha at draw time, not by
<g class="secondary">or layer name. Usefill-opacity(or RGBA) to mark secondary detail. - Theme tint is
Foreground, not a custom brush.GumIcon's template binds pathFilltoTemplateBinding Foreground. Tinting a single icon differently means settingForegroundon theGumIcon(or its containing button). There's no separateIconBrushresource. - Tree-view PNG source must be white. A pre-colored tree-view PNG will multiply with the theme color and look wrong. The tree-view pipeline does not support two-tone.