mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
editor keycodes work
This commit is contained in:
parent
525923d057
commit
fc3ecfb241
4 changed files with 94 additions and 86 deletions
|
|
@ -1,20 +1,22 @@
|
||||||
(:enter add :false)
|
(@up note/pos :note-pos-next)
|
||||||
(:shift-enter add :true)
|
(@down note/pos :note-pos-prev)
|
||||||
(:del del :false)
|
|
||||||
(:shift-del del :true)
|
(@left time/pos :time-pos-next)
|
||||||
(:comma note/length :prev-note-length)
|
(@right time/pos :time-pos-prev)
|
||||||
(:period note/length :next-note-length)
|
|
||||||
(:plus note/range :next-note-range)
|
(@enter add :false)
|
||||||
(:underscore note/range :prev-note-range)
|
(@shift-enter add :true)
|
||||||
(:up note/point :next-note-point)
|
(@del del :false)
|
||||||
(:down note/point :prev-note-point)
|
(@shift-del del :true)
|
||||||
(:left time/point :next-time-point)
|
(@comma note/length :prev-note-length)
|
||||||
(:right time/point :prev-time-point)
|
(@period note/length :next-note-length)
|
||||||
(:z time/lock :next-time-lock)
|
(@plus note/range :next-note-range)
|
||||||
(:equal time/zoom :next-time-zoom)
|
(@underscore note/range :prev-note-range)
|
||||||
(:minus time/zoom :prev-time-zoom)
|
(@z time/lock :next-time-lock)
|
||||||
(:space clock/play :play-current)
|
(@equal time/zoom :next-time-zoom)
|
||||||
(:shift-space clock/play :play-start)
|
(@minus time/zoom :prev-time-zoom)
|
||||||
(:u history :history-prev)
|
(@space clock/play :play-current)
|
||||||
(:r history :history-next)
|
(@shift-space clock/play :play-start)
|
||||||
(:tab compact :next-compact)
|
(@u history :history-prev)
|
||||||
|
(@r history :history-next)
|
||||||
|
(@tab compact :next-compact)
|
||||||
|
|
|
||||||
|
|
@ -56,10 +56,17 @@ edn_provide!(bool: |self: MidiEditor| {
|
||||||
":false" => false
|
":false" => false
|
||||||
});
|
});
|
||||||
edn_provide!(usize: |self: MidiEditor| {
|
edn_provide!(usize: |self: MidiEditor| {
|
||||||
":note-length" => self.note_len(),
|
":note-length" => self.note_len(),
|
||||||
":note-point" => self.note_point(),
|
|
||||||
":time-point" => self.time_point(),
|
":note-pos" => self.note_point(),
|
||||||
":time-zoom" => self.time_zoom().get(),
|
":note-pos-next" => self.note_point() + 1,
|
||||||
|
":note-pos-prev" => self.note_point().saturating_sub(1),
|
||||||
|
|
||||||
|
":time-pos" => self.time_point(),
|
||||||
|
":time-pos-next" => self.time_point() + self.time_zoom().get(),
|
||||||
|
":time-pos-prev" => self.time_point().saturating_sub(self.time_zoom().get()),
|
||||||
|
|
||||||
|
":time-zoom" => self.time_zoom().get(),
|
||||||
});
|
});
|
||||||
impl std::fmt::Debug for MidiEditor {
|
impl std::fmt::Debug for MidiEditor {
|
||||||
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
fn fmt (&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@
|
||||||
(@e editor show :pool-clip)
|
(@e editor show :pool-clip)
|
||||||
(@ctrl-a scene add)
|
(@ctrl-a scene add)
|
||||||
(@ctrl-t track add)
|
(@ctrl-t track add)
|
||||||
(@tab compact)
|
(@tab edit)
|
||||||
|
|
|
||||||
121
tek/src/lib.rs
121
tek/src/lib.rs
|
|
@ -5,7 +5,7 @@
|
||||||
#![feature(if_let_guard)]
|
#![feature(if_let_guard)]
|
||||||
#![feature(impl_trait_in_assoc_type)]
|
#![feature(impl_trait_in_assoc_type)]
|
||||||
#![feature(type_alias_impl_trait)]
|
#![feature(type_alias_impl_trait)]
|
||||||
pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicBool, Ordering::{self, *}}};
|
pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicBool, Ordering::Relaxed}};
|
||||||
/// Standard result type.
|
/// Standard result type.
|
||||||
pub type Usually<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
pub type Usually<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||||
/// Standard optional result type.
|
/// Standard optional result type.
|
||||||
|
|
@ -119,7 +119,6 @@ impl TekCli {
|
||||||
pub edn: String,
|
pub edn: String,
|
||||||
pub clock: Clock,
|
pub clock: Clock,
|
||||||
pub color: ItemPalette,
|
pub color: ItemPalette,
|
||||||
pub editing: AtomicBool,
|
|
||||||
pub pool: Option<MidiPool>,
|
pub pool: Option<MidiPool>,
|
||||||
pub editor: Option<MidiEditor>,
|
pub editor: Option<MidiEditor>,
|
||||||
pub player: Option<MidiPlayer>,
|
pub player: Option<MidiPlayer>,
|
||||||
|
|
@ -136,7 +135,7 @@ impl TekCli {
|
||||||
pub splits: Vec<u16>,
|
pub splits: Vec<u16>,
|
||||||
pub size: Measure<TuiOut>,
|
pub size: Measure<TuiOut>,
|
||||||
pub perf: PerfModel,
|
pub perf: PerfModel,
|
||||||
pub compact: bool,
|
pub editing: AtomicBool,
|
||||||
pub history: Vec<TekCommand>,
|
pub history: Vec<TekCommand>,
|
||||||
}
|
}
|
||||||
has_size!(<TuiOut>|self: Tek|&self.size);
|
has_size!(<TuiOut>|self: Tek|&self.size);
|
||||||
|
|
@ -174,10 +173,10 @@ edn_view!(TuiOut: |self: Tek| self.size.of(EdnView::from_source(self, self.edn.a
|
||||||
// Provide sizes:
|
// Provide sizes:
|
||||||
u16 {
|
u16 {
|
||||||
":sidebar-w" => self.sidebar_w(),
|
":sidebar-w" => self.sidebar_w(),
|
||||||
":sample-h" => if self.compact() { 0 } else { 5 },
|
":sample-h" => if self.is_editing() { 0 } else { 5 },
|
||||||
":samples-w" => if self.compact() { 4 } else { 11 },
|
":samples-w" => if self.is_editing() { 4 } else { 11 },
|
||||||
":samples-y" => if self.compact() { 1 } else { 0 },
|
":samples-y" => if self.is_editing() { 1 } else { 0 },
|
||||||
":pool-w" => if self.compact() { 5 } else {
|
":pool-w" => if self.is_editing() { 5 } else {
|
||||||
let w = self.size.w();
|
let w = self.size.w();
|
||||||
if w > 60 { 20 } else if w > 40 { 15 } else { 10 } } };
|
if w > 60 { 20 } else if w > 40 { 15 } else { 10 } } };
|
||||||
// Provide components:
|
// Provide components:
|
||||||
|
|
@ -193,7 +192,7 @@ edn_view!(TuiOut: |self: Tek| self.size.of(EdnView::from_source(self, self.edn.a
|
||||||
":outputs" => self.view_row(self.w(), 3, self.output_header(), self.output_cells()).boxed(),
|
":outputs" => self.view_row(self.w(), 3, self.output_header(), self.output_cells()).boxed(),
|
||||||
":scenes" => Outer(Style::default().fg(TuiTheme::g(0))).enclose_bg(self.view_row(
|
":scenes" => Outer(Style::default().fg(TuiTheme::g(0))).enclose_bg(self.view_row(
|
||||||
self.w(), self.size.h().saturating_sub(12) as u16,
|
self.w(), self.size.h().saturating_sub(12) as u16,
|
||||||
self.scene_header(), self.scene_cells()
|
self.scene_header(), self.clip_columns()
|
||||||
)).boxed() }});
|
)).boxed() }});
|
||||||
impl Tek {
|
impl Tek {
|
||||||
fn new_arranger (
|
fn new_arranger (
|
||||||
|
|
@ -289,8 +288,6 @@ impl Tek {
|
||||||
fn sync_follow (&self) {
|
fn sync_follow (&self) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
fn compact (&self) -> bool { self.compact }
|
|
||||||
fn is_editing (&self) -> bool { self.editing.load(Relaxed) }
|
|
||||||
fn editor (&self) -> impl Content<TuiOut> + '_ { &self.editor }
|
fn editor (&self) -> impl Content<TuiOut> + '_ { &self.editor }
|
||||||
fn view_clock (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_clock (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
Outer(Style::default().fg(TuiTheme::g(0))).enclose(row!(
|
Outer(Style::default().fg(TuiTheme::g(0))).enclose(row!(
|
||||||
|
|
@ -300,14 +297,14 @@ impl Tek {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
fn view_beat_stats (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_beat_stats (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
let Self { compact, ref clock, .. } = self;
|
let clock = self.clock();
|
||||||
let now = clock.started.read().unwrap().as_ref().map(|start|clock.global.usec.get() - start.usec.get());
|
let now = clock.started.read().unwrap().as_ref().map(|start|clock.global.usec.get() - start.usec.get());
|
||||||
let beat = ||now.map(|now|clock.timebase.format_beats_1(clock.timebase.usecs_to_pulse(now)))
|
let beat = ||now.map(|now|clock.timebase.format_beats_1(clock.timebase.usecs_to_pulse(now)))
|
||||||
.unwrap_or("-.-.--".into());
|
.unwrap_or("-.-.--".into());
|
||||||
let time = ||now.map(|now|format!("{:.3}s", now/1000000.))
|
let time = ||now.map(|now|format!("{:.3}s", now/1000000.))
|
||||||
.unwrap_or("-.---s".into());
|
.unwrap_or("-.---s".into());
|
||||||
let bpm = ||format!("{:.3}", clock.timebase.bpm.get());
|
let bpm = ||format!("{:.3}", clock.timebase.bpm.get());
|
||||||
Either::new(self.compact,
|
Either::new(self.is_editing(),
|
||||||
row!(FieldV(TuiTheme::g(128).into(), "BPM", bpm()),
|
row!(FieldV(TuiTheme::g(128).into(), "BPM", bpm()),
|
||||||
FieldV(TuiTheme::g(128).into(), "Beat", beat()),
|
FieldV(TuiTheme::g(128).into(), "Beat", beat()),
|
||||||
FieldV(TuiTheme::g(128).into(), "Time", time()),),
|
FieldV(TuiTheme::g(128).into(), "Time", time()),),
|
||||||
|
|
@ -316,13 +313,14 @@ impl Tek {
|
||||||
Bsp::e("Time ", Tui::fg(TuiTheme::g(255), time()))))
|
Bsp::e("Time ", Tui::fg(TuiTheme::g(255), time()))))
|
||||||
}
|
}
|
||||||
fn view_engine_stats (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_engine_stats (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
let Self { compact, ref clock, .. } = self;
|
let clock = self.clock();
|
||||||
|
let compact = self.is_editing();
|
||||||
let rate = clock.timebase.sr.get();
|
let rate = clock.timebase.sr.get();
|
||||||
let chunk = clock.chunk.load(Relaxed);
|
let chunk = clock.chunk.load(Relaxed);
|
||||||
let sr = move||format!("{}", if *compact {format!("{:.1}kHz", rate / 1000.)} else {format!("{:.0}Hz", rate)});
|
let sr = move||format!("{}", if compact {format!("{:.1}kHz", rate / 1000.)} else {format!("{:.0}Hz", rate)});
|
||||||
let buffer_size = move||format!("{chunk}");
|
let buffer_size = move||format!("{chunk}");
|
||||||
let latency = move||format!("{:.1}ms", chunk as f64 / rate * 1000.);
|
let latency = move||format!("{:.1}ms", chunk as f64 / rate * 1000.);
|
||||||
Either::new(self.compact,
|
Either::new(compact,
|
||||||
row!(FieldV(TuiTheme::g(128).into(), "SR", sr()),
|
row!(FieldV(TuiTheme::g(128).into(), "SR", sr()),
|
||||||
FieldV(TuiTheme::g(128).into(), "Buf", buffer_size()),
|
FieldV(TuiTheme::g(128).into(), "Buf", buffer_size()),
|
||||||
FieldV(TuiTheme::g(128).into(), "Lat", latency())),
|
FieldV(TuiTheme::g(128).into(), "Lat", latency())),
|
||||||
|
|
@ -360,7 +358,7 @@ impl Tek {
|
||||||
let playing = self.clock.is_rolling();
|
let playing = self.clock.is_rolling();
|
||||||
Tui::bg(
|
Tui::bg(
|
||||||
if playing{Color::Rgb(0,128,0)}else{Color::Rgb(128,64,0)},
|
if playing{Color::Rgb(0,128,0)}else{Color::Rgb(128,64,0)},
|
||||||
Either::new(self.compact,
|
Either::new(self.is_editing(),
|
||||||
Thunk::new(move||Fixed::x(9, Either::new(playing,
|
Thunk::new(move||Fixed::x(9, Either::new(playing,
|
||||||
Tui::fg(Color::Rgb(0, 255, 0), " PLAYING "),
|
Tui::fg(Color::Rgb(0, 255, 0), " PLAYING "),
|
||||||
Tui::fg(Color::Rgb(255, 128, 0), " STOPPED ")))),
|
Tui::fg(Color::Rgb(255, 128, 0), " STOPPED ")))),
|
||||||
|
|
@ -372,11 +370,11 @@ impl Tek {
|
||||||
self.editor.as_ref().map(|e|Bsp::e(e.clip_status(), e.edit_status()))
|
self.editor.as_ref().map(|e|Bsp::e(e.clip_status(), e.edit_status()))
|
||||||
}
|
}
|
||||||
fn view_pool (&self) -> impl Content<TuiOut> + use<'_> {
|
fn view_pool (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
self.pool.as_ref().map(|pool|PoolView(self.compact(), pool))
|
self.pool.as_ref().map(|pool|PoolView(self.is_editing(), pool))
|
||||||
}
|
}
|
||||||
fn pool (&self) -> impl Content<TuiOut> + use<'_> {
|
fn pool (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
self.pool.as_ref()
|
self.pool.as_ref()
|
||||||
.map(|pool|Align::e(Fixed::x(self.sidebar_w(), PoolView(self.compact(), pool))))
|
.map(|pool|Align::e(Fixed::x(self.sidebar_w(), PoolView(self.is_editing(), pool))))
|
||||||
}
|
}
|
||||||
fn w (&self) -> u16 {
|
fn w (&self) -> u16 {
|
||||||
self.tracks_sizes(self.is_editing(), self.editor_w())
|
self.tracks_sizes(self.is_editing(), self.editor_w())
|
||||||
|
|
@ -406,6 +404,12 @@ impl Tek {
|
||||||
clip.write().unwrap().toggle_loop()
|
clip.write().unwrap().toggle_loop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn track_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||||
|
(||Tui::bg(TuiTheme::g(32), Bsp::s(
|
||||||
|
Fill::x(Align::w(button(" C-a ".to_string(), format!(" add scene ({})", self.scenes().len())))),
|
||||||
|
Fill::x(Align::w(button(" C-t ".to_string(), format!(" add track ({})", self.tracks().len())))),
|
||||||
|
)).boxed()).into()
|
||||||
|
}
|
||||||
fn track_add (
|
fn track_add (
|
||||||
&mut self,
|
&mut self,
|
||||||
name: Option<&str>,
|
name: Option<&str>,
|
||||||
|
|
@ -478,7 +482,7 @@ impl Tek {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn scene_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
fn clip_columns <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||||
let editing = self.is_editing();
|
let editing = self.is_editing();
|
||||||
let tracks = move||self.tracks_sizes(editing, self.editor_w());
|
let tracks = move||self.tracks_sizes(editing, self.editor_w());
|
||||||
let scenes = move||self.scenes_sizes(editing, 2, 15);
|
let scenes = move||self.scenes_sizes(editing, 2, 15);
|
||||||
|
|
@ -498,24 +502,22 @@ impl Tek {
|
||||||
} else {
|
} else {
|
||||||
("⏹ ".to_string(), TuiTheme::g(64), TuiTheme::g(32))
|
("⏹ ".to_string(), TuiTheme::g(64), TuiTheme::g(32))
|
||||||
};
|
};
|
||||||
let last = last_color.read().unwrap().clone();
|
map_south(y1 as u16, h, Push::y(1, Fixed::y(h, Either::new(
|
||||||
let active = editing && selected_scene == Some(s) && selected_track == Some(t);
|
editing && selected_scene == Some(s) && selected_track == Some(t),
|
||||||
let editor = Thunk::new(||self.editor());
|
Thunk::new(||self.editor()),
|
||||||
let cell = Thunk::new(move||phat_sel_3(
|
Thunk::new(move||phat_sel_3(
|
||||||
selected_track == Some(t) && selected_scene == Some(s),
|
selected_track == Some(t) && selected_scene == Some(s),
|
||||||
Tui::fg(fg, Push::x(1, Tui::bold(true, name.to_string()))),
|
Tui::fg(fg, Push::x(1, Tui::bold(true, name.to_string()))),
|
||||||
Tui::fg(fg, Push::x(1, Tui::bold(true, name.to_string()))),
|
Tui::fg(fg, Push::x(1, Tui::bold(true, name.to_string()))),
|
||||||
if selected_track == Some(t) && selected_scene.map(|s|s+1) == Some(s) {
|
if selected_track == Some(t) && selected_scene.map(|s|s+1) == Some(s) {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(bg.into())
|
Some(bg.into())
|
||||||
},
|
},
|
||||||
bg.into(),
|
bg.into(),
|
||||||
bg.into(),
|
bg.into(),
|
||||||
));
|
)),
|
||||||
let cell = Either::new(active, editor, cell);
|
))))
|
||||||
*last_color.write().unwrap() = bg.into();
|
|
||||||
map_south(y1 as u16, h, Push::y(1, Fixed::y(h, cell)))
|
|
||||||
}))).boxed()
|
}))).boxed()
|
||||||
})).boxed()).into()
|
})).boxed()).into()
|
||||||
}
|
}
|
||||||
|
|
@ -553,6 +555,12 @@ const KEYS_MIX: &str = include_str!("keys_mix.edn");
|
||||||
handle!(TuiIn: |self: Tek, input|Ok({
|
handle!(TuiIn: |self: Tek, input|Ok({
|
||||||
use EdnItem::*;
|
use EdnItem::*;
|
||||||
let mut command: Option<TekCommand> = None;
|
let mut command: Option<TekCommand> = None;
|
||||||
|
// If editing, editor keys take priority
|
||||||
|
if self.is_editing() {
|
||||||
|
if self.editor.handle(input)? == Some(true) {
|
||||||
|
return Ok(Some(true))
|
||||||
|
}
|
||||||
|
}
|
||||||
// Handle from root keymap
|
// Handle from root keymap
|
||||||
if let Some(command) = EdnKeyMapToCommand::new(KEYS_APP)?.from::<_, TekCommand>(self, input) {
|
if let Some(command) = EdnKeyMapToCommand::new(KEYS_APP)?.from::<_, TekCommand>(self, input) {
|
||||||
if let Some(undo) = command.execute(self)? { self.history.push(undo); }
|
if let Some(undo) = command.execute(self)? { self.history.push(undo); }
|
||||||
|
|
@ -576,7 +584,7 @@ handle!(TuiIn: |self: Tek, input|Ok({
|
||||||
Clip(ClipCommand),
|
Clip(ClipCommand),
|
||||||
Clock(ClockCommand),
|
Clock(ClockCommand),
|
||||||
Color(ItemPalette),
|
Color(ItemPalette),
|
||||||
Compact(Option<bool>),
|
Edit(Option<bool>),
|
||||||
Editor(MidiEditCommand),
|
Editor(MidiEditCommand),
|
||||||
Enqueue(Option<Arc<RwLock<MidiClip>>>),
|
Enqueue(Option<Arc<RwLock<MidiClip>>>),
|
||||||
History(isize),
|
History(isize),
|
||||||
|
|
@ -589,8 +597,8 @@ handle!(TuiIn: |self: Tek, input|Ok({
|
||||||
Zoom(Option<usize>),
|
Zoom(Option<usize>),
|
||||||
}
|
}
|
||||||
edn_command!(TekCommand: |app: Tek| {
|
edn_command!(TekCommand: |app: Tek| {
|
||||||
("compact" [] Self::Compact(None))
|
("edit" [] Self::Edit(None))
|
||||||
("compact" [c: bool] Self::Compact(c))
|
("edit" [c: bool] Self::Edit(c))
|
||||||
|
|
||||||
("color" [c: Color] Self::Color(c.map(ItemPalette::from).unwrap_or_default()))
|
("color" [c: Color] Self::Color(c.map(ItemPalette::from).unwrap_or_default()))
|
||||||
|
|
||||||
|
|
@ -661,19 +669,16 @@ command!(|self: TekCommand, app: Tek|match self {
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
Self::Compact(compact) => match compact {
|
Self::Edit(value) => if let Some(value) = value {
|
||||||
Some(compact) => {
|
if app.is_editing() != value {
|
||||||
if app.compact != compact {
|
app.editing.store(value, Relaxed);
|
||||||
app.compact = compact;
|
Some(Self::Edit(Some(!value)))
|
||||||
Some(Self::Compact(Some(!compact)))
|
} else {
|
||||||
} else {
|
None
|
||||||
None
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
app.compact = !app.compact;
|
|
||||||
Some(Self::Compact(Some(!app.compact)))
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
app.editing.store(!app.is_editing(), Relaxed);
|
||||||
|
Some(Self::Edit(Some(!app.is_editing())))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
/// Represents the current user selection in the arranger
|
/// Represents the current user selection in the arranger
|
||||||
|
|
@ -817,12 +822,6 @@ trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
||||||
fn track_mut (&mut self) -> Option<&mut Track> {
|
fn track_mut (&mut self) -> Option<&mut Track> {
|
||||||
self.selected().track().and_then(|s|self.tracks_mut().get_mut(s))
|
self.selected().track().and_then(|s|self.tracks_mut().get_mut(s))
|
||||||
}
|
}
|
||||||
fn track_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
|
||||||
(||Tui::bg(TuiTheme::g(32), Bsp::s(
|
|
||||||
button(" C-t ", " add track "),
|
|
||||||
button(" C-a ", " add scene "),
|
|
||||||
)).boxed()).into()
|
|
||||||
}
|
|
||||||
fn track_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
fn track_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||||
let iter = ||self.tracks_sizes(self.is_editing(), self.editor_w());
|
let iter = ||self.tracks_sizes(self.is_editing(), self.editor_w());
|
||||||
(move||Align::x(Map::new(iter, move|(_, track, x1, x2), i| {
|
(move||Align::x(Map::new(iter, move|(_, track, x1, x2), i| {
|
||||||
|
|
@ -841,7 +840,7 @@ trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
||||||
fn input_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
fn input_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||||
let fg = TuiTheme::g(224);
|
let fg = TuiTheme::g(224);
|
||||||
let bg = TuiTheme::g(64);
|
let bg = TuiTheme::g(64);
|
||||||
(move||Bsp::s(button(" I ", " midi ins "), self.midi_ins().get(0).map(|inp|Bsp::s(
|
(move||Bsp::s(Fill::x(Align::w(button(" I ".to_string(), format!(" midi ins ({})", self.midi_ins().len())))), self.midi_ins().get(0).map(|inp|Bsp::s(
|
||||||
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(inp.name.clone())))),
|
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(inp.name.clone())))),
|
||||||
inp.connect.get(0).map(|connect|Fill::x(Align::w(Tui::bold(false,
|
inp.connect.get(0).map(|connect|Fill::x(Align::w(Tui::bold(false,
|
||||||
Tui::fg_bg(fg, bg, connect.info()))))),
|
Tui::fg_bg(fg, bg, connect.info()))))),
|
||||||
|
|
@ -869,7 +868,7 @@ trait HasTracks: HasSelection + HasClock + HasJack + HasEditor + Send + Sync {
|
||||||
fn output_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
fn output_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||||
let fg = TuiTheme::g(224);
|
let fg = TuiTheme::g(224);
|
||||||
let bg = TuiTheme::g(64);
|
let bg = TuiTheme::g(64);
|
||||||
(move||Bsp::s(button(" O ", " midi outs "), self.midi_outs().get(0).map(|out|Bsp::s(
|
(move||Bsp::s(Fill::x(Align::w(button(" O ".to_string(), format!(" midi outs ({}) ", self.midi_outs().len())))), self.midi_outs().get(0).map(|out|Bsp::s(
|
||||||
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(out.name.clone())))),
|
Fill::x(Tui::bold(true, Tui::fg_bg(fg, bg, Align::w(out.name.clone())))),
|
||||||
out.connect.get(0).map(|connect|Fill::x(Align::w(Tui::bold(false,
|
out.connect.get(0).map(|connect|Fill::x(Align::w(Tui::bold(false,
|
||||||
Tui::fg_bg(fg, bg, connect.info()))))),
|
Tui::fg_bg(fg, bg, connect.info()))))),
|
||||||
|
|
@ -1138,7 +1137,7 @@ audio!(|self: Tek, client, scope|{
|
||||||
self.perf.update(t0, scope);
|
self.perf.update(t0, scope);
|
||||||
Control::Continue
|
Control::Continue
|
||||||
});
|
});
|
||||||
fn button <'a> (key: &'a str, label: &'a str) -> impl Content<TuiOut> + 'a {
|
fn button (key: String, label: String) -> impl Content<TuiOut> {
|
||||||
Tui::bold(true, Bsp::e(
|
Tui::bold(true, Bsp::e(
|
||||||
Margin::x(1, Tui::fg_bg(TuiTheme::g(0), TuiTheme::orange(), key)),
|
Margin::x(1, Tui::fg_bg(TuiTheme::g(0), TuiTheme::orange(), key)),
|
||||||
Margin::x(1, Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(96), label)),
|
Margin::x(1, Tui::fg_bg(TuiTheme::g(255), TuiTheme::g(96), label)),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue