Skip to main content

Crate bevy_gooey

Crate bevy_gooey 

Source
Expand description

Game interfaces made easy for Bevy: a skin, ready-made game widgets and keyboard and gamepad navigation, on Bevy’s own headless widgets (bevy_ui_widgets) and input focus (bevy_input_focus).

A menu is a few nested calls, every widget looks like one family, and a pad or a keyboard reaches everything a mouse does:

model holds the engine-free maths under the skin: contrast_ratio, composite, meter_fraction, slider_fraction, scroll_to_reveal, tab_step, window_ui_scale and toast_hold.

use bevy::prelude::*;
use bevy_gooey::*;

fn main() {
    App::new()
        .add_plugins((DefaultPlugins, GooeyPlugins))
        .add_systems(Startup, setup)
        .run();
}

fn setup(mut commands: Commands) {
    commands.spawn(Camera2d);
    commands.spawn((
        screen(),
        children![(
            panel(),
            children![
                heading("Paused"),
                (
                    menu(),
                    children![
                        (button("Resume"), observe(|_: On<Activate>| info!("resume"))),
                        button("Quit"),
                    ]
                ),
            ]
        )],
    ));
}

Every plugin is independent; adding some and not others is supported. None of them adds UiWidgetsPlugins, InputFocusPlugin or InputDispatchPlugin: DefaultPlugins adds those, and adding one twice panics. A host without DefaultPlugins adds them itself.

§What this crate does not own

World-space speech balloons and dialogue belong to bevy_speech_bubbles; the game’s states and pausing, to the game. Audio is the host’s: it hears UiFeedback. Localization is the host’s: every widget takes the string to show. Fonts are the host’s: it fills GooeyFonts.

§Units

Sizes are logical pixels at a window whose shorter side is UiScaleSettings::reference_short_side (720). GooeyScalePlugin sets Bevy’s UiScale from the window, so a 1920x1080 window draws them at 1.5x; a host that drives UiScale itself leaves that plugin out (GooeyPlugins.build().disable::<GooeyScalePlugin>()). Line weights (borders, the focus ring, a meter’s frame and gap) are the exception to “multiplied”: they are drawn a whole number of device pixels wide at whatever scale the node has, rounded down (snap_line_width), so each is one weight on all four sides.

Re-exports§

pub use model::COMFORT_TARGET_PX;
pub use model::COOLDOWN_WHOLE_SECONDS_FROM;
pub use model::DIALOG_SLIDE_PX;
pub use model::DIALOG_SLIDE_SECONDS;
pub use model::DOCK_EDGE_FRACTION;
pub use model::DOCK_EDGE_SHARE;
pub use model::DOCK_PANE_MIN_PX;
pub use model::DockZone;
pub use model::ELEVATION_STEP;
pub use model::ENHANCED_CONTRAST;
pub use model::HexError;
pub use model::INTERFACE_SIZE_STEPS;
pub use model::METER_GAIN_TAU_SECONDS;
pub use model::METER_SNAP;
pub use model::METER_TRAIL_HOLD_SECONDS;
pub use model::METER_TRAIL_RATE;
pub use model::MIN_TARGET_PX;
pub use model::MeterShown;
pub use model::NON_TEXT_CONTRAST;
pub use model::NumberError;
pub use model::PAD_REPEAT_DELAY;
pub use model::PAD_REPEAT_RATE;
pub use model::PAD_STYLES;
pub use model::POPOVER_SLIDE_PX;
pub use model::POPOVER_SLIDE_SECONDS;
pub use model::PadStyle;
pub use model::RADIAL_DEAD_ZONE;
pub use model::RADIAL_STICK_PUSH;
pub use model::SPINNER_PERIOD_SECS;
pub use model::SPLIT_KEY_STEP_PX;
pub use model::STATE_STEP;
pub use model::STICK_PUSH;
pub use model::TABLE_LEAST_COLUMN;
pub use model::TEXT_CONTRAST;
pub use model::TEXT_SIZE_STEPS;
pub use model::TYPE_AHEAD_SECS;
pub use model::TableStep;
pub use model::Toward;
pub use model::area_values;
pub use model::bar_fit;
pub use model::box_outside;
pub use model::choice_next;
pub use model::choice_step;
pub use model::cie_lightness;
pub use model::clock_text;
pub use model::column_resize;
pub use model::composite;
pub use model::contrast_ratio;
pub use model::cooldown_sweep;
pub use model::cooldown_text;
pub use model::cooldown_words;
pub use model::dock_drop_rect;
pub use model::dock_edge_zone;
pub use model::dock_neighbour;
pub use model::dock_tab_slot;
pub use model::dock_zone;
pub use model::ease_out;
pub use model::eta_words;
pub use model::format_number;
pub use model::fuzzy_score;
pub use model::hex_text;
pub use model::hsv_to_rgb;
pub use model::is_modifier_key;
pub use model::key_name;
pub use model::list_height;
pub use model::meter_fraction;
pub use model::meter_motion;
pub use model::mouse_name;
pub use model::natural_cmp;
pub use model::nearest_step;
pub use model::number_decimals;
pub use model::pad_name;
pub use model::page_target;
pub use model::parse_hex;
pub use model::parse_number;
pub use model::pin_to_edge;
pub use model::progress_text;
pub use model::radial_pick;
pub use model::radial_place;
pub use model::radial_step;
pub use model::relative_luminance;
pub use model::repeat_steps;
pub use model::rgb_to_hsv;
pub use model::scroll_to_reveal;
pub use model::scrub_value;
pub use model::shortcut_conflicts;
pub use model::shortcut_label;
pub use model::slider_fraction;
pub use model::slider_text;
pub use model::slot_edge;
pub use model::snap_line_width;
pub use model::snap_to_row;
pub use model::spinner_angle;
pub use model::split_clamp;
pub use model::split_drag;
pub use model::split_mins;
pub use model::step_value;
pub use model::tab_step;
pub use model::table_anchor;
pub use model::table_step;
pub use model::table_window;
pub use model::target_step;
pub use model::target_toward;
pub use model::toast_alpha;
pub use model::toast_grow;
pub use model::toast_hold;
pub use model::toast_life;
pub use model::tree_ends;
pub use model::tree_heir;
pub use model::tree_indent;
pub use model::tree_parent;
pub use model::tree_visible;
pub use model::type_ahead;
pub use model::window_ui_scale;

Modules§

model
The engine-free maths under the skin: contrast, compositing, meter fill, the interface’s scale against the window and line weights on whole device pixels.

Structs§

Activate
Notification sent by a button or menu item.
AnchorPinned
On an anchored node exactly while it is pinned to the screen’s edge: direction is the unit vector from the middle of the viewport toward the world point, in screen space (y down), for a beacon to turn its arrow by.
AreaMarker
The ring on the area at the colour’s saturation and value. Part of the picker.
BadgesShown
Whether the overlay is up, for a host that has to react to it: dim the ground under the badges, leave the shortcuts out of an ink census, re-place on a tab change. true from the frame update_shortcut_badges has the reveal held for ShortcutBadges::delay_seconds until the frame it is let go, switched off or blocked, whether or not any widget has a chord to show. The crate writes it, only when it changes; a host reads it (Res<BadgesShown>) and never writes it.
BindingSettings
What crate::binding says and which keys end it. The crate has no strings of its own, so the prompts are the host’s to translate; {exit} in a prompt is replaced by the name of the input that exits (BindingSettings::cancel_key on a keyboard row, BindingSettings::cancel_button on a pad row).
BindingValue
What a crate::binding row has bound: the widget’s state. Read it to know the control, or set it to change the row from code (the keycap follows in the same frame, and no ValueChange is sent for a change the game made itself): a game that loads the player’s bindings spawns its rows with them, and one that refuses a clash puts the old value back.
Cancel
The player asked to back out: Escape, or any gamepad’s East button (B on Xbox, Circle on PlayStation), pressed once. Nothing is closed for you; say what leaving means by observing it on the dialog or the screen the player is in.
CancelScope
How a Cancel travels: to the parent, and no further than a dialog.
Capturing
On a crate::binding row while it waits for the player’s next press. While any row has it the crate’s own input systems stand still (see not_capturing) and nothing else can be pressed with the pointer, so a game that reads raw keys of its own gates them on this too: Query<(), With<Capturing>> is empty when none waits. Handle Back through crate::Cancel: it is never sent for the press that exits a capture.
Checked
Component that indicates whether a checkbox or radio button is in a checked state.
ChoiceCount
How many options a crate::choice has: set when it is spawned and read by the widget to know where its ends are. Leave it alone; a choice’s options are fixed for its life.
ChoiceValue
Which option a crate::choice has selected: an index into its options, in the order they were given. It is the widget’s state: read it to know the setting, set it to move the choice from code (the screen follows in the same frame, and no ValueChange is sent for a change the game made itself). A value past the last option is pulled back to the last.
ColorArea
The picker’s saturation and value area, a focusable plane: the pointer sets both, the arrow keys step them, and the D-pad’s Left and Right step the saturation. Part of the picker.
ColorPicker
The open picker of a crate::color_field: the popover crate::color_field’s swatch opens. It keeps the hue, saturation and value the player is on, which the row’s ColorValue cannot (a grey has no hue and a black no saturation, so dragging to black and back would forget where the player was). A game never builds one; it may read which row a picker belongs to.
ColorRail
The gradient a strip’s rail shows. Part of the picker.
ColorRefused
Text the player typed that a crate::color_field would not take, sent on the row with the reason (HexError reads as words). The field shows the colour again.
ColorStrip
A picker’s slider: hue, brightness or alpha. Part of the picker.
ColorSwatch
On a colour field’s swatch button: its row. Part of what crate::color_field spawns, a game never builds one.
ColorValue
What a crate::color_field holds: its colour, sRGB with alpha. It is the widget’s state: read it to know the colour, set it to change the field from code (the swatch, the text and an open picker show it in the same frame and no ValueChange is sent for a change the game made itself). The player’s own changes are one ValueChange<Srgba> on the row each: is_final is false while a drag is still rolling the colour and true when it ends, on Enter, when focus leaves the text after an edit, and for a key or D-pad step.
Column
One column of a crate::table.
CommandList
Every command a command_palette lists. It is the one list: the game fills it once and changes it as commands come and go or switch on and off, and an open palette follows the change in the same frame.
CommandPalette
An open command_palette: which of its matches is lit and which matches there are. Its fields are the palette’s own; read them through the methods.
Confirm
A modal question: a title, a line of body and the choices, as one component. Spawn it, observe ConfirmChosen, and nothing else: it is a dialog (focus goes in and stays in, and comes back to the opener), its panel is the dialog’s, and it despawns itself when it is answered.
ConfirmButton
On a confirmation’s button: the dialog it answers and its place in the list.
ConfirmChosen
The player answered a Confirm: sent once, on the dialog, in the flush that despawns it. index is the choice’s place in the list it was built from; cancelled is true when Escape or a pad’s East answered, with the safe choice’s index.
ContextMenu
On any entity (a UI node, a sprite, a mesh): the crate::context_menu panel that is its menu. A secondary click that reaches the entity opens it at the pointer, and Shift+F10 or the Menu key with focus on the entity or a widget under it opens it below that widget. The nearest entity above the click or the focus that has one is the one used. One menu may be named by many entities (every row of a list); ContextTarget says which it was opened for.
ContextTarget
On a context menu’s panel exactly while it is open: the entity that has the ContextMenu it was opened for (never the widget a key opened it beside, when that is one of its descendants). Read it in an item’s Activate observer with ContextTarget::of, or in an On<Add<ContextTarget>> observer, which runs before the menu is first drawn, to enable, disable or relabel the items for this thing.
Cooldown
A timer on a widget: until it is spent the widget carries a dimmed cover whose clear wedge opens clockwise from twelve o’clock, with the seconds left on a chip in the middle. Put it on any node that is a positioning context (a button, an icon_button, a slot of a slot_grid); it is ready, and draws nothing, until Cooldown::start.
CooldownReady
Sent on a widget the frame its Cooldown reaches zero (not when a game sets remaining to zero itself): the place to play the “ready” sound, XAG’s second channel for the same news.
Dialog
What a crate::dialog remembers: the widget that had focus when it opened, which gets focus back when the dialog closes, and whether focus has moved in yet. Part of dialog(); a game never builds one.
Disabled
Makes the item it is on unavailable, and says why: Bevy’s InteractionDisabled (so it never activates, by key, pad or pointer, and is drawn muted) and a Tooltip with the reason. The item stays focusable, so the player who walks onto it by key or pad reads the reason too. Removing it makes the item available and removes the tooltip; inserting it again with another reason changes the line.
Dock
A crate::dock’s layout: the state. Write a DockLayout to it to load or reset the layout (the dock shows it the same frame; panels already shown are kept and moved, the rest are spawned and the ones no longer named despawned); read it, or observe DockLayoutChanged, to save what the player did.
DockDropTarget
Where a dragged panel lands: next to or into the group holding onto, or at an edge of the whole dock.
DockLayoutChanged
The player changed a Dock’s layout, by dropping a tab (in a group, beside one, at the dock’s edge or on a tab strip), moving a divider (when it is let go, and for each step of a key) or picking a tab. It holds the layout now shown: save it.
DockPanel
The page of a panel, in the dock that shows it: put on the entity PanelRegistry::register’s function fills, so a game can find a panel’s widgets by its id.
DockPanelSkipped
A panel the dock was told to show but could not: sent once for each, when the dock is built from a layout that names it, so a game finds a typo or a panel it forgot to register.
DragLabel
What the carried thing is, for the ghost beside the pointer. Without one the ghost shows the first text the source holds (a row’s name, a button’s label).
DragPayload
Makes a node a drag source: pressing it and moving more than DRAG_LIFT_PX picks T up. The node needs Pickable (every gooey widget has it; a sprite or mesh needs it added).
DragSettings
The keys that carry a payload without a pointer, so a drag is never the only way (WCAG 2.2, 2.5.7): a keyboard or gamepad player focuses a source (DragPayload), presses DragSettings::pick_up (a pad’s DragSettings::pick_up_button), steers the mark with the arrows or the D-pad (PageUp and PageDown, LB and RB step through the targets in reading order), and drops with the same key again (a pad’s South too). Escape or East puts it down. A game that wants other keys writes this resource; a keymap the player edits is this value.
DragState
The one drag in progress, if any: a resource, because one pointer carries one thing. GooeyNavPlugin adds it; read it to know what the pointer holds.
Dragging
On a source exactly while it is carried (the pointer has moved past DRAG_LIFT_PX and not let go): dim it, or hide it, or ignore it. The ghost and the mark are the crate’s.
DropCandidate
On every DropTarget node that takes what is being carried, exactly while a drag is lifted: the places the item may land, known the moment it is picked up (WAI-ARIA: “authors SHOULD show a visual indication of potential drop targets”). It is the test the drop and the keyboard steering use, so a candidate is a place the carry can really land: not the source itself, not a target whose DropTarget::accepting test or a slot’s rule says no, not a disabled or hidden one. The crate draws nothing for it (see DropRefusing); style your own targets with Has<DropCandidate>. Put on and taken off by the crate; never add it yourself.
DropRefused
A T was let go over a DropZone that does not take it: another type, or DropTarget::accepting said no. An event on the target. Nothing moved.
DropRefusing
On every enabled, visible DropTarget node that refuses what is being carried, exactly while a drag is lifted: the opposite of DropCandidate, for a source that is not the target itself. The crate dims an inventory slot that has it, so in an equipment panel the one slot that fits stays bright, and when everything takes the item nothing changes on screen. Put on and taken off by the crate; never add it yourself.
DropTarget
Makes a node a place a T may be dropped. A node may carry several, one for each type it takes. The type is the match: a DragPayload<A> over a node with only a DropTarget<B> is refused, visibly, and so is one the target’s own test (DropTarget::accepting) says no to.
Dropped
A T was dropped on a DropTarget<T> that takes it. An event on the target, so commands.spawn(..).observe(|on: On<Dropped<T>>| ..) hears the drops on that node.
DroppedOnWorld
A T was let go over nothing the interface draws (the game world under a HUD): a host raycasts from pointer to see what is there. Sent as a global event.
FieldProblem
What is wrong with a text row (text_input, number_field, color_field, a vec_field’s component): put it on the row and text is drawn under it in words, with a bar in the kind’s colour beside them; an Error also frames the field in crate::GooeySkin::danger while the field has no focus (the ring is the ring). A warning leaves the frame alone: it does not block, and the accent is the focus ring’s blue in some looks. Remove it and the message is gone in the same frame; insert another over it and the line changes in place.
FocusRegion
A part of the screen focus can be cycled to: put it on a panel, a viewport or a toolbar.
FocusScopes
Where focus may go: the tab stops and groups Bevy’s Tab navigation sees, which group is an open dialog, and where each group starts. Part of navigate_by_input’s parameters.
GooeyFonts
The fonts widgets draw with. A separate resource from GooeySkin because a font is an asset handle the host loads, not data a project saves.
GooeyNavPlugin
Keyboard and gamepad navigation: arrows and the D-pad move focus, the pad’s South button activates, Tab cycles, and focus moves are written as UiFeedback. Keys and the pad show focus (Bevy’s InputFocusVisible; a pointer press hides it), and a direction press with nothing focused lands where the screen starts. An open dialog holds focus: it takes it on opening (focus_opened_dialogs), Tab and the arrows stay inside it, and closing it gives focus back to the widget that opened it. Escape and the pad’s East button (B) send a Cancel to the focused widget or the open dialog (cancel_by_input), for the game to observe.
GooeyPlugins
Every plugin in the crate: GooeyStylePlugin, GooeyNavPlugin and GooeyScalePlugin.
GooeyScalePlugin
Draws the whole interface in proportion to the window: sets Bevy’s UiScale from the primary window’s shorter side and UiScaleSettings (scale_with_window), so a 1440p window draws everything twice the size a 720p one does.
GooeySkin
The look of every widget: colours and sizes, as plain data a project saves and an editor edits live.
GooeyStylePlugin
Styles every widget from GooeySkin and GooeyFonts, moves Meter fills, and writes UiFeedback for activations.
GroupOption
One option of a crate::toggle_group: a picture with its name, or a word or two. Build it with GroupOption::icon or GroupOption::text.
Icon
What an icon shows. Change it and the picture changes in the same frame (update_icons). The size and the tint are the skin’s: see IconSize and IconTone.
IconMissing
On an Icon whose image failed to load, or that has none. The icon keeps its size and draws nothing, so a toolbar never reflows; a warning is logged once when the marker is added.
IconSize
An icon’s side: a step of crate::GooeySkin::type_scale, so it is as tall as the text of the same step and grows with the player’s text size. The default, step 2, is the body’s line.
LegendRow
One row of a ShortcutLegend: a chord and what it does.
ListView
The scrolling part of a crate::list: the clipped column its rows are children of. It stands rows rows tall (a row is a button’s height, plus a crate::GooeySkin::gap between two: crate::model::list_height), so 4.5 shows four rows and half of the fifth, the cut-off that tells the player there is more.
MenuBar
A crate::menu_bar: the row of MenuTitles. It remembers the widget that had focus when F10 or Alt took focus into it, so Escape (a Cancel reaching the bar) and choosing a command give it back.
MenuItem
One command of a menu: crate::menu_item, crate::check_item, crate::radio_item and (through crate::submenu) a row that opens another menu. It is a component whose insertion builds the row (Bevy’s Button, Role::MenuItem and a mark, a label, a shortcut and a chevron as the item has them), so it chains .with_shortcut(..) and sits in a children![] beside the game’s own observe(..). It sets the row’s Node: put your own layout on a wrapper, not on the item.
MenuMarked
On every item of an open menu that has a check or a radio item in it: they keep the slot at the start of the row that holds the tick, so labels share one edge. A menu with none leaves labels at the row’s own padding.
MenuOpen
On a MenuTitle or a submenu item exactly while its menu is open: the anchor stays lit.
MenuPanel
The card a MenuTitle or a crate::submenu opens. It exists from spawn, closed (not drawn, in no scope); it is open exactly while it has a PopoverPanel.
MenuTitle
A crate::menu_title: a bar’s button that opens a menu. Down, Enter, Space, South and a click open it; Left and Right walk the bar.
Meter
A meter’s reading. Change it and update_meters moves the fill: a loss drops it at once and leaves a Role::MeterTrail of the lost length that holds a moment and drains; a gain eases it up (see meter_motion; MotionSettings::off makes both instant). Any value is safe: the fill is clamped to empty and full, and a non-finite or non-positive maximum reads as empty.
MixedValue
On a crate::number_field whose value is not one number: a multi-selection whose members differ. The field is empty and shows a muted MIXED_HINT; NumberValue is the number a drag or a step starts from. Any change the player makes (a scrub, a step, a typed number) takes the marker off and is the one value for every member; Enter on the untouched field changes nothing. The game puts it back when the selection still differs.
Modifiers
The modifier keys held with a key, as the physical keys (either side of the keyboard counts): a saved keymap says what was pressed, so a mac player’s Control-S and Command-S are two different chords. Modifiers::PRIMARY is the platform’s own “primary” (Command on a mac, Ctrl elsewhere), which is what a game binds “Save” to once for every platform.
MotionSettings
How much motion the player wants: the one switch for every motion the crate draws.
NotificationCenter
A crate::notification_center’s root. Query for it to find the center.
NotificationRow
On a row update_notification_centers spawned: a button for a log entry, or the line that says there is none.
NumberInput
On a number field’s text field (the one a crate::number_field row types in), which steps on Up and Down. Part of what number_field() spawns, a game never builds one.
NumberRange
The least and the greatest a player can make a crate::number_field: a drag, a step and a typed number are all held to it. A value the game sets is shown as it is. On a crate::vec_field it is every component’s.
NumberRefused
Text the player typed that a crate::number_field would not take, sent on the row with the reason (NumberError reads as words). The field shows the number again. Nothing is sent for a number held to the range: that is taken, as the range’s end.
NumberStep
How far one step moves a crate::number_field: a pixel of drag (Shift a tenth of it, Ctrl ten times it), an Up or Down press (Shift ten) and a D-pad press. It also sets the digits the field shows: a step of 0.1 shows one. Put it on the row, at spawn or later; on a crate::vec_field it is every component’s.
NumberValue
What a crate::number_field holds: its number. It is the widget’s state: read it to know the number, set it to change the field from code (the field shows it in the same frame and no ValueChange is sent for a change the game made itself). The player’s own changes are one ValueChange<f32> on the row each: is_final is false while a drag is scrubbing it and true when the drag ends, on Enter, when focus leaves after an edit and on a key or D-pad step.
Overflowed
On a bar’s item that its width has no room for now: it is not laid out (Display::None), and holds the display it comes back with. Query for it to know what a bar has hidden.
PaletteCommand
One command a command_palette lists.
PaletteCount
On the line that says which of how many is lit. Part of what crate::command_palette spawns.
PaletteHistory
The ids of the commands the palette ran, the most recent first, PaletteHistory::LIMIT at most. An empty query lists them first, and so does a query, among the commands that match it. Save it with the game’s settings (it is serde data with the serde feature) to keep recents between runs, or clear it to forget them.
PaletteInput
On a palette’s field row: which palette it is in. Part of what crate::command_palette spawns; a game never builds one.
PaletteNote
On the line that says “No command matches”. Part of what crate::command_palette spawns.
PaletteRow
One of a palette’s reused rows: its palette and its place among the rows shown. Part of what crate::command_palette spawns.
PanelRegistry
The panels a game offers a crate::dock: an id, the title on its tab and the function that fills its page. A layout names panels by id, so it can be saved and loaded as plain data; an id no panel is registered for is skipped and reported (DockPanelSkipped).
PopoverClosed
A popover is closing because of the player, and is despawned right after this event is delivered. Observe it on the popover (commands.spawn((popover(..), observe(..)))) or globally. A popover the game despawns, or whose anchor was despawned, sends nothing.
PopoverPanel
A popover’s panel: what a game queries to find the one open for an anchor. Added by popover and popover_modal; a game never builds one.
PopoverPoint
The zero-size node at the pointer that a Placement::AtPointer popover is anchored to: a child of the popover’s anchor, laid out on the window, removed with its popover. A game never builds one.
PopoverSlide
A popover opening: it starts POPOVER_SLIDE_PX closer to its anchor and settles at its gap.
Progress
How far along a progress is, 0.0 to 1.0. Change it and update_progress moves the fill the same frame. A value outside the range, or NaN, is drawn as the nearest end (NaN as empty) and reported once: see ProgressClamped.
ProgressClamped
On a Progress whose value is outside 0.0..=1.0 (or NaN) while it is. A warning is logged once when it is added, not every frame; it is taken off when the value is back in range.
ProgressText
The words under a progress bar: which step of how many, and about how long is left, drawn “3 of 7: Measuring meshes, about 20 s left”. With neither the line is not drawn. Insert it on the progress and edit it in place as the work goes.
Prompt
One action’s two inputs: what a crate::prompt shows, the keyboard’s when the player last used the keyboard or the mouse and the pad’s when they used a pad. It is the prompt’s state: set it (a game that rebinds the action does, from the ValueChange<Binding> of a crate::binding row) and the keycap follows in the same frame.
RadialCount
How many items a crate::radial has: set when it is spawned and read by the widget to know where its ring closes. Leave it alone; a radial’s items are fixed for its life.
RadialItem
One item of a crate::radial: its name and, optionally, a picture.
RadialSlot
One item of a crate::radial, by its place on the ring, and its name (so the middle of the disc can read it whether the item draws words or a picture). Part of what radial() spawns; a game never builds one.
RadialValue
Which item a crate::radial has highlighted: an index into its items, in the order they were given (item 0 is at the top, the rest follow clockwise). It is the widget’s state: read it to know the highlight, set it to move the highlight from code (the screen follows in the same frame, and no ValueChange is sent for a change the game made itself). A value past the last item is pulled back to the last.
RowActivated
The player opened a row of a crate::table: Enter or the pad’s South button on the cursor row, or a double click.
RunCommand
The player chose a command in a palette: observe it with app.add_observer(|run: On<RunCommand> | ..) and do what id names. The palette is already despawned and focus is back where it was, so a command may open a dialog or move focus. Sent once per choice, never for a disabled command.
SectionHeader
On a section’s header, the button that opens and closes it. Part of what crate::section spawns; query for it to find the header of a section.
SectionId
A name that keeps a crate::section’s state across a despawn and a respawn: put it on the section’s entity ((section("Physics", true, ..), SectionId::new("physics"))) and the section is open or closed as the player last left the section of that name, whatever the open it was spawned with (that is only its first choice). Every section with the same id shares the state, so an inspector that is rebuilt for another thing and then this one again comes back as it was. The states are in SectionStates.
SectionOpen
Whether a crate::section is open: the widget’s state. Read it to know, set it to open or close the section from code (the screen follows in the same frame, and no ValueChange is sent for a change the game made itself). The player’s Enter, Space, South or click sends one ValueChange<bool> on the section and flips it.
SectionStates
The last state of every SectionId: a section with an id writes it when it changes and a new section of the same id starts from it. It is plain data (with the serde feature, serde data), so a game can save it with the player’s settings and insert it again at start-up, and clear it to forget what the player folded.
Select
The options of a crate::select, as text. Part of what it spawns; the row’s value is its ChoiceValue.
Shortcut
A key chord: a key and the modifiers held with it. Eq + Hash, serde under the serde feature, so a game saves its keymap as data and crate::model::shortcut_conflicts finds two commands on one chord.
ShortcutBadge
A badge, a child of the widget it names: query for it to read the words on show.
ShortcutBadges
The shortcut overlay’s settings: what reveals the badges and how long it is held first. While ShortcutBadges::hold is held for ShortcutBadges::delay_seconds, every visible widget on screen that has a Shortcut (the component, or the chord of its Tooltip) gets a badge with the chord’s words on its top-right corner, inside its frame so the focus ring is never covered; releasing the modifier removes them in the same frame. A disabled widget shows none, its chord does nothing.
ShortcutLegend
Chords that act on nothing on screen: “undo”, “save all”, “toggle the grid”. A shortcut with a widget is badged on it; a verb with none has nowhere to stand, so the host lists it here and the crate draws the rows as a card in the middle of the window for as long as the overlay is up (BadgesShown), over the badges, never taking the pointer or focus. An empty list draws nothing. Changing the rows while the card is up redraws it in that frame; the crate never runs a chord.
ShortcutLegendCard
The legend’s card, a root node standing while the overlay is up and the ShortcutLegend has rows; it holds the rows it was built from, so a settled legend writes nothing and a host can read what is on show.
SkinScope
A skin for one subtree: the node that carries it and everything below it is styled from this skin and not from the GooeySkin resource, so a preview of a skin, a tool’s own chrome or a vendor’s window can stand next to the rest of the interface in another look.
SlideIn
A panel arriving: its UiTransform translation eases out from from to nothing over seconds of real time (so a paused game’s menu still moves), and then the component is removed and the translation is left at zero. Only the picture moves: layout, focus and the hit test see the panel where it ends up from its first frame, and it writes the translation only, never the scale.
SliderRange
A component which represents the allowed range of the slider value. Defaults to 0.0..=1.0.
SliderStep
Defines the amount by which to increment or decrement the slider value when using keyboard shortcuts. Defaults to 1.0.
SliderValue
A component which stores the current value of the slider.
Slot
What a slot of a crate::slot_grid holds: an item’s name, its picture, how many there are and a line for its tooltip.
SlotCursor
The slot of a grid that Tab enters on: the one the player last had focus on. It is the grid’s state and its one tab stop (every other slot is reached by the arrows). Focus moving to a slot writes it and sends one non-final ValueChange<usize> on the grid; write it yourself to move the stop from code (no event is sent for that). A value past the last slot is pulled back to it.
SlotGrid
The root of a crate::slot_grid: how many slots are in a row. Its slots are SlotItems and its state is SlotCursor.
SlotItems
The contents of a crate::slot_grid, in reading order: Some for an item, None for an empty slot. It is the grid’s data and the one place to change it: push, remove or write a slot and the grid follows in the same frame (slots are added and removed to match its length, and a slot whose content did not change is not touched). A game whose inventory lives elsewhere writes it from there when that changes.
SlotMoved
The player moved an item: dragged it from one slot onto another, or carried it there with the keyboard or a pad (crate::DragSettings). An event on the grid the item was dropped on. The grid has changed nothing: SlotMoved::apply swaps the two slots in their SlotItems (onto an empty slot that is a move), and a game with rules (stacks that merge, a slot that takes only helmets) does its own and writes the result.
SlotRef
Where a slot is: its grid and its index there. It is on every slot the grid draws, and it is what a drag from a slot carries (the payload of crate::DragPayload), so a drop knows which slot an item came from even when it came from another grid.
SlotRefused
A slot refused an item: the player let go of it over a slot that its grid’s SlotRules do not let hold it (or whose own item the origin’s rules do not take back). An event on the grid of the slot that refused; nothing moved. A game plays its “no” here.
SlotRules
Which items a crate::slot_grid’s slots take: accepts(item, index) says whether slot index of this grid may hold item. The default takes everything. It is a plain fn (a closure that captures nothing), like crate::DropTarget::accepting, so it is data a game writes once.
SortBy
The player picked a sortable column’s header: the table is already sorted that way (TableSort holds it), so this is for a game that keeps its own order or a note of the choice. The first click on a column sorts it ascending and each next one turns it round. A sort the game sets itself sends nothing.
Spinner
An indeterminate indicator: a ring with one lit quarter turning once every SPINNER_PERIOD_SECS, on real time, so it keeps turning while the game is paused or a frame stalls. Use it for 2 to 10 seconds of work; use a progress for longer. There is no static variant.
Split
A crate::split’s root: which way it lays its panes out. Part of what split() spawns; it requires SplitFraction and SplitMin, so a game sets either in the same tuple as the split and its own value wins.
SplitDivider
A crate::split’s divider, the part a pointer grabs and focus rests on. Part of what split() spawns. Give it InteractionDisabled to fix the layout: it still takes focus, and moves nothing.
SplitFraction
How much of a crate::split the first pane has, from 0 to 1: its share of the split’s length on its axis less the divider’s. It is the widget’s state: read it to know the layout, set it to move the divider from code (the panes follow in the same frame, and no ValueChange is sent for a change the game made itself) or save it, as plain data, with the player’s other settings.
SplitGeometry
A system parameter that reads a divider’s split (its fraction, minimums and room); it is in the signature of split_by_pad, so it is public. Nothing outside the crate has a use for it.
SplitMin
The smallest each pane of a crate::split may be, in logical pixels: the divider never takes either below it, and a window too small for both shrinks the second pane first. Zero (the default) lets a pane collapse to nothing.
StatusBar
A crate::status_bar’s root. Query for it to find the bar.
StatusItem
A crate::status_item. It requires StatusKind, so a StatusKind of your own in the same tuple is the one the item has: (status_item("2 problems"), StatusKind::Warning).
StatusPriority
Which items of a narrow crate::status_bar stay: the lowest priority hides first, and an item of the right group before any of the left’s. Higher is kept longer; the default is 128.
SwatchHalf
One half of a swatch: the colour opaque (alpha false) or at its own alpha (alpha true), so a translucent colour shows as one. Part of what crate::color_field spawns.
Table
A crate::table’s root: its columns and its rows. Change the rows through it (source_mut, set_source): the table sees a changed component, sorts the new rows the way they were sorted and keeps the row the player was looking at where it was.
TableCursor
The row of a crate::table that keys act on, by RowSource::key: the row ringed while the table has focus. Arrows and Page keys move it, Enter opens it (RowActivated), Space selects it. A game sets it to move the ring from code.
TableRow
One row of a table’s pool, the entity a row of text is drawn on: which table, which display row it shows now, that row’s key and whether it is the cursor’s. A table has only as many as it shows, and each is rebound as the table scrolls, so what an entity shows changes: ask this component which row it is (for a tooltip or a context menu on the row under the pointer), and never keep the entity.
TableRows
How many rows tall a crate::table stands; a fraction cuts the last row visible, the cut-off that tells the player there is more. The default is 8.5. Part of what the table requires, so a game sets its own in the same tuple: (table(..), TableRows(12.0)).
TableSelection
The rows a crate::table has selected, by RowSource::key: the widget’s state. A game sets it (no event is sent for what the game does itself) or reads it; the player’s change sends ValueChange<TableSelection> with the whole selection.
TableSort
How a crate::table is sorted: the column and which way. It is the widget’s state: the player’s click on a header sets it (and sends SortBy); a game sets it to sort from code or to start a table sorted, and the rows follow in the same frame with no event.
TableWidths
The widths of a crate::table’s columns in body text sizes, as the player has dragged them: the state a game saves with the player’s other settings. A column with no entry has its Column::width.
TabsCount
How many tabs a crate::tabs widget has: set when it is spawned and read by the widget to know where its ends are. Leave it alone; a widget’s tabs are fixed for its life.
TabsValue
Which tab a crate::tabs widget has selected: an index into its labels, in the order they were given. It is the widget’s state: read it to know the page, set it to turn the page from code (the screen follows in the same frame, and no ValueChange is sent for a change the game made itself). A value past the last tab is pulled back to the last.
TextEdited
On a crate::text_input row whose text changed since the last time an edit ended: when focus leaves it, that is a final change. Put on and taken off by the row’s own systems.
TextEditing
On a crate::text_input row exactly while its field has focus: the player is typing. A game’s own hotkeys wait on it (is_text_editing), and a host that opens the platform’s on-screen keyboard for a pad player does it when this is added. It is put on and taken off in crate::GooeySystems::Navigate, so a system that must see the frame’s change runs after that set, and one that must not act on the press that ends the edit (Escape) runs before it.
TextHint
The words a crate::text_input field shows, muted, while it is empty (“Enter a name”): a hint at what to type, never the field’s label (the row’s own label stays outside the field and always shows). Put it on the row, at spawn or later.
TextInputOf
Which crate::text_input row a field or its hint belongs to. Part of what text_input() spawns, a game never builds one; read it to find the row from the field a Bevy event names (FocusGained, TextEditChange).
TextInputValue
What a crate::text_input row holds: the text in its field. It is the widget’s state: read it to know what the player typed, set it to change the field from code (the field shows the text in the same frame, the caret at its end, and no ValueChange is sent for a change the game made itself). A value longer than the row’s TextLimit is shown whole: a limit stops what the player types, never what the game sets.
TextLimit
The most characters a crate::text_input field takes from the player, typed or pasted. Put it on the row, at spawn or later. It never cuts a TextInputValue the game set.
Toast
A line of news at the edge of the screen, from crate::toast or crate::toast_alert. It stands for as long as its message takes to read (ToastSettings), fades out, and is despawned; despawn it yourself to take it back sooner.
ToastAction
A button of a Toast was pressed. Sent on the toast, and observable globally, once per press: the toast is dismissed with it.
ToastBundle
A toast, with the buttons it was built with: commands.spawn(toast("Item deleted").action("Undo", "undo")). crate::toast and crate::toast_alert return one; it is a bundle like any other, so commands.spawn(toast("Game saved")) and (toast("Game saved"), MyMarker) work as ever.
ToastButton
On a toast’s button: which toast, and which id it sends (none for a sticky toast’s Dismiss).
ToastLog
The last ToastLog::CAPACITY toasts that were spawned, oldest first, whether or not they were merged into another: a toast the player missed can be found here (crate::notification_center). It is plain data, so a game may read it, save it or clear it.
ToastLogEntry
One line of the ToastLog: a toast that was spawned.
ToastSettings
How long toasts stand, how many, how they fade and where: the timing a player may change.
ToastStack
The one column every Toast stands in: a full-window, pointer-transparent node the first toast spawns, aligned by ToastSettings::anchor and kept above a dialog (GlobalZIndex 150). Query it to hide the toasts (a cutscene) by setting its Visibility.
ToggleGroupCount
How many options a crate::toggle_group has: set when it is spawned. Leave it alone.
ToggleGroupValue
Which option a crate::toggle_group has lit: an index into its options, in the order they were given. It is the widget’s state: read it to know the mode, set it to move the group from code (the screen follows in the same frame, and no ValueChange is sent for a change the game made itself). A value past the last option is pulled back to the last.
Toolbar
A crate::toolbar’s root. It holds the “More” button the bar grows when its items do not fit, and the items that button lists.
Tooltip
Shows its text in a box beside this entity while the pointer is over it, or while it has focus and focus is visible (a keyboard or pad player has moved it), so every input reaches it.
TooltipBox
The box a Tooltip spawned, a child of the widget it describes: query it to find the box (its Text is its child).
Tree
A crate::tree’s nodes: the RowSource of its Table. Change the tree through the table (table.source_mut::<Tree>()), and the table keeps the row the player was looking at where it was.
TreeNode
One node of a crate::tree and the nodes under it. A node’s key is its identity: the selection, the cursor and the player’s place are kept by key, so they stay with a node while others come and go. Two nodes of one tree never share one (a repeated key is left out, with a warning).
TreeToggled
The player opened or closed a node of a crate::tree: a click on its chevron, Left, Right or *. A change the game makes with Tree::set_open sends none. The place to load a node’s children the first time it opens.
UiFeedback
Something a player did to a widget, written the frame it happens. The crate plays no sound: read these and play your own, so every action answers on a second channel.
UiScaleSettings
How large the whole interface is drawn against the window, for scale_with_window.
ValueChange
Notification sent by a widget that edits a scalar value.
VecChange
A change the player made to one component of a crate::vec_field, sent on the vec row. A game that edits a mixed multi-selection applies value to component index of every member and leaves the others alone; values is the whole vector as it now stands.
VecMixed
On a crate::vec_field: which components of a multi-selection differ (true shows the MIXED_HINT of MixedValue in that component). A component the player changes is taken off. A missing entry is false.
VecPart
On each component’s number row of a crate::vec_field: the vec row it belongs to, and its place. Part of what vec_field() spawns, a game never builds one.
VecValue
What a crate::vec_field holds: one number per component, in order. Like NumberValue it is the state: a game’s write shows at once and sends nothing, the player’s change is a VecChange.
WorldAnchor
An interface node that stays on a point in the world: the GlobalTransform of WorldAnchor::target plus a world-space offset, seen by a camera.
WorldAnchors
The nodes anchored to an entity, kept by Bevy; they are despawned with it.

Enums§

ArrowPolicy
Who the arrow keys belong to while focus is in a FocusRegion.
Binding
A physical input a player can bind an action to: what a crate::binding row shows, waits for and reports. A key is its place on the keyboard (Bevy’s KeyCode, so WASD is the same four keys on a QWERTY and an AZERTY keyboard), which is what a game’s own input code reads from ButtonInput<KeyCode>.
CloseReason
Why a popover closed.
Density
How much room a skin gives each widget: a game menu’s comfortable one, or a desktop tool’s compact one (GooeySkin::density).
DockLayout
The panels of a crate::dock and how they are arranged: a tree whose leaves are tab groups and whose other nodes split their room in two. Plain data, serde with the serde feature: a game saves it, loads it and resets it by writing it into crate::Dock.
DockSkip
Why DockLayout::prune left a panel out.
FieldProblemKind
How serious a FieldProblem is. The words are what say it; the kind picks the second cue, the colour of the bar beside the message, and for an error the field’s frame too.
GooeySystems
The order the crate’s systems run in Update.
IconSource
The picture an Icon draws: a whole image, or one cell of a texture atlas the host laid out (a sprite sheet of white-on-transparent glyphs is the usual one: the skin tints it).
IconTone
Which colour of the skin tints an icon. The image is multiplied by it, so draw icons white on transparent and let the skin colour them; a tone is a colour of the skin and never a number in the host.
InputDevice
Which family of device the player used last: what crate::prompt shows the words of, and what a game reads to swap glyphs of its own. track_input_device keeps it: a key or a mouse button pressed makes it InputDevice::Keyboard, a pad button pressed or a stick pushed InputDevice::Pad. It starts as Keyboard; a game that knows better (a console, a handheld) writes the resource at start-up.
OffScreen
What an anchored node does when its world point is not in view.
OptionRow
Which of the crate’s own settings a crate::choice row edits. Part of what crate::text_size, crate::interface_size, crate::pad_style and crate::skin_preset spawn, for update_option_rows to find them by; a game never builds one.
Placement
Where a popover opens, relative to the widget it is anchored to.
Platform
The platform a chord is spelled for: a mac says “⇧⌘P”, every other platform “Ctrl+Shift+P”. Platform::current is the one this build runs on; a test or an editor that shows another platform’s keymap names it.
PromptsAnchor
Where a crate::prompts_at legend stands in its parent: a corner or the middle of an edge, 5% in from the edges it touches (the safe area of a television, the dialog scrim’s own margin). The default is the bottom-left corner, where Xbox’s guideline 112 puts “select” and “back”; what that guideline asks is that they stay in one place on every screen, so a game that needs the bottom-left for its own HUD picks another anchor once and spawns every legend, a dialog’s too, with it. Set it on a live legend (a component) and the legend moves in the same frame.
Reveal
What reveals the shortcut overlay: a modifier, a plain key, or nothing.
Role
What a widget is, which decides how apply_skin styles it. Every widget function puts one on its root (and on the parts it spawns); put one on your own node to have it styled the same way.
SelectMode
How many rows a crate::table’s player may select.
SkinPreset
The looks the crate ships, in the order a crate::skin_preset row offers them.
SkinProblem
One way a GooeySkin breaks a rule, from GooeySkin::problems.
SplitAxis
How a crate::split lays its two panes out.
StatusKind
How much a crate::status_item means, shown as a mark at its start: StatusKind::Info draws none; a warning’s is crate::GooeySkin::accent and an error’s crate::GooeySkin::danger. The words never change colour (4.5:1 against the bar in every kind, and the mark is a shape, not only a hue). Change it to change the mark in the same frame.
ToastAnchor
Where a toast’s stack stands in the window. The newest toast stands nearest the screen’s edge, and the older ones are pushed inward as room opens for it.
ToastKind
What a toast tells the player; the mark down its left edge shows it (the words carry it too).
UiFeedbackKind
What happened, in a UiFeedback.

Constants§

DRAG_LIFT_PX
How far, in logical pixels, a press must move before it is a drag: a click with a shaking hand is still a click.
MIXED_HINT
The words a mixed number field shows, muted, in its empty field. Two hyphens, because the em dash a mixed value is usually drawn with is not in every font and the host supplies the font: a missing glyph would be a box.
PALETTE_ROWS
How many rows a palette shows at once. They are reused: the list scrolls under them as the lit row moves, so a thousand commands cost the same entities as eight.
SELECT_FILTER_ABOVE
A crate::select shows a list to filter when it has more options than this; with this many or fewer it is a plain crate::choice that cycles.

Traits§

RowSource
The rows a crate::table shows: the one trait a game implements. The table asks for what is in view, so a source of ten thousand rows costs what ten cost; it holds no copy.

Functions§

anchor_pointer_popovers
Puts each new Placement::AtPointer popover at the pointer: a zero-size node at the pointer’s position, with the panel moved under it. Bevy’s Popover then places the panel against that point and flips it at the window’s edge like any other. The point is a child of the anchor, laid out on the window and not the anchor (FixedNode), so it goes with its anchor; an anchor that is not a UI node (a sprite or a mesh in the world, whose children are never laid out) gets a point of its own at the root, which the panel’s closing removes. Runs in crate::GooeySystems::Navigate.
apply_skin
Styles every entity with a Role from GooeySkin (or the SkinScope it stands in) and GooeyFonts: the one place widgets are styled. Runs in crate::GooeySystems::Style.
begin_entrances
Gives a dialog’s card and each popover panel that appeared this frame its SlideIn, unless motion is off or the panel already has one. A card is a Panel or Palette whose parent is a scrim. Runs in crate::GooeySystems::Style, before update_motion.
bind_by_input
Listens for the press a waiting crate::binding row is waiting for. Runs last in crate::GooeySystems::Navigate, after every system that reads the same keys and was held back (they run under not_capturing and so did not see this press).
binding
A row that rebinds one action: the action’s name on the left and a keycap on the right showing the key, mouse button or pad button it is bound to (“Space”, “Right Click”, “A”). It is Bevy’s headless bevy::ui_widgets::Button, so Tab, the arrows and the D-pad reach it, and Enter, Space, the pad’s South button or a click start a capture: the keycap lights and says what it waits for, and the player’s next press is the new binding. A key row hears any key or mouse button (the primary one too: the pointer cannot press anything while a row waits), and a pad row any pad button; Escape (and, on a pad row, Start) exits without binding, and cannot be bound (see crate::BindingSettings). While a row waits nothing else hears the player: arrows, Tab, the D-pad and Back move and close nothing.
button
A button: Bevy’s headless bevy::ui_widgets::Button, reachable by Tab and by arrows and the D-pad, styled by its state. Observe crate::Activate on it to act.
cancel_by_input
Sends a Cancel when Escape or any gamepad’s East button is just pressed, and shows focus (InputFocusVisible). Runs in crate::GooeySystems::Navigate.
cancel_drags
Escape or a pad’s East button puts a carried thing down where it was: nothing is sent, and the press is no Back (crate::cancel_by_input does not run while a drag is lifted; the drag itself is put down by track_drag after it, in the same frame). Runs in crate::GooeySystems::Navigate, before cancel_by_input.
catch_pointer
Puts the catcher over the window while a row waits and takes it away when none does (or the row is gone). A node above every widget takes the pointer, so a click binds the mouse button (XAG 112: “Any mouse input will be applied as the new control”) and cannot press anything. At rest the two queries are empty.
check_item
A menu item that is on or off: it keeps its state in Bevy’s Checked (a tick in the mark slot while on) and flips it on every choice, sending a ValueChange<bool> with the new value. The menu closes, like any command.
choice
A choice for a setting that takes one of a few named values (Low, Medium, High; Easy, Normal, Hard): a row with the label on the left and the selected option on the right between two arrows. It is Bevy’s headless bevy::ui_widgets::Button with a state, so Tab, the arrows and the D-pad reach it, and with it focused Left and Right (keys or the D-pad, held to repeat) step to the previous and next option and stop at the ends, Home and End jump to the first and last, and Up and Down still move focus on, so a pad steps a column of settings with no mode to enter. A click on an arrow steps once, and Enter, Space, the pad’s South button and a click anywhere else on the row cycle to the next option, wrapping from the last to the first, so every option is reachable by one repeated press. The arrow that cannot step is dimmed.
close_popovers_on_press
Closes every popover a pointer press landed outside of, with CloseReason::Outside, once each. Outside is anywhere that is not the panel or, for a popover on a side of its anchor, the anchor itself (a game’s own toggle on the anchor opens and closes with one rule); the press that opened a popover, in the frame it opened, is not outside. The press goes on to whatever it landed on. Runs in crate::GooeySystems::Navigate.
color_field
A row with a colour: a label, a swatch and a framed field showing the colour as hex, which the player types (#ff8800, #f80, ff8800; #ff880080 with an alpha) or picks. Enter or leaving the field applies what was typed; anything that is not a hex colour is refused with its reason as a ColorRefused and the field shows the colour again; Escape puts the old colour back.
command_palette
A command palette: a modal field over a searchable list of the game’s crate::CommandList, each command with its chord and, when it is off, why. Spawn it when the player presses the game’s own chord (Ctrl+Shift+P, say); it takes focus, and everything else is the palette’s.
confirm
A modal question and its choices: see Confirm, which this builds.
context_by_key
Shift+F10 or the Menu key opens the context menu of the focused widget, or of its nearest ancestor that has one, below the focused widget, with focus on its first item. A widget inside a menu is not asked. Runs in crate::GooeySystems::Navigate.
context_menu
A menu that belongs to a thing: spawn it once, anywhere, and name it with ContextMenu on whatever should open it. A secondary click on the thing opens it at the pointer (flipping at the window’s edge), and Shift+F10 or the Menu key with focus on the thing, or a widget under it, opens it below that widget. items are the rows of a menu (menu_item, check_item, radio_item, submenu, separator), live entities, so a game’s observe(..) sits on the item; ContextTarget says which thing it was opened for. Closed, it is drawn nowhere and in no focus scope; open, it is a modal popover, so Escape, B or a press outside close it and give focus back.
cycle_regions
F6 and Shift+F6 (and nothing held but Shift) move focus to the next or previous FocusRegion’s first widget, and show focus (InputFocusVisible). Runs in crate::GooeySystems::Navigate with the other navigation, gated by crate::not_capturing.
dialog
A modal dialog: a veil over the whole window that centres its children and holds focus. When it opens, focus moves to its first button (or to the one carrying Bevy’s AutoFocus, the way to pick the least destructive default); Tab, the arrows and the D-pad stay inside it; and when it closes, focus returns to the button that opened it. Its contents are yours, in children![…]; close it with commands.entity(dialog).despawn(), from a button’s Activate and from an observer of crate::Cancel on the dialog (Escape and the pad’s B send one).
dock
A workbench of panels the player arranges: a tree of splits and tab groups built from a DockLayout, which is plain data (serde with the serde feature), so it can be saved, loaded and reset. What a panel shows is spawned once by the function registered under its id in the PanelRegistry; the dock builds the tree, and a panel’s page is moved, never rebuilt, when the layout changes.
drop_pointer_anchors
Removes the pointer node of a popover that is gone.
feedback_on_focus
Writes UiFeedbackKind::Focus when focus moves onto a button, toggle, slider, choice or tab. Runs in crate::GooeySystems::Navigate, after crate::navigate_by_input.
fit_bars
Holds each bar’s items to the room its width has (crate::toolbar and crate::status_bar).
fit_menus
Caps an open menu’s height at the room the window leaves it on the larger side of its anchor (below its title, or from the top of its submenu item, or the side a context menu flips to), so a long menu scrolls and a short one is unchanged. Runs in crate::GooeySystems::Navigate.
focus_menu_bar
F10, or Alt pressed and released with no other key between, puts focus on the first title of the first MenuBar (the same press, with focus already in the bar, gives focus back to where it came from). Runs in crate::GooeySystems::Navigate.
focus_opened_dialogs
Moves focus into a dialog that just opened, to its first widget in tab order, unless focus is already inside it (an AutoFocus child picked the default), and shows focus (InputFocusVisible), so a dialog opened with the pointer still shows which button Enter or South will press. Runs in crate::GooeySystems::Navigate. A dialog spawned this frame is not in Tab order until its visibility propagates, so a hidden one is tried again next frame; a visible one with nothing to focus is left alone.
gamepad_adjust
Steps the focused, enabled crate::slider or crate::choice with the D-pad: Left and Right take one step a press, and a direction held down repeats after PAD_REPEAT_DELAY at PAD_REPEAT_RATE a second, so a pad player sweeps a volume without twenty presses and never holds a second button to keep the control selected. A choice stops at its ends. Shows focus (InputFocusVisible). Runs in crate::GooeySystems::Navigate. The keys are the controls’ own (Left and Right step, Home and End jump) and are not handled here.
gamepad_select
Activates the focused, enabled button, or flips the focused, enabled crate::toggle, when any gamepad’s South button (A on Xbox, Cross on PlayStation) is just pressed, and shows focus (InputFocusVisible). A crate::choice is a button that cycles to its next option when activated, so South cycles it. Enter and Space are bevy_ui_widgets’ own, so they are not handled here: a second handler would act twice.
heading
Heading text, in the skin’s heading size and font.
icon
A small image the skin sizes and tints: source is the host’s own art, a whole image or one cell of an atlas. It is a step of the skin’s crate::GooeySkin::type_scale square (the body’s line by default, crate::IconSize), so it is as tall as the text beside it at any text size, and tinted by its crate::IconTone: the image is multiplied by a colour of the skin, so draw it white on transparent. Inside a button it follows the button’s state as the text does. An image that is missing draws an empty box of the right size and reports once (crate::IconMissing).
icon_button
A toolbar’s button: a target-sized square with a picture and no words, so tooltip is its name, shown on hover and on visible focus (with its shortcut, if it has one) and listed in the bar’s “More” menu when it does not fit. Observe Activate on it like any button; the picture is tinted by the button’s state (icon).
interface_size
The player’s interface size: a choice row over 75%, 100%, 125% and 150% (INTERFACE_SIZE_STEPS) that sets UiScaleSettings::scale, which enlarges everything, where text_size enlarges text alone: on top of the window’s own share, so 125% is 1.25 times what the window would draw. label is the row’s name, in the host’s language.
is_dragging
A run condition: whether something is being dragged.
is_text_editing
A run condition: whether any crate::text_input has the player’s keys. A game gates its own key handling on not(is_text_editing), so typing a name does not also walk the character.
label
Body text, in the skin’s text size and font.
land_tab_focus
Keeps focus off a page that is not shown. When focus rests on a widget in a page the widget’s tabs have turned away from (the player pressed a bumper in it, or the game set TabsValue), it moves to the first widget of the page now shown, in tab order, or to the selected tab when the page has none; the ring stays as visible as it was. Runs in crate::GooeySystems::Navigate, before crate::navigate_by_input, and reads the page’s visibility from the frame before, so the move comes one frame after the page turned. Focus the pointer set can never be there: a hidden page takes no pointer.
list
A column of rows that scrolls when they do not all fit: save slots, an inventory, a key-binding screen, a long settings page. rows is how many rows tall it stands, in the units of a button and the gap beside it, so 4.5 shows four rows and half of the fifth, which cuts it, the sign that more is below. The rows are the list’s children, in children![…]: any widget, each its own tab stop.
menu
A column of buttons, stretched to the widest.
menu_bar
A menu bar: a row of menu_titles across the top of its parent, each opening a menu of commands. F10, or Alt pressed and let go on its own, puts focus on the first title; Left and Right walk the titles (wrapping), Down, Enter, Space or a click opens one with focus on its first item, a pointer moving onto another title switches menus while one is open, and Escape (or the pad’s B) closes the menu and then gives focus back to where F10 took it from. Inside a menu Right opens a submenu or moves on to the next title’s menu, Left closes a submenu or moves to the previous title’s, and Up, Down, Home and End walk the items.
menu_by_input
Left, Right, Down, Home and End on a focused title or menu item, from the keyboard and the D-pad: Down on a title opens its menu; Left and Right walk the bar (wrapping) and, inside a menu, Right opens a submenu or moves to the next title’s menu, Left closes a submenu or moves to the previous title’s; Home and End go to the first and last item. Up and Down among a menu’s items are crate::navigate_by_input’s, which leaves the other directions of a menu row to this system. Runs in crate::GooeySystems::Navigate, before it.
menu_item
A command in a menu: a row with label that sends Activate when chosen by Enter, Space, the pad’s South button or a click, and closes the menu. Chain MenuItem::with_shortcut to show its chord at the end of the row, and add Disabled to make it unavailable with a reason.
menu_title
A title of a menu_bar: a button with the menu items (a children![] of menu_item, check_item, radio_item, separator and submenu) that opens under it. The menu is spawned once with the title and shown by opening it, so an observe(..) on an item stays where you wrote it. Its title stays lit while its menu is open.
meter
A HUD meter (health, stamina, progress): a framed track with a fill value / max of its length. The frame marks the whole length against the panel; the fill sits one border inside it, with concentric rounded corners. It is crate::GooeySkin::meter_height high times the text scale, so it grows with the player’s size option. Change its Meter component to move it: a loss drops the fill at once and leaves the lost length behind it, in the skin’s danger colour, for a moment before it drains; a gain eases up (crate::MotionSettings::off makes both instant).
navigate_by_input
Moves focus to the nearest widget in the direction the arrow keys or any gamepad’s D-pad were just pressed (diagonals included), and shows focus (InputFocusVisible), which a pointer press hides. Runs in crate::GooeySystems::Navigate; no neighbour that way leaves focus where it is.
not_capturing
Run condition: no crate::binding row waits for a press and no payload is carried from the keyboard or a pad (crate::DragSettings). The crate’s systems that read keys and pad buttons (crate::navigate_by_input, crate::gamepad_select, crate::gamepad_adjust, crate::cancel_by_input, crate::page_lists, crate::step_tabs) run under it, so the arrow or button that is the new binding, or that steers a carried payload, never also moves focus. A host that registers those systems itself adds it to them.
notification_center
The log of every toast, as a list the player can scroll and read: “0:07 Item deleted”, the newest first, so a toast that faded before it was read can be found. Put it in a panel or a dialog of your own; it is a list of buttons (rows are tab stops, so the keys and the D-pad scroll it like any list), and an alert’s words start with “! “.
number_field
A row with a number: a label and a framed field the player types a number in, scrubs with a drag and steps with a key or the D-pad. step is how far one pixel of drag, one Up or Down press or one D-pad press moves it (and the digits the field shows: 0.1 shows one), and range is the least and greatest the player can make it.
observe
Adds an observer as a bundle effect.
pad_style
The player’s controller: a choice row over Xbox, PlayStation and Switch (PAD_STYLES) that sets BindingSettings::pad_style, so every binding row and prompts legend names a pad’s buttons as the player’s controller prints them (“A” or “Cross”, “B” or “Circle”). label is the row’s name, in the host’s language; the options are the makers’ names. The crate does not detect a pad’s make: the setting starts at the host’s BindingSettings (Xbox by default) and this row is how the player changes it.
page_lists
PageUp and PageDown, and the pad’s left and right triggers, move focus a viewport up or down the list it is in, to the row that far away (page_target), and show focus; the list then follows (scroll_to_focus). A single press, as every navigation here is. Focus outside a list is left alone. With Ctrl held the page keys are crate::step_tabs’s: they turn the page of a crate::tabs widget and never also page a list. Runs in crate::GooeySystems::Navigate.
palette_by_input
The keys of a palette, with focus in its field: Down and Up move the lit row (wrapping), PageDown and PageUp a page (stopping at the ends), Enter runs it; on a pad the D-pad moves it (a held direction repeats on real time) and South runs it. A held key repeats by the keyboard’s own repeat. Left, Right, Home, End and every character are the field’s own.
panel
A framed, padded column on the skin’s surface colour.
place_prompts
Centres a PromptsAnchor::BottomCenter or TopCenter legend: apply_skin writes its left at 50% and this writes the constant translation of half its own width back, which is the only way to centre an absolute node that is its content’s width (a left and a right together would stretch it). Runs in crate::GooeySystems::Style, before crate::apply_skin, in the frame a legend or its anchor is added or changed, and writes only a difference.
popover
A panel that opens beside anchor, stays inside the window, and closes when the player presses anywhere else or backs out.
popover_modal
A popover that holds focus, as a menu does: focus moves into it when it opens (to its first widget, or the one carrying Bevy’s AutoFocus), Tab, the arrows and the D-pad stay inside it, Escape or the pad’s B closes it, and when it closes focus goes back to the widget that was focused when it opened. It is the same scope as a dialog without the veil.
progress
Work that takes ten seconds or more (a save, a bake, a download): a track like a meter’s with its fill fraction of the length (clamped to 0.0..=1.0; anything else is reported once, see crate::ProgressClamped) and, under it, the words of its crate::ProgressText: which step of how many and about how long is left, “3 of 7: Measuring meshes, about 20 s left”. Change its crate::Progress to move it; edit the ProgressText in place.
prompt
One hint of what an input does: a keycap and the words for it (“Esc Back”). The keycap shows the input of the device the player used last, the keyboard’s or the pad’s from keys, in the words of a binding row (“Esc”, “Enter”, “A” or “Cross”), and follows the player the frame they pick up the other (InputDevice). A key is a rounded keycap and a pad button is fully round, in the same colours.
prompts
The legend of a screen: a slim bar of prompts in its parent’s bottom-left corner (see prompts_at for another), 5% in from the edges (the safe area of a television), where Xbox’s guideline 112 puts “select” and “back” on every screen, in the same place and order. It is a bar on the skin’s panel colour, so its words read over any game world. It is laid out apart from its parent’s other children (absolute, so it moves nothing) and is no wider than 90% of its parent: a longer legend squeezes its words and never leaves the window. The pointer goes through it.
prompts_at
A prompts legend in the corner or at the edge the game chooses: prompts_at( PromptsAnchor::BottomRight) for a game whose own HUD holds the bottom-left. Everything else is prompts’s: 5% in from the edges it touches, no wider than 90% of its parent, nothing else moves. Choose one anchor and use it on every screen and dialog, which is what Xbox’s guideline 112 asks. The anchor is a component: insert another and the legend moves.
radial
A radial menu: a weapon wheel, an emote wheel, a build menu. The items stand on a ring round a disc, item 0 at the top and the rest clockwise, and the player points at one and chooses it. With a pad, push a stick (either one) toward the item, and press South; with a pointer, move over the item’s side of the disc and click, the whole wedge being the target; with a keyboard, step with the arrows (Right and Down forward, Left and Up back, wrapping round), Home and End, and press Enter or Space. The highlighted item is lit and its name is read in the middle of the disc, where the thumb is. A stick that is only brushed, or a pointer in the middle, leaves the highlight where it is.
radial_by_pad
Points the focused, enabled crate::radial with a pad: a stick (the left or the right, of any pad, whichever is pushed further) pushed past RADIAL_STICK_PUSH highlights the item it points at (radial_pick), and one inside that dead zone leaves the highlight where it is; the D-pad’s Right and Down step forward and Left and Up back, wrapping round. Shows focus (InputFocusVisible). Runs in crate::GooeySystems::Navigate. South chooses, through crate::gamepad_select; the keys are the radial’s own observer.
radio_item
One of a run of choices in a menu, exactly one of which is on: choosing it sets its own Checked (a dot in the mark slot) and clears the radio_items next to it, up to the nearest separator or other kind of row either way, and sends a ValueChange<bool> with true for it. Choosing the one that is on changes nothing and sends nothing.
reveal_popovers
Shows each popover the frame after it was styled. A new popover is born hidden: Bevy lays out a node’s text a frame after it first appears, so a card drawn in its first frame would be as narrow as its padding and stand where the next frame’s width moves it from. crate::apply_skin shows it (Display::Flex) in the frame it is spawned, the layout of that frame measures it, and this reveals it in the next, at its final place. Runs in crate::GooeySystems::Navigate.
scale_with_window
Sets UiScale from the primary window’s shorter side and UiScaleSettings (window_ui_scale), writing it only when it changes, so a resized window is drawn at its new scale the next frame. Runs in crate::GooeySystems::Style.
screen
A full-window column that centres its children: the root of a menu screen or a HUD. It is a tab group, so Tab cycles through the buttons on it.
scroll_menus_to_focus
Scrolls an open menu that does not fit to keep the focused item in view. Runs in crate::GooeySystems::Navigate.
scroll_to_focus
Scrolls a list to follow the focus a key, the pad or Tab moved onto one of its widgets: the least scroll that leaves a row and a half of list beyond it (a row is the widget’s height and the gap), so the player always sees the next row whole and the one after cut: the list visibly goes on (scroll_to_reveal). A widget taller than the list scrolls to its top; a jump of more than a viewport (PageDown, a focus set from code) centres it.
section
A collapsible section: a header you press to fold the group of widgets under it away, so a long inspector or settings screen stays scannable. children is any bundle (children![..]); a section inside it is a nested section. Enter, Space, South and a click on the header toggle it and send one ValueChange<bool> on the section (the new state); the state is SectionOpen, which the game may set (no event). A closed section is only its header: its widgets are not laid out and focus never stops in them, and focus inside one that closes goes to the header. A section with nothing in it shows “Empty”.
select
A row that chooses one of a list of options: a choice with up to eight, and above eight a searchable list. The row looks and steps like a choice (Left and Right, Home and End, the D-pad), and its state is the same ChoiceValue; with more than SELECT_FILTER_ABOVE options Enter, Space, South or a click opens a list instead of cycling: type to narrow it, Up and Down (or the D-pad) move the lit option, Enter, South or a click chooses it and Escape leaves the value alone. Choosing sends one ValueChange<usize> on the row, with the option’s index in the list you gave, and none when the lit option is the one already chosen.
separator
A line between two groups of a menu. It is not focusable and the pointer goes through it to the card, and it ends a run of radio_items.
show_tooltips
Shows each Tooltip box while its widget is hovered or has visible focus (a crate::text_input row has it while its field does), and hides it otherwise; records whether the widget sits in a row and how much room the window leaves beside it, for crate::apply_skin to place and fit the box. Writes only what changed. Runs in crate::GooeySystems::Style, before crate::apply_skin.
skin_preset
The player’s theme: a choice row over Dark, Parchment, High contrast and Tool (SkinPreset::ALL) that sets the colours of GooeySkin, so the whole interface changes look in the frame the player steps it, and the high-contrast one holds every colour to 7:1 (GooeySkin::high_contrast; Xbox Accessibility Guideline 102 asks a game for such a mode). label is the row’s name, in the host’s language; the options are English words (SkinPreset::name), and a host that localises writes a choice over its own strings with SkinPreset::ALL and GooeySkin::with_colours_of.
slider
A slider for a value the player scrubs (volume, brightness, sensitivity): a row with the label and the value on one line and a rail under them with a thumb on it. It is Bevy’s headless bevy::ui_widgets::Slider, and the whole row is the target: a click anywhere on it puts the thumb under the pointer and a drag goes on from there. With it focused, Left and Right (keys or the D-pad, held to repeat) step the value by a twentieth of the range, Home and End jump to the ends, and Up and Down still move focus on, so one press is enough on a pad.
slot_grid
An inventory: a grid of square slots, columns to a row, each holding an item or empty (None), in reading order. A backpack, a hotbar, a chest, a shop shelf. The contents are data, SlotItems on the root: change it and the grid follows in the same frame, however many slots it has. A Slot is an item’s name, its picture, its count and a tooltip line; a slot with a picture draws it (tinted by the skin, so draw it white on transparent) and one without draws its name, and a count above one sits in the corner.
spinner
Work whose length is not known, or that takes two to ten seconds: a ring with one lit quarter turning once every crate::model::SPINNER_PERIOD_SECS on real time, so it keeps turning while the game is paused. For ten seconds and more use a progress; there is no static variant.
split
Two panes side by side or one above the other, with a divider between them that the player moves: a docked layout, an inventory beside a map, a log under a viewport. The panes’ content is yours, any bundle each (a panel fills its pane on both axes); the divider is a channel with a grip in the middle, a target the pointer lands on without aiming, that takes focus like any widget.
split_by_pad
The D-pad steps a focused divider along its axis, held to repeat like a slider’s, and the pad’s South button collapses or restores its first pane. Shows focus. Runs in crate::GooeySystems::Navigate. The keys are the divider’s own observer’s.
status_bar
A tool’s status line along the foot of the window: workspace state on the left, the context’s on the right, each a row of status_items. When the window is too narrow the lowest StatusPriority hides first, the right group’s before the left’s (fit_bars); a hidden item returns when the room does.
status_item
One entry of a status_bar: a short line of text a target high that sends Activate on Enter, Space, South or a click, and takes a Tooltip, a StatusKind and a StatusPriority. Edit its Text child to change the words.
status_progress
A status_item that also shows a short progress bar after its words, for a task that runs while the player works: change the Progress on the bar (the item’s second child’s child) or query for it.
step_tabs
Turns the page of a tabs widget with the pad’s bumpers, LB and RB, and with Ctrl+PageUp and Ctrl+PageDown: to the previous and next tab, wrapping round, one step a press (crate::tab_step); and steps it with the D-pad’s Left and Right while a tab has focus. Shows focus (InputFocusVisible). Runs in crate::GooeySystems::Navigate. Left and Right with the keyboard on a focused tab are Bevy’s own (they move focus and select), so they are not handled here; PageUp and PageDown without Ctrl are crate::page_lists’, and the pad’s triggers are its too.
submenu
A menu item that opens another menu items to its right (Right, Enter, Space or a click opens it; Left or Escape closes it and puts focus back on the item). A submenu with nothing in it says “Nothing here”. Add Disabled to the item to make it unavailable.
surface
A column filled with one step of the skin’s surface ladder, crate::GooeySkin::surfaces, and nothing else: no padding, frame or corner, which a host takes from the skin’s tokens (crate::GooeySkin::space, crate::GooeySkin::corner). level 0 is the lowest step; a level past the top is the top.
switch_menus_on_hover
A pointer moving onto another title while a menu of the bar is open opens that title’s menu instead, as every desktop menu bar does. Runs in crate::GooeySystems::Navigate.
tab_page
One page of tabs: a column of widgets spaced like a menu, shown while its tab is selected. Its widgets are the page’s children, in children![…]. It stands hidden until update_tabs shows it, so a page never draws on top of another.
table
A table of ten thousand rows in a dozen entities: a header of columns over rows from a RowSource, of which only the rows in view are spawned (the rows in view and one more, whatever the length). A click on a sortable header sorts by the column (the first click ascending, each next one turning it round) and sends SortBy; a column’s right edge is dragged to size it (Ctrl and Left or Right on its focused header does it 16 px a press, for no drag); a click selects a row (see SelectMode: one by default, Multi for Ctrl and Shift) and sends ValueChange<TableSelection> (TableSelection), and a double click or Enter opens it (RowActivated). Rows change through the Table component and the player keeps their place.
table_by_input
The keys and the pad on a focused table: Up and Down move the cursor row (the D-pad too, held to repeat), Page Up and Page Down a page (the triggers too), Home and End the first and last rows of the data, Space selects the cursor row (toggles it in a SelectMode::Multi table), Ctrl and A select every row, Enter and the pad’s South button open it (RowActivated). Shift extends the selection and Ctrl moves the cursor and leaves the selection where it is. Shows focus. Runs in crate::GooeySystems::Navigate, after crate::navigate_by_input, which leaves Up and Down to a table that has a row to move to that way and lets focus leave it from its first and last rows.
tabs
Tabs: a strip of one- or two-word labels above pages of widgets, one page shown at a time. The i-th label opens the i-th page, each a tab_page in children![…]; selected is the page shown first. A settings screen is the use: Audio, Display and Controls, each its own page of toggles, sliders and choices.
text_area
A row with a text field several lines high: the label over a framed field that wraps its words at its width and scrolls past rows lines, for notes and descriptions. It is a text_input in every other way: crate::TextInputValue is the text, a game’s write shows in the same frame with no event, crate::TextHint, crate::TextLimit (a paste is cut at it), crate::FieldProblem and crate::TextEditing go on the row, and every edit is one ValueChange<String> on it.
text_input
A row for a line of text the player types (a name, a seed, a server address): the label on the left, outside the field and always visible, and a framed field on the right that holds 16 characters, and the caret’s room, at the body size and scrolls past that, so the row never changes size while the player types. The field is Bevy’s headless TextInput, so it has a caret, selection, copy and paste and the platform’s input methods; a click on the field, the label or the row’s padding focuses it, and a focused field takes the keys at once, with no step to begin typing.
text_size
The player’s text size: a choice row over 100%, 125%, 150% and 200% (TEXT_SIZE_STEPS) that sets GooeySkin::text_scale, so every heading, label, button, dialog, toast and legend grows the frame the player steps it (WCAG 2.2 SC 1.4.4 and Xbox Accessibility Guideline 101 ask for 200%). label is the row’s name, in the host’s language.
toast
A line of news at the edge of the screen: “Game saved”, “Quest updated”. Spawn it from any system, with no layout and nothing else to set up; it stands as long as its message takes to read, fades out and removes itself (crate::Toast, crate::ToastSettings).
toast_alert
A toast for a refusal or a failure (“Inventory full”, “Could not save”): the same line with a mark in crate::GooeySkin::danger where an ordinary one’s is the accent. The words say it too; the mark is never the only sign.
toggle
A switch for an option that takes effect the moment it flips (Fullscreen, Subtitles): a row with the label on the left and a framed track with a sliding knob on the right. It is Bevy’s headless bevy::ui_widgets::Checkbox, so a click anywhere on the row, Enter, Space and the pad’s South button flip it, and Tab, the arrows and the D-pad reach it. It keeps its own state, Checked on the entity; observe ValueChange<bool> on it to apply the setting. The knob’s place says whether it is on, so the state survives a colour-blind player; the label never changes with it.
toggle_group
A row of options of which exactly one is on, like a toolbar’s tool modes: the one on is lit in the accent, like the selected tab. Choosing another with Enter, Space, South or a click sends one ValueChange<usize> on the group (the index of the option) and moves the light; choosing the one that is on sends nothing. The state is ToggleGroupValue: set it to change the mode from code, and the group follows with no event.
toolbar
A tool’s bar: a full-width row of icon_buttons, toggle_groups, toolbar_separators and any other widget, on the menu bar’s surface with one quiet line under it. When the items do not fit the bar’s width the last ones hide and a “More” button appears whose menu lists them; choosing a row there activates the item (fit_bars).
toolbar_separator
A thin vertical line between two groups of a toolbar. (The menu’s separator is the horizontal one.)
track_input_device
Follows what the player is using: a key or a mouse button pressed, a pad button pressed or a stick pushed past STICK_PUSH. Mouse motion alone does not switch, so a bump of the mouse does not swap a pad player’s hints; a click does. A pad press in the same frame as a key wins. Runs first in crate::GooeySystems::Navigate; it reads four message queues, empty in a frame with no input, and writes InputDevice only when it changes.
track_text_editing
Puts TextEditing on the row whose field has focus and takes it off the row that lost it, which ends that row’s edit (a final change, if the text changed since the last one). Focus on the row itself (an AutoFocus on it, or a game that set it there) goes to its field. Runs in crate::GooeySystems::Navigate, and only when focus moved.
tree
A tree: nodes that open and close, as many as you have, in a handful of entities. A node is a TreeNode (a key that is its identity, a label, its children, open or closed to start); the player opens one with a click on its chevron or Right and closes it with a click or Left, and the tree shows only the nodes whose parents are open, a row each, a button’s height, the children indented one level more. A closed node keeps its descendants’ state (reopened, they are as they were). It is the table’s rows in one column: the same scrolling, virtualized pool (an outliner of 10,000 nodes is a screenful of entities), the same cursor and selection by key (SelectMode Single by default, Multi for Ctrl and Shift), the same ValueChange<TableSelection> (TableSelection) and RowActivated for Enter and a double click.
tree_by_input
The keys a focused tree takes beyond the table’s (Up, Down, the Page keys, Home, End, Space, Ctrl+A, Enter and the pad’s South are crate::table_by_input’s): Right opens a closed node, or goes to the first child of an open one; Left closes an open node, or goes to the parent of a closed one or an end node (the D-pad’s Left and Right too); * opens every sibling of the cursor node; and typing goes to the next shown node whose label starts with the characters typed within a second (type_ahead). Shows focus. Runs in crate::GooeySystems::Navigate, after crate::navigate_by_input, which leaves Left and Right to a tree.
update_bindings
Writes each changed row’s keycap: the bound input’s name when it rests, the prompt while it waits (the other is hidden, which keeps its room, so the keycap is as wide as the wider and waiting moves nothing). Runs in crate::GooeySystems::Style, before crate::apply_skin, the same frame a value changes, a capture begins or ends, or BindingSettings does.
update_choices
Shows each changed choice’s selected option and no other, and pulls a value past the last option back to it. Runs in crate::GooeySystems::Style, before crate::apply_skin: the same frame the value changes, from a key, the pad, a click or the game.
update_colors
Brings every part of a colour field up to its colour: a ColorValue or MixedValue that changed writes the hex into the row’s text (or nothing and the MIXED_HINT, while mixed) and the colour into the swatch; an open picker moves its area’s marker and hue, its three strips and their gradients to the colour, keeping the hue, saturation and value it was on where the colour does not say them (a grey). Writes only what differs, so a colour nobody moved costs nothing. Runs in crate::GooeySystems::Style, before crate::update_text_inputs.
update_cooldowns
Counts every running Cooldown down on game time, sends CooldownReady for each that reaches zero, and keeps its cover true: hidden while ready, otherwise the sweep and the seconds. Writes a node only on a difference, and walks the children of a cooldown only while it runs or changed, so a hotbar of ready widgets costs a query. Runs in crate::GooeySystems::Style.
update_field_problems
Measures each message so its row keeps the room below itself. Runs in crate::GooeySystems::Style before crate::apply_skin, which writes the margin.
update_icons
Puts each changed Icon’s picture on its ImageNode, and marks an icon whose image is missing (IconMissing, one warning). Runs in crate::GooeySystems::Style before crate::apply_skin.
update_lists
Shows each list’s rail only while its content does not fit, the way a browser’s bar comes and goes: Display::None when there is nowhere to scroll, so it costs no draw and no hit test. Writes a rail’s node only when the answer changes, so a list at rest costs a comparison.
update_meters
Moves each Meter’s fill and trail toward its value: the fill’s width, the trail’s width and its negative start. A settled meter whose value did not change is skipped before any node is touched. Runs in crate::GooeySystems::Style, on real time (a paused game’s HUD still settles).
update_motion
Moves every SlideIn to where real time puts it and takes a spent one off, leaving its translation at zero; with MotionSettings off every one ends at once. Writes the translation only when it differs. Runs in crate::GooeySystems::Style, before layout.
update_notification_centers
Keeps every crate::notification_center as the crate::ToastLog says: a row for each entry, the newest first, as m:ss words (an alert’s words start with ! : the mark is not only a colour), or “No notifications yet” while the log is empty. Rebuilt when the log changes or a center is added; a log that has not changed writes nothing. Runs in crate::GooeySystems::Style before the list is laid out.
update_numbers
Brings a number row’s text up to its number: a NumberValue, NumberStep or MixedValue that changed writes the digits (or nothing and the MIXED_HINT, while mixed) into the row’s text, which the text input then shows. Writes only what differs, so a scrub that the field already shows costs nothing. Runs in crate::GooeySystems::Style, before crate::update_text_inputs.
update_option_rows
Moves each option row to the step nearest its setting: when the setting changes (a loaded save, another row, the host) and on the frame a row is spawned, so a row never draws one frame at the wrong step. The row’s state is set directly, and no ValueChange is sent, so a game’s observer hears the player and never this. Runs in crate::GooeySystems::Style, before crate::update_choices, which draws the option; a setting that did not change and a row that was not just spawned are not looked at past a flag.
update_palette
Ranks the commands against what the field holds and shows them: the lit row (the first match whenever the query changes), the window of rows that keeps it in view (up to PALETTE_ROWS, fewer when text is large or the window short, so the card never leaves the window), each row’s words (the label, and the chord or the reason the command is off), the “No command matches” line and the count. Writes only what differs, and runs only for a palette whose field, lit row, list, history or size changed. Runs in crate::GooeySystems::Style, before crate::apply_skin, the frame the change happens.
update_progress
Sets each changed Progress’s fill and each changed ProgressText’s line. Runs in crate::GooeySystems::Style.
update_prompts
Writes each prompt’s keycap: the name of the input for the device the player is using, and the keycap’s shape (Role::PromptKey for a key, Role::PromptButton for a pad button). Runs in crate::GooeySystems::Style, before crate::apply_skin, in the frame a Prompt, InputDevice or BindingSettings (whose pad_style names the buttons) changes; at rest it reads only those flags.
update_radials
Lights each changed radial’s highlighted item (Bevy’s Selected, the lit look of a tab) and no other, names it in the middle, and pulls a value past the last item back to it. Runs in crate::GooeySystems::Style, before crate::apply_skin: the same frame the value changes, from a stick, a key, the pointer or the game. A radial whose value did not change costs nothing.
update_sections
Keeps every section as its state says: the id’s remembered state, the body laid out or not, the chevron’s direction, “Empty” for an open section with nothing in it, and focus kept out of a closed body. Runs in crate::GooeySystems::Style, before crate::apply_skin: the frame the state changes, from the player or from the game; a section whose state did not change writes nothing.
update_shortcut_badges
Shows and hides the badges (see ShortcutBadges) and keeps BadgesShown. Writes nothing while the reveal is not held and no badge stands. Runs in crate::GooeySystems::Style.
update_shortcut_legend
Shows and hides the ShortcutLegend card with the overlay. Reads one resource and writes nothing while the overlay is down and no card stands. Runs in crate::GooeySystems::Style, after update_shortcut_badges.
update_sliders
Moves each changed slider’s thumb, fill and readout to its SliderValue within its SliderRange: the same frame the value changes, from a drag, a key, the D-pad or the game. Runs in crate::GooeySystems::Style.
update_slot_grids
Keeps every crate::slot_grid true to its SlotItems: slots are spawned and despawned to match the length, a slot whose item changed is updated (the name, the count, the picture, the tooltip, whether it can be lifted), and the grid’s SlotCursor follows focus and is the one slot with a TabIndex of 0. Writes nothing for a grid that did not change. Runs in crate::GooeySystems::Style before crate::update_icons.
update_spinners
Turns every Spinner to where real time puts it. Runs in crate::GooeySystems::Style.
update_splits
Lays each split’s panes out from its SplitFraction and SplitMin: the first pane grows by the fraction (held to the minimums) and the second by what is left, from a basis of nothing, so they share the room the divider leaves in exactly that ratio, and each pane’s own minimum is the one split_mins leaves for the room it has now. A window that shrinks is laid out by flexbox the frame it does and the minimums follow the next. Runs in crate::GooeySystems::Style, before crate::apply_skin; a split that did not change costs a comparison and writes nothing.
update_tables
Keeps every table drawn from its rows: the order (rebuilt when the rows or the sort change), the rows in view bound to the pool’s entities, the pool’s size, the room above and below the pool that stands for the rows not drawn, the columns’ widths and the sort mark, and the scroll (the anchor row kept where it was when the rows change, the cursor row kept in sight when a key moved it). A table at rest costs a comparison. Runs in crate::GooeySystems::Style, before crate::apply_skin.
update_tabs
Shows each changed widget’s selected page and no other, lights its selected tab and pulls a value past the last tab back to it. Runs in crate::GooeySystems::Style, before crate::apply_skin: the same frame the value changes, from a click, a key, the pad or the game, so a tab is never lit for a page that is not shown.
update_text_inputs
Brings a row’s parts up to what the row says: a TextInputValue the game set goes into the field (caret at the end), the hint shows exactly while the value is empty, the limit goes to the field, and a disabled row disables its field. Writes only what differs, so the field’s own edits (which already match the row) cost nothing. Runs in crate::GooeySystems::Style, before crate::apply_skin.
update_toasts
Ages every Toast, fades it in and out, sends the oldest into its fade when more than ToastSettings::max_visible stand, despawns the spent, and lays the stack out for ToastSettings::anchor. Runs in crate::GooeySystems::Style, before crate::apply_skin, which draws the result.
update_toggle_groups
Lights each changed group’s option and no other (Bevy’s Checked, which crate::apply_skin draws as the selected tab), and pulls a value past the last option back to it. Runs in crate::GooeySystems::Style, before crate::apply_skin: the same frame the value changes, from an activation or from the game; a group whose value did not change costs nothing.
update_tooltip_text
Copies each Tooltip’s text and shortcut into its box when the Tooltip changed: a new Tooltip inserted over the old one, or an edit in place (a reflection-driven inspector makes one, and no component hook runs for it). The keycap is spawned when a shortcut appears and despawned when it goes. Writes only when the line differs. Runs in crate::GooeySystems::Style, before show_tooltips.
update_trees
Moves what a removed node held to its heir (Tree::remove): a selected node, the cursor and the range anchor that were in the removed subtree go to the node that takes its place. Sends no ValueChange (a game’s own write sends none). Runs in crate::GooeySystems::Style, before crate::update_tables.
update_vecs
Brings a vec field’s components up to the row: a VecValue, NumberStep, NumberRange or VecMixed the game set goes into each component’s number row (which shows it, with no event). Runs in crate::GooeySystems::Style, before update_numbers.
update_world_anchors
Places every WorldAnchor on its world point. Runs in PostUpdate after transform propagation and the camera update and before UI layout, so a node is where the thing is in the frame it is drawn; see WorldAnchor.
vec_field
A row with a label and one number_field for each of N numbers (X, Y, Z and W, then 5, 6 …), as a position or a scale: each component’s letter is its scrub handle, and each has the typing, steps, range and refusals of a number field. step and range are every component’s.
viewport
A frame for what the host draws itself (a 3D view, a map, a canvas): it fills the room its parent leaves, is a tab stop, shows the focus ring while it has focus, and is a FocusRegion::host: with focus in it the arrow keys are the host’s (read them from ButtonInput<KeyCode>), Tab and F6 still leave, so the keyboard is never trapped. Put what draws into it (a ViewportNode, an image) as children or on the entity itself, and .insert(DropTarget::<T>::new()) makes it a place pieces are dropped.