chain word and better save/load UI
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use cagire_ratatui::ListSelect;
|
||||
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
|
||||
use ratatui::style::{Color, Modifier, Style};
|
||||
use ratatui::text::{Line, Span};
|
||||
@@ -44,8 +45,10 @@ fn render_audio_section(frame: &mut Frame, app: &App, area: Rect) {
|
||||
height: inner.height.saturating_sub(1),
|
||||
};
|
||||
|
||||
let devices_height = devices_section_height(app);
|
||||
|
||||
let [devices_area, _, settings_area, _, samples_area] = Layout::vertical([
|
||||
Constraint::Length(4),
|
||||
Constraint::Length(devices_height),
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(8),
|
||||
Constraint::Length(1),
|
||||
@@ -58,39 +61,57 @@ fn render_audio_section(frame: &mut Frame, app: &App, area: Rect) {
|
||||
render_samples(frame, app, samples_area);
|
||||
}
|
||||
|
||||
fn list_height(item_count: usize) -> u16 {
|
||||
let visible = item_count.min(5) as u16;
|
||||
if item_count > 5 { visible + 1 } else { visible }
|
||||
}
|
||||
|
||||
fn devices_section_height(app: &App) -> u16 {
|
||||
// header(1) + "Output" label(1) + output list + "Input" label(1) + input list
|
||||
1 + 1 + list_height(app.audio.output_devices.len())
|
||||
+ 1 + list_height(app.audio.input_devices.len())
|
||||
}
|
||||
|
||||
fn render_devices(frame: &mut Frame, app: &App, area: Rect) {
|
||||
let header_style = Style::new()
|
||||
.fg(Color::Rgb(100, 160, 180))
|
||||
.add_modifier(Modifier::BOLD);
|
||||
|
||||
let [header_area, content_area] =
|
||||
Layout::vertical([Constraint::Length(1), Constraint::Min(1)]).areas(area);
|
||||
|
||||
frame.render_widget(Paragraph::new("Devices").style(header_style), header_area);
|
||||
|
||||
let highlight = Style::new().fg(Color::Yellow).add_modifier(Modifier::BOLD);
|
||||
let normal = Style::new().fg(Color::White);
|
||||
let label_style = Style::new().fg(Color::Rgb(120, 125, 135));
|
||||
|
||||
let output_name = truncate_name(app.audio.current_output_device_name(), 35);
|
||||
let input_name = truncate_name(app.audio.current_input_device_name(), 35);
|
||||
let output_h = list_height(app.audio.output_devices.len());
|
||||
let input_h = list_height(app.audio.input_devices.len());
|
||||
|
||||
let output_focused = app.audio.focus == AudioFocus::OutputDevice;
|
||||
let input_focused = app.audio.focus == AudioFocus::InputDevice;
|
||||
let [header_area, output_label_area, output_list_area, input_label_area, input_list_area] =
|
||||
Layout::vertical([
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(output_h),
|
||||
Constraint::Length(1),
|
||||
Constraint::Length(input_h),
|
||||
])
|
||||
.areas(area);
|
||||
|
||||
let rows = vec![
|
||||
Row::new(vec![
|
||||
Span::styled("Output", label_style),
|
||||
render_selector(&output_name, output_focused, highlight, normal),
|
||||
]),
|
||||
Row::new(vec![
|
||||
Span::styled("Input", label_style),
|
||||
render_selector(&input_name, input_focused, highlight, normal),
|
||||
]),
|
||||
];
|
||||
frame.render_widget(Paragraph::new("Devices").style(header_style), header_area);
|
||||
frame.render_widget(Paragraph::new(Span::styled("Output", label_style)), output_label_area);
|
||||
frame.render_widget(Paragraph::new(Span::styled("Input", label_style)), input_label_area);
|
||||
|
||||
let table = Table::new(rows, [Constraint::Length(8), Constraint::Fill(1)]);
|
||||
frame.render_widget(table, content_area);
|
||||
let output_items: Vec<String> = app.audio.output_devices.iter()
|
||||
.map(|d| truncate_name(&d.name, 35))
|
||||
.collect();
|
||||
let output_selected = app.audio.current_output_device_index();
|
||||
ListSelect::new(&output_items, output_selected, app.audio.output_list.cursor)
|
||||
.focused(app.audio.focus == AudioFocus::OutputDevice)
|
||||
.scroll_offset(app.audio.output_list.scroll_offset)
|
||||
.render(frame, output_list_area);
|
||||
|
||||
let input_items: Vec<String> = app.audio.input_devices.iter()
|
||||
.map(|d| truncate_name(&d.name, 35))
|
||||
.collect();
|
||||
let input_selected = app.audio.current_input_device_index();
|
||||
ListSelect::new(&input_items, input_selected, app.audio.input_list.cursor)
|
||||
.focused(app.audio.focus == AudioFocus::InputDevice)
|
||||
.scroll_offset(app.audio.input_list.scroll_offset)
|
||||
.render(frame, input_list_area);
|
||||
}
|
||||
|
||||
fn render_settings(frame: &mut Frame, app: &App, area: Rect) {
|
||||
|
||||
Reference in New Issue
Block a user