mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
allow event bubbling
This commit is contained in:
parent
f77c84a99c
commit
225c686db9
10 changed files with 90 additions and 100 deletions
|
|
@ -88,25 +88,28 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn E
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Device: Send + Sync {
|
pub trait Device: Send + Sync {
|
||||||
fn handle (&mut self, _event: &AppEvent) -> Usually<()> {
|
// Returns Ok(true) if the device handled the event.
|
||||||
Ok(())
|
// This is the mechanism which allows nesting of components;.
|
||||||
|
fn handle (&mut self, _event: &AppEvent) -> Usually<bool> {
|
||||||
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
// Returns space used by component.
|
||||||
|
// This is insufficient but for the most basic dynamic layout algorithms.
|
||||||
fn render (&self, _buffer: &mut Buffer, _area: Rect) -> Usually<Rect> {
|
fn render (&self, _buffer: &mut Buffer, _area: Rect) -> Usually<Rect> {
|
||||||
Ok(Rect { x: 0, y: 0, width: 0, height: 0 })
|
Ok(Rect { x: 0, y: 0, width: 0, height: 0 })
|
||||||
}
|
}
|
||||||
fn process (&mut self, _client: Client, _scope: ProcessScope) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct DynamicDevice<T> {
|
pub struct DynamicDevice<T> {
|
||||||
pub state: Arc<Mutex<T>>,
|
pub state: Arc<Mutex<T>>,
|
||||||
pub render: Mutex<Box<dyn FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send>>,
|
pub render: Mutex<Box<dyn FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send>>,
|
||||||
pub handle: Arc<Mutex<Box<dyn FnMut(&mut T, &AppEvent)->Usually<()> + Send>>>,
|
pub handle: Arc<Mutex<Box<dyn FnMut(&mut T, &AppEvent)->Usually<bool> + Send>>>,
|
||||||
pub process: Arc<Mutex<Box<dyn FnMut(&mut T, &Client, &ProcessScope)->Control + Send>>>,
|
pub process: Arc<Mutex<Box<dyn FnMut(&mut T, &Client, &ProcessScope)->Control + Send>>>,
|
||||||
client: Option<DynamicAsyncClient>
|
client: Option<DynamicAsyncClient>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Send + Sync> Device for DynamicDevice<T> {
|
impl<T: Send + Sync> Device for DynamicDevice<T> {
|
||||||
fn handle (&mut self, event: &AppEvent) -> Usually<()> {
|
fn handle (&mut self, event: &AppEvent) -> Usually<bool> {
|
||||||
self.handle.lock().unwrap()(&mut *self.state.lock().unwrap(), event)
|
self.handle.lock().unwrap()(&mut *self.state.lock().unwrap(), event)
|
||||||
}
|
}
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
|
|
@ -120,9 +123,9 @@ type DynamicProcessHandler = ClosureProcessHandler<BoxedProcessHandler>;
|
||||||
|
|
||||||
impl<T: Send + Sync + 'static> DynamicDevice<T> {
|
impl<T: Send + Sync + 'static> DynamicDevice<T> {
|
||||||
fn new <'a, R, H, P> (render: R, handle: H, process: P, state: T) -> Self where
|
fn new <'a, R, H, P> (render: R, handle: H, process: P, state: T) -> Self where
|
||||||
R: FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send + 'static,
|
R: FnMut(&T, &mut Buffer, Rect) -> Usually<Rect> + Send + 'static,
|
||||||
H: FnMut(&mut T, &AppEvent) -> Result<(), Box<dyn Error>> + Send + 'static,
|
H: FnMut(&mut T, &AppEvent) -> Usually<bool> + Send + 'static,
|
||||||
P: FnMut(&mut T, &Client, &ProcessScope)->Control + Send + 'static,
|
P: FnMut(&mut T, &Client, &ProcessScope) -> Control + Send + 'static,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
state: Arc::new(Mutex::new(state)),
|
state: Arc::new(Mutex::new(state)),
|
||||||
|
|
@ -142,7 +145,7 @@ impl<T: Send + Sync + 'static> DynamicDevice<T> {
|
||||||
move|event|{
|
move|event|{
|
||||||
let mut state = state.lock().unwrap();
|
let mut state = state.lock().unwrap();
|
||||||
let mut handle = handle.lock().unwrap();
|
let mut handle = handle.lock().unwrap();
|
||||||
handle(&mut state, &event).unwrap()
|
handle(&mut state, &event).unwrap();
|
||||||
}
|
}
|
||||||
}) as Box<dyn Fn(AppEvent) + Send + Sync>), ClosureProcessHandler::new(Box::new({
|
}) as Box<dyn Fn(AppEvent) + Send + Sync>), ClosureProcessHandler::new(Box::new({
|
||||||
let state = self.state.clone();
|
let state = self.state.clone();
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,6 @@ pub fn render (state: &Chain, buf: &mut Buffer, area: Rect)
|
||||||
Ok(Rect { x: area.x, y: area.y, width: x, height: y })
|
Ok(Rect { x: area.x, y: area.y, width: x, height: y })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (_: &mut Chain, _: &AppEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (_: &mut Chain, _: &AppEvent) -> Usually<bool> {
|
||||||
Ok(())
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ pub fn render (_: &Looper, _: &mut Buffer, _: Rect) -> Usually<Rect> {
|
||||||
Ok(Rect::default())
|
Ok(Rect::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (_: &mut Looper, _: &AppEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (_: &mut Looper, _: &AppEvent) -> Usually<bool> {
|
||||||
Ok(())
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ACTIONS: [(&'static str, &'static str);1] = [
|
pub const ACTIONS: [(&'static str, &'static str);1] = [
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ pub fn render (state: &Mixer, buf: &mut Buffer, mut area: Rect)
|
||||||
Ok(area)
|
Ok(area)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (state: &mut Mixer, event: &AppEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (state: &mut Mixer, event: &AppEvent) -> Usually<bool> {
|
||||||
if let AppEvent::Input(crossterm::event::Event::Key(event)) = event {
|
if let AppEvent::Input(crossterm::event::Event::Key(event)) = event {
|
||||||
|
|
||||||
match event.code {
|
match event.code {
|
||||||
|
|
@ -112,6 +112,7 @@ pub fn handle (state: &mut Mixer, event: &AppEvent) -> Result<(), Box<dyn Error>
|
||||||
KeyCode::Down => {
|
KeyCode::Down => {
|
||||||
state.selected_track = (state.selected_track + 1) % state.tracks.len();
|
state.selected_track = (state.selected_track + 1) % state.tracks.len();
|
||||||
println!("{}", state.selected_track);
|
println!("{}", state.selected_track);
|
||||||
|
return Ok(true)
|
||||||
},
|
},
|
||||||
KeyCode::Up => {
|
KeyCode::Up => {
|
||||||
if state.selected_track == 0 {
|
if state.selected_track == 0 {
|
||||||
|
|
@ -120,6 +121,7 @@ pub fn handle (state: &mut Mixer, event: &AppEvent) -> Result<(), Box<dyn Error>
|
||||||
state.selected_track = state.selected_track - 1;
|
state.selected_track = state.selected_track - 1;
|
||||||
}
|
}
|
||||||
println!("{}", state.selected_track);
|
println!("{}", state.selected_track);
|
||||||
|
return Ok(true)
|
||||||
},
|
},
|
||||||
KeyCode::Left => {
|
KeyCode::Left => {
|
||||||
if state.selected_column == 0 {
|
if state.selected_column == 0 {
|
||||||
|
|
@ -127,6 +129,7 @@ pub fn handle (state: &mut Mixer, event: &AppEvent) -> Result<(), Box<dyn Error>
|
||||||
} else {
|
} else {
|
||||||
state.selected_column = state.selected_column - 1;
|
state.selected_column = state.selected_column - 1;
|
||||||
}
|
}
|
||||||
|
return Ok(true)
|
||||||
},
|
},
|
||||||
KeyCode::Right => {
|
KeyCode::Right => {
|
||||||
if state.selected_column == 6 {
|
if state.selected_column == 6 {
|
||||||
|
|
@ -134,6 +137,7 @@ pub fn handle (state: &mut Mixer, event: &AppEvent) -> Result<(), Box<dyn Error>
|
||||||
} else {
|
} else {
|
||||||
state.selected_column = state.selected_column + 1;
|
state.selected_column = state.selected_column + 1;
|
||||||
}
|
}
|
||||||
|
return Ok(true)
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
println!("\n{event:?}");
|
println!("\n{event:?}");
|
||||||
|
|
@ -141,8 +145,7 @@ pub fn handle (state: &mut Mixer, event: &AppEvent) -> Result<(), Box<dyn Error>
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Ok(false)
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// TODO:
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,6 @@ pub fn render (state: &Plugin, buf: &mut Buffer, Rect { x, y, .. }: Rect)
|
||||||
Ok(Rect { x, y, width: 40, height: 7 })
|
Ok(Rect { x, y, width: 40, height: 7 })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (_: &mut Plugin, _: &AppEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (_: &mut Plugin, _: &AppEvent) -> Usually<bool> {
|
||||||
Ok(())
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,8 @@ pub fn render (state: &Sampler, buf: &mut Buffer, Rect { x, y, .. }: Rect)
|
||||||
//Ok(())
|
//Ok(())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
pub fn handle (_: &mut Sampler, _: &AppEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (_: &mut Sampler, _: &AppEvent) -> Usually<bool> {
|
||||||
|
Ok(false)
|
||||||
//if let Event::Input(crossterm::event::Event::Key(event)) = event {
|
//if let Event::Input(crossterm::event::Event::Key(event)) = event {
|
||||||
//match event.code {
|
//match event.code {
|
||||||
//KeyCode::Char('c') => {
|
//KeyCode::Char('c') => {
|
||||||
|
|
@ -208,5 +209,4 @@ pub fn handle (_: &mut Sampler, _: &AppEvent) -> Result<(), Box<dyn Error>> {
|
||||||
//}
|
//}
|
||||||
//}
|
//}
|
||||||
//}
|
//}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,6 @@ fn render (s: &Sequencer, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let (note0, note1) = s.note_axis;
|
let (note0, note1) = s.note_axis;
|
||||||
let pos = s.transport.query().unwrap().pos;
|
let pos = s.transport.query().unwrap().pos;
|
||||||
let frame = pos.frame();
|
let frame = pos.frame();
|
||||||
let rate = pos.frame_rate().unwrap();
|
|
||||||
let usecs = s.timebase.frame_to_usec(frame as usize);
|
let usecs = s.timebase.frame_to_usec(frame as usize);
|
||||||
let usec_per_step = s.timebase.usec_per_step(s.resolution as usize);
|
let usec_per_step = s.timebase.usec_per_step(s.resolution as usize);
|
||||||
let steps = usecs / usec_per_step;
|
let steps = usecs / usec_per_step;
|
||||||
|
|
@ -415,7 +414,7 @@ fn draw_horizontal (s: &Sequencer, buf: &mut Buffer, area: Rect) -> Usually<Rect
|
||||||
Ok(Rect { x, y, width: time1 - time0 + 6, height})
|
Ok(Rect { x, y, width: time1 - time0 + 6, height})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle (s: &mut Sequencer, event: &AppEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (s: &mut Sequencer, event: &AppEvent) -> Usually<bool> {
|
||||||
handle_keymap(COMMANDS, s, event)
|
handle_keymap(COMMANDS, s, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -450,7 +449,6 @@ fn nop (_: &mut Sequencer) {
|
||||||
fn note_add (s: &mut Sequencer) {
|
fn note_add (s: &mut Sequencer) {
|
||||||
let pos = s.transport.query().unwrap().pos;
|
let pos = s.transport.query().unwrap().pos;
|
||||||
let usecs = s.timebase.frame_to_usec(pos.frame() as usize);
|
let usecs = s.timebase.frame_to_usec(pos.frame() as usize);
|
||||||
let steps = usecs / s.timebase.usec_per_step(s.resolution as usize);
|
|
||||||
let step = (s.time_axis.0 + s.time_cursor) as u32;
|
let step = (s.time_axis.0 + s.time_cursor) as u32;
|
||||||
let start = (step as usize * s.timebase.ppq() / s.resolution) as u32;
|
let start = (step as usize * s.timebase.ppq() / s.resolution) as u32;
|
||||||
let end = ((step + 1) as usize * s.timebase.ppq() / s.resolution) as u32;
|
let end = ((step + 1) as usize * s.timebase.ppq() / s.resolution) as u32;
|
||||||
|
|
|
||||||
|
|
@ -237,8 +237,8 @@ pub fn render (state: &Transport, buf: &mut Buffer, mut area: Rect)
|
||||||
//Ok(())
|
//Ok(())
|
||||||
//}
|
//}
|
||||||
|
|
||||||
pub fn handle (_: &mut Transport, _: &AppEvent) -> Result<(), Box<dyn Error>> {
|
pub fn handle (_: &mut Transport, _: &AppEvent) -> Usually<bool> {
|
||||||
Ok(())
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ACTIONS: [(&'static str, &'static str);4] = [
|
pub const ACTIONS: [(&'static str, &'static str);4] = [
|
||||||
|
|
|
||||||
130
src/layout.rs
130
src/layout.rs
|
|
@ -13,45 +13,39 @@ impl Rows {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device for Rows {
|
impl Device for Rows {
|
||||||
fn handle (&mut self, event: &AppEvent) -> Usually<()> {
|
fn handle (&mut self, event: &AppEvent) -> Usually<bool> {
|
||||||
if !self.focused {
|
Ok(self.items[self.focus].handle(event)? || match event {
|
||||||
match event {
|
AppEvent::Input(event) => match event {
|
||||||
AppEvent::Input(Event::Key(KeyEvent { code: KeyCode::Esc, .. })) => {
|
Event::Key(KeyEvent { code: KeyCode::Up, .. }) => {
|
||||||
|
if self.focus == 0 {
|
||||||
|
self.focus = self.items.len();
|
||||||
|
}
|
||||||
|
self.focus = self.focus - 1;
|
||||||
|
true
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Down, .. }) => {
|
||||||
|
self.focus = self.focus + 1;
|
||||||
|
if self.focus >= self.items.len() {
|
||||||
|
self.focus = 0;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => {
|
||||||
|
self.focused = false;
|
||||||
|
self.items[self.focus].handle(&AppEvent::Focus)?;
|
||||||
|
true
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => {
|
||||||
self.focused = true;
|
self.focused = true;
|
||||||
self.items[self.focus].handle(&AppEvent::Blur)?;
|
self.items[self.focus].handle(&AppEvent::Blur)?;
|
||||||
Ok(())
|
true
|
||||||
},
|
},
|
||||||
_ => self.items[self.focus].handle(event)
|
_ => {
|
||||||
}
|
false
|
||||||
} else {
|
}
|
||||||
match event {
|
},
|
||||||
AppEvent::Input(event) => match event {
|
_ => false
|
||||||
Event::Key(KeyEvent { code: KeyCode::Up, .. }) => {
|
})
|
||||||
if self.focus == 0 {
|
|
||||||
self.focus = self.items.len();
|
|
||||||
}
|
|
||||||
self.focus = self.focus - 1;
|
|
||||||
},
|
|
||||||
Event::Key(KeyEvent { code: KeyCode::Down, .. }) => {
|
|
||||||
self.focus = self.focus + 1;
|
|
||||||
if self.focus >= self.items.len() {
|
|
||||||
self.focus = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => {
|
|
||||||
self.focused = false;
|
|
||||||
self.items[self.focus].handle(&AppEvent::Focus)?;
|
|
||||||
},
|
|
||||||
Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => {
|
|
||||||
self.focused = true;
|
|
||||||
self.items[self.focus].handle(&AppEvent::Blur)?;
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let mut w = 0u16;
|
let mut w = 0u16;
|
||||||
|
|
@ -91,45 +85,37 @@ impl Columns {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device for Columns {
|
impl Device for Columns {
|
||||||
fn handle (&mut self, event: &AppEvent) -> Usually<()> {
|
fn handle (&mut self, event: &AppEvent) -> Usually<bool> {
|
||||||
if !self.focused {
|
Ok(self.items[self.focus].handle(event)? || match event {
|
||||||
match event {
|
AppEvent::Input(event) => match event {
|
||||||
AppEvent::Input(Event::Key(KeyEvent { code: KeyCode::Esc, .. })) => {
|
Event::Key(KeyEvent { code: KeyCode::Left, .. }) => {
|
||||||
|
if self.focus == 0 {
|
||||||
|
self.focus = self.items.len();
|
||||||
|
}
|
||||||
|
self.focus = self.focus - 1;
|
||||||
|
true
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Right, .. }) => {
|
||||||
|
self.focus = self.focus + 1;
|
||||||
|
if self.focus >= self.items.len() {
|
||||||
|
self.focus = 0;
|
||||||
|
}
|
||||||
|
true
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => {
|
||||||
|
self.focused = false;
|
||||||
|
self.items[self.focus].handle(&AppEvent::Focus)?;
|
||||||
|
true
|
||||||
|
},
|
||||||
|
Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => {
|
||||||
self.focused = true;
|
self.focused = true;
|
||||||
self.items[self.focus].handle(&AppEvent::Blur)?;
|
self.items[self.focus].handle(&AppEvent::Blur)?;
|
||||||
Ok(())
|
true
|
||||||
},
|
},
|
||||||
_ => self.items[self.focus].handle(event)
|
_ => false
|
||||||
}
|
},
|
||||||
} else {
|
_ => false
|
||||||
match event {
|
})
|
||||||
AppEvent::Input(event) => match event {
|
|
||||||
Event::Key(KeyEvent { code: KeyCode::Left, .. }) => {
|
|
||||||
if self.focus == 0 {
|
|
||||||
self.focus = self.items.len();
|
|
||||||
}
|
|
||||||
self.focus = self.focus - 1;
|
|
||||||
},
|
|
||||||
Event::Key(KeyEvent { code: KeyCode::Right, .. }) => {
|
|
||||||
self.focus = self.focus + 1;
|
|
||||||
if self.focus >= self.items.len() {
|
|
||||||
self.focus = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Event::Key(KeyEvent { code: KeyCode::Enter, .. }) => {
|
|
||||||
self.focused = false;
|
|
||||||
self.items[self.focus].handle(&AppEvent::Focus)?;
|
|
||||||
},
|
|
||||||
Event::Key(KeyEvent { code: KeyCode::Esc, .. }) => {
|
|
||||||
self.focused = true;
|
|
||||||
self.items[self.focus].handle(&AppEvent::Blur)?;
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let mut w = 0u16;
|
let mut w = 0u16;
|
||||||
|
|
|
||||||
|
|
@ -112,17 +112,17 @@ pub use crate::{key, keymap};
|
||||||
|
|
||||||
pub fn handle_keymap <T> (
|
pub fn handle_keymap <T> (
|
||||||
commands: &[KeyBinding<T>], state: &mut T, event: &AppEvent
|
commands: &[KeyBinding<T>], state: &mut T, event: &AppEvent
|
||||||
) -> Result<(), Box<dyn Error>> {
|
) -> Result<bool, Box<dyn Error>> {
|
||||||
match event {
|
match event {
|
||||||
AppEvent::Input(Event::Key(event)) => {
|
AppEvent::Input(Event::Key(event)) => {
|
||||||
for (code, modifiers, _, _, command) in commands.iter() {
|
for (code, modifiers, _, _, command) in commands.iter() {
|
||||||
if *code == event.code && modifiers.bits() == event.modifiers.bits() {
|
if *code == event.code && modifiers.bits() == event.modifiers.bits() {
|
||||||
command(state);
|
command(state);
|
||||||
break
|
return Ok(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue