Feat: WIP pattern view redesign
This commit is contained in:
@@ -11,8 +11,6 @@ use crate::views::{dict_view, engine_view, help_view, main_view, patterns_view};
|
||||
|
||||
use super::InputContext;
|
||||
|
||||
const STEPS_PER_PAGE: usize = 32;
|
||||
|
||||
pub fn handle_mouse(ctx: &mut InputContext, mouse: MouseEvent, term: Rect) {
|
||||
let kind = mouse.kind;
|
||||
let col = mouse.column;
|
||||
@@ -156,7 +154,7 @@ fn handle_scroll(ctx: &mut InputContext, col: u16, row: u16, term: Rect, up: boo
|
||||
}
|
||||
}
|
||||
Page::Patterns => {
|
||||
let [banks_area, _gap, patterns_area] = patterns_view::layout(body);
|
||||
let [banks_area, patterns_area, _] = patterns_view::layout(body);
|
||||
|
||||
if contains(banks_area, col, row) {
|
||||
if up {
|
||||
@@ -304,13 +302,7 @@ fn handle_main_click(ctx: &mut InputContext, col: u16, row: u16, area: Rect) {
|
||||
return;
|
||||
}
|
||||
|
||||
let pattern = ctx.app.current_edit_pattern();
|
||||
let has_viz = ctx.app.audio.config.show_scope
|
||||
|| ctx.app.audio.config.show_spectrum
|
||||
|| ctx.app.audio.config.show_preview;
|
||||
let seq_h = main_view::sequencer_height(pattern.length, ctx.app.editor_ctx.step);
|
||||
let (_, sequencer_area) =
|
||||
main_view::viz_seq_split(main_area, ctx.app.audio.config.layout, has_viz, seq_h);
|
||||
let sequencer_area = main_view::sequencer_rect(ctx.app, main_area);
|
||||
|
||||
if !contains(sequencer_area, col, row) {
|
||||
return;
|
||||
@@ -324,9 +316,10 @@ fn handle_main_click(ctx: &mut InputContext, col: u16, row: u16, area: Rect) {
|
||||
fn hit_test_grid(ctx: &InputContext, col: u16, row: u16, area: Rect) -> Option<usize> {
|
||||
let pattern = ctx.app.current_edit_pattern();
|
||||
let length = pattern.length;
|
||||
let page = ctx.app.editor_ctx.step / STEPS_PER_PAGE;
|
||||
let page_start = page * STEPS_PER_PAGE;
|
||||
let steps_on_page = (page_start + STEPS_PER_PAGE).min(length) - page_start;
|
||||
let spp = ctx.app.editor_ctx.steps_per_page.get();
|
||||
let page = ctx.app.editor_ctx.step / spp;
|
||||
let page_start = page * spp;
|
||||
let steps_on_page = (page_start + spp).min(length) - page_start;
|
||||
|
||||
for (tile_rect, step_offset) in main_view::grid_layout(area, steps_on_page) {
|
||||
if contains(tile_rect, col, row) {
|
||||
@@ -343,7 +336,7 @@ fn hit_test_grid(ctx: &InputContext, col: u16, row: u16, area: Rect) -> Option<u
|
||||
// --- Patterns page ---
|
||||
|
||||
fn handle_patterns_click(ctx: &mut InputContext, col: u16, row: u16, area: Rect) {
|
||||
let [banks_area, _gap, patterns_area] = patterns_view::layout(area);
|
||||
let [banks_area, patterns_area, _] = patterns_view::layout(area);
|
||||
|
||||
if contains(banks_area, col, row) {
|
||||
if let Some(bank) = hit_test_patterns_list(ctx, col, row, banks_area, true) {
|
||||
@@ -366,9 +359,9 @@ fn hit_test_patterns_list(
|
||||
is_banks: bool,
|
||||
) -> Option<usize> {
|
||||
use crate::model::{MAX_BANKS, MAX_PATTERNS};
|
||||
use ratatui::widgets::{Block, Borders};
|
||||
|
||||
let [_title, inner] =
|
||||
Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]).areas(area);
|
||||
let inner = Block::default().borders(Borders::ALL).inner(area);
|
||||
|
||||
let max_items = if is_banks { MAX_BANKS } else { MAX_PATTERNS };
|
||||
let cursor = if is_banks {
|
||||
@@ -377,7 +370,14 @@ fn hit_test_patterns_list(
|
||||
ctx.app.patterns_nav.pattern_cursor
|
||||
};
|
||||
|
||||
let max_visible = (inner.height as usize).max(1);
|
||||
let available = inner.height as usize;
|
||||
// Patterns column: cursor row takes 2 lines
|
||||
let max_visible = if is_banks {
|
||||
available.max(1)
|
||||
} else {
|
||||
available.saturating_sub(1).max(1)
|
||||
};
|
||||
|
||||
let scroll_offset = if max_items <= max_visible {
|
||||
0
|
||||
} else {
|
||||
@@ -387,19 +387,34 @@ fn hit_test_patterns_list(
|
||||
};
|
||||
|
||||
let visible_count = max_items.min(max_visible);
|
||||
let row_height = (inner.height / visible_count as u16).max(1);
|
||||
|
||||
if row < inner.y {
|
||||
return None;
|
||||
}
|
||||
|
||||
let relative_y = row - inner.y;
|
||||
let visible_idx = (relative_y / row_height) as usize;
|
||||
|
||||
if visible_idx < visible_count {
|
||||
let idx = scroll_offset + visible_idx;
|
||||
if idx < max_items {
|
||||
return Some(idx);
|
||||
if is_banks {
|
||||
let row_height = (inner.height / visible_count as u16).max(1);
|
||||
let relative_y = row - inner.y;
|
||||
let visible_idx = (relative_y / row_height) as usize;
|
||||
if visible_idx < visible_count {
|
||||
let idx = scroll_offset + visible_idx;
|
||||
if idx < max_items {
|
||||
return Some(idx);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let mut y = inner.y;
|
||||
for visible_idx in 0..visible_count {
|
||||
let idx = scroll_offset + visible_idx;
|
||||
let row_h: u16 = if idx == cursor { 2 } else { 1 };
|
||||
let actual_h = row_h.min(inner.y + inner.height - y);
|
||||
if row >= y && row < y + actual_h {
|
||||
return Some(idx);
|
||||
}
|
||||
y += actual_h;
|
||||
if y >= inner.y + inner.height {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user