Feat: UI / UX fixes

This commit is contained in:
2026-02-26 21:17:53 +01:00
parent f618f47811
commit 6b56655661
20 changed files with 268 additions and 169 deletions

View File

@@ -120,7 +120,7 @@ pub(super) fn handle_main_page(ctx: &mut InputContext, key: KeyEvent, ctrl: bool
KeyCode::Char(']') => ctx.dispatch(AppCommand::SpeedIncrease),
KeyCode::Char('L') => ctx.dispatch(AppCommand::OpenPatternModal(PatternField::Length)),
KeyCode::Char('S') => ctx.dispatch(AppCommand::OpenPatternModal(PatternField::Speed)),
KeyCode::Char('p') => ctx.dispatch(AppCommand::OpenModal(Modal::Preview)),
KeyCode::Char('p') => ctx.dispatch(AppCommand::OpenPreludeEditor),
KeyCode::Delete | KeyCode::Backspace => {
let (bank, pattern) = (ctx.app.editor_ctx.bank, ctx.app.editor_ctx.pattern);
if let Some(range) = ctx.app.editor_ctx.selection_range() {
@@ -231,9 +231,6 @@ pub(super) fn handle_main_page(ctx: &mut InputContext, key: KeyEvent, ctrl: bool
ctx.app.send_mute_state(ctx.seq_cmd_tx);
}
KeyCode::Char('d') => {
ctx.dispatch(AppCommand::OpenPreludeEditor);
}
KeyCode::Char('D') => {
ctx.dispatch(AppCommand::EvaluatePrelude);
}
KeyCode::Char('g') => {

View File

@@ -14,7 +14,7 @@ use arc_swap::ArcSwap;
use crossbeam_channel::Sender;
use crossterm::event::{KeyCode, KeyEvent, KeyEventKind, KeyModifiers, MouseEvent};
use ratatui::layout::Rect;
use std::sync::atomic::{AtomicBool, AtomicI64};
use std::sync::atomic::{AtomicBool, AtomicI64, Ordering};
use std::sync::Arc;
use std::time::{Duration, Instant};
@@ -87,7 +87,7 @@ fn handle_live_keys(ctx: &mut InputContext, key: &KeyEvent) -> bool {
match (key.code, key.kind) {
_ if !matches!(ctx.app.ui.modal, Modal::None) => false,
_ if ctx.app.page == Page::Script && ctx.app.script_editor.focused => false,
(KeyCode::Char('f'), KeyEventKind::Press) => {
(KeyCode::Char('f'), KeyEventKind::Press) if !key.modifiers.contains(KeyModifiers::ALT) => {
ctx.dispatch(AppCommand::ToggleLiveKeysFill);
true
}
@@ -97,11 +97,42 @@ fn handle_live_keys(ctx: &mut InputContext, key: &KeyEvent) -> bool {
fn handle_normal_input(ctx: &mut InputContext, key: KeyEvent) -> InputResult {
let ctrl = key.modifiers.contains(KeyModifiers::CONTROL);
let alt = key.modifiers.contains(KeyModifiers::ALT);
if key.code == KeyCode::F(12) && !ctx.app.plugin_mode {
if !ctx.app.playback.playing {
ctx.dispatch(AppCommand::TogglePlaying);
ctx.playing.store(true, Ordering::Relaxed);
}
let _ = ctx.seq_cmd_tx.send(SeqCommand::RestartAll);
return InputResult::Continue;
}
if ctx.app.panel.visible && ctx.app.panel.focus == PanelFocus::Side {
return panel::handle_panel_input(ctx, key);
}
if alt {
match key.code {
KeyCode::Up => {
ctx.dispatch(AppCommand::PrevPattern);
return InputResult::Continue;
}
KeyCode::Down => {
ctx.dispatch(AppCommand::NextPattern);
return InputResult::Continue;
}
KeyCode::Left | KeyCode::Char('b') => {
ctx.dispatch(AppCommand::PrevBank);
return InputResult::Continue;
}
KeyCode::Right | KeyCode::Char('f') => {
ctx.dispatch(AppCommand::NextBank);
return InputResult::Continue;
}
_ => {}
}
}
if ctrl {
let minimap_timed = MinimapMode::Timed(Instant::now() + Duration::from_millis(250));
match key.code {

View File

@@ -383,19 +383,19 @@ pub(super) fn handle_modal_input(ctx: &mut InputContext, key: KeyEvent) -> Input
KeyCode::Char('c') if ctrl => {
ctx.app.editor_ctx.editor.copy();
let text = ctx.app.editor_ctx.editor.yank_text();
if let Some(clip) = &mut ctx.app.clipboard {
if let Ok(mut clip) = arboard::Clipboard::new() {
let _ = clip.set_text(text);
}
}
KeyCode::Char('x') if ctrl => {
ctx.app.editor_ctx.editor.cut();
let text = ctx.app.editor_ctx.editor.yank_text();
if let Some(clip) = &mut ctx.app.clipboard {
if let Ok(mut clip) = arboard::Clipboard::new() {
let _ = clip.set_text(text);
}
}
KeyCode::Char('v') if ctrl => {
if let Some(clip) = &mut ctx.app.clipboard {
if let Ok(mut clip) = arboard::Clipboard::new() {
if let Ok(text) = clip.get_text() {
ctx.app.editor_ctx.editor.set_yank_text(text);
}
@@ -417,14 +417,6 @@ pub(super) fn handle_modal_input(ctx: &mut InputContext, key: KeyEvent) -> Input
crate::services::stack_preview::update_cache(&ctx.app.editor_ctx);
}
}
Modal::Preview => match key.code {
KeyCode::Esc | KeyCode::Char('p') => ctx.dispatch(AppCommand::CloseModal),
KeyCode::Left => ctx.dispatch(AppCommand::PrevStep),
KeyCode::Right => ctx.dispatch(AppCommand::NextStep),
KeyCode::Up => ctx.dispatch(AppCommand::StepUp),
KeyCode::Down => ctx.dispatch(AppCommand::StepDown),
_ => {}
},
Modal::PatternProps {
bank,
pattern,

View File

@@ -130,7 +130,7 @@ fn handle_click(ctx: &mut InputContext, col: u16, row: u16, term: Rect) {
ctx.dispatch(AppCommand::ClearStatus);
// If a modal is active, clicks outside dismiss it (except Editor/Preview)
// If a modal is active, clicks outside dismiss it (except Editor)
if !matches!(ctx.app.ui.modal, Modal::None) {
handle_modal_click(ctx, col, row, term);
return;
@@ -893,9 +893,6 @@ fn handle_modal_click(ctx: &mut InputContext, col: u16, row: u16, term: Rect) {
Modal::Editor => {
handle_editor_mouse(ctx, col, row, term, false);
}
Modal::Preview => {
// Don't dismiss preview on click
}
Modal::Confirm { .. } => {
handle_confirm_click(ctx, col, row, term);
}