Feat: early mouse support

This commit is contained in:
2026-02-14 16:26:29 +01:00
parent b2871ac251
commit 10ca567ac5
23 changed files with 1256 additions and 285 deletions

View File

@@ -13,15 +13,18 @@ use crate::widgets::{render_search_bar, CategoryItem, CategoryList};
use CatEntry::{Category, Section};
pub fn render(frame: &mut Frame, app: &App, area: Rect) {
pub fn layout(area: Rect) -> (Rect, [Rect; 2]) {
let [header_area, body_area] =
Layout::vertical([Constraint::Length(5), Constraint::Fill(1)]).areas(area);
let body = Layout::horizontal([Constraint::Length(16), Constraint::Fill(1)]).areas(body_area);
(header_area, body)
}
pub fn render(frame: &mut Frame, app: &App, area: Rect) {
let (header_area, [cat_area, words_area]) = layout(area);
render_header(frame, header_area);
let [cat_area, words_area] =
Layout::horizontal([Constraint::Length(16), Constraint::Fill(1)]).areas(body_area);
let is_searching = !app.ui.dict_search_query.is_empty();
render_categories(frame, app, cat_area, is_searching);
render_words(frame, app, words_area, is_searching);

View File

@@ -12,13 +12,17 @@ use crate::widgets::{
render_scroll_indicators, render_section_header, IndicatorAlign, Orientation, Scope, Spectrum,
};
pub fn render(frame: &mut Frame, app: &App, area: Rect) {
let [left_col, _, right_col] = Layout::horizontal([
pub fn layout(area: Rect) -> [Rect; 3] {
Layout::horizontal([
Constraint::Percentage(55),
Constraint::Length(2),
Constraint::Percentage(45),
])
.areas(area);
.areas(area)
}
pub fn render(frame: &mut Frame, app: &App, area: Rect) {
let [left_col, _, right_col] = layout(area);
render_settings_section(frame, app, left_col);
render_visualizers(frame, app, right_col);
@@ -185,7 +189,7 @@ fn truncate_name(name: &str, max_len: usize) -> String {
}
}
fn list_height(item_count: usize) -> u16 {
pub fn list_height(item_count: usize) -> u16 {
let visible = item_count.min(5) as u16;
if item_count > 5 {
visible + 1
@@ -194,7 +198,7 @@ fn list_height(item_count: usize) -> u16 {
}
}
fn devices_section_height(app: &App) -> u16 {
pub fn devices_section_height(app: &App) -> u16 {
let output_h = list_height(app.audio.output_devices.len());
let input_h = list_height(app.audio.input_devices.len());
3 + output_h.max(input_h)

View File

@@ -91,9 +91,12 @@ impl CodeHighlighter for ForthHighlighter {
}
}
pub fn layout(area: Rect) -> [Rect; 2] {
Layout::horizontal([Constraint::Length(24), Constraint::Fill(1)]).areas(area)
}
pub fn render(frame: &mut Frame, app: &App, area: Rect) {
let [topics_area, content_area] =
Layout::horizontal([Constraint::Length(24), Constraint::Fill(1)]).areas(area);
let [topics_area, content_area] = layout(area);
render_topics(frame, app, topics_area);
render_content(frame, app, content_area);

View File

@@ -9,15 +9,19 @@ use crate::state::MainLayout;
use crate::theme;
use crate::widgets::{ActivePatterns, Orientation, Scope, Spectrum, VuMeter};
pub fn render(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, area: Rect) {
let [patterns_area, _, main_area, _, vu_area] = Layout::horizontal([
pub fn layout(area: Rect) -> [Rect; 5] {
Layout::horizontal([
Constraint::Length(13),
Constraint::Length(2),
Constraint::Fill(1),
Constraint::Length(2),
Constraint::Length(10),
])
.areas(area);
.areas(area)
}
pub fn render(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, area: Rect) {
let [patterns_area, _, main_area, _, vu_area] = layout(area);
let show_scope = app.audio.config.show_scope;
let show_spectrum = app.audio.config.show_spectrum;

View File

@@ -206,26 +206,7 @@ pub fn render(frame: &mut Frame, app: &App, link: &LinkState, area: Rect) {
let total_lines = lines.len();
let max_visible = padded.height as usize;
let focus_line: usize = match focus {
OptionsFocus::ColorScheme => 2,
OptionsFocus::HueRotation => 3,
OptionsFocus::RefreshRate => 4,
OptionsFocus::RuntimeHighlight => 5,
OptionsFocus::ShowScope => 6,
OptionsFocus::ShowSpectrum => 7,
OptionsFocus::ShowCompletion => 8,
OptionsFocus::LinkEnabled => 12,
OptionsFocus::StartStopSync => 13,
OptionsFocus::Quantum => 14,
OptionsFocus::MidiOutput0 => 25,
OptionsFocus::MidiOutput1 => 26,
OptionsFocus::MidiOutput2 => 27,
OptionsFocus::MidiOutput3 => 28,
OptionsFocus::MidiInput0 => 32,
OptionsFocus::MidiInput1 => 33,
OptionsFocus::MidiInput2 => 34,
OptionsFocus::MidiInput3 => 35,
};
let focus_line = focus.line_index();
let scroll_offset = if total_lines <= max_visible {
0

View File

@@ -13,13 +13,12 @@ use crate::widgets::{render_scroll_indicators, IndicatorAlign};
const MIN_ROW_HEIGHT: u16 = 1;
pub fn layout(area: Rect) -> [Rect; 3] {
Layout::horizontal([Constraint::Fill(1), Constraint::Length(1), Constraint::Fill(1)]).areas(area)
}
pub fn render(frame: &mut Frame, app: &App, snapshot: &SequencerSnapshot, area: Rect) {
let [banks_area, gap, patterns_area] = Layout::horizontal([
Constraint::Fill(1),
Constraint::Length(1),
Constraint::Fill(1),
])
.areas(area);
let [banks_area, gap, patterns_area] = layout(area);
render_banks(frame, app, snapshot, banks_area);
// gap is just empty space

View File

@@ -1,5 +1,5 @@
use std::collections::HashSet;
use std::time::{Duration, Instant};
use std::time::Duration;
use ratatui::layout::{Alignment, Constraint, Layout, Rect};
use ratatui::style::{Modifier, Style};
@@ -134,13 +134,7 @@ pub fn render(frame: &mut Frame, app: &App, link: &LinkState, snapshot: &Sequenc
render_footer(frame, app, footer_area);
let modal_area = render_modal(frame, app, snapshot, term);
let show_minimap = app
.ui
.minimap_until
.map(|until| Instant::now() < until)
.unwrap_or(false);
if show_minimap {
if app.ui.show_minimap() {
let tiles: Vec<NavTile> = Page::ALL
.iter()
.map(|p| {