Parameters
Range-clamped values - the unit ui_menu edits and the encoder drives
A params_t holds a target and a current val. The app moves the target; param_update_fast() copies it into val (one call, no easing), fires the registered callback when refresh is set, and returns true once val == target.
typedef struct { params_t gain; } my_model_t;
// init(): a ranged value - name, start, min, max, step
m->gain = (params_t)PARAM_RANGE("gain", 0.5f, 0.f, 1.f, 0.05f);Driving a param from the encoder
// in tick() param_write_delta_val(&m->cutoff, os_controls_encoder_get_delta()); param_update_fast(&m->cutoff, m); // in redraw() gfx_draw_strf(gfx, 10, 40, "cutoff %d%%", (int)(m->cutoff.val * 100.f));
Placing the same params_t in a ui_menu_node_t's param field lets the menu edit it directly - the two paths are interchangeable.
Note — There is no param_init(): it hands back a slot from a firmware-owned pool. Declare params_t values in the app's own model and initialise them with PARAM_RANGE() (or fill the fields directly; option lists use option_name[] + ParamValSelectType).
Move `val` to `target` and fire the callback if `refresh`; true once val == target (also true for a NULL param or `refresh == false`)
| params_t* | param | |
| void* | ctx |
Move `val` to `target` without firing the callback; true when it was already within `fine` of the target and snapped
| params_t* | param |
Apply an encoder delta to the target using the param's `fine` step
| params_t* | param | |
| int32_t | acc |
Called from param_update_fast() when `refresh` is set; receives the param and the ctx
| params_t* | param | |
| void (*callback)(params_t* self, void* context) |