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:
GooeySkin— the look, as plain data: colours, sizes and a player’sGooeySkin::text_scale.GooeyStylePluginrestyles everything on screen the frame it changes, andGooeySkin::problemschecks it against the WCAG 2.2 contrast and target-size rules. Three presets,GooeySkin::dark,GooeySkin::parchmentandGooeySkin::high_contrast(every pair at 7:1, checked byGooeySkin::high_contrast_problems). Fonts are the host’s, inGooeyFonts.- The widgets —
screen,panel,menu,heading,label,button,meter(a HUD bar driven byMeter),toggle,sliderandchoice(an options screen’s switch, scrubber and stepper, reporting throughValueChange),binding(a controls screen’s row: the player’s next key, mouse button or pad button is the newBinding),text_input(a row with a field the player types in, kept inTextInputValue; the field never traps focus, andTextEditingandis_text_editingtell a game when it has the player’s keys;text_areais the same several lines high),viewportandFocusRegion(a tool’s parts F6 walks between, one keeping the arrow keys for the host),DragPayloadandDropTarget(typed drag and drop:Dropped,DroppedOnWorld),slot_grid(an inventory ofSlots kept inSlotItems, moved by that drag and drop:SlotMoved),number_fieldandvec_field(a number the player scrubs with a drag on its label, types, or steps with Up, Down and the D-pad, held to aNumberRange; kept inNumberValue, withMixedValuefor a multi-selection that differs),text_size,interface_size,pad_styleandskin_preset(the player’s own text size, interface size, controller and theme: a line each, editingGooeySkin::text_scale,UiScaleSettings::scale,BindingSettings::pad_styleand the skin’s colours and following them),tabs(its pages, each atab_page, turned by a click, the arrows and the pad’s bumpers),list(rows that scroll, following focus),split(two panes and a divider the player drags or steps with the arrows, kept inSplitFractionand never belowSplitMin),dock(tab groups and splits of the panels in aPanelRegistry, kept as aDockLayoutand rearranged by dragging a tab),promptsandprompt(the “Esc Back” hints in the corner, in the words of the device the player used last, whichInputDevicetracks),toastandtoast_alert(a line of news spawned from any system, stood in oneToastStackand timed byToastSettings),Tooltip(with a command’sShortcuton a keycap: “Ctrl+S”, or “⌘S” on a mac), the modaldialogand the anchoredpopover(popover_modalholds focus;Placementsays where it opens,PopoverClosedwhy it closed), and themenu_barofmenu_titles withmenu_item,check_item,radio_item,submenuandseparatorrows (chords right-aligned,Disableditems that say why), or acontext_menuthat any entity opens withContextMenuon a right-click or Shift+F10. Each is a free function returning a bundle, so they compose insidechildren![]and withobserve; each carries aRolethatapply_skinstyles it by. Ascreenis layout: its empty part lets the pointer through to the game under a HUD, while every widget on it takes the pointer. AWorldAnchoron a root node makes it follow a point in the world (a health bar, a prompt, a beacon pinned to the screen’s edge). A toast takes no input and no focus. - Navigation —
GooeyNavPlugin: arrows and the D-pad move focus to the nearest widget (navigate_by_input), the pad’s South button activates it (gamepad_select), Tab cycles. Keys and the pad show the focus ring; a pointer press hides it. With nothing focused (a click on empty space, a despawned widget), the first arrow or D-pad press lands where the screen starts. An opendialogholds focus: it takes it, keeps arrows, D-pad and Tab inside, and gives it back to its opener on closing. ATooltipopens when its widget has visible focus, as it does under the pointer. Enter and Space are Bevy’s own button handling. A focusedsliderorchoicekeeps Left and Right (the D-pad steps it, held to repeat:gamepad_adjust); Up and Down still move on.LBandRBturn the page of atabswidget from anywhere in it (step_tabs), and focus never rests on a page that is not shown (land_tab_focus). Alistscrolls to keep the focused row and the next one in sight (scroll_to_focus), and PageUp and PageDown (page_lists) move a viewport at a time. Escape and a pad’s B are oneCancelevent, sent to the focused widget (or the open dialog) and bubbling up to the layer the game observes (cancel_by_input), except while abindingrow waits for a press: then nothing else hears the player (not_capturing,bind_by_input). - Scale —
GooeyScalePlugin: the whole interface keeps its share of the screen at every resolution, so text legible at 720p is legible on a 1440p monitor and a 4K television (UiScaleSettings,scale_with_window). - Feedback —
UiFeedbackis written for every focus move onto a widget and every activation or flip, for the host to turn into sound.
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.
- Anchor
Pinned - On an anchored node exactly while it is pinned to the screen’s edge:
directionis the unit vector from the middle of the viewport toward the world point, in screen space (ydown), for a beacon to turn its arrow by. - Area
Marker - The ring on the area at the colour’s saturation and value. Part of the picker.
- Badges
Shown - 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.
truefrom the frameupdate_shortcut_badgeshas the reveal held forShortcutBadges::delay_secondsuntil 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. - Binding
Settings - What
crate::bindingsays 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_keyon a keyboard row,BindingSettings::cancel_buttonon a pad row). - Binding
Value - What a
crate::bindingrow 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 noValueChangeis 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.
- Cancel
Scope - How a
Canceltravels: to the parent, and no further than adialog. - Capturing
- On a
crate::bindingrow while it waits for the player’s next press. While any row has it the crate’s own input systems stand still (seenot_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 throughcrate::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.
- Choice
Count - How many options a
crate::choicehas: 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. - Choice
Value - Which option a
crate::choicehas 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 noValueChangeis sent for a change the game made itself). A value past the last option is pulled back to the last. - Color
Area - 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.
- Color
Picker - The open picker of a
crate::color_field: the popovercrate::color_field’s swatch opens. It keeps the hue, saturation and value the player is on, which the row’sColorValuecannot (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. - Color
Rail - The gradient a strip’s rail shows. Part of the picker.
- Color
Refused - Text the player typed that a
crate::color_fieldwould not take, sent on the row with the reason (HexErrorreads as words). The field shows the colour again. - Color
Strip - A picker’s slider: hue, brightness or alpha. Part of the picker.
- Color
Swatch - On a colour field’s swatch button: its row. Part of what
crate::color_fieldspawns, a game never builds one. - Color
Value - What a
crate::color_fieldholds: 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 noValueChangeis sent for a change the game made itself). The player’s own changes are oneValueChange<Srgba>on the row each:is_finalis 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. - Command
List - Every command a
command_palettelists. 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. - Command
Palette - 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 adialog(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. - Confirm
Button - On a confirmation’s button: the dialog it answers and its place in the list.
- Confirm
Chosen - The player answered a
Confirm: sent once, on the dialog, in the flush that despawns it.indexis the choice’s place in the list it was built from;cancelledis true when Escape or a pad’s East answered, with the safe choice’s index. - Context
Menu - On any entity (a UI node, a sprite, a mesh): the
crate::context_menupanel 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);ContextTargetsays which it was opened for. - Context
Target - On a context menu’s panel exactly while it is open: the entity that has the
ContextMenuit was opened for (never the widget a key opened it beside, when that is one of its descendants). Read it in an item’sActivateobserver withContextTarget::of, or in anOn<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, anicon_button, a slot of aslot_grid); it is ready, and draws nothing, untilCooldown::start. - Cooldown
Ready - Sent on a widget the frame its
Cooldownreaches zero (not when a game setsremainingto zero itself): the place to play the “ready” sound, XAG’s second channel for the same news. - Dialog
- What a
crate::dialogremembers: the widget that had focus when it opened, which gets focus back when the dialog closes, and whether focus has moved in yet. Part ofdialog(); 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 aTooltipwith 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 aDockLayoutto 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 observeDockLayoutChanged, to save what the player did. - Dock
Drop Target - Where a dragged panel lands: next to or into the group holding
onto, or at an edge of the whole dock. - Dock
Layout Changed - 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. - Dock
Panel - 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. - Dock
Panel Skipped - 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.
- Drag
Label - 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).
- Drag
Payload - Makes a node a drag source: pressing it and moving more than
DRAG_LIFT_PXpicksTup. The node needsPickable(every gooey widget has it; a sprite or mesh needs it added). - Drag
Settings - 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), pressesDragSettings::pick_up(a pad’sDragSettings::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. - Drag
State - The one drag in progress, if any: a resource, because one pointer carries one thing.
GooeyNavPluginadds 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_PXand not let go): dim it, or hide it, or ignore it. The ghost and the mark are the crate’s. - Drop
Candidate - On every
DropTargetnode 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 whoseDropTarget::acceptingtest or a slot’s rule says no, not a disabled or hidden one. The crate draws nothing for it (seeDropRefusing); style your own targets withHas<DropCandidate>. Put on and taken off by the crate; never add it yourself. - Drop
Refused - A
Twas let go over aDropZonethat does not take it: another type, orDropTarget::acceptingsaid no. An event on the target. Nothing moved. - Drop
Refusing - On every enabled, visible
DropTargetnode that refuses what is being carried, exactly while a drag is lifted: the opposite ofDropCandidate, 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. - Drop
Target - Makes a node a place a
Tmay be dropped. A node may carry several, one for each type it takes. The type is the match: aDragPayload<A>over a node with only aDropTarget<B>is refused, visibly, and so is one the target’s own test (DropTarget::accepting) says no to. - Dropped
- A
Twas dropped on aDropTarget<T>that takes it. An event on the target, socommands.spawn(..).observe(|on: On<Dropped<T>>| ..)hears the drops on that node. - Dropped
OnWorld - A
Twas let go over nothing the interface draws (the game world under a HUD): a host raycasts frompointerto see what is there. Sent as a global event. - Field
Problem - What is wrong with a text row (
text_input,number_field,color_field, avec_field’s component): put it on the row andtextis drawn under it in words, with a bar in the kind’s colour beside them; anErroralso frames the field incrate::GooeySkin::dangerwhile 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. - Focus
Region - A part of the screen focus can be cycled to: put it on a panel, a viewport or a toolbar.
- Focus
Scopes - 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. - Gooey
Fonts - The fonts widgets draw with. A separate resource from
GooeySkinbecause a font is an asset handle the host loads, not data a project saves. - Gooey
NavPlugin - 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’sInputFocusVisible; a pointer press hides it), and a direction press with nothing focused lands where the screen starts. An opendialogholds 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 aCancelto the focused widget or the open dialog (cancel_by_input), for the game to observe. - Gooey
Plugins - Every plugin in the crate:
GooeyStylePlugin,GooeyNavPluginandGooeyScalePlugin. - Gooey
Scale Plugin - Draws the whole interface in proportion to the window: sets Bevy’s
UiScalefrom the primary window’s shorter side andUiScaleSettings(scale_with_window), so a 1440p window draws everything twice the size a 720p one does. - Gooey
Skin - The look of every widget: colours and sizes, as plain data a project saves and an editor edits live.
- Gooey
Style Plugin - Styles every widget from
GooeySkinandGooeyFonts, movesMeterfills, and writesUiFeedbackfor activations. - Group
Option - One option of a
crate::toggle_group: a picture with its name, or a word or two. Build it withGroupOption::iconorGroupOption::text. - Icon
- What an
iconshows. Change it and the picture changes in the same frame (update_icons). The size and the tint are the skin’s: seeIconSizeandIconTone. - Icon
Missing - On an
Iconwhose 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. - Icon
Size - 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. - Legend
Row - One row of a
ShortcutLegend: a chord and what it does. - List
View - The scrolling part of a
crate::list: the clipped column its rows are children of. It standsrowsrows tall (a row is a button’s height, plus acrate::GooeySkin::gapbetween two:crate::model::list_height), so4.5shows four rows and half of the fifth, the cut-off that tells the player there is more. - MenuBar
- A
crate::menu_bar: the row ofMenuTitles. It remembers the widget that had focus when F10 or Alt took focus into it, so Escape (aCancelreaching the bar) and choosing a command give it back. - Menu
Item - One command of a menu:
crate::menu_item,crate::check_item,crate::radio_itemand (throughcrate::submenu) a row that opens another menu. It is a component whose insertion builds the row (Bevy’sButton,Role::MenuItemand a mark, a label, a shortcut and a chevron as the item has them), so it chains.with_shortcut(..)and sits in achildren![]beside the game’s ownobserve(..). It sets the row’sNode: put your own layout on a wrapper, not on the item. - Menu
Marked - 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.
- Menu
Open - On a
MenuTitleor a submenu item exactly while its menu is open: the anchor stays lit. - Menu
Panel - The card a
MenuTitleor acrate::submenuopens. It exists from spawn, closed (not drawn, in no scope); it is open exactly while it has aPopoverPanel. - Menu
Title - 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_metersmoves the fill: a loss drops it at once and leaves aRole::MeterTrailof the lost length that holds a moment and drains; a gain eases it up (seemeter_motion;MotionSettings::offmakes 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. - Mixed
Value - On a
crate::number_fieldwhose value is not one number: a multi-selection whose members differ. The field is empty and shows a mutedMIXED_HINT;NumberValueis 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::PRIMARYis the platform’s own “primary” (Command on a mac, Ctrl elsewhere), which is what a game binds “Save” to once for every platform. - Motion
Settings - How much motion the player wants: the one switch for every motion the crate draws.
- Notification
Center - A
crate::notification_center’s root. Query for it to find the center. - Notification
Row - On a row
update_notification_centersspawned: a button for a log entry, or the line that says there is none. - Number
Input - On a number field’s text field (the one a
crate::number_fieldrow types in), which steps on Up and Down. Part of whatnumber_field()spawns, a game never builds one. - Number
Range - 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 acrate::vec_fieldit is every component’s. - Number
Refused - Text the player typed that a
crate::number_fieldwould not take, sent on the row with the reason (NumberErrorreads 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. - Number
Step - 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 acrate::vec_fieldit is every component’s. - Number
Value - What a
crate::number_fieldholds: 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 noValueChangeis sent for a change the game made itself). The player’s own changes are oneValueChange<f32>on the row each:is_finalis 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. - Palette
Command - One command a
command_palettelists. - Palette
Count - On the line that says which of how many is lit. Part of what
crate::command_palettespawns. - Palette
History - The ids of the commands the palette ran, the most recent first,
PaletteHistory::LIMITat 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 theserdefeature) to keep recents between runs, or clear it to forget them. - Palette
Input - On a palette’s field row: which palette it is in. Part of what
crate::command_palettespawns; a game never builds one. - Palette
Note - On the line that says “No command matches”. Part of what
crate::command_palettespawns. - Palette
Row - One of a palette’s reused rows: its palette and its place among the rows shown. Part of what
crate::command_palettespawns. - Panel
Registry - 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). - Popover
Closed - 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. - Popover
Panel - A popover’s panel: what a game queries to find the one open for an anchor. Added by
popoverandpopover_modal; a game never builds one. - Popover
Point - The zero-size node at the pointer that a
Placement::AtPointerpopover is anchored to: a child of the popover’s anchor, laid out on the window, removed with its popover. A game never builds one. - Popover
Slide - A popover opening: it starts
POPOVER_SLIDE_PXcloser to its anchor and settles at its gap. - Progress
- How far along a
progressis,0.0to1.0. Change it andupdate_progressmoves the fill the same frame. A value outside the range, or NaN, is drawn as the nearest end (NaN as empty) and reported once: seeProgressClamped. - Progress
Clamped - On a
Progresswhose value is outside0.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. - Progress
Text - The words under a
progressbar: 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::promptshows, 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 theValueChange<Binding>of acrate::bindingrow) and the keycap follows in the same frame. - Radial
Count - How many items a
crate::radialhas: 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. - Radial
Item - One item of a
crate::radial: its name and, optionally, a picture. - Radial
Slot - 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 whatradial()spawns; a game never builds one. - Radial
Value - Which item a
crate::radialhas 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 noValueChangeis 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 whatidnames. 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. - Section
Header - On a section’s header, the button that opens and closes it. Part of what
crate::sectionspawns; query for it to find the header of a section. - Section
Id - 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 theopenit 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 inSectionStates. - Section
Open - Whether a
crate::sectionis 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 noValueChangeis sent for a change the game made itself). The player’s Enter, Space, South or click sends oneValueChange<bool>on the section and flips it. - Section
States - 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 theserdefeature, 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 itsChoiceValue. - Shortcut
- A key chord: a key and the modifiers held with it.
Eq + Hash, serde under theserdefeature, so a game saves its keymap as data andcrate::model::shortcut_conflictsfinds two commands on one chord. - Shortcut
Badge - A badge, a child of the widget it names: query for it to read the words on show.
- Shortcut
Badges - The shortcut overlay’s settings: what reveals the badges and how long it is held
first. While
ShortcutBadges::holdis held forShortcutBadges::delay_seconds, every visible widget on screen that has aShortcut(the component, or the chord of itsTooltip) 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. - Shortcut
Legend - 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. - Shortcut
Legend Card - The legend’s card, a root node standing while the overlay is up and the
ShortcutLegendhas rows; it holds the rows it was built from, so a settled legend writes nothing and a host can read what is on show. - Skin
Scope - A skin for one subtree: the node that carries it and everything below it is styled from this
skin and not from the
GooeySkinresource, 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
UiTransformtranslation eases out fromfromto nothing oversecondsof 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. - Slider
Range - A component which represents the allowed range of the slider value. Defaults to 0.0..=1.0.
- Slider
Step - Defines the amount by which to increment or decrement the slider value when using keyboard shortcuts. Defaults to 1.0.
- Slider
Value - A component which stores the current value of the slider.
- Slot
- What a slot of a
crate::slot_gridholds: an item’s name, its picture, how many there are and a line for its tooltip. - Slot
Cursor - 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. - Slot
Grid - The root of a
crate::slot_grid: how many slots are in a row. Its slots areSlotItemsand its state isSlotCursor. - Slot
Items - The contents of a
crate::slot_grid, in reading order:Somefor an item,Nonefor 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. - Slot
Moved - 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::applyswaps the two slots in theirSlotItems(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. - Slot
Refused - A slot refused an item: the player let go of it over a slot that its grid’s
SlotRulesdo 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. - Slot
Rules - Which items a
crate::slot_grid’s slots take:accepts(item, index)says whether slotindexof this grid may holditem. The default takes everything. It is a plainfn(a closure that captures nothing), likecrate::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
(
TableSortholds 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 aprogressfor longer. There is no static variant. - Split
- A
crate::split’s root: which way it lays its panes out. Part of whatsplit()spawns; it requiresSplitFractionandSplitMin, so a game sets either in the same tuple as the split and its own value wins. - Split
Divider - A
crate::split’s divider, the part a pointer grabs and focus rests on. Part of whatsplit()spawns. Give itInteractionDisabledto fix the layout: it still takes focus, and moves nothing. - Split
Fraction - How much of a
crate::splitthe 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 noValueChangeis sent for a change the game made itself) or save it, as plain data, with the player’s other settings. - Split
Geometry - 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. - Split
Min - The smallest each pane of a
crate::splitmay 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. - Status
Bar - A
crate::status_bar’s root. Query for it to find the bar. - Status
Item - A
crate::status_item. It requiresStatusKind, so aStatusKindof your own in the same tuple is the one the item has:(status_item("2 problems"), StatusKind::Warning). - Status
Priority - Which items of a narrow
crate::status_barstay: 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. - Swatch
Half - One half of a swatch: the colour opaque (
alphafalse) or at its own alpha (alphatrue), so a translucent colour shows as one. Part of whatcrate::color_fieldspawns. - 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. - Table
Cursor - The row of a
crate::tablethat keys act on, byRowSource::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. - Table
Row - 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.
- Table
Rows - How many rows tall a
crate::tablestands; 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)). - Table
Selection - The rows a
crate::tablehas selected, byRowSource::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 sendsValueChange<TableSelection>with the whole selection. - Table
Sort - How a
crate::tableis sorted: the column and which way. It is the widget’s state: the player’s click on a header sets it (and sendsSortBy); 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. - Table
Widths - 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 itsColumn::width. - Tabs
Count - How many tabs a
crate::tabswidget 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. - Tabs
Value - Which tab a
crate::tabswidget 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 noValueChangeis sent for a change the game made itself). A value past the last tab is pulled back to the last. - Text
Edited - On a
crate::text_inputrow 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. - Text
Editing - On a
crate::text_inputrow 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 incrate::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. - Text
Hint - The words a
crate::text_inputfield 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. - Text
Input Of - Which
crate::text_inputrow a field or its hint belongs to. Part of whattext_input()spawns, a game never builds one; read it to find the row from the field a Bevy event names (FocusGained,TextEditChange). - Text
Input Value - What a
crate::text_inputrow 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 noValueChangeis sent for a change the game made itself). A value longer than the row’sTextLimitis shown whole: a limit stops what the player types, never what the game sets. - Text
Limit - The most characters a
crate::text_inputfield takes from the player, typed or pasted. Put it on the row, at spawn or later. It never cuts aTextInputValuethe game set. - Toast
- A line of news at the edge of the screen, from
crate::toastorcrate::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. - Toast
Action - A button of a
Toastwas pressed. Sent on the toast, and observable globally, once per press: the toast is dismissed with it. - Toast
Bundle - A toast, with the buttons it was built with:
commands.spawn(toast("Item deleted").action("Undo", "undo")).crate::toastandcrate::toast_alertreturn one; it is a bundle like any other, socommands.spawn(toast("Game saved"))and(toast("Game saved"), MyMarker)work as ever. - Toast
Button - On a toast’s button: which toast, and which id it sends (none for a sticky toast’s Dismiss).
- Toast
Log - The last
ToastLog::CAPACITYtoasts 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. - Toast
LogEntry - One line of the
ToastLog: a toast that was spawned. - Toast
Settings - How long toasts stand, how many, how they fade and where: the timing a player may change.
- Toast
Stack - The one column every
Toaststands in: a full-window, pointer-transparent node the first toast spawns, aligned byToastSettings::anchorand kept above a dialog (GlobalZIndex150). Query it to hide the toasts (a cutscene) by setting itsVisibility. - Toggle
Group Count - How many options a
crate::toggle_grouphas: set when it is spawned. Leave it alone. - Toggle
Group Value - Which option a
crate::toggle_grouphas 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 noValueChangeis 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.
- Tooltip
Box - The box a
Tooltipspawned, a child of the widget it describes: query it to find the box (itsTextis its child). - Tree
- A
crate::tree’s nodes: theRowSourceof itsTable. Change the tree through the table (table.source_mut::<Tree>()), and the table keeps the row the player was looking at where it was. - Tree
Node - One node of a
crate::treeand the nodes under it. A node’skeyis 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). - Tree
Toggled - The player opened or closed a node of a
crate::tree: a click on its chevron, Left, Right or*. A change the game makes withTree::set_opensends 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.
- UiScale
Settings - How large the whole interface is drawn against the window, for
scale_with_window. - Value
Change - 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 appliesvalueto componentindexof every member and leaves the others alone;valuesis the whole vector as it now stands. - VecMixed
- On a
crate::vec_field: which components of a multi-selection differ (trueshows theMIXED_HINTofMixedValuein that component). A component the player changes is taken off. A missing entry isfalse. - VecPart
- On each component’s number row of a
crate::vec_field: the vec row it belongs to, and its place. Part of whatvec_field()spawns, a game never builds one. - VecValue
- What a
crate::vec_fieldholds: one number per component, in order. LikeNumberValueit is the state: a game’s write shows at once and sends nothing, the player’s change is aVecChange. - World
Anchor - An interface node that stays on a point in the world: the
GlobalTransformofWorldAnchor::targetplus a world-spaceoffset, seen by a camera. - World
Anchors - The nodes anchored to an entity, kept by Bevy; they are despawned with it.
Enums§
- Arrow
Policy - 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::bindingrow shows, waits for and reports. A key is its place on the keyboard (Bevy’sKeyCode, so WASD is the same four keys on a QWERTY and an AZERTY keyboard), which is what a game’s own input code reads fromButtonInput<KeyCode>. - Close
Reason - 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). - Dock
Layout - The panels of a
crate::dockand how they are arranged: a tree whose leaves are tab groups and whose other nodes split their room in two. Plain data, serde with theserdefeature: a game saves it, loads it and resets it by writing it intocrate::Dock. - Dock
Skip - Why
DockLayout::pruneleft a panel out. - Field
Problem Kind - How serious a
FieldProblemis. 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. - Gooey
Systems - The order the crate’s systems run in
Update. - Icon
Source - The picture an
Icondraws: 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). - Icon
Tone - 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.
- Input
Device - Which family of device the player used last: what
crate::promptshows the words of, and what a game reads to swap glyphs of its own.track_input_devicekeeps it: a key or a mouse button pressed makes itInputDevice::Keyboard, a pad button pressed or a stick pushedInputDevice::Pad. It starts asKeyboard; 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.
- Option
Row - Which of the crate’s own settings a
crate::choicerow edits. Part of whatcrate::text_size,crate::interface_size,crate::pad_styleandcrate::skin_presetspawn, forupdate_option_rowsto find them by; a game never builds one. - Placement
- Where a
popoveropens, 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::currentis the one this build runs on; a test or an editor that shows another platform’s keymap names it. - Prompts
Anchor - Where a
crate::prompts_atlegend 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_skinstyles 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. - Select
Mode - How many rows a
crate::table’s player may select. - Skin
Preset - The looks the crate ships, in the order a
crate::skin_presetrow offers them. - Skin
Problem - One way a
GooeySkinbreaks a rule, fromGooeySkin::problems. - Split
Axis - How a
crate::splitlays its two panes out. - Status
Kind - How much a
crate::status_itemmeans, shown as a mark at its start:StatusKind::Infodraws none; a warning’s iscrate::GooeySkin::accentand an error’scrate::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. - Toast
Anchor - 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.
- Toast
Kind - What a toast tells the player; the mark down its left edge shows it (the words carry it too).
- UiFeedback
Kind - 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::selectshows a list to filter when it has more options than this; with this many or fewer it is a plaincrate::choicethat cycles.
Traits§
- RowSource
- The rows a
crate::tableshows: 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::AtPointerpopover at the pointer: a zero-size node at the pointer’s position, with the panel moved under it. Bevy’sPopoverthen 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 incrate::GooeySystems::Navigate. - apply_
skin - Styles every entity with a
RolefromGooeySkin(or theSkinScopeit stands in) andGooeyFonts: the one place widgets are styled. Runs incrate::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 aPanelorPalettewhose parent is a scrim. Runs incrate::GooeySystems::Style, beforeupdate_motion. - bind_
by_ input - Listens for the press a waiting
crate::bindingrow is waiting for. Runs last incrate::GooeySystems::Navigate, after every system that reads the same keys and was held back (they run undernot_capturingand 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 (seecrate::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. Observecrate::Activateon it to act. - cancel_
by_ input - Sends a
Cancelwhen Escape or any gamepad’s East button is just pressed, and shows focus (InputFocusVisible). Runs incrate::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_inputdoes not run while a drag is lifted; the drag itself is put down bytrack_dragafter it, in the same frame). Runs incrate::GooeySystems::Navigate, beforecancel_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 aValueChange<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::Buttonwith 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 incrate::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;#ff880080with 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 aColorRefusedand 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
ContextMenuon 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.itemsare the rows of a menu (menu_item,check_item,radio_item,submenu,separator), live entities, so a game’sobserve(..)sits on the item;ContextTargetsays 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 incrate::GooeySystems::Navigatewith the other navigation, gated bycrate::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, inchildren![…]; close it withcommands.entity(dialog).despawn(), from a button’sActivateand from an observer ofcrate::Cancelon 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 theserdefeature), so it can be saved, loaded and reset. What a panel shows is spawned once by the function registered under its id in thePanelRegistry; 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::Focuswhen focus moves onto a button, toggle, slider, choice or tab. Runs incrate::GooeySystems::Navigate, aftercrate::navigate_by_input. - fit_
bars - Holds each bar’s items to the room its width has (
crate::toolbarandcrate::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 incrate::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
AutoFocuschild picked the default), and shows focus (InputFocusVisible), so a dialog opened with the pointer still shows which button Enter or South will press. Runs incrate::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::sliderorcrate::choicewith the D-pad: Left and Right take one step a press, and a direction held down repeats afterPAD_REPEAT_DELAYatPAD_REPEAT_RATEa 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 incrate::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). Acrate::choiceis a button that cycles to its next option when activated, so South cycles it. Enter and Space arebevy_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:
sourceis the host’s own art, a whole image or one cell of an atlas. It is a step of the skin’scrate::GooeySkin::type_scalesquare (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 itscrate::IconTone: the image is multiplied by a colour of the skin, so draw it white on transparent. Inside abuttonit 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
tooltipis 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. ObserveActivateon it like anybutton; the picture is tinted by the button’s state (icon). - interface_
size - The player’s interface size: a
choicerow over 75%, 100%, 125% and 150% (INTERFACE_SIZE_STEPS) that setsUiScaleSettings::scale, which enlarges everything, wheretext_sizeenlarges text alone: on top of the window’s own share, so 125% is 1.25 times what the window would draw.labelis 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_inputhas the player’s keys. A game gates its own key handling onnot(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 incrate::GooeySystems::Navigate, beforecrate::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.
rowsis how many rows tall it stands, in the units of a button and the gap beside it, so4.5shows four rows and half of the fifth, which cuts it, the sign that more is below. The rows are the list’s children, inchildren![…]: 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 asubmenuor 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 incrate::GooeySystems::Navigate, before it. - menu_
item - A command in a menu: a row with
labelthat sendsActivatewhen chosen by Enter, Space, the pad’s South button or a click, and closes the menu. ChainMenuItem::with_shortcutto show its chord at the end of the row, and addDisabledto make it unavailable with a reason. - menu_
title - A title of a
menu_bar: a button with the menuitems(achildren![]ofmenu_item,check_item,radio_item,separatorandsubmenu) that opens under it. The menu is spawned once with the title and shown by opening it, so anobserve(..)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 / maxof its length. The frame marks the whole length against the panel; the fill sits one border inside it, with concentric rounded corners. It iscrate::GooeySkin::meter_heighthigh times the text scale, so it grows with the player’s size option. Change itsMetercomponent 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::offmakes 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 incrate::GooeySystems::Navigate; no neighbour that way leaves focus where it is. - not_
capturing - Run condition: no
crate::bindingrow 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
listof 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.
stepis 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), andrangeis the least and greatest the player can make it. - observe
- Adds an observer as a bundle effect.
- pad_
style - The player’s controller: a
choicerow over Xbox, PlayStation and Switch (PAD_STYLES) that setsBindingSettings::pad_style, so everybindingrow andpromptslegend names a pad’s buttons as the player’s controller prints them (“A” or “Cross”, “B” or “Circle”).labelis 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’sBindingSettings(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 arecrate::step_tabs’s: they turn the page of acrate::tabswidget and never also page a list. Runs incrate::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::BottomCenterorTopCenterlegend:apply_skinwrites itsleftat 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 (aleftand arighttogether would stretch it). Runs incrate::GooeySystems::Style, beforecrate::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
popoverthat holds focus, as a menu does: focus moves into it when it opens (to its first widget, or the one carrying Bevy’sAutoFocus), 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 adialogwithout 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
fractionof the length (clamped to0.0..=1.0; anything else is reported once, seecrate::ProgressClamped) and, under it, the words of itscrate::ProgressText: which step of how many and about how long is left, “3 of 7: Measuring meshes, about 20 s left”. Change itscrate::Progressto move it; edit theProgressTextin 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 abindingrow (“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 (seeprompts_atfor 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
promptslegend 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 isprompts’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::radialwith a pad: a stick (the left or the right, of any pad, whichever is pushed further) pushed pastRADIAL_STICK_PUSHhighlights 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 incrate::GooeySystems::Navigate. South chooses, throughcrate::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 theradio_items next to it, up to the nearestseparatoror other kind of row either way, and sends aValueChange<bool>withtruefor 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_skinshows 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 incrate::GooeySystems::Navigate. - scale_
with_ window - Sets
UiScalefrom the primary window’s shorter side andUiScaleSettings(window_ui_scale), writing it only when it changes, so a resized window is drawn at its new scale the next frame. Runs incrate::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.
childrenis any bundle (children![..]); a section inside it is a nested section. Enter, Space, South and a click on the header toggle it and send oneValueChange<bool>on the section (the new state); the state isSectionOpen, 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
choicewith 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 sameChoiceValue; with more thanSELECT_FILTER_ABOVEoptions 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 oneValueChange<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
Tooltipbox while its widget is hovered or has visible focus (acrate::text_inputrow 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, forcrate::apply_skinto place and fit the box. Writes only what changed. Runs incrate::GooeySystems::Style, beforecrate::apply_skin. - skin_
preset - The player’s theme: a
choicerow over Dark, Parchment, High contrast and Tool (SkinPreset::ALL) that sets the colours ofGooeySkin, 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).labelis the row’s name, in the host’s language; the options are English words (SkinPreset::name), and a host that localises writes achoiceover its own strings withSkinPreset::ALLandGooeySkin::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,
columnsto 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,SlotItemson the root: change it and the grid follows in the same frame, however many slots it has. ASlotis 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_SECSon real time, so it keeps turning while the game is paused. For ten seconds and more use aprogress; 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
panelfills 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 lowestStatusPriorityhides 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 sendsActivateon Enter, Space, South or a click, and takes aTooltip, aStatusKindand aStatusPriority. Edit itsTextchild to change the words. - status_
progress - A
status_itemthat also shows a shortprogressbar after its words, for a task that runs while the player works: change theProgresson 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,
LBandRB, 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 incrate::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 arecrate::page_lists’, and the pad’s triggers are its too. - submenu
- A menu item that opens another menu
itemsto 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”. AddDisabledto 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).level0 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 amenu, shown while its tab is selected. Its widgets are the page’s children, inchildren![…]. It stands hidden untilupdate_tabsshows it, so a page never draws on top of another. - table
- A table of ten thousand rows in a dozen entities: a header of
columnsover rows from aRowSource, 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 sendsSortBy; 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 (seeSelectMode: one by default,Multifor Ctrl and Shift) and sendsValueChange<TableSelection>(TableSelection), and a double click or Enter opens it (RowActivated). Rows change through theTablecomponent 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::Multitable), 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 incrate::GooeySystems::Navigate, aftercrate::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_pageinchildren![…];selectedis the page shown first. A settings screen is the use: Audio, Display and Controls, each its own page oftoggles,sliders andchoices. - 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
rowslines, for notes and descriptions. It is atext_inputin every other way:crate::TextInputValueis 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::FieldProblemandcrate::TextEditinggo on the row, and every edit is oneValueChange<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
choicerow over 100%, 125%, 150% and 200% (TEXT_SIZE_STEPS) that setsGooeySkin::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%).labelis 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
toastfor a refusal or a failure (“Inventory full”, “Could not save”): the same line with a mark incrate::GooeySkin::dangerwhere 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,Checkedon the entity; observeValueChange<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 isToggleGroupValue: 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’sseparatoris 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 incrate::GooeySystems::Navigate; it reads four message queues, empty in a frame with no input, and writesInputDeviceonly when it changes. - track_
text_ editing - Puts
TextEditingon 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 (anAutoFocuson it, or a game that set it there) goes to its field. Runs incrate::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 thetable’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 (SelectModeSingleby default,Multifor Ctrl and Shift), the sameValueChange<TableSelection>(TableSelection) andRowActivatedfor 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 incrate::GooeySystems::Navigate, aftercrate::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, beforecrate::apply_skin, the same frame a value changes, a capture begins or ends, orBindingSettingsdoes. - 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, beforecrate::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
ColorValueorMixedValuethat changed writes the hex into the row’s text (or nothing and theMIXED_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 incrate::GooeySystems::Style, beforecrate::update_text_inputs. - update_
cooldowns - Counts every running
Cooldowndown on game time, sendsCooldownReadyfor 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 incrate::GooeySystems::Style. - update_
field_ problems - Measures each message so its row keeps the room below itself. Runs in
crate::GooeySystems::Stylebeforecrate::apply_skin, which writes the margin. - update_
icons - Puts each changed
Icon’s picture on itsImageNode, and marks an icon whose image is missing (IconMissing, one warning). Runs incrate::GooeySystems::Stylebeforecrate::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::Nonewhen 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 incrate::GooeySystems::Style, on real time (a paused game’s HUD still settles). - update_
motion - Moves every
SlideInto where real time puts it and takes a spent one off, leaving its translation at zero; withMotionSettingsoff every one ends at once. Writes the translation only when it differs. Runs incrate::GooeySystems::Style, before layout. - update_
notification_ centers - Keeps every
crate::notification_centeras thecrate::ToastLogsays: a row for each entry, the newest first, asm: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 incrate::GooeySystems::Stylebefore the list is laid out. - update_
numbers - Brings a number row’s text up to its number: a
NumberValue,NumberSteporMixedValuethat changed writes the digits (or nothing and theMIXED_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 incrate::GooeySystems::Style, beforecrate::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
ValueChangeis sent, so a game’s observer hears the player and never this. Runs incrate::GooeySystems::Style, beforecrate::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 incrate::GooeySystems::Style, beforecrate::apply_skin, the frame the change happens. - update_
progress - Sets each changed
Progress’s fill and each changedProgressText’s line. Runs incrate::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::PromptKeyfor a key,Role::PromptButtonfor a pad button). Runs incrate::GooeySystems::Style, beforecrate::apply_skin, in the frame aPrompt,InputDeviceorBindingSettings(whosepad_stylenames 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 incrate::GooeySystems::Style, beforecrate::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, beforecrate::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 keepsBadgesShown. Writes nothing while the reveal is not held and no badge stands. Runs incrate::GooeySystems::Style. - update_
shortcut_ legend - Shows and hides the
ShortcutLegendcard with the overlay. Reads one resource and writes nothing while the overlay is down and no card stands. Runs incrate::GooeySystems::Style, afterupdate_shortcut_badges. - update_
sliders - Moves each changed slider’s thumb, fill and readout to its
SliderValuewithin itsSliderRange: the same frame the value changes, from a drag, a key, the D-pad or the game. Runs incrate::GooeySystems::Style. - update_
slot_ grids - Keeps every
crate::slot_gridtrue to itsSlotItems: 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’sSlotCursorfollows focus and is the one slot with aTabIndexof 0. Writes nothing for a grid that did not change. Runs incrate::GooeySystems::Stylebeforecrate::update_icons. - update_
spinners - Turns every
Spinnerto where real time puts it. Runs incrate::GooeySystems::Style. - update_
splits - Lays each split’s panes out from its
SplitFractionandSplitMin: 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 onesplit_minsleaves 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 incrate::GooeySystems::Style, beforecrate::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, beforecrate::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, beforecrate::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
TextInputValuethe 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 incrate::GooeySystems::Style, beforecrate::apply_skin. - update_
toasts - Ages every
Toast, fades it in and out, sends the oldest into its fade when more thanToastSettings::max_visiblestand, despawns the spent, and lays the stack out forToastSettings::anchor. Runs incrate::GooeySystems::Style, beforecrate::apply_skin, which draws the result. - update_
toggle_ groups - Lights each changed group’s option and no other (Bevy’s
Checked, whichcrate::apply_skindraws as the selected tab), and pulls a value past the last option back to it. Runs incrate::GooeySystems::Style, beforecrate::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 theTooltipchanged: a newTooltipinserted 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 incrate::GooeySystems::Style, beforeshow_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 noValueChange(a game’s own write sends none). Runs incrate::GooeySystems::Style, beforecrate::update_tables. - update_
vecs - Brings a vec field’s components up to the row: a
VecValue,NumberStep,NumberRangeorVecMixedthe game set goes into each component’s number row (which shows it, with no event). Runs incrate::GooeySystems::Style, beforeupdate_numbers. - update_
world_ anchors - Places every
WorldAnchoron its world point. Runs inPostUpdateafter transform propagation and the camera update and before UI layout, so a node is where the thing is in the frame it is drawn; seeWorldAnchor. - vec_
field - A row with a label and one
number_fieldfor each ofNnumbers (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.stepandrangeare 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 fromButtonInput<KeyCode>), Tab and F6 still leave, so the keyboard is never trapped. Put what draws into it (aViewportNode, an image) as children or on the entity itself, and.insert(DropTarget::<T>::new())makes it a place pieces are dropped.