mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-07-17 15:56:57 +02:00
109e...
This commit is contained in:
parent
b44dc635ef
commit
80fe958476
8 changed files with 69 additions and 45 deletions
|
|
@ -787,11 +787,10 @@ impl Arrangement {
|
||||||
for track in self.tracks().iter() {
|
for track in self.tracks().iter() {
|
||||||
h = h.max(track.devices.len() as u16 * 2);
|
h = h.max(track.devices.len() as u16 * 2);
|
||||||
}
|
}
|
||||||
view_track_row_section(theme,
|
let tracks = ||self.tracks_with_sizes();
|
||||||
button_3("d", "evice", format!("{}", self.track().map(|t|t.devices.len()).unwrap_or(0)), false),
|
let track = move|(_, track, _x1, _x2), index| wh_exact(
|
||||||
button_2("D", "+", false),
|
Some(track_width(index, track)),
|
||||||
iter(||self.tracks_with_sizes(), move|(_, track, _x1, _x2), index| {
|
Some(h + 1),
|
||||||
wh_exact(Some(track_width(index, track)), Some(h + 1),
|
|
||||||
bg(track.color.dark.term, origin_nw(iter_south(move||0..h,
|
bg(track.color.dark.term, origin_nw(iter_south(move||0..h,
|
||||||
|_, _index|wh_exact(Some(track.width as u16), Some(2),
|
|_, _index|wh_exact(Some(track.width as u16), Some(2),
|
||||||
fg_bg(
|
fg_bg(
|
||||||
|
|
@ -800,8 +799,10 @@ impl Arrangement {
|
||||||
origin_nw(format!(" · {}", "--"))
|
origin_nw(format!(" · {}", "--"))
|
||||||
)
|
)
|
||||||
)))));
|
)))));
|
||||||
todo!()
|
view_track_row_section(theme,
|
||||||
})
|
button_3("d", "evice", format!("{}", self.track().map(|t|t.devices.len()).unwrap_or(0)), false),
|
||||||
|
button_2("D", "+", false),
|
||||||
|
iter(tracks, track)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -251,12 +251,12 @@ impl<'a> PoolView<'a> {
|
||||||
let f = color.lightest.term;
|
let f = color.lightest.term;
|
||||||
let name = if false { format!(" {i:>3}") } else { format!(" {i:>3} {name}") };
|
let name = if false { format!(" {i:>3}") } else { format!(" {i:>3} {name}") };
|
||||||
let length = if false { String::default() } else { format!("{length} ") };
|
let length = if false { String::default() } else { format!("{length} ") };
|
||||||
h_exact(1, iter_south(item_offset, item_height, bg(b, below!(
|
h_exact(1, bg(b, below!(
|
||||||
w_full(origin_w(fg(fg, bold(selected, name)))),
|
w_full(origin_w(fg(f, bold(selected, name)))),
|
||||||
w_full(origin_e(fg(fg, bold(selected, length)))),
|
w_full(origin_e(fg(f, bold(selected, length)))),
|
||||||
w_full(origin_w(When::new(selected, bold(true, fg(g(255), "▶"))))),
|
w_full(origin_w(when(selected, bold(true, fg(g(255), "▶"))))),
|
||||||
w_full(origin_e(When::new(selected, bold(true, fg(g(255), "◀"))))),
|
w_full(origin_e(when(selected, bold(true, fg(g(255), "◀"))))),
|
||||||
))))
|
)))
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -312,12 +312,14 @@ impl Browse {
|
||||||
}
|
}
|
||||||
impl Browse {
|
impl Browse {
|
||||||
fn tui (&self) -> impl Draw<Tui> {
|
fn tui (&self) -> impl Draw<Tui> {
|
||||||
iter_south(1, ||EntriesIterator {
|
let item = |entry, _index|w_full(origin_w(entry));
|
||||||
|
let iterate = ||EntriesIterator {
|
||||||
offset: 0,
|
offset: 0,
|
||||||
index: 0,
|
index: 0,
|
||||||
length: self.dirs.len() + self.files.len(),
|
length: self.dirs.len() + self.files.len(),
|
||||||
browser: self,
|
browser: self,
|
||||||
}, |entry, _index|w_full(origin_w(entry)))
|
};
|
||||||
|
iter_south_fixed(1, iterate, item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> Iterator for EntriesIterator<'a> {
|
impl<'a> Iterator for EntriesIterator<'a> {
|
||||||
|
|
|
||||||
|
|
@ -525,6 +525,7 @@ impl PianoHorizontal {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PianoHorizontal {
|
impl PianoHorizontal {
|
||||||
|
|
||||||
/// Draw the piano roll background.
|
/// Draw the piano roll background.
|
||||||
///
|
///
|
||||||
/// This mode uses full blocks on note on and half blocks on legato: █▄ █▄ █▄
|
/// This mode uses full blocks on note on and half blocks on legato: █▄ █▄ █▄
|
||||||
|
|
@ -559,6 +560,7 @@ impl PianoHorizontal {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw the piano roll foreground.
|
/// Draw the piano roll foreground.
|
||||||
///
|
///
|
||||||
/// This mode uses full blocks on note on and half blocks on legato: █▄ █▄ █▄
|
/// This mode uses full blocks on note on and half blocks on legato: █▄ █▄ █▄
|
||||||
|
|
@ -596,14 +598,16 @@ impl PianoHorizontal {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn notes (&self) -> impl Draw<Tui> {
|
fn notes (&self) -> impl Draw<Tui> {
|
||||||
let time_start = self.get_time_start();
|
let time_start = self.get_time_start();
|
||||||
let note_lo = self.get_note_lo();
|
let note_lo = self.get_note_lo();
|
||||||
let note_hi = self.get_note_hi();
|
let note_hi = self.get_note_hi();
|
||||||
let buffer = self.buffer.clone();
|
let buffer = self.buffer.clone();
|
||||||
Thunk::new(move|to: &mut Tui|{
|
thunk(move|to: &mut Tui|{
|
||||||
|
let xywh = to.area().into();
|
||||||
|
let XYWH(x0, y0, w, _h) = xywh;
|
||||||
let source = buffer.read().unwrap();
|
let source = buffer.read().unwrap();
|
||||||
let XYWH(x0, y0, w, _h) = to.area();
|
|
||||||
//if h as usize != note_axis {
|
//if h as usize != note_axis {
|
||||||
//panic!("area height mismatch: {h} <> {note_axis}");
|
//panic!("area height mismatch: {h} <> {note_axis}");
|
||||||
//}
|
//}
|
||||||
|
|
@ -618,15 +622,17 @@ impl PianoHorizontal {
|
||||||
let is_in_y = source_y < source.height;
|
let is_in_y = source_y < source.height;
|
||||||
if is_in_x && is_in_y {
|
if is_in_x && is_in_y {
|
||||||
if let Some(source_cell) = source.get(source_x, source_y) {
|
if let Some(source_cell) = source.get(source_x, source_y) {
|
||||||
if let Some(cell) = to.buffer.cell_mut(ratatui::prelude::Position::from((screen_x, screen_y))) {
|
if let Some(cell) = to.0.cell_mut(ratatui::prelude::Position::from((screen_x, screen_y))) {
|
||||||
*cell = source_cell.clone();
|
*cell = source_cell.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(xywh)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cursor (&self) -> impl Draw<Tui> {
|
fn cursor (&self) -> impl Draw<Tui> {
|
||||||
let note_hi = self.get_note_hi();
|
let note_hi = self.get_note_hi();
|
||||||
let note_lo = self.get_note_lo();
|
let note_lo = self.get_note_lo();
|
||||||
|
|
@ -636,8 +642,9 @@ impl PianoHorizontal {
|
||||||
let time_start = self.get_time_start();
|
let time_start = self.get_time_start();
|
||||||
let time_zoom = self.get_time_zoom();
|
let time_zoom = self.get_time_zoom();
|
||||||
let style = Some(Style::default().fg(self.color.lightest.term));
|
let style = Some(Style::default().fg(self.color.lightest.term));
|
||||||
Thunk::new(move|to: &mut Tui|{
|
thunk(move|to: &mut Tui|{
|
||||||
let XYWH(x0, y0, w, _) = to.area();
|
let xywh = to.area().into();
|
||||||
|
let XYWH(x0, y0, w, _h) = xywh;
|
||||||
for (_area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
for (_area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
||||||
if note == note_pos {
|
if note == note_pos {
|
||||||
for x in 0..w {
|
for x in 0..w {
|
||||||
|
|
@ -656,8 +663,10 @@ impl PianoHorizontal {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(xywh)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn keys (&self) -> impl Draw<Tui> {
|
fn keys (&self) -> impl Draw<Tui> {
|
||||||
let state = self;
|
let state = self;
|
||||||
let color = state.color;
|
let color = state.color;
|
||||||
|
|
@ -667,8 +676,9 @@ impl PianoHorizontal {
|
||||||
let key_style = Some(Style::default().fg(Rgb(192, 192, 192)).bg(Rgb(0, 0, 0)));
|
let key_style = Some(Style::default().fg(Rgb(192, 192, 192)).bg(Rgb(0, 0, 0)));
|
||||||
let off_style = Some(Style::default().fg(g(255)));
|
let off_style = Some(Style::default().fg(g(255)));
|
||||||
let on_style = Some(Style::default().fg(Rgb(255,0,0)).bg(color.base.term).bold());
|
let on_style = Some(Style::default().fg(Rgb(255,0,0)).bg(color.base.term).bold());
|
||||||
h_full(w_exact(self.keys_width, Thunk::new(move|to: &mut Tui|{
|
h_full(w_exact(self.keys_width, thunk(move|to: &mut Tui|{
|
||||||
let XYWH(x, y0, _w, _h) = to.area();
|
let xywh = to.area().into();
|
||||||
|
let XYWH(x, y0, _w, _h) = xywh;
|
||||||
for (_area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
for (_area_y, screen_y, note) in note_y_iter(note_lo, note_hi, y0) {
|
||||||
to.blit(&to_key(note), x, screen_y, key_style);
|
to.blit(&to_key(note), x, screen_y, key_style);
|
||||||
if note > 127 {
|
if note > 127 {
|
||||||
|
|
@ -680,11 +690,14 @@ impl PianoHorizontal {
|
||||||
to.blit(¬e_pitch_to_name(note), x, screen_y, off_style)
|
to.blit(¬e_pitch_to_name(note), x, screen_y, off_style)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Ok(xywh)
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn timeline (&self) -> impl Draw<Tui> + '_ {
|
fn timeline (&self) -> impl Draw<Tui> + '_ {
|
||||||
w_full(h_exact(1, Thunk::new(move|to: &mut Tui|{
|
w_full(h_exact(1, thunk(move|to: &mut Tui|{
|
||||||
let XYWH(x, y, w, _h) = to.area();
|
let xywh = to.area().into();
|
||||||
|
let XYWH(x, y, w, _h) = xywh;
|
||||||
let style = Some(Style::default().dim());
|
let style = Some(Style::default().dim());
|
||||||
let length = self.clip.as_ref().map(|p|p.read().unwrap().length).unwrap_or(1);
|
let length = self.clip.as_ref().map(|p|p.read().unwrap().length).unwrap_or(1);
|
||||||
for (area_x, screen_x) in (0..w).map(|d|(d, d+x)) {
|
for (area_x, screen_x) in (0..w).map(|d|(d, d+x)) {
|
||||||
|
|
@ -693,6 +706,7 @@ impl PianoHorizontal {
|
||||||
to.blit(&"|", screen_x, y, style);
|
to.blit(&"|", screen_x, y, style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Ok(xywh)
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ pub enum MixingMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_meters (meters: &[f32]) -> impl Draw<Tui> + use<'_> {
|
fn draw_meters (meters: &[f32]) -> impl Draw<Tui> + use<'_> {
|
||||||
Tui::bg(Black, w_exact(2, iter_east(1, ||meters.iter(), |value, _index|{
|
bg(Black, w_exact(2, iter_east_fixed(1, ||meters.iter(), |value, _index|{
|
||||||
h_full(RmsMeter(*value))
|
h_full(RmsMeter(*value))
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -596,8 +596,9 @@ fn draw_list_item (sample: &Option<Arc<RwLock<Sample>>>) -> String {
|
||||||
|
|
||||||
fn draw_viewer (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
fn draw_viewer (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
||||||
let min_db = -64.0;
|
let min_db = -64.0;
|
||||||
Thunk::new(move|to: &mut Tui|{
|
thunk(move|to: &mut Tui|{
|
||||||
let XYWH(x, y, width, height) = to.area();
|
let xywh = to.area().into();
|
||||||
|
let XYWH(x, y, width, height) = xywh;
|
||||||
let area = Rect { x, y, width, height };
|
let area = Rect { x, y, width, height };
|
||||||
if let Some(sample) = &sample {
|
if let Some(sample) = &sample {
|
||||||
let sample = sample.read().unwrap();
|
let sample = sample.read().unwrap();
|
||||||
|
|
@ -631,7 +632,8 @@ fn draw_viewer (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_
|
||||||
//height as f64 / 2.0,
|
//height as f64 / 2.0,
|
||||||
//text.red()
|
//text.red()
|
||||||
//);
|
//);
|
||||||
}).render(area, &mut to.1);
|
})
|
||||||
|
.render(area, to.as_mut());
|
||||||
} else {
|
} else {
|
||||||
Canvas::default()
|
Canvas::default()
|
||||||
.x_bounds([0.0, width as f64])
|
.x_bounds([0.0, width as f64])
|
||||||
|
|
@ -644,8 +646,9 @@ fn draw_viewer (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_
|
||||||
//text.red()
|
//text.red()
|
||||||
//);
|
//);
|
||||||
})
|
})
|
||||||
.render(area, &mut to.1);
|
.render(area, to.as_mut());
|
||||||
}
|
}
|
||||||
|
Ok(xywh)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,12 +118,16 @@ pub trait HasPlayClip: HasClock {
|
||||||
let MidiClip { ref name, color, .. } = *clip.read().unwrap();
|
let MidiClip { ref name, color, .. } = *clip.read().unwrap();
|
||||||
(name.clone(), color)
|
(name.clone(), color)
|
||||||
} else {
|
} else {
|
||||||
("".into(), Tui::g(64).into())
|
("".into(), ItemTheme::G[64].into())
|
||||||
};
|
};
|
||||||
let time: String = self.pulses_since_start_looped()
|
field_v(color, "Now:", format!("{} {}", self.play_status_time(), name))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn play_status_time (&self) -> String {
|
||||||
|
self.pulses_since_start_looped()
|
||||||
.map(|(times, time)|format!("{:>3}x {:>}", times+1.0, self.clock().timebase.format_beats_1(time)))
|
.map(|(times, time)|format!("{:>3}x {:>}", times+1.0, self.clock().timebase.format_beats_1(time)))
|
||||||
.unwrap_or_else(||String::from(" ")).into();
|
.unwrap_or_else(||String::from(" "))
|
||||||
field_v(color, "Now:", format!("{} {}", time, name))
|
.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_status (&self) -> impl Draw<Tui> {
|
fn next_status (&self) -> impl Draw<Tui> {
|
||||||
|
|
|
||||||
12
src/tek.rs
12
src/tek.rs
|
|
@ -368,7 +368,7 @@ def_sizes_iter!(TracksSizes => Track);
|
||||||
/// let _ = tek::view_logo();
|
/// let _ = tek::view_logo();
|
||||||
/// ```
|
/// ```
|
||||||
pub fn view_logo () -> impl Draw<Tui> {
|
pub fn view_logo () -> impl Draw<Tui> {
|
||||||
wh_exact(32, 7, bold(true, fg(Rgb(240,200,180), south!{
|
wh_exact(Some(32), Some(7), bold(true, fg(Rgb(240, 200, 180), south!{
|
||||||
h_exact(1, ""),
|
h_exact(1, ""),
|
||||||
h_exact(1, ""),
|
h_exact(1, ""),
|
||||||
h_exact(1, "~~ ╓─╥─╖ ╓──╖ ╥ ╖ ~~~~~~~~~~~~"),
|
h_exact(1, "~~ ╓─╥─╖ ╓──╖ ╥ ╖ ~~~~~~~~~~~~"),
|
||||||
|
|
@ -384,9 +384,9 @@ pub fn view_logo () -> impl Draw<Tui> {
|
||||||
/// ```
|
/// ```
|
||||||
pub fn view_transport (
|
pub fn view_transport (
|
||||||
play: bool,
|
play: bool,
|
||||||
bpm: Arc<RwLock<String>>,
|
bpm: &Arc<RwLock<String>>,
|
||||||
beat: Arc<RwLock<String>>,
|
beat: &Arc<RwLock<String>>,
|
||||||
time: Arc<RwLock<String>>,
|
time: &Arc<RwLock<String>>,
|
||||||
) -> impl Draw<Tui> {
|
) -> impl Draw<Tui> {
|
||||||
let theme = ItemTheme::G[96];
|
let theme = ItemTheme::G[96];
|
||||||
bg(Black, east!(above(
|
bg(Black, east!(above(
|
||||||
|
|
@ -788,7 +788,7 @@ fn app_interpret_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usua
|
||||||
Some(":templates") => {
|
Some(":templates") => {
|
||||||
let modes = state.config.modes.clone();
|
let modes = state.config.modes.clone();
|
||||||
let height = (modes.read().unwrap().len() * 2) as u16;
|
let height = (modes.read().unwrap().len() * 2) as u16;
|
||||||
h_exact(height, w_min(30, thunk(move |to: &mut Tui|{
|
h_exact(height, w_min(Some(30), thunk(move |to: &mut Tui|{
|
||||||
for (index, (id, profile)) in modes.read().unwrap().iter().enumerate() {
|
for (index, (id, profile)) in modes.read().unwrap().iter().enumerate() {
|
||||||
let bg = if index == 0 { Rgb(70,70,70) } else { Rgb(50,50,50) };
|
let bg = if index == 0 { Rgb(70,70,70) } else { Rgb(50,50,50) };
|
||||||
let name = profile.name.get(0).map(|x|x.as_ref()).unwrap_or("<no name>");
|
let name = profile.name.get(0).map(|x|x.as_ref()).unwrap_or("<no name>");
|
||||||
|
|
@ -804,7 +804,7 @@ fn app_interpret_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usua
|
||||||
}
|
}
|
||||||
})))
|
})))
|
||||||
}.draw(to),
|
}.draw(to),
|
||||||
Some(":sessions") => h_exact(6, w_min(30, thunk(|to: &mut Tui|{
|
Some(":sessions") => h_exact(Some(6), w_min(Some(30), thunk(|to: &mut Tui|{
|
||||||
let fg = Rgb(224, 192, 128);
|
let fg = Rgb(224, 192, 128);
|
||||||
for (index, name) in ["session1", "session2", "session3"].iter().enumerate() {
|
for (index, name) in ["session1", "session2", "session3"].iter().enumerate() {
|
||||||
let bg = if index == 0 { Rgb(50,50,50) } else { Rgb(40,40,40) };
|
let bg = if index == 0 { Rgb(50,50,50) } else { Rgb(40,40,40) };
|
||||||
|
|
|
||||||
2
tengri
2
tengri
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9c5bfafb7a4163022c5a96c3a25d0aca258a28d2
|
Subproject commit e0781571c42cb72e7445a2adbdb7a99e37600562
|
||||||
Loading…
Add table
Add a link
Reference in a new issue