mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: command palette
This commit is contained in:
parent
6a738375e2
commit
145827913a
4 changed files with 137 additions and 15 deletions
|
|
@ -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)
|
||||
}],
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
18
src/view.rs
18
src/view.rs
|
|
@ -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
88
src/view/help.rs
Normal 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)
|
||||
}],
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue