Slider / Check Box / Combo Box String: values, setters, and change events¶
At a glance
Slider value: float in a configured domain; Get Normalized Value
separately reports its 0–1 position ·
Check Box value: ECheckBoxState (Unchecked, Checked, or
Undetermined); Is Checked returns only a bool ·
Combo Box String value: one option String, or no valid selection
(Get Selected Index = -1) ·
User events: On Value Changed, On Check State Changed, and
On Selection Changed ·
These widgets do not: apply, save, validate, or replicate a game setting ·
Official pages: Slider ·
Check Box ·
Combo Box String
The one-minute version¶
- A Slider, Check Box, or Combo Box is presentation state. It reports an edit; your options model decides whether that edit is valid, previews it, applies it to the real system, and eventually saves it.
- A Slider's
Valueis already in its Min Value–Max Value domain. With a 0–100 volume Slider,Get Valuereturns values such as35, whileGet Normalized Valuereturns0.35. Step Sizeis the keyboard/controller increment in that same value domain. Mouse movement is continuous unless Mouse Uses Step is enabled.- A Check Box has three display states.
Is Checkedis only true forChecked; useGet Checked StatewhenUndeterminedhas real meaning. - Combo Box String stores strings, not localized Text or typed setting values. Use stable internal option IDs, then map them to localized display labels.
- Programmatic setters are not one uniform event contract. In current UMG,
Slider and Check Box setters do not synthesize their user-change delegates;
Combo Box selection setters can report
On Selection Changedwith selection typeDirect. Guard initialization anyway. On Value Changedcan run repeatedly while a Slider is dragged. Update the draft or a cheap preview there; defer expensive application and saving until Apply or, for a preview, capture end.- Focusability, enabled state, and gamepad navigation are part of the control's contract. A mouse-only options menu is not a finished controller menu.
What these controls actually do¶
Each widget owns a small value plus the interaction that edits it:
| Widget | Full value getter | Other useful result | Empty / special state |
|---|---|---|---|
| Slider | Get Value → float in Min–Max space |
Get Normalized Value → float position from 0 to 1 |
No separate None state; your model must decide whether a number is valid |
| Check Box | Get Checked State → ECheckBoxState |
Is Checked → bool |
Undetermined means neither checked nor unchecked; the bool getter cannot preserve that distinction |
| Combo Box String | Get Selected Option → String |
Get Selected Index → int |
No selection is index -1; the selected string is empty, so an empty-string option is ambiguous |
The return types are the real values—there is no broader UObject pin hiding a
more specific runtime class. The important type loss happens elsewhere:
Is Checked collapses a three-state enum to a Boolean, and Combo Box String
turns every option into an untyped, non-localized String.
pseudocode — project architecture, not engine source
control interaction
-> widget updates its presentation value
-> widget change event reports the new primitive value
-> options screen requests a typed draft edit
-> coordinator validates and stores the draft
-> optional preview updates the real runtime system
-> Apply commits and persists through the setting's actual owner
See Options/settings screen architecture for the draft/applied/persisted boundary.
Slider: domain value, normalized value, and capture¶
Min, max, and normalization¶
The default Slider domain is 0–1, but it does not have to remain normalized. Choose a domain that matches the setting:
| Setting | Useful Slider domain | Draft value |
|---|---|---|
| Master volume | 0–1 | 0.65 |
| Field of view | 70–110 | 95 degrees |
| Mouse sensitivity | project-defined, for example 0.1–5 | 1.25 |
Validate the domain before wiring it to the control: Min and Max must be finite, and Min must be lower than Max. Clamp a loaded draft into that valid domain or reject it with a clear message. Choose a non-negative Step Size; when keyboard/controller input must make discrete edits, use a positive step that is meaningful inside the domain. A reversed or zero-width range makes the normalized readout meaningless.
Get Value returns the domain value. Get Normalized Value maps the current
position between Min and Max to 0–1; it does not mean your setting itself is
stored as a normalized percentage.
Keep one source of truth. If the project stores volume as 0–1, configure the
Slider that way instead of repeatedly converting 0–100 in several handlers.
If the UI must show 65%, format the label from the model in one place.
Step Size and input methods¶
Step Size is the amount added or subtracted by keyboard/controller input.
For a 70–110 field-of-view Slider, a step of 1 means one degree. It is not a
fraction of the whole range.
- Mouse Uses Step off: pointer dragging can produce values between steps.
- Mouse Uses Step on: pointer changes snap according to the configured step behavior.
- Locked on: the handle displays its value but cannot be interactively changed. This is different from disabling the whole widget.
- Requires Controller Lock on: the focused Slider must enter controller capture before directional input edits it. Capture begin/end events tell you when that adjustment session starts and stops.
Use On Value Changed for the current draft number. Use mouse/controller
capture end when a live preview is costly enough that every intermediate value
should not rebuild it. Saving a config file on every drag sample is the wrong
side effect.
Check Box: Boolean or three-state policy¶
The enum values mean:
Unchecked— an explicit off/false choice;Checked— an explicit on/true choice; andUndetermined— neither choice is represented, commonly “mixed values” or “inherit from another policy.”
Set Is Checked(bool) can express only Checked or Unchecked.
Set Checked State(ECheckBoxState) can express all three. Likewise, use
Get Checked State rather than Is Checked when Undetermined is possible.
Do not use Undetermined as a decorative “maybe.” Give it a named domain
meaning, such as UseProjectDefault. The Blueprint On Check State Changed
event exposes the checked Boolean for the ordinary toggle path; if project code
can assign Undetermined, read Get Checked State before creating the typed
request so the third state is not silently flattened.
A Check Box can be styled as a box, toggle button, or radio-like control, but styling does not create radio-group exclusivity. If exactly one choice must be active, use a Combo Box or enforce the group invariant in one model owner.
Combo Box String: options, selection, and identity¶
Combo Box String owns a list of string options plus one current selection.
Add Option, Remove Option, Clear Options, and Refresh Options manage the
display list. Set Selected Option searches by string; Set Selected Index
uses list position.
Treat these states explicitly:
| State | Get Selected Index |
Get Selected Option |
Screen response |
|---|---|---|---|
| Valid selection | 0 or greater |
selected option string | Map the ID to a typed draft value |
| No options / cleared selection | -1 |
empty string | Disable Apply for this field or choose a deliberate fallback |
| Requested string is absent | -1 after selection is cleared |
empty string | Keep the draft unchanged and show a supported fallback |
Do not add duplicate strings. The API does not give duplicates separate IDs, so selecting/removing by string becomes ambiguous. Do not add an empty string as a real choice either; it collides with the no-selection representation.
Stable IDs, localized labels¶
String is suitable for a stable internal option ID such as
WindowMode.Borderless; it is a poor persisted display label. Translated text
can change with language, and two languages can need different wording.
Use this shape:
stable ID (String/Name/Enum) -> localized Text label
"WindowMode.Windowed" -> LOCTEXT / String Table Text: "Windowed"
"WindowMode.Borderless" -> LOCTEXT / String Table Text: "Borderless"
"WindowMode.Fullscreen" -> LOCTEXT / String Table Text: "Fullscreen"
Generate the row widget from the ID and display Text; never save the
translated label as the setting value. For rich data, disabled rows, icons, or
separate identity/display fields, a ListView-style item model or a project
control is a better fit than stuffing more meaning into one string.
User events versus programmatic setters¶
The three controls do not make the same promise:
| Operation | Current UMG change-event behavior | Safe screen rule |
|---|---|---|
Slider Set Value |
Updates the value; does not synthesize On Value Changed |
Repaint inside the initialization guard; update the model deliberately |
Check Box Set Is Checked / Set Checked State |
Updates state; does not synthesize On Check State Changed |
Do not call the user handler by hand; set the draft first, then repaint |
Combo Box Set Selected Option / Set Selected Index |
A changed selection can flow through On Selection Changed as Direct |
Assume population can re-enter the handler and guard it |
On Selection Changed also reports an ESelectInfo reason: mouse click, key
press, navigation, or Direct for code-driven selection. The reason is useful
for presentation, but it is not authority. A Direct change during Open should
not dirty the draft; a Direct change issued by a deliberate project action
may still be a real edit.
This difference is why “the event did not fire” and “the event fired while I was loading” can both be real bugs in the same screen. Do not make correctness depend on a setter broadcasting exactly once.
The initialization pattern¶
Populate the model first, then the controls:
pseudocode — Blueprint screen flow
OpenOptions
-> bInitializing = true
-> Draft = Coordinator.OpenDraft(LocalPlayer)
-> VolumeSlider.SetValue(Draft.MasterVolume)
-> VSyncCheckBox.SetIsChecked(Draft.bVSync)
-> WindowModeCombo.ClearOptions()
-> add each stable supported option ID
-> WindowModeCombo.SetSelectedOption(Draft.WindowModeId)
-> bInitializing = false
-> bDirty = false
every control event
-> if bInitializing: return
-> build a typed request from the new value
-> Coordinator.RequestDraftChange(Request)
Also compare old and new values. That stops model → view → model loops after initialization and avoids treating a reselected identical option as new work.
Do not mix Designer property bindings with manual setters for the same value. A binding can repaint the widget from a second owner after your setter runs, making the control appear to “ignore” initialization.
One typed settings-change request¶
Avoid handlers that pass field names and display strings:
bad
RequestSettingChange("VSync", "On")
Do not force every setting payload through one string or Object pin. In ordinary Blueprint, a clear beginner-friendly typed shape is an enum identifying the edited field plus the complete typed draft:
ST_OptionsEditRequest
Field: EOptionField
Draft: ST_OptionsDraft
Source: EOptionEditSource // User, Preview, Restore
OnVSyncChanged(NewChecked)
-> NewDraft = Draft
-> NewDraft.bVSync = NewChecked
-> RequestDraftChange({ VSync, NewDraft, User })
The coordinator validates the field, accepts a normalized draft, and returns the authoritative draft to repaint. Strings remain IDs, numbers remain floats, and Boolean fields never depend on localized text.
Focus, enabled state, and navigation¶
- Make each interactive control focusable when keyboard/gamepad users must reach it. Set initial user focus for the initiating local player.
- If a focused option becomes disabled, move focus to a valid neighbor before or immediately after disabling it. Do not strand navigation on a dead widget.
- Disabled means no interaction. Use it for unsupported settings and pair it with a visible explanation; do not merely grey out a mystery row.
- Combo Box String's Enable Gamepad Navigation Mode changes whether an activation button opens/captures the list or directional keys directly change selection. Test the chosen policy with the rest of the menu's navigation rules.
- Keep Slider direction intuitive and expose a formatted value label; a handle position alone is weak feedback for accessibility and precise settings.
See Set Keyboard Focus / Set User Focus / Set Is Enabled for per-user focus and recovery.
When it fails (and what failure does)¶
These widgets fail quietly because they are presentation controls:
- an invalid Combo Box selection becomes no valid selection rather than a typed validation error;
- an empty or duplicate string remains ambiguous;
- a disabled/locked control simply does not accept the expected interaction;
- a non-focusable or badly routed control can work by mouse and appear broken by controller;
- a Slider can produce a value your gameplay system rejects if the UI domain and model validation disagree; and
- a stale widget reference can be
Noneafter the screen is destroyed, which is the ordinary Unreal reference problem rather than a setting failure.
The setters have no success Boolean, failure execution pin, automatic log, save, rollback, or network request. Validate before dispatch, retain the last valid draft, and show a specific message when the model rejects an edit.
What these controls do not do¶
- They do not know
UGameUserSettings, Sound Mixes, Enhanced Input profiles, SaveGame slots, or project defaults. - They do not distinguish draft, applied, and persisted state for you.
- They do not make an option supported on the current platform.
- They do not localize arbitrary String option values.
- They do not debounce expensive previews or persistence.
- They do not replicate local preferences or authorize gameplay changes.
Lookalikes — which one do I want?¶
| Control / pattern | Use it when | Do not confuse it with |
|---|---|---|
| Slider | The value is continuous or has many ordered steps | Spin Box, which is better when exact typed numeric entry matters |
| Progress Bar | Displaying read-only completion, health, or volume | A Slider; it does not accept the same edit interaction |
| Check Box | On/off, or a deliberately named three-state policy | Radio exclusivity; several styled Check Boxes can all be checked |
| Combo Box String | A small list can use stable string IDs and simple labels | A typed enum/data model or searchable/rich list |
| Buttons / segmented controls | A few choices should all remain visible | A Combo Box, which hides choices until opened |
| Options draft/coordinator | Validating, previewing, applying, cancelling, and saving | The widgets themselves; controls are only the editing surface |
Going deeper¶
- Options/settings screen architecture — the draft/applied/persisted model these events should edit.
- Updating a Widget: Bindings vs Events — one owner and event-driven repainting.
- Set Text / Format Text / Text vs String vs Name — formatted numbers, stable IDs, and localization-safe labels.
- Set Keyboard Focus / Set User Focus / Set Is Enabled — controller/keyboard reachability and focus recovery.
- Engine source (requires engine access; we do not reproduce it):
USlider::SetValue,USlider::HandleOnValueChanged, and widget rebuilding inEngine/Source/Runtime/UMG/Private/Components/Slider.cpp;UCheckBox::SetCheckedStateandUCheckBox::SlateOnCheckStateChangedCallbackinEngine/Source/Runtime/UMG/Private/Components/CheckBox.cpp;UComboBoxString::SetSelectedIndex,SetSelectedOption,HandleSelectionChanged, and option management inEngine/Source/Runtime/UMG/Private/Components/ComboBoxString.cpp; andSComboBox::SetSelectedIteminEngine/Source/Runtime/Slate/Public/Widgets/Input/SComboBox.h.