mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
add Exit trait to modals
This commit is contained in:
parent
0cc8d88e5f
commit
33e5f47526
6 changed files with 67 additions and 33 deletions
|
|
@ -47,7 +47,7 @@ impl AppPaths {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct SetupModal(pub Option<Arc<XdgApp>>);
|
||||
pub struct SetupModal(pub Option<Arc<XdgApp>>, pub bool);
|
||||
|
||||
render!(SetupModal |self, buf, area| {
|
||||
for cell in buf.content.iter_mut() {
|
||||
|
|
@ -83,9 +83,17 @@ handle!(SetupModal |self, e| {
|
|||
..
|
||||
})) = e {
|
||||
AppPaths::new(&self.0.as_ref().unwrap())?.create()?;
|
||||
self.0 = None;
|
||||
self.exit();
|
||||
Ok(true)
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
});
|
||||
impl Exit for SetupModal {
|
||||
fn exited (&self) -> bool {
|
||||
self.1
|
||||
}
|
||||
fn exit (&mut self) {
|
||||
self.1 = true
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,9 @@ handle!{
|
|||
App |self, e| {
|
||||
if let Some(ref mut modal) = self.modal {
|
||||
if modal.handle(e)? {
|
||||
self.modal = None;
|
||||
if modal.exited() {
|
||||
self.modal = None;
|
||||
}
|
||||
return Ok(true)
|
||||
};
|
||||
}
|
||||
|
|
@ -145,10 +147,12 @@ pub const KEYMAP: &'static [KeyBinding<App>] = keymap!(App {
|
|||
|
||||
fn focus_next (app: &mut App) -> Usually<bool> {
|
||||
app.section.next();
|
||||
app.transport.focused = app.section == AppSection::Transport;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn focus_prev (app: &mut App) -> Usually<bool> {
|
||||
app.section.prev();
|
||||
app.transport.focused = app.section == AppSection::Transport;
|
||||
Ok(true)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,6 +41,14 @@ pub trait Component: Render + Handle + Sync {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Exit: Component {
|
||||
fn exited (&self) -> bool;
|
||||
fn exit (&mut self);
|
||||
fn boxed (self) -> Box<dyn Exit> where Self: Sized + 'static {
|
||||
Box::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Anything that implements `Render` + `Handle` can be used as a UI component.
|
||||
impl<T: Render + Handle + Sync> Component for T {}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ pub struct App {
|
|||
/// Display buffer for sequencer
|
||||
pub seq_buf: BufferedSequencerView,
|
||||
/// Optional modal dialog
|
||||
pub modal: Option<Box<dyn Component>>,
|
||||
pub modal: Option<Box<dyn Exit>>,
|
||||
/// Currently focused section
|
||||
pub section: AppSection,
|
||||
/// Whether the current focus section has input priority
|
||||
|
|
@ -57,8 +57,6 @@ pub struct App {
|
|||
xdg: Option<Arc<XdgApp>>,
|
||||
/// Main audio outputs.
|
||||
audio_outs: Vec<Arc<Port<Unowned>>>,
|
||||
/// Tick enable?
|
||||
metronome: bool,
|
||||
/// Number of frames requested by process callback
|
||||
chunk_size: usize,
|
||||
|
||||
|
|
@ -78,10 +76,8 @@ impl App {
|
|||
chunk_size: 0,
|
||||
entered: true,
|
||||
jack: Some(jack),
|
||||
metronome: false,
|
||||
midi_in: None,
|
||||
midi_ins: vec![],
|
||||
modal: first_run.then(||crate::config::SetupModal(Some(xdg.clone())).boxed()),
|
||||
note_cursor: 0,
|
||||
note_start: 2,
|
||||
scene_cursor: 1,
|
||||
|
|
@ -92,6 +88,9 @@ impl App {
|
|||
time_cursor: 0,
|
||||
track_cursor: 1,
|
||||
tracks: vec![],
|
||||
modal: first_run.then(
|
||||
||Exit::boxed(crate::config::SetupModal(Some(xdg.clone()), false))
|
||||
),
|
||||
xdg: Some(xdg),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,27 +1,29 @@
|
|||
use crate::core::*;
|
||||
|
||||
pub struct TransportToolbar {
|
||||
pub mode: bool,
|
||||
pub focused: bool,
|
||||
pub entered: bool,
|
||||
pub metronome: bool,
|
||||
pub mode: bool,
|
||||
pub focused: bool,
|
||||
pub entered: bool,
|
||||
/// Current sample rate, tempo, and PPQ.
|
||||
pub timebase: Arc<Timebase>,
|
||||
pub timebase: Arc<Timebase>,
|
||||
/// JACK transport handle.
|
||||
transport: Option<Transport>,
|
||||
transport: Option<Transport>,
|
||||
/// Quantization factor
|
||||
pub quant: usize,
|
||||
pub quant: usize,
|
||||
/// Current transport state
|
||||
pub playing: Option<TransportState>,
|
||||
pub playing: Option<TransportState>,
|
||||
/// Current position according to transport
|
||||
playhead: usize,
|
||||
playhead: usize,
|
||||
/// Global frame and usec at which playback started
|
||||
pub started: Option<(usize, usize)>,
|
||||
pub started: Option<(usize, usize)>,
|
||||
}
|
||||
|
||||
impl TransportToolbar {
|
||||
pub fn new (transport: Option<Transport>) -> Self {
|
||||
Self {
|
||||
transport,
|
||||
metronome: false,
|
||||
mode: false,
|
||||
focused: false,
|
||||
entered: false,
|
||||
|
|
|
|||
|
|
@ -3,18 +3,27 @@ use crate::{core::*, view::*};
|
|||
pub struct HelpModal {
|
||||
cursor: usize,
|
||||
search: Option<String>,
|
||||
exited: bool,
|
||||
}
|
||||
|
||||
impl HelpModal {
|
||||
pub fn new () -> Self {
|
||||
Self { cursor: 0, search: None }
|
||||
Self { cursor: 0, search: None, exited: false }
|
||||
}
|
||||
}
|
||||
impl Exit for HelpModal {
|
||||
fn exited (&self) -> bool {
|
||||
self.exited
|
||||
}
|
||||
fn exit (&mut self) {
|
||||
self.exited = true;
|
||||
}
|
||||
}
|
||||
|
||||
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.bg = ratatui::style::Color::Rgb(30,30,30);
|
||||
cell.fg = ratatui::style::Color::Rgb(100,100,100);
|
||||
cell.modifier = ratatui::style::Modifier::DIM;
|
||||
}
|
||||
let width = 64.min(area.width * 3 / 5);
|
||||
|
|
@ -40,25 +49,28 @@ render!(HelpModal |self, buf, area|{
|
|||
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)?;
|
||||
format!("{:?}", command.0).blit(buf, x, y, Some(Style::default().white().bold()))?;
|
||||
command.2.blit(buf, x + 11, y, Some(Style::default().white().bold()))?;
|
||||
command.3.blit(buf, x + 26, y, Some(Style::default().white().dim()))?;
|
||||
} 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)?;
|
||||
format!("{:?}", command.0).blit(buf, x, y, Some(Style::default().white().bold()))?;
|
||||
command.2.blit(buf, x + 11, y, Some(Style::default().white().bold()))?;
|
||||
command.3.blit(buf, x + 26, y, Some(Style::default().white().dim()))?;
|
||||
} 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);
|
||||
fill_fg(buf, hi_area, Color::White);
|
||||
Lozenge(Style::default()).draw(buf, area)
|
||||
});
|
||||
|
||||
handle!(HelpModal |self, e| {
|
||||
Ok(handle_keymap(self, e, KEYMAP_HELP)? || match e {
|
||||
if handle_keymap(self, e, KEYMAP_HELP)? {
|
||||
return Ok(true)
|
||||
}
|
||||
Ok(match e {
|
||||
AppEvent::Input(Event::Key(KeyEvent {
|
||||
code: KeyCode::Char(c),
|
||||
modifiers: KeyModifiers::NONE, ..
|
||||
|
|
@ -67,22 +79,23 @@ handle!(HelpModal |self, e| {
|
|||
self.search = Some(String::new());
|
||||
}
|
||||
self.search.as_mut().unwrap().push(*c);
|
||||
false
|
||||
true
|
||||
},
|
||||
_ => false
|
||||
_ => true
|
||||
})
|
||||
});
|
||||
|
||||
pub const KEYMAP_HELP: &'static [KeyBinding<HelpModal>] = keymap!(HelpModal {
|
||||
[Esc, NONE, "help_close", "close help dialog", |_: &mut HelpModal|{
|
||||
[Esc, NONE, "help_close", "close help dialog", |modal: &mut HelpModal|{
|
||||
modal.exit();
|
||||
Ok(true)
|
||||
}],
|
||||
[Up, NONE, "help_prev", "select previous command", |modal: &mut HelpModal|{
|
||||
modal.cursor = modal.cursor.saturating_sub(1);
|
||||
Ok(false)
|
||||
Ok(true)
|
||||
}],
|
||||
[Down, NONE, "help_next", "select next command", |modal: &mut HelpModal|{
|
||||
modal.cursor = modal.cursor + 1;
|
||||
Ok(false)
|
||||
Ok(true)
|
||||
}],
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue