-
Notifications
You must be signed in to change notification settings - Fork 4
Open
Labels
enhancementNew feature or requestNew feature or request
Milestone
Description
Add a declarative <DragValue> numeric input with a controlled binding. Support drag-to-change with configurable speed, optional clamping to a range, formatting (prefix/suffix, decimals), enable/disable, and tooltips. Emit onChange during updates and optionally onRelease when the user stops dragging/commits.
- Covers a precise numeric input pattern common in tooling, inspectors, and property panels.
- Reduces imperative glue around
egui::DragValuewhile keeping a controlled-value model. - Complements
<Slider>for “fine-grained” adjustments and typed entry.
Scope
-
Tag:
<DragValue> -
Required:
value={number_expr} -
Optional attributes:
- Behavior:
speed=number(default sensible),clampToRange=bool(defaulttrue) - Range:
min=number,max=numberorrange="a..=b"(mutually exclusive withmin/max) - Formatting:
prefix="...",suffix="...",minDecimals=u8,maxDecimals=u8,fixedDecimals=u8(mutually exclusive withminDecimals/maxDecimals) - Quantization (optional):
step=number(snap to multiples inside range after change) - Common:
enabled=bool,tooltip="...",id="...",width=f32
- Behavior:
-
Events:
onChange={|v| ...}— fires when value changes;
onRelease={|v| ...}— fires when drag ends (commit-like).
Non-goals (here): custom formatter callbacks; exponential/logarithmic scaling.
Proposed API (sketch)
Float with range, prefix/suffix
efx!(ui, r#"
<DragValue value={props.price} range="0.0..=9999.0" speed="0.25"
prefix="$" fixedDecimals="2" onChange={|v| props.price = v}/>
"#);Integer with min/max, quantization and release event
efx!(ui, r#"
<DragValue value={model.count} min="0" max="1000" speed="1.0" step="5"
suffix=" pcs" onRelease={|v| persist(v)}/>
"#);Conceptual mapping to egui
let mut v = /* bound number */;
let mut dv = egui::DragValue::new(&mut v).speed(speed);
// Clamp range
if let Some(r) = clamp_range { dv = dv.clamp_range(r); }
if !clamp_to_range { dv = dv.clamp_to_range(false); }
// Formatting
if let Some(p) = prefix { dv = dv.prefix(p); }
if let Some(s) = suffix { dv = dv.suffix(s); }
if let Some(n) = fixed_decimals { dv = dv.fixed_decimals(n); }
else {
if let Some(n) = min_decimals { dv = dv.min_decimals(n); }
if let Some(n) = max_decimals { dv = dv.max_decimals(n); }
}
// Width hint
if let Some(w) = width { dv = dv.width(w); }
let resp = if enabled { ui.add(dv) } else { ui.add_enabled(false, dv) };
if let Some(tip) = tooltip { resp.on_hover_text(tip); }
// Optional quantization
let v_out = if let Some(step) = step { quantize(v, step, clamp_range) } else { v };
let changed = resp.changed() /* and v_out != old */;
if changed { /* write back bound value */ /* emit onChange(v_out) */ }
if resp.drag_released() { /* emit onRelease(v_out) */ }Tasks
-
AST & parsing
- Add
<DragValue>node; parsevalue,speed,min/maxorrange,clampToRange, formatting attrs,step, and common attrs. - Enforce attr exclusivity:
rangexor (min&max);fixedDecimalsxor (minDecimals/maxDecimals). - Validate numeric types and that
min ≤ max.
- Add
-
Codegen
- Bind
value={expr}via local copy →egui::DragValue::new(&mut v)→ write back on change. - Map range to
clamp_range(..); respectclampToRange=false. - Apply formatting (
prefix,suffix, decimals) andwidth. - Implement optional
stepquantization (snap to nearest multiple within range) before emitting events. - Emit
onChange(v)andonRelease(v)appropriately.
- Bind
-
Diagnostics
- Missing
valueor bad type → clear error (expects numeric). - Conflicting attrs (range vs min/max; fixed vs min/max decimals) → actionable message.
-
min > maxor malformedrange→ compile error with example. - Unknown attrs → list allowed attributes for
<DragValue>.
- Missing
-
Examples & docs
-
examples/drag_value_price.rs(float with currency, fixed decimals). -
examples/drag_value_int.rs(int with step snapping and onRelease). - Cookbook snippet + entry in
docs/tags.md.
-
-
Tests
- trybuild UI tests: missing/invalid attrs, conflicts, type errors.
- Unit tests: quantization helper; decimals precedence rules.
- Ensure examples build for
wasm32-unknown-unknown(no runtime launch).
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request