wip: command palette

This commit is contained in:
🪞👃🪞 2024-07-12 15:39:38 +03:00
parent 6a738375e2
commit 145827913a
4 changed files with 137 additions and 15 deletions

View file

@ -46,7 +46,11 @@ fn handle_device (state: &mut App, e: &AppEvent) -> Usually<bool> {
.map(|x|x.unwrap_or(false))
}
const KEYMAP_FOCUS: &'static [KeyBinding<App>] = keymap!(App {
pub const KEYMAP_FOCUS: &'static [KeyBinding<App>] = keymap!(App {
[Char(';'), NONE, "command", "open command palette", |app: &mut App| {
app.modal = Some(Box::new(crate::view::HelpModal::new()));
Ok(true)
}],
[Tab, NONE, "focus_next", "focus next area", focus_next],
[Tab, SHIFT, "focus_prev", "focus previous area", focus_prev],
[Esc, NONE, "focus_exit", "unfocus", |app: &mut App|{
@ -59,8 +63,8 @@ const KEYMAP_FOCUS: &'static [KeyBinding<App>] = keymap!(App {
}],
});
const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
[F(1), NONE, "help_toggle", "toggle help", |_: &mut App| {Ok(true)}],
pub const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
//[F(1), NONE, "help_toggle", "toggle help", |_: &mut App| {Ok(true)}],
[Up, NONE, "focus_prev", "focus previous area", |app: &mut App|match app.track_cursor {
0 => {app.section = AppSection::Arranger;Ok(true)},
@ -88,20 +92,20 @@ const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
Ok(true)
}],
[Char('+'), NONE, "quant_inc", "Quantize coarser", |app: &mut App| {
[Char('+'), NONE, "quant_inc", "quantize coarser", |app: &mut App| {
app.transport.quant = next_note_length(app.transport.quant);
Ok(true)
}],
[Char('_'), NONE, "quant_dec", "Quantize finer", |app: &mut App| {
[Char('_'), NONE, "quant_dec", "quantize finer", |app: &mut App| {
app.transport.quant = prev_note_length(app.transport.quant);
Ok(true)
}],
[Char('='), NONE, "zoom_in", "Zoom in", |app: &mut App| {
[Char('='), NONE, "zoom_in", "show fewer ticks per block", |app: &mut App| {
app.seq_buf.time_zoom = prev_note_length(app.seq_buf.time_zoom);
Ok(true)
}],
[Char('-'), NONE, "zoom_out", "Zoom out", |app: &mut App| {
[Char('-'), NONE, "zoom_out", "show more ticks per block", |app: &mut App| {
app.seq_buf.time_zoom = next_note_length(app.seq_buf.time_zoom);
Ok(true)
}],

View file

@ -5,6 +5,20 @@ pub(crate) use ratatui::layout::Rect;
pub(crate) use ratatui::buffer::{Buffer, Cell};
use ratatui::widgets::WidgetRef;
pub fn fill_fg (buf: &mut Buffer, area: Rect, color: Color) {
let Rect { x, y, width, height } = area;
for y in y..y+height {
if y >= buf.area.height {
break
}
for x in x..x+width {
if x >= buf.area.width {
break
}
buf.get_mut(x, y).set_fg(color);
}
}
}
pub fn fill_bg (buf: &mut Buffer, area: Rect, color: Color) {
let Rect { x, y, width, height } = area;
for y in y..y+height {
@ -19,6 +33,20 @@ pub fn fill_bg (buf: &mut Buffer, area: Rect, color: Color) {
}
}
}
pub fn fill_char (buf: &mut Buffer, area: Rect, c: char) {
let Rect { x, y, width, height } = area;
for y in y..y+height {
if y >= buf.area.height {
break
}
for x in x..x+width {
if x >= buf.area.width {
break
}
buf.get_mut(x, y).set_char(c);
}
}
}
pub trait Blit {
// Render something to X, Y coordinates in a buffer, ignoring width/height.

View file

@ -1,18 +1,20 @@
pub mod chain;
pub mod arranger;
pub mod sequencer;
pub mod transport;
pub mod plugin;
pub mod border;
pub mod theme;
pub mod chain;
pub mod help;
pub mod plugin;
pub mod sequencer;
pub mod split;
pub mod theme;
pub mod transport;
pub use self::split::*;
pub use self::border::*;
pub use self::theme::*;
pub use self::arranger::*;
pub use self::border::*;
pub use self::chain::ChainView;
pub use self::help::*;
pub use self::sequencer::{SequencerView, BufferedSequencerView};
pub use self::split::*;
pub use self::theme::*;
use crate::{render, App, core::*};

88
src/view/help.rs Normal file
View file

@ -0,0 +1,88 @@
use crate::{core::*, view::*};
pub struct HelpModal {
cursor: usize,
search: Option<String>,
}
impl HelpModal {
pub fn new () -> Self {
Self { cursor: 0, search: None }
}
}
render!(HelpModal |self, buf, area|{
for cell in buf.content.iter_mut() {
cell.bg = ratatui::style::Color::Rgb(44,44,44);
cell.fg = ratatui::style::Color::Rgb(88,88,88);
cell.modifier = ratatui::style::Modifier::DIM;
}
let width = 64.min(area.width * 3 / 5);
let height = 20.min(area.width * 3 / 5);
let x = area.x + (area.width - width) / 2;
let y = area.y + (area.height - height) / 2;
let area = Rect { x, y, width, height };
fill_fg(buf, area, Color::Reset);
fill_bg(buf, area, Nord::bg_lo(true, true));
fill_char(buf, area, ' ');
let x = area.x + 2;
let y = area.y + 1;
"Command:"
.blit(buf, x, y, Some(Style::default().bold()))?;
" ".repeat(area.width as usize - 13)
.blit(buf, x + 9, y, Some(Style::default().bg(Color::Reset)))?;
if let Some(search) = self.search.as_ref() {
search.blit(buf, x + 9, y, Some(Style::default().not_dim()))?;
}
let y = y + 1;
fill_char(buf, Rect { y, height: 1, ..area }, '-');
let y = y + 1;
for i in 0..height-3 {
let y = y + i;
if let Some(command) = crate::control::KEYMAP_FOCUS.get(i as usize) {
format!("{:?}", command.0).blit(buf, x, y, Some(Style::default().bold()))?;
command.2.blit(buf, x + 11, y, Some(Style::default().bold()))?;
command.3.blit(buf, x + 26, y, None)?;
} else if let Some(command) = crate::control::KEYMAP.get((i as usize) - crate::control::KEYMAP_FOCUS.len()) {
format!("{:?}", command.0).blit(buf, x, y, Some(Style::default().bold()))?;
command.2.blit(buf, x + 11, y, Some(Style::default().bold()))?;
command.3.blit(buf, x + 26, y, None)?;
} else {
break
}
}
let hi_area = Rect { x: area.x + 1, width: area.width - 2, y: area.y + 3 + self.cursor as u16, height: 1 };
fill_bg(buf, hi_area, Nord::bg_hi(true, true));
fill_fg(buf, hi_area, Color::Reset);
Lozenge(Style::default()).draw(buf, area)
});
handle!(HelpModal |self, e| {
Ok(handle_keymap(self, e, KEYMAP_HELP)? || match e {
AppEvent::Input(Event::Key(KeyEvent {
code: KeyCode::Char(c),
modifiers: KeyModifiers::NONE, ..
})) => {
if self.search.is_none() {
self.search = Some(String::new());
}
self.search.as_mut().unwrap().push(*c);
false
},
_ => false
})
});
pub const KEYMAP_HELP: &'static [KeyBinding<HelpModal>] = keymap!(HelpModal {
[Esc, NONE, "help_close", "close help dialog", |_: &mut HelpModal|{
Ok(true)
}],
[Up, NONE, "help_prev", "select previous command", |modal: &mut HelpModal|{
modal.cursor = modal.cursor.saturating_sub(1);
Ok(false)
}],
[Down, NONE, "help_next", "select next command", |modal: &mut HelpModal|{
modal.cursor = modal.cursor + 1;
Ok(false)
}],
});