Feat: documentation
This commit is contained in:
@@ -432,7 +432,7 @@ fn render_samples(frame: &mut Frame, app: &App, area: Rect) {
|
||||
dim,
|
||||
)));
|
||||
lines.push(Line::from(Span::styled(
|
||||
" Add folders containing .wav files",
|
||||
" Add folders containing audio files",
|
||||
dim,
|
||||
)));
|
||||
} else {
|
||||
|
||||
@@ -56,11 +56,19 @@ pub fn adjust_resolved_for_line(
|
||||
) -> Vec<(SourceSpan, String)> {
|
||||
resolved
|
||||
.iter()
|
||||
.filter_map(|(s, display)| clip_span(*s, line_start, line_len).map(|cs| (cs, display.clone())))
|
||||
.filter_map(|(s, display)| {
|
||||
clip_span(*s, line_start, line_len).map(|cs| (cs, display.clone()))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn render(frame: &mut Frame, app: &App, link: &LinkState, snapshot: &SequencerSnapshot, elapsed: Duration) {
|
||||
pub fn render(
|
||||
frame: &mut Frame,
|
||||
app: &App,
|
||||
link: &LinkState,
|
||||
snapshot: &SequencerSnapshot,
|
||||
elapsed: Duration,
|
||||
) {
|
||||
let term = frame.area();
|
||||
|
||||
let theme = theme::get();
|
||||
@@ -212,7 +220,11 @@ fn render_side_panel(frame: &mut Frame, app: &App, area: Rect) {
|
||||
});
|
||||
|
||||
let duration = sample.total_frames as f32 / app.audio.config.sample_rate;
|
||||
let ch_label = if sample.channels == 1 { "mono" } else { "stereo" };
|
||||
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);
|
||||
@@ -349,7 +361,9 @@ fn render_header(
|
||||
} else {
|
||||
theme.header.stats_fg
|
||||
};
|
||||
let dim = Style::new().bg(theme.header.stats_bg).fg(theme.header.stats_fg);
|
||||
let dim = Style::new()
|
||||
.bg(theme.header.stats_bg)
|
||||
.fg(theme.header.stats_fg);
|
||||
let stats_line = Line::from(vec![
|
||||
Span::styled(format!(" CPU {cpu_pct:.0}%"), dim.fg(cpu_color)),
|
||||
Span::styled(format!(" V:{voices} L:{peers} "), dim),
|
||||
@@ -407,9 +421,9 @@ fn render_footer(frame: &mut Frame, app: &App, area: Rect) {
|
||||
Page::Engine => vec![
|
||||
("Tab", "Section"),
|
||||
("←→", "Switch/Adjust"),
|
||||
("↑↓", "Navigate"),
|
||||
("Enter", "Select"),
|
||||
("A", "Add path"),
|
||||
("R", "Restart"),
|
||||
("h", "Hush"),
|
||||
("?", "Keys"),
|
||||
],
|
||||
Page::Options => vec![
|
||||
@@ -484,14 +498,18 @@ fn render_footer(frame: &mut Frame, app: &App, area: Rect) {
|
||||
frame.render_widget(footer, area);
|
||||
}
|
||||
|
||||
fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term: Rect) -> Option<Rect> {
|
||||
fn render_modal(
|
||||
frame: &mut Frame,
|
||||
app: &App,
|
||||
snapshot: &SequencerSnapshot,
|
||||
term: Rect,
|
||||
) -> Option<Rect> {
|
||||
let theme = theme::get();
|
||||
let user_words: HashSet<String> = app.dict.lock().keys().cloned().collect();
|
||||
let inner = match &app.ui.modal {
|
||||
Modal::None => return None,
|
||||
Modal::Confirm { action, selected } => {
|
||||
ConfirmModal::new("Confirm", &action.message(), *selected)
|
||||
.render_centered(frame, term)
|
||||
ConfirmModal::new("Confirm", &action.message(), *selected).render_centered(frame, term)
|
||||
}
|
||||
Modal::FileBrowser(state) => {
|
||||
use crate::state::file_browser::FileBrowserMode;
|
||||
@@ -577,26 +595,42 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
|
||||
} => {
|
||||
use crate::state::PatternPropsField;
|
||||
|
||||
let inner =
|
||||
ModalFrame::new(&format!(" Pattern B{:02}:P{:02} ", bank + 1, pattern + 1))
|
||||
.width(50)
|
||||
.height(12)
|
||||
.border_color(theme.modal.input)
|
||||
.render_centered(frame, term);
|
||||
let inner = ModalFrame::new(&format!(" Pattern B{:02}:P{:02} ", bank + 1, pattern + 1))
|
||||
.width(50)
|
||||
.height(12)
|
||||
.border_color(theme.modal.input)
|
||||
.render_centered(frame, term);
|
||||
|
||||
let speed_label = speed.label();
|
||||
let fields: Vec<(&str, &str, bool)> = vec![
|
||||
("Name", name.as_str(), *field == PatternPropsField::Name),
|
||||
("Length", length.as_str(), *field == PatternPropsField::Length),
|
||||
(
|
||||
"Length",
|
||||
length.as_str(),
|
||||
*field == PatternPropsField::Length,
|
||||
),
|
||||
("Speed", &speed_label, *field == PatternPropsField::Speed),
|
||||
("Quantization", quantization.label(), *field == PatternPropsField::Quantization),
|
||||
("Sync Mode", sync_mode.label(), *field == PatternPropsField::SyncMode),
|
||||
(
|
||||
"Quantization",
|
||||
quantization.label(),
|
||||
*field == PatternPropsField::Quantization,
|
||||
),
|
||||
(
|
||||
"Sync Mode",
|
||||
sync_mode.label(),
|
||||
*field == PatternPropsField::SyncMode,
|
||||
),
|
||||
];
|
||||
|
||||
render_props_form(frame, inner, &fields);
|
||||
|
||||
let hint_area = Rect::new(inner.x, inner.y + inner.height - 1, inner.width, 1);
|
||||
let hints = hint_line(&[("↑↓", "nav"), ("←→", "change"), ("Enter", "save"), ("Esc", "cancel")]);
|
||||
let hints = hint_line(&[
|
||||
("↑↓", "nav"),
|
||||
("←→", "change"),
|
||||
("Enter", "save"),
|
||||
("Esc", "cancel"),
|
||||
]);
|
||||
frame.render_widget(Paragraph::new(hints), hint_area);
|
||||
|
||||
inner
|
||||
@@ -625,7 +659,8 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
|
||||
lines
|
||||
};
|
||||
let key_lines = keys.len() as u16;
|
||||
let modal_height = (3 + desc_lines + 1 + key_lines + 2).min(term.height.saturating_sub(4));
|
||||
let modal_height =
|
||||
(3 + desc_lines + 1 + key_lines + 2).min(term.height.saturating_sub(4));
|
||||
|
||||
let title = if page_count > 1 {
|
||||
format!(" {} ({}/{}) ", app.page.name(), page_idx + 1, page_count)
|
||||
@@ -654,16 +689,13 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
|
||||
}
|
||||
let line = Line::from(vec![
|
||||
Span::raw(" "),
|
||||
Span::styled(
|
||||
format!("{:>8}", key),
|
||||
Style::new().fg(theme.hint.key),
|
||||
),
|
||||
Span::styled(
|
||||
format!(" {action}"),
|
||||
Style::new().fg(theme.hint.text),
|
||||
),
|
||||
Span::styled(format!("{:>8}", key), Style::new().fg(theme.hint.key)),
|
||||
Span::styled(format!(" {action}"), Style::new().fg(theme.hint.text)),
|
||||
]);
|
||||
frame.render_widget(Paragraph::new(line), Rect::new(inner.x + 1, y, inner.width.saturating_sub(2), 1));
|
||||
frame.render_widget(
|
||||
Paragraph::new(line),
|
||||
Rect::new(inner.x + 1, y, inner.width.saturating_sub(2), 1),
|
||||
);
|
||||
y += 1;
|
||||
}
|
||||
|
||||
@@ -677,7 +709,10 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
|
||||
}
|
||||
hints_vec.push(("Enter", "don't show again"));
|
||||
let hints = hint_line(&hints_vec);
|
||||
frame.render_widget(Paragraph::new(hints).alignment(Alignment::Center), hint_area);
|
||||
frame.render_widget(
|
||||
Paragraph::new(hints).alignment(Alignment::Center),
|
||||
hint_area,
|
||||
);
|
||||
|
||||
inner
|
||||
}
|
||||
@@ -702,7 +737,11 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
|
||||
let fields: Vec<(&str, &str, bool)> = vec![
|
||||
("Pulses", pulses.as_str(), *field == EuclideanField::Pulses),
|
||||
("Steps", steps.as_str(), *field == EuclideanField::Steps),
|
||||
("Rotation", rotation.as_str(), *field == EuclideanField::Rotation),
|
||||
(
|
||||
"Rotation",
|
||||
rotation.as_str(),
|
||||
*field == EuclideanField::Rotation,
|
||||
),
|
||||
];
|
||||
|
||||
render_props_form(frame, inner, &fields);
|
||||
@@ -723,7 +762,12 @@ fn render_modal(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, term
|
||||
}
|
||||
|
||||
let hint_area = Rect::new(inner.x, inner.y + inner.height - 1, inner.width, 1);
|
||||
let hints = hint_line(&[("↑↓", "nav"), ("←→", "adjust"), ("Enter", "apply"), ("Esc", "cancel")]);
|
||||
let hints = hint_line(&[
|
||||
("↑↓", "nav"),
|
||||
("←→", "adjust"),
|
||||
("Enter", "apply"),
|
||||
("Esc", "cancel"),
|
||||
]);
|
||||
frame.render_widget(Paragraph::new(hints), hint_area);
|
||||
|
||||
inner
|
||||
@@ -791,12 +835,7 @@ fn render_modal_preview(
|
||||
};
|
||||
|
||||
let resolved_display: Vec<(SourceSpan, String)> = trace
|
||||
.map(|t| {
|
||||
t.resolved
|
||||
.iter()
|
||||
.map(|(s, v)| (*s, v.display()))
|
||||
.collect()
|
||||
})
|
||||
.map(|t| t.resolved.iter().map(|(s, v)| (*s, v.display())).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut line_start = 0usize;
|
||||
@@ -804,21 +843,10 @@ fn render_modal_preview(
|
||||
.lines()
|
||||
.map(|line_str| {
|
||||
let tokens = if let Some(t) = trace {
|
||||
let exec = adjust_spans_for_line(
|
||||
&t.executed_spans,
|
||||
line_start,
|
||||
line_str.len(),
|
||||
);
|
||||
let sel = adjust_spans_for_line(
|
||||
&t.selected_spans,
|
||||
line_start,
|
||||
line_str.len(),
|
||||
);
|
||||
let res = adjust_resolved_for_line(
|
||||
&resolved_display,
|
||||
line_start,
|
||||
line_str.len(),
|
||||
);
|
||||
let exec = adjust_spans_for_line(&t.executed_spans, line_start, line_str.len());
|
||||
let sel = adjust_spans_for_line(&t.selected_spans, line_start, line_str.len());
|
||||
let res =
|
||||
adjust_resolved_for_line(&resolved_display, line_start, line_str.len());
|
||||
highlight_line_with_runtime(line_str, &exec, &sel, &res, user_words)
|
||||
} else {
|
||||
highlight_line_with_runtime(line_str, &[], &[], &[], user_words)
|
||||
@@ -898,12 +926,7 @@ fn render_modal_editor(
|
||||
}
|
||||
|
||||
let resolved_display: Vec<(SourceSpan, String)> = trace
|
||||
.map(|t| {
|
||||
t.resolved
|
||||
.iter()
|
||||
.map(|(s, v)| (*s, v.display()))
|
||||
.collect()
|
||||
})
|
||||
.map(|t| t.resolved.iter().map(|(s, v)| (*s, v.display())).collect())
|
||||
.unwrap_or_default();
|
||||
|
||||
let highlighter = |row: usize, line: &str| -> Vec<(Style, String, bool)> {
|
||||
@@ -919,8 +942,8 @@ fn render_modal_editor(
|
||||
highlight::highlight_line_with_runtime(line, &exec, &sel, &res, user_words)
|
||||
};
|
||||
|
||||
let show_search = app.editor_ctx.editor.search_active()
|
||||
|| !app.editor_ctx.editor.search_query().is_empty();
|
||||
let show_search =
|
||||
app.editor_ctx.editor.search_active() || !app.editor_ctx.editor.search_query().is_empty();
|
||||
|
||||
let reserved_lines = 1 + if show_search { 1 } else { 0 };
|
||||
let editor_height = inner.height.saturating_sub(reserved_lines);
|
||||
@@ -1061,10 +1084,7 @@ fn render_modal_keybindings(frame: &mut Frame, app: &App, scroll: usize, term: R
|
||||
height: 1,
|
||||
};
|
||||
let hints = hint_line(&[("↑↓", "scroll"), ("PgUp/Dn", "page"), ("Esc/?", "close")]);
|
||||
frame.render_widget(
|
||||
Paragraph::new(hints).alignment(Alignment::Right),
|
||||
hint_area,
|
||||
);
|
||||
frame.render_widget(Paragraph::new(hints).alignment(Alignment::Right), hint_area);
|
||||
|
||||
inner
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user