Select

Extends: UiWidget

A focusable option picker. Its interaction style is controlled by Select.style (see BGE.UI.SelectStyle): inline (the default) cycles through m.options in place with Left/Right, matching Slider's existing interaction pattern; popup expands a full option list on OK; horizontal shows every option side-by-side in one row, with Left/Right moving directly between them.

Properties

  • options (dynamic)
  • selectedIndex (integer)
  • drawableText (BGE.DrawableText)
  • onChanged (dynamic) — Called after selectedIndex changes - function(select as Select) as void
  • lastChangedValue (dynamic) — Test accessor: last value an onChanged callback stashed here. Not part ' of the public API - exists purely because a plain local var captured by ' an anonymous sub assigned to onChanged doesn't reliably update under ' brs-cli, so tests need a field on the widget itself to observe.
  • style (BGE.UI.SelectStyle) — Which interaction style this Select uses - see BGE.UI.SelectStyle. ' Defaults to inline (Left/Right cycling), matching this widget's original ' (and only) behavior - popup is opt-in, not a breaking change.
  • expanded (boolean) — popup style only: is the option list currently expanded?
  • highlightedIndex (integer) — popup style only: index within m.options currently highlighted while expanded.
  • lastDrawnRowCount (integer) — Test accessor: how many option rows drawOverlay() drew last call. Not ' part of the public API - exists purely so tests can distinguish ' drawOverlay() actually rendering the popup list from its no-op paths.
  • optionTextDrawables (object) — popup and horizontal styles only: one BGE.DrawableText per unique ' option string, keyed by that string - reused across frames/rows instead ' of drawOverlay()/drawHorizontal() cycling every option's text through ' the single m.drawableText field (also used by draw() for the inline/ ' popup current value), which would defeat DrawableText.getTextImage()'s ' own cache (keyed on the instance's last text/color) every single frame ' the popup stays open or a horizontal Select is drawn. See getOptionText(). ' m.options is a plain public field with no change hook, so entries for ' strings no longer present in m.options are pruned each use (see ' pruneOptionTextCache()) rather than left to accumulate forever across ' an options reassignment (e.g. search/filter results changing over time).
  • repeatThrottle (BGE.UI.RepeatThrottle) — Throttles repeat-while-held Left/Right to one step per ' WIDGET_REPEAT_DELAY_MS - see handleInput().

Constructor

new Select(game: BGE.Game): Select

Parameters


Instance Methods

getValue(): dynamic

Gets the currently selected option's value.

Returns

  • dynamic

next(): void

Advances to the next option, wrapping to the first after the last.

Returns

  • void

previous(): void

Goes back to the previous option, wrapping to the last after the first.

Returns

  • void

handleInput(input: BGE.GameInput): boolean

Left/Right (while focused) cycle the selection and consume the event. Called only while focused - see UiWidget.handleInput()/ BGE.UI.FocusManager.update(). A held Left/Right event is always consumed too - Game.bs synthesizes one alongside every press, and it has to be consumed rather than leaking through to GameEntity.onInput() - but it only CYCLES once WIDGET_REPEAT_DELAY_MS has passed since the last step, so a single tap's press+held pair steps exactly once while a sustained hold still repeats.

Parameters

Returns

  • boolean

onClick(): void

popup style only: toggles expand/commit on OK click. FocusManager.update() intercepts OK press itself and calls onClick() directly rather than forwarding it to handleInput() - so the popup commits on this SECOND onClick() call (while already m.expanded), not through handleInput(). First click (not expanded): expands, seeding highlightedIndex from selectedIndex. Second click (expanded): commits highlightedIndex to selectedIndex, fires onChanged, and collapses.

Returns

  • void

onBlur(): void

Collapses the popup list whenever this Select loses focus. Only the currently-focused widget's drawOverlay() runs, so an expanded-but- unfocused Select would be invisible while still holding a stale highlight that the next OK press would immediately commit. Covers every blur path (list navigation, pointer hover-out, analog cursor) in one place.

Returns

  • void

draw(parent?: UiWidget): void

Parameters

  • parent (UiWidget, optional, default: "invalid")

Returns

  • void

drawOverlay(canvas: BGE.Canvas, theme: BGE.UI.Theme): void

Draws the popup option list below this Select's own bounds, one row per option, with the highlighted row visually distinct. No-op unless m.style = popup and m.expanded - fires every frame while expanded via UiWidget.drawOverlay() (called for the currently-focused widget only).

Non-goal: every option draws unclipped/unscrolled, so a list long enough to overflow the canvas bottom is a known limitation, not a bug - no scrolling/clipping here.

Parameters

Returns

  • void

getOptionTextDrawableCount(): integer

Test accessor: how many distinct option strings have a cached DrawableText so far. Not part of the public API - exists purely so tests can confirm optionTextDrawables stays bounded by the option list rather than growing every drawOverlay() call.

Returns

  • integer