Input numeric widgets

The input_* numeric family is type-the-number editing: click to focus, type, Enter to commit. Optional + / - step buttons turn scalar forms into discrete-step editors. Same call shape spans scalar / vector / double-precision — nine widgets, one mental model.

input_float(IDENT, (text = "..", step = 0.0f, step_fast = 0.0f,
                    format = "%.3f", flags = ImGuiInputTextFlags....))
input_int(IDENT, (text = "..", step = 1, step_fast = 100,
                  flags = ImGuiInputTextFlags....))
input_double(IDENT, (text = "..", step = 0.0lf, step_fast = 0.0lf,
                     format = "%.6f"))
input_float2 / input_float3 / input_float4   // vector — no step args
input_int2   / input_int3   / input_int4

No bounds. input_* is for typed entry; if you need clamped scrubbing, use Drag widgets or Slider widgets.

Source: examples/tutorial/input_numeric.das.

Walkthrough

  1options gen2
  2
  3require imgui
  4require imgui_app
  5require opengl/opengl_boost
  6require live/glfw_live
  7require live/live_api
  8require live/live_commands
  9require live/live_vars
 10require live_host
 11require imgui/imgui_live
 12require imgui/imgui_boost_runtime
 13require imgui/imgui_boost_v2
 14require imgui/imgui_widgets_builtin
 15require imgui/imgui_containers_builtin
 16require imgui/imgui_visual_aids
 17
 18// =============================================================================
 19// TUTORIAL: input_numeric widgets — type the number, optionally with
 20// +/- step buttons.
 21//
 22//   input_float(IDENT, (text = "..", step = 0.0f, step_fast = 0.0f,
 23//                       format = "%.3f", flags = ImGuiInputTextFlags....))
 24//   input_int(IDENT, (text = "..", step = 1, step_fast = 100,
 25//                     flags = ImGuiInputTextFlags....))
 26//   input_double / input_float2/3/4 / input_int2/3/4 — same shape;
 27//   scalar / vector / double-precision variants.
 28//
 29// Scalar forms get step / step_fast args — non-zero shows ImGui's +/-
 30// buttons, click = step, ctrl-click = step_fast. Vector forms (2/3/4)
 31// have no step args — the buttons would crowd the row.
 32//
 33// Default int step = 1 / step_fast = 100; float defaults are 0.0 (no
 34// buttons). input_double defaults to 0.0lf (no buttons) with format
 35// "%.6f" for the extra precision.
 36//
 37// STANDALONE: daslang.exe modules/dasImgui/examples/tutorial/input_numeric.das
 38// LIVE:       daslang-live modules/dasImgui/examples/tutorial/input_numeric.das
 39//
 40// DRIVE (when running live):
 41//   curl -X POST -d '{"name":"imgui_force_set","args":{"target":"IN_WIN/I_FLOAT","value":12.5}}' \
 42//        localhost:9090/command
 43//   curl -X POST -d '{"name":"imgui_force_set","args":{"target":"IN_WIN/I_VEC3","value":[1.0,2.0,3.0]}}' \
 44//        localhost:9090/command
 45// =============================================================================
 46
 47[export]
 48def init() {
 49    live_create_window("dasImgui input_numeric tutorial", 760, 560)
 50    live_imgui_init(live_window)
 51    let io & = unsafe(GetIO())
 52    GetStyle().FontScaleMain = 1.4
 53}
 54
 55[export]
 56def update() {
 57    if (!live_begin_frame()) return
 58    begin_frame()
 59
 60    ImGui_ImplGlfw_NewFrame()
 61    apply_synth_io_override()
 62    NewFrame()
 63
 64    SetNextWindowPos(ImVec2(20.0f, 20.0f), ImGuiCond.Always)
 65    SetNextWindowSize(ImVec2(720.0f, 520.0f), ImGuiCond.Always)
 66    window(IN_WIN, (text = "input_numeric tutorial", closable = false,
 67                    flags = ImGuiWindowFlags.None)) {
 68
 69        text("Click to focus, type the number, Enter to commit.")
 70        text(I_HINT, (text = "Scalar forms have step / step_fast - non-zero shows +/- buttons."))
 71        separator()
 72
 73        // ---- Stage 1: scalar float with step buttons ----
 74        input_float(I_FLOAT, (text = "mass (kg)",
 75                              step = 0.1f, step_fast = 1.0f,
 76                              format = "%.3f"))
 77        text("I_FLOAT.value = {I_FLOAT.value}")
 78        spacing()
 79
 80        // ---- Stage 2: scalar int with step buttons ----
 81        input_int(I_INT, (text = "level",
 82                          step = 1, step_fast = 100))
 83        text("I_INT.value = {I_INT.value}")
 84        spacing()
 85
 86        // ---- Stage 3: vector float3 — no step buttons (vector forms omit them) ----
 87        input_float3(I_VEC3, (text = "position", format = "%.2f"))
 88        text("I_VEC3.value = ({I_VEC3.value.x}, {I_VEC3.value.y}, {I_VEC3.value.z})")
 89        spacing()
 90
 91        // ---- Stage 4: double precision ----
 92        input_double(I_DOUBLE, (text = "epoch (s)",
 93                                step = 1.0lf, step_fast = 60.0lf,
 94                                format = "%.6f"))
 95        text("I_DOUBLE.value = {I_DOUBLE.value}")
 96    }
 97
 98    end_of_frame()
 99    Render()
100    var w, h : int
101    live_get_framebuffer_size(w, h)
102    glViewport(0, 0, w, h)
103    glClearColor(0.10f, 0.10f, 0.12f, 1.0f)
104    glClear(GL_COLOR_BUFFER_BIT)
105    live_imgui_render()
106
107    live_end_frame()
108}
109
110[export]
111def shutdown() {
112    live_imgui_shutdown()
113    live_destroy_window()
114}
115
116[export]
117def main() {
118    init()
119    while (!exit_requested()) {
120        update()
121    }
122    shutdown()
123}

Requires

Already in the baseline boost layer:

  • imgui/imgui_widgets_builtin — every input_* numeric rail.

  • imgui/imgui_boost_runtimeInputStateFloat / InputStateInt / InputStateDouble (+ vector variants) state structs.

Step buttons

Scalar forms (input_float, input_int, input_double) accept step and step_fast. Non-zero values surface ImGui’s + / - buttons on the right of the field:

input_float(MASS, (text = "mass (kg)",
                   step = 0.1f, step_fast = 1.0f))    // +/- buttons visible
input_int(LEVEL, (text = "level",
                  step = 1, step_fast = 100))         // defaults match this

Plain click = step. Ctrl-click = step_fast. Defaults differ per type: input_int defaults step = 1 / step_fast = 100 (buttons visible by default); input_float and input_double default to 0.0 (buttons hidden — pure text entry).

Vector forms (input_float2 / 3 / 4, input_int2 / etc.) omit step args — three or four +/- pairs would crowd the row. Component-wise editing only.

Format

format is the printf-style label format. Defaults are sane for most cases; bump precision when the user needs to see it:

input_float(MASS, (text = "mass", format = "%.6f"))   // 6 decimal places
input_int(LEVEL, (text = "level", format = "%03d"))   // 003, 042, etc.
input_double(EPOCH, (text = "epoch", format = "%.9f")) // sub-ns precision

Vector forms

Same 2 / 3 / 4 convention — that many fields on one row. state.value becomes float2 / float3 / float4 (or int2 / int3 / int4). Tab cycles between components; Enter commits the whole row.

input_float3(POSITION, (text = "position", format = "%.2f"))
// POSITION.value.x, POSITION.value.y, POSITION.value.z

Double precision

input_double is the only path to double-precision values in the input family — drag and slider don’t have a double variant. Use it for timestamps, geographic coordinates, anything that needs more than 7 significant digits:

input_double(EPOCH_SEC, (text = "epoch",
                         step = 1.0lf, step_fast = 60.0lf,
                         format = "%.6f"))

Default format "%.6f" (six places) vs input_float’s "%.3f" reflects the extra precision.

Flags

flags : ImGuiInputTextFlags carries the standard text-input modifiers — CharsDecimal, CharsHexadecimal, CharsScientific, ReadOnly, Password (rarely useful on numeric inputs but allowed), EscapeClearsAll, etc. Composable via |:

input_int(HEX_ADDR, (text = "addr",
                     flags = ImGuiInputTextFlags.CharsHexadecimal,
                     format = "0x%08X"))

Driving from outside

Every input_* widget exposes the same telemetry channel as drag and slider — imgui_force_set writes state.pending_value which the next frame consumes:

# Scalar:
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"IN_WIN/I_FLOAT","value":12.5}}' \
     localhost:9090/command
# Vector — one number per component:
curl -X POST -d '{"name":"imgui_force_set","args":{"target":"IN_WIN/I_VEC3","value":[1.0,2.0,3.0]}}' \
     localhost:9090/command

The dispatcher ([widget_dispatch] on InputStateFloat and friends) accepts the right JSON shape per state type.

Input vs drag vs slider

The three numeric-edit families differ in interaction shape:

  • input — type the number, optionally with step buttons. Best for precise values where the user already knows the number.

  • drag — click and scrub, no fixed track. Best for “tweak this value” with open-ended range.

  • slider — click and drag along a fixed-width track between v_min / v_max. Best for bounded percentages, settings.

All three families share vector / scalar / format conventions. See Drag widgets and Slider widgets.

Caller-owned variant

For sites where the value lives on an external scalar (not a widget state struct), use the edit_input_* rail instead — it takes a T? pointer via safe_addr and skips the state-struct allocation:

var g_mass : float = 1.0f
edit_input_float(safe_addr(g_mass), (id = "MASS",
                                     text = "mass", step = 0.1f))

See External-pointer editing rail.

See also

Full source: examples/tutorial/input_numeric.das

Features-side demo: examples/features/inputs_numeric.das — every numeric input in one window, useful for imgui_force_set smoke testing.

Sibling tutorials: Drag widgets, Slider widgets, Input text widgets.

Boost macros — the macro layer.