BGE/UI

Alias: BGE.UI


Static Methods

loadBackgroundImage(path: string): dynamic

static

Loads an image at path for use as Theme.backgroundImage, picking between a stretchable BGE.UI.NinePatchImage and a plain BGE.UI.ImageBackground automatically: a path ending in ".9.png" (case-insensitive), Android's own naming convention for this asset format, loads as a 9-patch (see loadNinePatchImage()); any other path loads as a plain image, stretched to fill entirely with no unstretched corners. Returns invalid if the image at path could not be loaded.

Parameters

  • path (string) — a pkg:/ path to a background image, ".9.png"-suffixed for a 9-patch

Returns

  • dynamic

isNinePatchPath(path: string): boolean

static

Parameters

  • path (string)

Returns

  • boolean

loadNinePatchImage(path: string): BGE.UI.NinePatchImage

static

Loads a PNG authored in Android's .9.png convention (a 1px transparent border with black-opaque pixel runs marking the stretch region on the top row and left column) and returns a ready-to-use NinePatchImage with insets read from the image itself - see BGE.UI.NinePatchImage for the full format. If a border has no marker pixels at all, that axis defaults to a 0 inset (the whole image stretches on that axis) rather than throwing - a game developer authoring their own asset should notice this visually (unstretched corners look wrong), but a missing marker is not otherwise treated as an error. Returns invalid if the image at path could not be loaded.

Parameters

  • path (string) — a pkg:/ path to a .9.png-style PNG

Returns

  • BGE.UI.NinePatchImage

loadBitmapOrLog(path: string, description: string): roBitmap

static

Loads a roBitmap from a pkg:/ path, logging and returning invalid instead of throwing if it can't be loaded - shared by loadNinePatchImage() and BGE.UI.loadBackgroundImage() instead of each duplicating this guard.

Parameters

  • path (string) — a pkg:/ path to an image
  • description (string) — what kind of image this is, for the log message (e.g. "9-patch bitmap")

Returns

  • roBitmap

parseNinePatchBitmap(bitmap: roBitmap): BGE.UI.NinePatchImage

static

Same as loadNinePatchImage(), but takes an already-loaded roBitmap - split out specifically so this parsing logic is testable against a synthetic in-memory bitmap without needing a packaged asset file.

Parameters

  • bitmap (roBitmap)

Returns

  • BGE.UI.NinePatchImage

findMarkerRun(pixels: roByteArray, lengthPx: integer): object

static

Internal helper for parseNinePatchBitmap() - not part of the public API surface (BrighterScript has no visibility modifier for a namespaced function), so deliberately not written as a JSDoc doc comment.

Scans a 1-pixel-wide/tall RGBA byte array (4 bytes/pixel, lengthPx being the top row's width or the left column's height) for the first and last near-black, near-opaque pixel, treating index 0 and index (length-1) as the border corners (never part of a marker run - Android's convention reserves the very first/last border pixel unconditionally). Returns {startIndex, endIndex, found} in full-bitmap pixel coordinates (both inclusive); if no marker pixel was found, found is false and the run spans the entire content region ({startIndex: 1, endIndex: lengthPx - 2}) so the caller's left/top = startIndex - 1 and right/bottom = contentLength - (endIndex - 1) - 1 formulas both resolve to 0 on that axis (the whole image stretches). (A sentinel of startIndex = lengthPx would NOT resolve to 0 under those formulas - verified by hand against a synthetic no-marker test case - so this is deliberately not "no run found" encoded as an empty/inverted range.)

Parameters

  • pixels (roByteArray)
  • lengthPx (integer)

Returns

  • object

Enums

BGE.UI.HorizAlignment

enumstaticreadonly

Properties

  • left (default: "left")
  • center (default: "center")
  • right (default: "right")

BGE.UI.VertAlignment

enumstaticreadonly

Properties

  • top (default: "top")
  • center (default: "center")
  • bottom (default: "bottom")

BGE.UI.FocusNavigationMode

enumstaticreadonly

How BGE.UI.FocusManager moves focus on directional input.

Properties

  • list (default: "list") — Default: discrete list navigation, like a typical menu - Up/Down/Left/ Right step currentlyFocused to the next/previous registered widget, no spatial cursor or hit-testing involved.
  • pointer (default: "pointer") — Opt-in: a virtual pixel cursor (cursorPosition) moves by cursorStep and is hit-tested against widget bounds each frame - see FocusManager.

BGE.UI.SelectStyle

enumstaticreadonly

Select's interaction style. inline (default): Left/Right cycle the current option in place, matching Slider's interaction pattern. popup: OK expands a list of every option; Up/Down move a highlight, OK commits, back cancels. horizontal: every option renders side-by-side in one row, with the current selection visually distinct; Left/Right move directly to the adjacent shown option (clamping at the ends, no wrap - there's nothing to wrap to once every option is already on screen). See Select.style.

Properties

  • inline (default: "inline")
  • popup (default: "popup")
  • horizontal (default: "horizontal")

Other

NINE_PATCH_FILENAME_SUFFIX

staticreadonly

Filename suffix marking a 9-patch source asset, matching Android's own .9.png naming convention (see NinePatchLoader's own doc comment for the pixel-format side of that convention). Checked case-insensitively.

Default: .9.png

Button

static

Extends: UiWidget

A focusable, clickable button: a label over a themed background. Set onActivate to a function(button as Button) to handle clicks, or subclass and override onClick() directly.

Parameters

Properties

  • drawableText (BGE.DrawableText)
  • onActivate (dynamic) — Called from onClick() when set - function(button as Button) as void

Returns

  • BGE.UI.Button

Checkbox

static

Extends: UiWidget

A focusable checkbox: a small toggle box plus a label. Set onChanged to a function(checkbox as Checkbox) to react to toggles.

Parameters

Properties

  • checked (boolean)
  • drawableText (BGE.DrawableText)
  • lastChangedValue (dynamic)
  • onChanged (dynamic) — Called from onClick() after checked flips - function(checkbox as Checkbox) as void

Returns

  • BGE.UI.Checkbox

CURSOR_ANALOG_DEADZONE

staticreadonly

Minimum analog-stick magnitude before updateAnalogCursor() moves the cursor at all. Local to the UI cursor, not applied in ControlMap - other axis consumers get the raw stick value.

Default: 0.15

FocusManager

static

Owns the single, global focused-widget/cursor state shared by every UiContainer that opts in (UiContainer.focusEnabled) - one Game instance owns one FocusManager (Game.focusManager). Widget positions are already absolute UI-canvas coordinates (each level of UiContainer.draw() adds its own parent's position - see UiWidget.getWorldPosition()), so one shared cursor/hit-test naturally spans nested containers with no translation.

Parameters

Properties

  • game (BGE.Game)
  • navigationMode (BGE.UI.FocusNavigationMode) — How directional input moves focus - see BGE.UI.FocusNavigationMode. ' Defaults to list (discrete next/previous, like a typical menu); a game ' opts into pointer (spatial cursor) explicitly.
  • wrapFocus (boolean) — list mode only: does moving past the last (or first) registered widget ' wrap around to the other end? Off by default - most menus stop at the ' ends rather than cycling.
  • focusOrder (dynamic) — Every focusable widget registered across every focusEnabled container ' (gameUi and any of its focusEnabled descendants) - flat, in register() ' order. In list mode this order IS the navigation order; in pointer mode ' it's used only to seed initial focus and as the hit-test target.
  • currentlyFocusedIndex (integer) — list mode only: index of currentlyFocused within focusOrder, or -1 ' before anything is focused.
  • cursorPosition (BGE.Math.Vector) — pointer mode only: virtual cursor position, in UI-canvas coordinate ' space. Moved by directional input; hit-tested against focusOrder each ' frame to drive hover/focus (cursor-primary - hovering a widget focuses ' it).
  • cursorStep (float) — pointer mode only: pixels the cursor moves per press/held-frame.
  • analogAxisName (dynamic) — Opt-in: name of a BGE.Controller.ControlMap axis (bound via ' ControlMap.bindAxis()) that continuously drives cursorPosition in pointer ' mode, alongside the existing d-pad press/held stepping. invalid (the ' default) means no analog input drives the cursor at all - zero behavior ' change. See updateAnalogCursor(). ' dynamic, not string, so a game can reset it back to invalid (e.g. when ' leaving the room that opted in) - the type checker rejects assigning ' invalid to a string-typed field.
  • cursorAnalogSpeed (float) — Pixels/second the cursor moves at full stick deflection (magnitude 1.0).
  • currentlyFocused (BGE.UI.UiWidget)
  • hasSeededFocus (boolean)
  • consumedThisFrame (boolean) — Latched true as soon as anything consumes during a frame, and reset ' once per frame (see resetFrame()). Game.bs dispatches more than one ' event per frame (a press, plus a synthesized held event while the ' button stays down) - without this latch a later, unconsumed event ' would undo an earlier one's input capture.
  • repeatThrottle (BGE.UI.RepeatThrottle) — Throttles repeat-while-held navigation to one step per ' WIDGET_REPEAT_DELAY_MS, the same way Slider/Select throttle their own ' adjustment - shared between list and pointer mode since only one mode ' is ever active at a time.

Returns

  • BGE.UI.FocusManager

ImageBackground

static

A plain (non-9-patch) image background: the whole source image is stretched to fill the widget's bounds, corners included - unlike BGE.UI.NinePatchImage, which keeps its corners unstretched. Assign to Theme.backgroundImage the same as a NinePatchImage; see BGE.UI.loadBackgroundImage(), which picks this or a NinePatchImage automatically from the asset's filename.

Parameters

  • sourceImage (roBitmap) — the full source image, stretched to fill on draw()

Properties

  • sourceImage (roBitmap)
  • sourceWidth (integer)
  • sourceHeight (integer)

Returns

  • BGE.UI.ImageBackground

Label

static

Extends: UiWidget

Parameters

Properties

Returns

  • BGE.UI.Label

MessagePanelButton

static

One button spec for MessagePanel: a label plus the same onActivate callback shape BGE.UI.Button itself uses (function(button as BGE.UI.Button) as void).

Parameters

  • label (string)
  • onActivate (dynamic)

Properties

  • label (string)
  • onActivate (dynamic)

Returns

  • BGE.UI.MessagePanelButton

MessagePanel

static

Extends: BGE.UI.UiContainer

A centered modal panel (translucent background, optional heading, optional body message, a vertical stack of buttons) for pause menus, win/game-over screens, and similar - promoted from the same shape hand-rolled independently by several BGE.UI-based examples, including the same focus-safety fix each needed by hand: a Button registers itself with the global FocusManager the instant it's added to any focusEnabled container, even one not yet attached to gameUi - so a panel must be built fresh right before it's shown and torn down (not just hidden) when closed, or its buttons stay focusable/clickable while invisible. show()/hide() handle this internally: hide() removes the panel (and its buttons) from its parent entirely, and show() rebuilds its children fresh each time.

Font-name assumption: the title is measured AND drawn with the same resolved "heading"-or-"default" font (self-consistent), but the message label is measured with "body"-or-"default" while actually DRAWN with whatever font its resolved theme yields (via the normal Label/resolveTheme() path). If a consumer's container theme sets a different font than what they registered as "body", the message text could measure slightly off from how it's centered.

Parameters

  • game (BGE.Game)
  • panelWidth (float)
  • panelHeight (float)
  • buttons (Array.<BGE.UI.MessagePanelButton>) — shown top to bottom
  • title (string, optional, default: "\"\"") — optional heading, drawn in a larger font
  • message (string, optional, default: "\"\"") — optional body text below the heading

Properties

  • title (string) — Panel heading, shown in a larger font above the message/buttons. Empty ("") means ' no heading is drawn.
  • message (string) — Body message, shown below the heading. Empty ("") means no message is drawn. Call ' setMessage() (not this field directly) to update it after the panel is already ' shown - it re-measures/re-centers the label.
  • buttons (dynamic) — Buttons, top to bottom, in the order given to the constructor.
  • buttonWidgets (dynamic) — The actual BGE.UI.Button widgets built from buttons, in the same order - only ' valid after show() has built the panel's children.

Returns

  • BGE.UI.MessagePanel

NinePatchSliceSpec

static

Describes one of a NinePatchImage's 9 slices: which segment of the source/destination grid it occupies along each axis. 0 = the fixed leading segment (the left/top inset), 1 = the stretchable middle segment, 2 = the fixed trailing segment (the right/bottom inset). Both slicing (in new()) and drawing (in draw()) are driven generically from this list instead of writing out 9 near-identical blocks by hand.

Properties

  • name (string)
  • gridX (integer)
  • gridY (integer)

NinePatchImage

static

A 9-patch ("scale-9") stretchable background image: a source bitmap is sliced once (at construction) into 9 roRegions - 4 corners (drawn at fixed size), 4 edges (stretched along one axis), and a center (stretched both axes) - so a single small source texture can back a background of any width/height without visibly stretching its corners. Assign to Theme.backgroundImage to opt a widget's background fill into this instead of a flat color - see Theme.backgroundImage's own doc comment.

Takes a roBitmap, not a roRegion: CreateObject("roRegion", ...) only accepts a roBitmap as its source, not another roRegion (confirmed via Roku's own component type data and an actual runtime Type Mismatch when a roRegion was tried) - so slicing has to start from the real bitmap.

Parameters

  • sourceBitmap (roBitmap) — the full source image
  • left (integer) — px from the left edge that stay unstretched
  • top (integer) — px from the top edge that stay unstretched
  • right (integer) — px from the right edge that stay unstretched
  • bottom (integer) — px from the bottom edge that stay unstretched

Properties

  • slices (object) — Slice name (see specs) -> roRegion, invalid if that slice's inset ' resolved to 0 (see makeSlice()).
  • specs (object) — The 9 slice specs, computed once in new() and reused by draw() every ' frame - see NinePatchSliceSpec. A fixed, unchanging list, so building ' it once avoids 9 fresh AA allocations on every single draw() call.
  • left (integer)
  • top (integer)
  • right (integer)
  • bottom (integer)
  • sourceWidth (integer)
  • sourceHeight (integer)

Returns

  • BGE.UI.NinePatchImage

NINE_PATCH_MARKER_THRESHOLD

staticreadonly

RGBA byte threshold below which a channel is considered "black" - PNG export/compression can introduce minor color drift in marker pixels, so this isn't an exact &h000000FF match.

Default: 40

NINE_PATCH_MARKER_MIN_ALPHA

staticreadonly

Default: 200

Select

static

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.

Parameters

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().

Returns

  • BGE.UI.Select

Slider

static

Extends: UiWidget

A horizontal value picker: a label, a filled bar, and a numeric readout. Adjust with increase()/decrease() (step-sized) or set an exact value with setValue().

Parameters

Properties

  • minValue (float)
  • maxValue (float)
  • step (float)
  • value (float)
  • repeatThrottle (BGE.UI.RepeatThrottle) — Throttles repeat-while-held Left/Right to one step per ' WIDGET_REPEAT_DELAY_MS - see handleInput().
  • barColor (dynamic)
  • backgroundColor (dynamic)
  • drawableText (BGE.DrawableText)

Returns

  • BGE.UI.Slider

DEFAULT_PADDING

staticreadonly

Default: 32

WIDGET_REPEAT_DELAY_MS

staticreadonly

Minimum time (ms) a direction must be held before a Slider/Select repeats its adjustment. Game.bs dispatches a press AND a synthesized held event (heldTimeMs ~0) in the same frame as every button press, so without this threshold a single tap would step twice - see RepeatThrottle below.

Default: 300

RepeatThrottle

static

Throttles repeat-while-held directional input to one action per WIDGET_REPEAT_DELAY_MS, while letting a single tap's press+synthesized- held pair act exactly once. Shared by Slider/Select.handleInput() and BGE.UI.FocusManager's list/pointer navigation - anywhere directional input should act at most once per tap, then repeat while held.

Properties

  • lastActionMs (float) — heldTimeMs of the last held event acted on, or -1 when no hold is in ' progress.

OffsetSize

static

Parameters

  • tOffset (float, optional, default: 0)
  • rOffset (dynamic, optional, default: "invalid")
  • bOffset (dynamic, optional, default: "invalid")
  • lOffset (dynamic, optional, default: "invalid")

Properties

  • top (float)
  • right (float)
  • bottom (float)
  • left (float)

Returns

  • BGE.UI.OffsetSize

TextInput

static

Extends: UiWidget

A focusable single-line text entry widget. Characters arrive via onECPKeyboard() (Roku's mobile-app on-screen keyboard sends individual characters this way - see Game.bs's existing onECPKeyboard dispatch, which already reaches every UiContainer child unconditionally, same as onInput()). Left/Right (while focused) move the caret; OK fires onSubmit. No on-screen virtual keyboard is drawn by this widget - it relies entirely on the platform's own text-entry mechanism delivering onECPKeyboard() characters.

Parameters

Properties

  • text (string) — Current text content.
  • cursorIndex (integer) — Caret position, 0..Len(text). Moved by Left/Right while focused, and ' advances/retreats as characters are inserted/deleted.
  • maxLength (integer) — Maximum text length, 0 = unlimited. A character typed once text.Len() ' already equals maxLength is silently dropped.
  • placeholder (string) — Text shown (dimmed) when text is empty and this widget isn't focused.
  • onChanged (dynamic) — Called after any edit (insert/delete) - function(input as TextInput) as void
  • onSubmit (dynamic) — Called on OK-press while focused - function(input as TextInput) 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.
  • drawableText (BGE.DrawableText)
  • repeatThrottle (BGE.UI.RepeatThrottle) — Throttles repeat-while-held Left/Right to one step per ' WIDGET_REPEAT_DELAY_MS - see handleInput().

Returns

  • BGE.UI.TextInput

Theme

static

Default colors/fonts/spacing for BGE.UI widgets. Game.defaultTheme is the engine-wide default (matching today's previously-hardcoded widget colors, so existing consumers see no visual change); a UiContainer.theme overrides it for that container's subtree.

Resolution happens on every draw() call, not once at add-time: a widget resolves the theme from its immediate parent's effectiveTheme() (which itself falls back to Game.defaultTheme when that parent has no theme set), and any per-widget color field left invalid picks up the theme's value. There is no multi-level walk up the tree - only the immediate parent is consulted, so a grandparent container's own override does not reach a grandchild through an intervening container that has no theme of its own.

font, when set, is applied once to a widget's rendered text - see UiWidget.applyThemeFont(), called from every widget that owns a BGE.DrawableText (Button, Label, Checkbox, Slider, Select, TextInput) right after resolveTheme() in its own draw(). This is a one-time application per widget (not dynamic font-swapping): re-applying on every theme change would mean detecting whether font changed, which can't be done by comparing roFont instances (= on native components is a runtime crash in BrightScript, confirmed for roFont specifically - even a cast as object doesn't avoid it). fontSize is still accepted and stored but not applied - a roFont from Game.loadFont()/GetFont() already has its size baked in at load time, so this field is effectively vestigial.

Properties

  • backgroundColor (integer)
  • foregroundColor (integer)
  • borderColor (integer)
  • focusedBorderColor (integer)
  • hoveredBackgroundColor (integer)
  • disabledColor (integer)
  • font (roFont)
  • fontSize (integer)
  • defaultPadding (OffsetSize)
  • defaultMargin (OffsetSize)
  • cursorColor (integer)
  • cursorSize (float)
  • backgroundImage (dynamic) — A background image, drawn instead of a flat backgroundColor fill when ' set. invalid (the default) means "flat color" - exactly today's ' behavior, so this is purely additive. Either a BGE.UI.NinePatchImage ' (a stretchable image with unstretched corners) or a BGE.UI.ImageBackground ' (a plain image, stretched to fill entirely) - see ' BGE.UI.loadBackgroundImage(), which picks the right one automatically ' from the asset's filename. Does not vary by hover/focus state - a ' themeable hovered/focused background image is a possible future ' follow-up, not supported here.

Returns

  • BGE.UI.Theme

UiContainer

static

Extends: BGE.UI.UiWidget

Parameters

Properties

  • backgroundRGBA (integer) — RGBA value for the background of the window/container
  • showBackground (boolean) — RGBA value for the background of the window/container
  • children (dynamic)
  • theme (BGE.UI.Theme) — This container's own theme override. When invalid, effectiveTheme() ' falls back to m.game.defaultTheme.
  • focusEnabled (boolean) — Does this container register its focusable children with the shared ' BGE.UI.FocusManager (Game.focusManager)? gameUi wants this (issue ' #133); debugUi opts out (set to false by Game.bs) since debug UI ' should be non-blocking and never capture input away from gameplay ' entities - its widgets, if any, would just never be focusable, and it ' still gets onInput()'s plain broadcast like any other GameEntity. ' Focus is global (issue #178): every focusEnabled container anywhere in ' the tree shares the same one focused widget, via Game.focusManager ' (driven once per frame by Game.processFocusManagerInput() - not ' per-container) - not tracked per-container.

Returns

  • BGE.UI.UiContainer

UiWidget

static

Extends: BGE.GameEntity

Base Abstract class for all UI Elements

Parameters

Properties

  • customPosition (boolean) — If position = "custom", then m.customX is horizontal position of this element from the parent position ' and m.customY is the vertical position of this element from the parent position (positive is down)
  • customX (float)
  • customY (float)
  • horizAlign (string) — If customPosition is false, this dictates where horizontally in the container this element should go. Can be: "left", "center" or "right"
  • vertAlign (string) — If customPosition is false, this dictates where vertically in the container this element should go. Can be: "top", "center" or "bottom"
  • width (integer) — Width of the element
  • height (integer) — Height of the element
  • focusable (boolean) — Can this widget receive focus/hover from its owning UiContainer's cursor?
  • focused (boolean) — Does this widget currently have focus? Set by the owning UiContainer - do not set directly.
  • hovered (boolean) — Is the owning UiContainer's cursor currently over this widget? Set by the owning UiContainer.
  • parentContainer (UiWidget) — The UiContainer this widget was added to via addChild() - set by ' UiContainer.addChild(). Used by BGE.UI.FocusManager to reposition a ' focusable widget correctly when seeding initial focus before the first ' draw() has ever positioned it (see FocusManager.update()).
  • canvas (BGE.Canvas)
  • padding (OffsetSize)
  • margin (OffsetSize)
  • hasAppliedThemeFont (boolean) — Latches true the first time this widget applies a resolved theme's ' custom font to its own DrawableText (see applyThemeFont()) - a theme's ' font is only ever applied once per widget, which sidesteps having to ' compare two roFont instances with = (a runtime crash on native ' components in BrightScript) to detect a later theme/font change.

Returns

  • BGE.UI.UiWidget