1# llimphi-widget-timeline23Clickable progress / scrub bar.
45The pattern is analogous to `llimphi-widget-slider` / `-progress`: the widget
6keeps **no state**. The caller stores the current position in its `Model`, passes
7the **progress fraction** (`0.0..=1.0` = position/duration) and a
8`Fn(f32) -> Option<Msg>` handler that receives the fraction **where the user
9clicked** (absolute scrub, VLC style). The widget knows nothing about time or
10duration: it only paints progress and reports where the click landed as a
11fraction of the bar's width (`on_click_at`). Mapping that fraction to a concrete
12seek is the app's job.
1314```text15 [ ██████████▏░░░░░░░░░░░░ ]
16 elapsed playhead rest
17```1819Typical use (a player):
2021```ignore22let frac = pos.as_secs_f64() / dur.as_secs_f64();
23timeline_view(frac as f32, &TimelinePalette::default(), |f| {
24 Some(Msg::Command(MediaCommand::SeekTo { fraction: f }))
25})
26```2728---
2930Part of **llimphi** — see [llimphi](../../README.md).
README.md
llimphi-widget-timeline
Clickable progress / scrub bar.
The pattern is analogous to llimphi-widget-slider / -progress: the widget
keeps no state. The caller stores the current position in its Model, passes
the progress fraction (0.0..=1.0 = position/duration) and a
Fn(f32) -> Option<Msg> handler that receives the fraction where the user
clicked (absolute scrub, VLC style). The widget knows nothing about time or
duration: it only paints progress and reports where the click landed as a
fraction of the bar's width (on_click_at). Mapping that fraction to a concrete
seek is the app's job.
[ ██████████▏░░░░░░░░░░░░ ]
elapsed playhead rest
Typical use (a player):
let frac = pos.as_secs_f64() / dur.as_secs_f64();
timeline_view(frac as f32, &TimelinePalette::default(), |f| {
Some(Msg::Command(MediaCommand::SeekTo { fraction: f }))
})