Feat: UI / UX improvements once more (mouse)

This commit is contained in:
2026-02-26 23:29:07 +01:00
parent 6b56655661
commit 0ecc4dae11
16 changed files with 680 additions and 99 deletions

View File

@@ -8,9 +8,10 @@ use ratatui::Frame;
use crate::app::App;
use crate::state::{DeviceKind, EngineSection, SettingKind};
use crate::theme;
use crate::state::{ScopeMode, SpectrumMode};
use crate::widgets::{
render_scroll_indicators, render_section_header, IndicatorAlign, Lissajous, Orientation, Scope,
Spectrum,
Spectrum, SpectrumStyle, Waveform,
};
pub fn layout(area: Rect) -> [Rect; 3] {
@@ -182,12 +183,28 @@ fn render_scope(frame: &mut Frame, app: &App, area: Rect) {
let inner = block.inner(area);
frame.render_widget(block, area);
let orientation = if app.audio.config.scope_vertical {
Orientation::Vertical
} else {
Orientation::Horizontal
};
let gain = viz_gain(&app.metrics.scope, &app.audio.config);
let scope = Scope::new(&app.metrics.scope)
.orientation(Orientation::Horizontal)
.color(theme.meter.low)
.gain(gain);
frame.render_widget(scope, inner);
match app.audio.config.scope_mode {
ScopeMode::Line => {
let scope = Scope::new(&app.metrics.scope)
.orientation(orientation)
.color(theme.meter.low)
.gain(gain);
frame.render_widget(scope, inner);
}
ScopeMode::Filled => {
let waveform = Waveform::new(&app.metrics.scope)
.orientation(orientation)
.color(theme.meter.low)
.gain(gain);
frame.render_widget(waveform, inner);
}
}
}
fn render_lissajous(frame: &mut Frame, app: &App, area: Rect) {
@@ -209,7 +226,8 @@ fn render_lissajous(frame: &mut Frame, app: &App, area: Rect) {
};
let lissajous = Lissajous::new(&app.metrics.scope, &app.metrics.scope_right)
.color(theme.meter.low)
.gain(gain);
.gain(gain)
.trails(app.audio.config.lissajous_trails);
frame.render_widget(lissajous, inner);
}
@@ -228,8 +246,15 @@ fn render_spectrum(frame: &mut Frame, app: &App, area: Rect) {
} else {
1.0
};
let style = match app.audio.config.spectrum_mode {
SpectrumMode::Bars => SpectrumStyle::Bars,
SpectrumMode::Line => SpectrumStyle::Line,
SpectrumMode::Filled => SpectrumStyle::Filled,
};
let spectrum = Spectrum::new(&app.metrics.spectrum)
.gain(gain);
.gain(gain)
.style(style)
.peaks(app.audio.config.spectrum_peaks);
frame.render_widget(spectrum, inner);
}

View File

@@ -12,7 +12,8 @@ use crate::engine::SequencerSnapshot;
use crate::state::MainLayout;
use crate::theme;
use crate::views::render::highlight_script_lines;
use crate::widgets::{Lissajous, Orientation, Scope, Spectrum, VuMeter};
use crate::state::{ScopeMode, SpectrumMode};
use crate::widgets::{Lissajous, Orientation, Scope, Spectrum, SpectrumStyle, VuMeter, Waveform};
pub fn layout(area: Rect) -> [Rect; 3] {
Layout::horizontal([
@@ -499,12 +500,28 @@ pub(crate) fn render_scope(frame: &mut Frame, app: &App, area: Rect, orientation
let inner = block.inner(area);
frame.render_widget(block, area);
let orientation = if app.audio.config.scope_vertical {
Orientation::Vertical
} else {
orientation
};
let gain = viz_gain(&app.metrics.scope, &app.audio.config);
let scope = Scope::new(&app.metrics.scope)
.orientation(orientation)
.color(theme.meter.low)
.gain(gain);
frame.render_widget(scope, inner);
match app.audio.config.scope_mode {
ScopeMode::Line => {
let scope = Scope::new(&app.metrics.scope)
.orientation(orientation)
.color(theme.meter.low)
.gain(gain);
frame.render_widget(scope, inner);
}
ScopeMode::Filled => {
let waveform = Waveform::new(&app.metrics.scope)
.orientation(orientation)
.color(theme.meter.low)
.gain(gain);
frame.render_widget(waveform, inner);
}
}
}
pub(crate) fn render_spectrum(frame: &mut Frame, app: &App, area: Rect) {
@@ -520,8 +537,15 @@ pub(crate) fn render_spectrum(frame: &mut Frame, app: &App, area: Rect) {
} else {
1.0
};
let style = match app.audio.config.spectrum_mode {
SpectrumMode::Bars => SpectrumStyle::Bars,
SpectrumMode::Line => SpectrumStyle::Line,
SpectrumMode::Filled => SpectrumStyle::Filled,
};
let spectrum = Spectrum::new(&app.metrics.spectrum)
.gain(gain);
.gain(gain)
.style(style)
.peaks(app.audio.config.spectrum_peaks);
frame.render_widget(spectrum, inner);
}
@@ -542,7 +566,8 @@ pub(crate) fn render_lissajous(frame: &mut Frame, app: &App, area: Rect) {
};
let lissajous = Lissajous::new(&app.metrics.scope, &app.metrics.scope_right)
.color(theme.meter.low)
.gain(gain);
.gain(gain)
.trails(app.audio.config.lissajous_trails);
frame.render_widget(lissajous, inner);
}

View File

@@ -371,8 +371,9 @@ fn render_header(
let pad = Padding::vertical(1);
let [transport_area, live_area, tempo_area, bank_area, pattern_area, stats_area] =
let [logo_area, transport_area, live_area, tempo_area, bank_area, pattern_area, stats_area] =
Layout::horizontal([
Constraint::Length(5),
Constraint::Min(12),
Constraint::Length(9),
Constraint::Min(14),
@@ -382,6 +383,18 @@ fn render_header(
])
.areas(area);
// Logo
let logo_style = Style::new()
.bg(theme.header.bank_bg)
.fg(theme.ui.accent)
.add_modifier(Modifier::BOLD);
frame.render_widget(
Paragraph::new("\u{28ff}")
.block(Block::default().padding(pad).style(logo_style))
.alignment(Alignment::Center),
logo_area,
);
// Transport block
let (transport_bg, transport_text) = if app.playback.playing {
(theme.status.playing_bg, " ▶ PLAYING ")