Feat: rework audio sample library viewer

This commit is contained in:
2026-02-05 18:37:32 +01:00
parent 636126e7c6
commit 3fe837653b
7 changed files with 496 additions and 63 deletions

View File

@@ -170,12 +170,49 @@ fn render_side_panel(frame: &mut Frame, app: &App, area: Rect) {
let focused = app.panel.focus == PanelFocus::Side;
match &app.panel.side {
Some(SidePanel::SampleBrowser(state)) => {
let [tree_area, preview_area] =
Layout::vertical([Constraint::Fill(1), Constraint::Length(6)]).areas(area);
let entries = state.entries();
SampleBrowser::new(&entries, state.cursor)
.scroll_offset(state.scroll_offset)
.search(&state.search_query, state.search_active)
.focused(focused)
.render(frame, area);
.render(frame, tree_area);
if let Some(sample) = state
.sample_key()
.and_then(|key| app.audio.sample_registry.as_ref()?.get(&key))
.filter(|s| s.frame_count >= s.total_frames)
{
use crate::widgets::Waveform;
use std::cell::RefCell;
thread_local! {
static MONO_BUF: RefCell<Vec<f32>> = const { RefCell::new(Vec::new()) };
}
let [wave_area, info_area] =
Layout::vertical([Constraint::Fill(1), Constraint::Length(1)])
.areas(preview_area);
MONO_BUF.with(|buf| {
let mut buf = buf.borrow_mut();
let channels = sample.channels as usize;
let frame_count = sample.frame_count as usize;
buf.clear();
buf.reserve(frame_count);
for i in 0..frame_count {
buf.push(sample.frames[i * channels]);
}
frame.render_widget(Waveform::new(&buf), wave_area);
});
let duration = sample.total_frames as f32 / app.audio.config.sample_rate;
let ch_label = if sample.channels == 1 { "mono" } else { "stereo" };
let info = Paragraph::new(format!(" {duration:.1}s · {ch_label}"))
.style(Style::new().fg(theme::get().ui.text_dim));
frame.render_widget(info, info_area);
}
}
None => {}
}