Skip to content

Authoring Layouts ButtonPopup

EmoTracker Community edited this page Apr 8, 2026 · 2 revisions

Authoring Layouts — Button Popup

A button popup is a clickable button in your layout that, when clicked, displays another layout as a popup. It's how packs implement settings panels, item pickers, "more info" toggles, and any other UI that you want hidden behind a single click.

See Authoring Layouts for the file format and base fields. This page only covers fields specific to the button_popup type.

JSON schema

Parsed in EmoTracker.Data/Layout/ButtonPopup.cs. Matches the button_popup branch in layouts.json.

Field Type Required Default Description
type "button_popup" yes Literal string.
layout string yes The name of a previously-loaded layout to display in the popup. Looked up via LayoutManager.FindLayout at parse time.
style string no "settings" The button's display style — see Button styles below.
image string no none Pack-relative image path. Used when style: "image".
image_filter string no none An image filter spec applied to image when style: "image".
mask_input boolean no false When style: "image", if true, only the visible (non-transparent) pixels of the image are clickable. If false, the entire bounding rectangle is clickable.
popup_background string no "#FF212121" Background color of the popup body in web color format.

Plus the standard base fields from Authoring Layouts → Fields every layout element shares.

Button styles

style value What it draws
"settings" (default) A small "gear" icon, suitable for "open settings"-type buttons.
"solid" A flat solid-color button, sized by the element's width/height. Useful when paired with a child or label.
"image" A button that draws the image referenced by image (with image_filter applied if set). The button's bounds are the image's natural size unless width/height override them.

Examples

A settings gear that opens a settings layout

layouts/popups.json:

{
  "settings_popup": {
    "type": "container",
    "content": {
      "type": "array",
      "orientation": "vertical",
      "content": [
        { "type": "text", "text": "Game Settings" },
        ...
      ]
    }
  }
}

layouts/tracker.json:

{
  "type": "button_popup",
  "layout": "settings_popup",
  "popup_background": "#FF1A1A1A"
}

An image button that toggles a help overlay

{
  "type": "button_popup",
  "style": "image",
  "image": "images/icons/help.png",
  "layout": "help_popup",
  "width": 24,
  "height": 24
}

Embedding a button in a group header

{
  "type": "group",
  "header": "Dungeons",
  "header_content": {
    "type": "button_popup",
    "style": "image",
    "image": "images/icons/cog.png",
    "layout": "dungeon_settings_popup",
    "mask_input": true
  },
  "content": {
    "type": "itemgrid",
    "rows": [ [...] ]
  }
}

mask_input: true makes only the actual cog pixels clickable, so clicks in the transparent corners of the icon fall through to whatever's behind it.

Loading order matters

layout is resolved at parse time via LayoutManager.FindLayout(name). The popup's target layout has to already be loaded when the layout containing the button is parsed, or the reference becomes a no-op.

Standard pattern: load all popup layouts first, then the main layout that opens them:

Tracker:AddLayouts("layouts/popups.json")
Tracker:AddLayouts("layouts/tracker.json")

Tips and pitfalls

  • The popup layout must already be loaded. Same rule as Layout Reference — load referenced layouts before referencing layouts.
  • mask_input only matters for image buttons. It has no effect on settings or solid styles.
  • Set width and height on the button when using style: "image" if you want it to appear at a specific size — without them, the image renders at its natural pixel size.
  • The popup is modal-light. Clicking outside it closes it; only one popup can be open at a time per surface. Don't try to nest button popups deep — it's confusing for players.
  • popup_background is the popup's body color, not the button's. The button's own background is controlled by the base background field.
  • For invisible click targets, use a solid button with a transparent background rather than trying to hide an image button — the bounds will be cleaner.

See also

Clone this wiki locally