mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-07-17 07:46:57 +02:00
argh
This commit is contained in:
parent
5ffa9472e1
commit
89df3cf191
7 changed files with 164 additions and 95 deletions
|
|
@ -244,11 +244,12 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
|
||||||
button_2("O", "+", false),
|
button_2("O", "+", false),
|
||||||
bg(theme.darker.term, origin_w(thunk(|to: &mut Tui|{
|
bg(theme.darker.term, origin_w(thunk(|to: &mut Tui|{
|
||||||
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
|
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
|
||||||
|
let iter = ||track.sequencer.midi_outs.iter();
|
||||||
|
let draw = |port: &MidiOutput|fg(Rgb(255, 255, 255),
|
||||||
|
h_exact(1, bg(track.color.dark.term, w_full(origin_w(
|
||||||
|
format!("·o{index:02} {}", port.port_name()))))));
|
||||||
to.place(&w_exact(track_width(index, track),
|
to.place(&w_exact(track_width(index, track),
|
||||||
origin_nw(h_full(iter_south(||track.sequencer.midi_outs.iter(),
|
origin_nw(h_full(iter_south(iter, draw)))));
|
||||||
|port, index|fg(Rgb(255, 255, 255),
|
|
||||||
h_exact(1, bg(track.color.dark.term, w_full(origin_w(
|
|
||||||
format!("·o{index:02} {}", port.port_name())))))))))));
|
|
||||||
}
|
}
|
||||||
Ok(XYWH(0, 0, 0, 0))
|
Ok(XYWH(0, 0, 0, 0))
|
||||||
}))))
|
}))))
|
||||||
|
|
@ -261,16 +262,16 @@ pub trait TracksView: ScenesView + HasMidiIns + HasMidiOuts + HasTrackScroll {
|
||||||
}
|
}
|
||||||
let content = thunk(move|to: &mut Tui|{
|
let content = thunk(move|to: &mut Tui|{
|
||||||
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
|
for (index, track, _x1, _x2) in self.tracks_with_sizes() {
|
||||||
to.place(&wh_exact(track_width(index, track), h + 1,
|
to.place(&wh_exact(Some(track_width(index, track)), Some(h + 1),
|
||||||
origin_nw(south(
|
origin_nw(south(
|
||||||
bg(track.color.base.term,
|
bg(track.color.base.term,
|
||||||
w_full(origin_w(east!(
|
w_full(origin_w(east!(
|
||||||
either(track.sequencer.monitoring, fg(Green, "●mon "), "·mon "),
|
either(track.sequencer.monitoring, fg(Green, "●mon "), "·mon "),
|
||||||
either(track.sequencer.recording, fg(Red, "●rec "), "·rec "),
|
either(track.sequencer.recording, fg(Red, "●rec "), "·rec "),
|
||||||
either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "),
|
either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "),
|
||||||
)))),
|
)))),
|
||||||
iter_south(1, ||track.sequencer.midi_ins.iter(),
|
iter_south(||track.sequencer.midi_ins.iter(),
|
||||||
|port, index|fg_bg(Rgb(255, 255, 255), track.color.dark.term,
|
|port|fg_bg(Rgb(255, 255, 255), track.color.dark.term,
|
||||||
w_full(origin_w(format!("·i{index:02} {}", port.port_name())))))))));
|
w_full(origin_w(format!("·i{index:02} {}", port.port_name())))))))));
|
||||||
}
|
}
|
||||||
Ok(XYWH(0, 0, 0, 0))
|
Ok(XYWH(0, 0, 0, 0))
|
||||||
|
|
@ -308,8 +309,11 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + HasClipsSize +
|
||||||
}
|
}
|
||||||
|
|
||||||
fn view_scenes_names (&self) -> impl Draw<Tui> {
|
fn view_scenes_names (&self) -> impl Draw<Tui> {
|
||||||
w_exact(20, thunk(|to: &mut Tui|for (index, scene, ..) in self.scenes_with_sizes() {
|
w_exact(20, thunk(|to: &mut Tui|{
|
||||||
to.place(&self.view_scene_name(index, scene));
|
for (index, scene, ..) in self.scenes_with_sizes() {
|
||||||
|
to.place(&self.view_scene_name(index, scene));
|
||||||
|
}
|
||||||
|
Ok(XYWH(1, 1, 1, 1))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -319,18 +323,18 @@ pub trait ScenesView: HasEditor + HasSelection + HasSceneScroll + HasClipsSize +
|
||||||
} else {
|
} else {
|
||||||
Self::H_SCENE as u16
|
Self::H_SCENE as u16
|
||||||
};
|
};
|
||||||
let bg = if self.selection().scene() == Some(index) {
|
|
||||||
scene.color.light.term
|
|
||||||
} else {
|
|
||||||
scene.color.base.term
|
|
||||||
};
|
|
||||||
let a = w_full(origin_w(east(format!("·s{index:02} "),
|
let a = w_full(origin_w(east(format!("·s{index:02} "),
|
||||||
fg(g(255), bold(true, &scene.name)))));
|
fg(g(255), bold(true, &scene.name)))));
|
||||||
let b = when(self.selection().scene() == Some(index) && self.is_editing(),
|
let b = when(self.selection().scene() == Some(index) && self.is_editing(),
|
||||||
wh_full(origin_nw(south(
|
wh_full(origin_nw(south(
|
||||||
self.editor().as_ref().map(|e|e.clip_status()),
|
self.editor().as_ref().map(|e|e.clip_status()),
|
||||||
self.editor().as_ref().map(|e|e.edit_status())))));
|
self.editor().as_ref().map(|e|e.edit_status())))));
|
||||||
wh_exact(20, h, bg(bg, origin_nw(south(a, b))))
|
let c = if self.selection().scene() == Some(index) {
|
||||||
|
scene.color.light.term
|
||||||
|
} else {
|
||||||
|
scene.color.base.term
|
||||||
|
};
|
||||||
|
wh_exact(Some(20), Some(h), bg(c, origin_nw(south(a, b))))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -577,6 +581,7 @@ pub trait HasTrack: AsRefOpt<Track> + AsMutOpt<Track> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Arrangement {
|
impl Arrangement {
|
||||||
|
|
||||||
/// Create a new arrangement.
|
/// Create a new arrangement.
|
||||||
pub fn new (
|
pub fn new (
|
||||||
jack: &Jack<'static>,
|
jack: &Jack<'static>,
|
||||||
|
|
@ -596,27 +601,33 @@ impl Arrangement {
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Width of display
|
/// Width of display
|
||||||
pub fn w (&self) -> u16 {
|
pub fn w (&self) -> u16 {
|
||||||
self.size.w() as u16
|
self.size.w() as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Width allocated for sidebar.
|
/// Width allocated for sidebar.
|
||||||
pub fn w_sidebar (&self, is_editing: bool) -> u16 {
|
pub fn w_sidebar (&self, is_editing: bool) -> u16 {
|
||||||
self.w() / if is_editing { 16 } else { 8 } as u16
|
self.w() / if is_editing { 16 } else { 8 } as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Width available to display tracks.
|
/// Width available to display tracks.
|
||||||
pub fn w_tracks_area (&self, is_editing: bool) -> u16 {
|
pub fn w_tracks_area (&self, is_editing: bool) -> u16 {
|
||||||
self.w().saturating_sub(self.w_sidebar(is_editing))
|
self.w().saturating_sub(self.w_sidebar(is_editing))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Height of display
|
/// Height of display
|
||||||
pub fn h (&self) -> u16 {
|
pub fn h (&self) -> u16 {
|
||||||
self.size.h() as u16
|
self.size.h() as u16
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Height taken by visible device slots.
|
/// Height taken by visible device slots.
|
||||||
pub fn h_devices (&self) -> u16 {
|
pub fn h_devices (&self) -> u16 {
|
||||||
2
|
2
|
||||||
//1 + self.devices_with_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
//1 + self.devices_with_sizes().last().map(|(_, _, _, _, y)|y as u16).unwrap_or(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add multiple tracks
|
/// Add multiple tracks
|
||||||
#[cfg(feature = "track")] pub fn tracks_add (
|
#[cfg(feature = "track")] pub fn tracks_add (
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -634,6 +645,7 @@ impl Arrangement {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a track
|
/// Add a track
|
||||||
#[cfg(feature = "track")] pub fn track_add (
|
#[cfg(feature = "track")] pub fn track_add (
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -669,6 +681,7 @@ impl Arrangement {
|
||||||
}
|
}
|
||||||
Ok((index, &mut self.tracks_mut()[index]))
|
Ok((index, &mut self.tracks_mut()[index]))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "track")] pub fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
|
#[cfg(feature = "track")] pub fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
|
||||||
south(
|
south(
|
||||||
h_exact(1, self.view_inputs_header()),
|
h_exact(1, self.view_inputs_header()),
|
||||||
|
|
@ -679,6 +692,7 @@ impl Arrangement {
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "track")] fn view_inputs_header (&self) -> impl Draw<Tui> + '_ {
|
#[cfg(feature = "track")] fn view_inputs_header (&self) -> impl Draw<Tui> + '_ {
|
||||||
east(w_exact(20, origin_w(button_3("i", "nput ", format!("{}", self.midi_ins.len()), false))),
|
east(w_exact(20, origin_w(button_3("i", "nput ", format!("{}", self.midi_ins.len()), false))),
|
||||||
west(w_exact(4, button_2("I", "+", false)), thunk(move|to: &mut Tui|for (_index, track, x1, _x2) in self.tracks_with_sizes() {
|
west(w_exact(4, button_2("I", "+", false)), thunk(move|to: &mut Tui|for (_index, track, x1, _x2) in self.tracks_with_sizes() {
|
||||||
|
|
@ -690,6 +704,7 @@ impl Arrangement {
|
||||||
))))))
|
))))))
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "track")] fn view_inputs_row (&self, port: &MidiInput) -> impl Draw<Tui> {
|
#[cfg(feature = "track")] fn view_inputs_row (&self, port: &MidiInput) -> impl Draw<Tui> {
|
||||||
east(w_exact(20, origin_w(east(" ● ", bold(true, fg(Rgb(255,255,255), port.port_name()))))),
|
east(w_exact(20, origin_w(east(" ● ", bold(true, fg(Rgb(255,255,255), port.port_name()))))),
|
||||||
west(w_exact(4, ()), thunk(move|to: &mut Tui|for (_index, track, _x1, _x2) in self.tracks_with_sizes() {
|
west(w_exact(4, ()), thunk(move|to: &mut Tui|for (_index, track, _x1, _x2) in self.tracks_with_sizes() {
|
||||||
|
|
@ -701,14 +716,20 @@ impl Arrangement {
|
||||||
)))))
|
)))))
|
||||||
})))
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "track")] pub fn view_outputs (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
#[cfg(feature = "track")] pub fn view_outputs (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||||
let mut h = 1;
|
let mut h = 1;
|
||||||
|
|
||||||
for output in self.midi_outs().iter() {
|
for output in self.midi_outs().iter() {
|
||||||
h += 1 + output.connections.len();
|
h += 1 + output.connections.len();
|
||||||
}
|
}
|
||||||
|
|
||||||
let h = h as u16;
|
let h = h as u16;
|
||||||
|
|
||||||
let list = south(
|
let list = south(
|
||||||
h_exact(1, w_full(origin_w(button_3("o", "utput", format!("{}", self.midi_outs.len()), false)))),
|
h_exact(1, w_full(origin_w(button_3(
|
||||||
|
"o", "utput", format!("{}", self.midi_outs.len()), false
|
||||||
|
)))),
|
||||||
h_exact(h - 1, wh_full(origin_nw(thunk(|to: &mut Tui|{
|
h_exact(h - 1, wh_full(origin_nw(thunk(|to: &mut Tui|{
|
||||||
for (_index, port) in self.midi_outs().iter().enumerate() {
|
for (_index, port) in self.midi_outs().iter().enumerate() {
|
||||||
to.place(&h_exact(1,w_full(east(
|
to.place(&h_exact(1,w_full(east(
|
||||||
|
|
@ -720,7 +741,9 @@ impl Arrangement {
|
||||||
to.place(&h_exact(1, w_full(origin_w(format!(" c{index:02}{}", conn.info())))));
|
to.place(&h_exact(1, w_full(origin_w(format!(" c{index:02}{}", conn.info())))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})))));
|
}))))
|
||||||
|
);
|
||||||
|
|
||||||
h_exact(h, view_track_row_section(theme, list, button_2("O", "+", false),
|
h_exact(h, view_track_row_section(theme, list, button_2("O", "+", false),
|
||||||
bg(theme.darker.term, origin_w(w_full(
|
bg(theme.darker.term, origin_w(w_full(
|
||||||
thunk(|to: &mut Tui|{
|
thunk(|to: &mut Tui|{
|
||||||
|
|
@ -739,7 +762,13 @@ impl Arrangement {
|
||||||
for (_index, _conn) in port.connections.iter().enumerate() {
|
for (_index, _conn) in port.connections.iter().enumerate() {
|
||||||
to.place(&h_exact(1, w_full("")));
|
to.place(&h_exact(1, w_full("")));
|
||||||
}
|
}
|
||||||
}})))}}))))))
|
}
|
||||||
|
})
|
||||||
|
))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)))
|
||||||
|
))
|
||||||
}
|
}
|
||||||
#[cfg(feature = "track")] pub fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
#[cfg(feature = "track")] pub fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||||
let mut h = 2u16;
|
let mut h = 2u16;
|
||||||
|
|
@ -756,9 +785,15 @@ impl Arrangement {
|
||||||
fg_bg(
|
fg_bg(
|
||||||
ItemTheme::G[32].lightest.term,
|
ItemTheme::G[32].lightest.term,
|
||||||
ItemTheme::G[32].dark.term,
|
ItemTheme::G[32].dark.term,
|
||||||
origin_nw(format!(" · {}", "--")))))))));
|
origin_nw(format!(" · {}", "--"))
|
||||||
}))
|
)
|
||||||
|
)))
|
||||||
|
)
|
||||||
|
));
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Put a clip in a slot
|
/// Put a clip in a slot
|
||||||
#[cfg(feature = "clip")] pub fn clip_put (
|
#[cfg(feature = "clip")] pub fn clip_put (
|
||||||
&mut self, track: usize, scene: usize, clip: Option<Arc<RwLock<MidiClip>>>
|
&mut self, track: usize, scene: usize, clip: Option<Arc<RwLock<MidiClip>>>
|
||||||
|
|
@ -767,6 +802,7 @@ impl Arrangement {
|
||||||
self.scenes[scene].clips[track] = clip;
|
self.scenes[scene].clips[track] = clip;
|
||||||
old
|
old
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Change the color of a clip, returning the previous one
|
/// Change the color of a clip, returning the previous one
|
||||||
#[cfg(feature = "clip")] pub fn clip_set_color (&self, track: usize, scene: usize, color: ItemTheme)
|
#[cfg(feature = "clip")] pub fn clip_set_color (&self, track: usize, scene: usize, color: ItemTheme)
|
||||||
-> Option<ItemTheme>
|
-> Option<ItemTheme>
|
||||||
|
|
@ -779,20 +815,24 @@ impl Arrangement {
|
||||||
//old
|
//old
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Toggle looping for the active clip
|
/// Toggle looping for the active clip
|
||||||
#[cfg(feature = "clip")] pub fn toggle_loop (&mut self) {
|
#[cfg(feature = "clip")] pub fn toggle_loop (&mut self) {
|
||||||
if let Some(clip) = self.selected_clip() {
|
if let Some(clip) = self.selected_clip() {
|
||||||
clip.write().unwrap().toggle_loop()
|
clip.write().unwrap().toggle_loop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the first sampler of the active track
|
/// Get the first sampler of the active track
|
||||||
#[cfg(feature = "sampler")] pub fn sampler (&self) -> Option<&Sampler> {
|
#[cfg(feature = "sampler")] pub fn sampler (&self) -> Option<&Sampler> {
|
||||||
self.selected_track()?.sampler(0)
|
self.selected_track()?.sampler(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the first sampler of the active track
|
/// Get the first sampler of the active track
|
||||||
#[cfg(feature = "sampler")] pub fn sampler_mut (&mut self) -> Option<&mut Sampler> {
|
#[cfg(feature = "sampler")] pub fn sampler_mut (&mut self) -> Option<&mut Sampler> {
|
||||||
self.selected_track_mut()?.sampler_mut(0)
|
self.selected_track_mut()?.sampler_mut(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
impl ScenesView for Arrangement {
|
impl ScenesView for Arrangement {
|
||||||
fn h_scenes (&self) -> u16 {
|
fn h_scenes (&self) -> u16 {
|
||||||
|
|
|
||||||
|
|
@ -245,28 +245,28 @@ impl Pool {
|
||||||
impl<'a> PoolView<'a> {
|
impl<'a> PoolView<'a> {
|
||||||
fn tui (&self) -> impl Draw<Tui> {
|
fn tui (&self) -> impl Draw<Tui> {
|
||||||
let Self(pool) = self;
|
let Self(pool) = self;
|
||||||
//let color = self.1.clip().map(|c|c.read().unwrap().color).unwrap_or_else(||Tui::g(32).into());
|
//let color = self.1.clip().map(|c|c.read().unwrap().color).unwrap_or_else(||g(32).into());
|
||||||
//let on_bg = |x|x;//below(Repeat(" "), Tui::bg(color.darkest.term, x));
|
//let on_bg = |x|x;//below(Repeat(" "), bg(color.darkest.term, x));
|
||||||
//let border = |x|x;//Outer(Style::default().fg(color.dark.term).bg(color.darkest.term)).enclose(x);
|
//let border = |x|x;//Outer(Style::default().fg(color.dark.term).bg(color.darkest.term)).enclose(x);
|
||||||
//let height = pool.clips.read().unwrap().len() as u16;
|
//let height = pool.clips.read().unwrap().len() as u16;
|
||||||
w_exact(20, h_full(origin_n(iter(
|
w_exact(20, h_full(origin_n(iter(
|
||||||
||pool.clips().clone().into_iter(),
|
||pool.clips().clone().into_iter(),
|
||||||
move|clip: Arc<RwLock<MidiClip>>, i: usize|{
|
move|clip: Arc<RwLock<MidiClip>>, i: usize|{
|
||||||
let item_height = 1;
|
let MidiClip { ref name, color, length, .. } = *clip.read().unwrap();
|
||||||
let item_offset = i as u16 * item_height;
|
let item_height = 1;
|
||||||
let selected = i == pool.clip_index();
|
let item_offset = i as u16 * item_height;
|
||||||
let MidiClip { ref name, color, length, .. } = *clip.read().unwrap();
|
let selected = i == pool.clip_index();
|
||||||
let bg = if selected { color.light.term } else { color.base.term };
|
let b = if selected { color.light.term } else { color.base.term };
|
||||||
let fg = 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, Tui::bg(bg, below!(
|
h_exact(1, iter_south(item_offset, item_height, bg(b, below!(
|
||||||
w_full(origin_w(Tui::fg(fg, Tui::bold(selected, name)))),
|
w_full(origin_w(fg(fg, bold(selected, name)))),
|
||||||
w_full(origin_e(Tui::fg(fg, Tui::bold(selected, length)))),
|
w_full(origin_e(fg(fg, bold(selected, length)))),
|
||||||
w_full(origin_w(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "▶"))))),
|
w_full(origin_w(When::new(selected, bold(true, fg(g(255), "▶"))))),
|
||||||
w_full(origin_e(When::new(selected, Tui::bold(true, Tui::fg(Tui::g(255), "◀"))))),
|
w_full(origin_e(When::new(selected, bold(true, fg(g(255), "◀"))))),
|
||||||
))))
|
))))
|
||||||
}))))
|
}))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ClipLength {
|
impl ClipLength {
|
||||||
|
|
@ -337,10 +337,10 @@ impl<'a> Iterator for EntriesIterator<'a> {
|
||||||
let index = self.index;
|
let index = self.index;
|
||||||
if self.index < dirs {
|
if self.index < dirs {
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
Some(Tui::bold(true, self.browser.dirs[index].1.as_str()))
|
Some(bold(true, self.browser.dirs[index].1.as_str()))
|
||||||
} else if self.index < dirs + files {
|
} else if self.index < dirs + files {
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
Some(Tui::bold(false, self.browser.files[index - dirs].1.as_str()))
|
Some(bold(false, self.browser.files[index - dirs].1.as_str()))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -460,6 +460,18 @@ impl JackPort for MidiOutput {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl View<Tui> for MidiInput {
|
||||||
|
fn view (&self) -> impl Draw<Tui> {
|
||||||
|
"TODO: MIDI IN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl View<Tui> for MidiOutput {
|
||||||
|
fn view (&self) -> impl Draw<Tui> {
|
||||||
|
"TODO: MIDI OUT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl MidiOutput {
|
impl MidiOutput {
|
||||||
/// Clear the section of the output buffer that we will be using,
|
/// Clear the section of the output buffer that we will be using,
|
||||||
/// emitting "all notes off" at start of buffer if requested.
|
/// emitting "all notes off" at start of buffer if requested.
|
||||||
|
|
|
||||||
|
|
@ -167,19 +167,19 @@ pub trait MidiViewer: MidiRange + MidiPoint + Debug + Send + Sync {
|
||||||
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();
|
||||||
if note_pos < note_lo {
|
if note_pos < note_lo {
|
||||||
self.note_lo().set(note_pos);
|
self.note_lo().store(note_pos, Relaxed);
|
||||||
} else if note_pos > note_hi {
|
} else if note_pos > note_hi {
|
||||||
self.note_lo().set((note_lo + note_pos).saturating_sub(note_hi));
|
self.note_lo().store((note_lo + note_pos).saturating_sub(note_hi), Relaxed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Make sure time range is within display
|
/// Make sure time range is within display
|
||||||
fn autozoom (&self) {
|
fn autozoom (&self) {
|
||||||
if self.time_lock().get() {
|
if self.time_lock().load(Relaxed) {
|
||||||
let time_len = self.get_time_len();
|
let time_len = self.get_time_len();
|
||||||
let time_axis = self.get_time_axis();
|
let time_axis = self.get_time_axis();
|
||||||
let time_zoom = self.get_time_zoom();
|
let time_zoom = self.get_time_zoom();
|
||||||
loop {
|
loop {
|
||||||
let time_zoom = self.time_zoom().get();
|
let time_zoom = self.time_zoom().load(Relaxed);
|
||||||
let time_area = time_axis * time_zoom;
|
let time_area = time_axis * time_zoom;
|
||||||
if time_area > time_len {
|
if time_area > time_len {
|
||||||
let next_time_zoom = note_duration_prev(time_zoom);
|
let next_time_zoom = note_duration_prev(time_zoom);
|
||||||
|
|
@ -205,7 +205,7 @@ pub trait MidiViewer: MidiRange + MidiPoint + Debug + Send + Sync {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if time_zoom != self.time_zoom().get() {
|
if time_zoom != self.time_zoom().load(Relaxed) {
|
||||||
self.redraw()
|
self.redraw()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -289,7 +289,7 @@ pub trait TimeRange {
|
||||||
self.time_axis().load(Relaxed)
|
self.time_axis().load(Relaxed)
|
||||||
}
|
}
|
||||||
fn get_time_end (&self) -> usize {
|
fn get_time_end (&self) -> usize {
|
||||||
self.time_start().get() + self.time_axis().get() * self.time_zoom().get()
|
self.time_start().load(Relaxed) + self.time_axis().load(Relaxed) * self.time_zoom().load(Relaxed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -419,13 +419,13 @@ impl MidiEditor {
|
||||||
w_exact(20, south!(
|
w_exact(20, south!(
|
||||||
w_full(origin_w(east(
|
w_full(origin_w(east(
|
||||||
button_2("f2", "name ", false),
|
button_2("f2", "name ", false),
|
||||||
w_full(origin_e(Tui::fg(Rgb(255, 255, 255), format!("{name} "))))))),
|
w_full(origin_e(fg(Rgb(255, 255, 255), format!("{name} "))))))),
|
||||||
w_full(origin_w(east(
|
w_full(origin_w(east(
|
||||||
button_2("l", "ength ", false),
|
button_2("l", "ength ", false),
|
||||||
w_full(origin_e(Tui::fg(Rgb(255, 255, 255), format!("{length} "))))))),
|
w_full(origin_e(fg(Rgb(255, 255, 255), format!("{length} "))))))),
|
||||||
w_full(origin_w(east(
|
w_full(origin_w(east(
|
||||||
button_2("r", "epeat ", false),
|
button_2("r", "epeat ", false),
|
||||||
w_full(origin_e(Tui::fg(Rgb(255, 255, 255), format!("{looped} "))))))),
|
w_full(origin_e(fg(Rgb(255, 255, 255), format!("{looped} "))))))),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
pub fn edit_status (&self) -> impl Draw<Tui> + '_ {
|
pub fn edit_status (&self) -> impl Draw<Tui> + '_ {
|
||||||
|
|
@ -442,15 +442,15 @@ impl MidiEditor {
|
||||||
w_exact(20, south!(
|
w_exact(20, south!(
|
||||||
w_full(origin_w(east(
|
w_full(origin_w(east(
|
||||||
button_2("t", "ime ", false),
|
button_2("t", "ime ", false),
|
||||||
w_full(origin_e(Tui::fg(Rgb(255, 255, 255),
|
w_full(origin_e(fg(Rgb(255, 255, 255),
|
||||||
format!("{length} /{time_zoom} +{time_pos} "))))))),
|
format!("{length} /{time_zoom} +{time_pos} "))))))),
|
||||||
w_full(origin_w(east(
|
w_full(origin_w(east(
|
||||||
button_2("z", "lock ", false),
|
button_2("z", "lock ", false),
|
||||||
w_full(origin_e(Tui::fg(Rgb(255, 255, 255),
|
w_full(origin_e(fg(Rgb(255, 255, 255),
|
||||||
format!("{time_lock}"))))))),
|
format!("{time_lock}"))))))),
|
||||||
w_full(origin_w(east(
|
w_full(origin_w(east(
|
||||||
button_2("x", "note ", false),
|
button_2("x", "note ", false),
|
||||||
w_full(origin_e(Tui::fg(Rgb(255, 255, 255),
|
w_full(origin_e(fg(Rgb(255, 255, 255),
|
||||||
format!("{note_name} {note_pos} {note_len}"))))))),
|
format!("{note_name} {note_pos} {note_len}"))))))),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
@ -665,7 +665,7 @@ impl PianoHorizontal {
|
||||||
let note_hi = state.get_note_hi();
|
let note_hi = state.get_note_hi();
|
||||||
let note_pos = state.get_note_pos();
|
let note_pos = state.get_note_pos();
|
||||||
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(Tui::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::new(move|to: &mut Tui|{
|
||||||
let XYWH(x, y0, _w, _h) = to.area();
|
let XYWH(x, y0, _w, _h) = to.area();
|
||||||
|
|
@ -688,7 +688,7 @@ impl PianoHorizontal {
|
||||||
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)) {
|
||||||
let t = area_x as usize * self.time_zoom().get();
|
let t = area_x as usize * self.time_zoom().load(Relaxed);
|
||||||
if t < length {
|
if t < length {
|
||||||
to.blit(&"|", screen_x, y, style);
|
to.blit(&"|", screen_x, y, style);
|
||||||
}
|
}
|
||||||
|
|
@ -724,7 +724,7 @@ impl MidiViewer for PianoHorizontal {
|
||||||
fn clip_mut (&mut self) -> &mut Option<Arc<RwLock<MidiClip>>> { &mut self.clip }
|
fn clip_mut (&mut self) -> &mut Option<Arc<RwLock<MidiClip>>> { &mut self.clip }
|
||||||
/// Determine the required space to render the clip.
|
/// Determine the required space to render the clip.
|
||||||
fn buffer_size (&self, clip: &MidiClip) -> (usize, usize) {
|
fn buffer_size (&self, clip: &MidiClip) -> (usize, usize) {
|
||||||
(clip.length / self.range.time_zoom().get(), 128)
|
(clip.length / self.range.time_zoom().load(Relaxed), 128)
|
||||||
}
|
}
|
||||||
fn redraw (&self) {
|
fn redraw (&self) {
|
||||||
*self.buffer.write().unwrap() = if let Some(clip) = self.clip.as_ref() {
|
*self.buffer.write().unwrap() = if let Some(clip) = self.clip.as_ref() {
|
||||||
|
|
@ -765,12 +765,12 @@ impl OctaveVertical {
|
||||||
impl OctaveVertical {
|
impl OctaveVertical {
|
||||||
fn tui (&self) -> impl Draw<Tui> {
|
fn tui (&self) -> impl Draw<Tui> {
|
||||||
east!(
|
east!(
|
||||||
Tui::fg_bg(self.color(0), self.color(1), "▙"),
|
fg_bg(self.color(0), self.color(1), "▙"),
|
||||||
Tui::fg_bg(self.color(2), self.color(3), "▙"),
|
fg_bg(self.color(2), self.color(3), "▙"),
|
||||||
Tui::fg_bg(self.color(4), self.color(5), "▌"),
|
fg_bg(self.color(4), self.color(5), "▌"),
|
||||||
Tui::fg_bg(self.color(6), self.color(7), "▟"),
|
fg_bg(self.color(6), self.color(7), "▟"),
|
||||||
Tui::fg_bg(self.color(8), self.color(9), "▟"),
|
fg_bg(self.color(8), self.color(9), "▟"),
|
||||||
Tui::fg_bg(self.color(10), self.color(11), "▟"),
|
fg_bg(self.color(10), self.color(11), "▟"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -631,7 +631,7 @@ 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.buffer);
|
}).render(area, &mut to.1);
|
||||||
} else {
|
} else {
|
||||||
Canvas::default()
|
Canvas::default()
|
||||||
.x_bounds([0.0, width as f64])
|
.x_bounds([0.0, width as f64])
|
||||||
|
|
@ -644,7 +644,7 @@ fn draw_viewer (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_
|
||||||
//text.red()
|
//text.red()
|
||||||
//);
|
//);
|
||||||
})
|
})
|
||||||
.render(area, &mut to.buffer);
|
.render(area, &mut to.1);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
77
src/tek.rs
77
src/tek.rs
|
|
@ -426,11 +426,11 @@ pub fn button_play_pause (playing: bool) -> impl Draw<Tui> {
|
||||||
let compact = true;//self.is_editing();
|
let compact = true;//self.is_editing();
|
||||||
bg(if playing { Rgb(0, 128, 0) } else { Rgb(128, 64, 0) },
|
bg(if playing { Rgb(0, 128, 0) } else { Rgb(128, 64, 0) },
|
||||||
either(compact,
|
either(compact,
|
||||||
Thunk::new(move|to: &mut Tui|to.place(&w_exact(9, either(playing,
|
thunk(move|to: &mut Tui|to.place(&w_exact(9, either(playing,
|
||||||
fg(Rgb(0, 255, 0), " PLAYING "),
|
fg(Rgb(0, 255, 0), " PLAYING "),
|
||||||
fg(Rgb(255, 128, 0), " STOPPED ")))
|
fg(Rgb(255, 128, 0), " STOPPED ")))
|
||||||
)),
|
)),
|
||||||
Thunk::new(move|to: &mut Tui|to.place(&w_exact(5, either(playing,
|
thunk(move|to: &mut Tui|to.place(&w_exact(5, either(playing,
|
||||||
fg(Rgb(0, 255, 0), south(" 🭍🭑🬽 ", " 🭞🭜🭘 ",)),
|
fg(Rgb(0, 255, 0), south(" 🭍🭑🬽 ", " 🭞🭜🭘 ",)),
|
||||||
fg(Rgb(255, 128, 0), south(" ▗▄▖ ", " ▝▀▘ ",))))
|
fg(Rgb(255, 128, 0), south(" ▗▄▖ ", " ▝▀▘ ",))))
|
||||||
))
|
))
|
||||||
|
|
@ -466,19 +466,19 @@ pub fn view_wrap (bg: Color, fg: Color, content: impl Draw<Tui>) -> impl Draw<Tu
|
||||||
pub fn view_meter <'a> (label: &'a str, value: f32) -> impl Draw<Tui> + 'a {
|
pub fn view_meter <'a> (label: &'a str, value: f32) -> impl Draw<Tui> + 'a {
|
||||||
south!(
|
south!(
|
||||||
field_h(ItemTheme::G[128], label, format!("{:>+9.3}", value)),
|
field_h(ItemTheme::G[128], label, format!("{:>+9.3}", value)),
|
||||||
wh_exact(if value >= 0.0 { 13 }
|
wh_exact(if value >= 0.0 { &"13" }
|
||||||
else if value >= -1.0 { 12 }
|
else if value >= -1.0 { &"12" }
|
||||||
else if value >= -2.0 { 11 }
|
else if value >= -2.0 { &"11" }
|
||||||
else if value >= -3.0 { 10 }
|
else if value >= -3.0 { &"10" }
|
||||||
else if value >= -4.0 { 9 }
|
else if value >= -4.0 { &"9" }
|
||||||
else if value >= -6.0 { 8 }
|
else if value >= -6.0 { &"8" }
|
||||||
else if value >= -9.0 { 7 }
|
else if value >= -9.0 { &"7" }
|
||||||
else if value >= -12.0 { 6 }
|
else if value >= -12.0 { &"6" }
|
||||||
else if value >= -15.0 { 5 }
|
else if value >= -15.0 { &"5" }
|
||||||
else if value >= -20.0 { 4 }
|
else if value >= -20.0 { &"4" }
|
||||||
else if value >= -25.0 { 3 }
|
else if value >= -25.0 { &"3" }
|
||||||
else if value >= -30.0 { 2 }
|
else if value >= -30.0 { &"2" }
|
||||||
else if value >= -40.0 { 1 }
|
else if value >= -40.0 { &"1" }
|
||||||
else { 0 }, 1, bg(if value >= 0.0 { Red }
|
else { 0 }, 1, bg(if value >= 0.0 { Red }
|
||||||
else if value >= -3.0 { Yellow }
|
else if value >= -3.0 { Yellow }
|
||||||
else { Green }, ())))
|
else { Green }, ())))
|
||||||
|
|
@ -491,7 +491,7 @@ pub fn view_meters (values: &[f32;2]) -> impl Draw<Tui> + use<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_info (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
pub fn draw_info (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
||||||
when(sample.is_some(), Thunk::new(move|to: &mut Tui|{
|
when(sample.is_some(), thunk(move|to: &mut Tui|{
|
||||||
let sample = sample.unwrap().read().unwrap();
|
let sample = sample.unwrap().read().unwrap();
|
||||||
let theme = sample.color;
|
let theme = sample.color;
|
||||||
to.place(&east!(
|
to.place(&east!(
|
||||||
|
|
@ -506,7 +506,7 @@ pub fn draw_info (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_info_v (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
pub fn draw_info_v (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + use<'_> {
|
||||||
either(sample.is_some(), Thunk::new(move|to: &mut Tui|{
|
either(sample.is_some(), thunk(move|to: &mut Tui|{
|
||||||
let sample = sample.unwrap().read().unwrap();
|
let sample = sample.unwrap().read().unwrap();
|
||||||
let theme = sample.color;
|
let theme = sample.color;
|
||||||
to.place(&w_exact(20, south!(
|
to.place(&w_exact(20, south!(
|
||||||
|
|
@ -517,7 +517,7 @@ pub fn draw_info_v (sample: Option<&Arc<RwLock<Sample>>>) -> impl Draw<Tui> + us
|
||||||
w_full(origin_w(field_h(theme, "Trans ", "0"))),
|
w_full(origin_w(field_h(theme, "Trans ", "0"))),
|
||||||
w_full(origin_w(field_h(theme, "Gain ", format!("{}", sample.gain)))),
|
w_full(origin_w(field_h(theme, "Gain ", format!("{}", sample.gain)))),
|
||||||
)))
|
)))
|
||||||
}), Thunk::new(|to: &mut Tui|to.place(&fg(Red, south!(
|
}), thunk(|to: &mut Tui|to.place(&fg(Red, south!(
|
||||||
bold(true, "× No sample."),
|
bold(true, "× No sample."),
|
||||||
"[r] record",
|
"[r] record",
|
||||||
"[Shift-F9] import",
|
"[Shift-F9] import",
|
||||||
|
|
@ -543,9 +543,9 @@ pub fn view_ports_status <'a, T: JackPort> (theme: ItemTheme, title: &'a str, po
|
||||||
let ins = ports.len() as u16;
|
let ins = ports.len() as u16;
|
||||||
let frame = Outer(true, Style::default().fg(g(96)));
|
let frame = Outer(true, Style::default().fg(g(96)));
|
||||||
let iter = move||ports.iter();
|
let iter = move||ports.iter();
|
||||||
let names = iter_south(1, iter, move|port, index|h_full(origin_w(format!(" {index} {}", port.port_name()))));
|
let names = iter_south(iter, move|port, index|h_full(origin_w(format!(" {index} {}", port.port_name()))));
|
||||||
let field = field_v(theme, title, names);
|
let field = field_v(theme, title, names);
|
||||||
wh_exact(20, 1 + ins, frame.enclose(wh_exact(20, 1 + ins, field)))
|
wh_exact(Some(20), Some(1 + ins), frame.enclose(wh_exact(Some(20), Some(1 + ins), field)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn io_ports <'a, T: PortsSizes<'a>> (
|
pub fn io_ports <'a, T: PortsSizes<'a>> (
|
||||||
|
|
@ -554,11 +554,22 @@ pub fn io_ports <'a, T: PortsSizes<'a>> (
|
||||||
iter(items, move|(
|
iter(items, move|(
|
||||||
_index, name, connections, y, y2
|
_index, name, connections, y, y2
|
||||||
): (usize, &'a Arc<str>, &'a [Connect], usize, usize), _|
|
): (usize, &'a Arc<str>, &'a [Connect], usize, usize), _|
|
||||||
iter_south(y as u16, (y2-y) as u16, south(
|
iter_south(
|
||||||
h_full(bold(true, fg_bg(fg, bg, origin_w(east(&" ", name))))),
|
y as u16,
|
||||||
iter(||connections.iter(), move|connect: &'a Connect, index|iter_south(index as u16, 1,
|
(y2-y) as u16,
|
||||||
h_full(origin_w(bold(false, fg_bg(fg, bg,
|
south(
|
||||||
&connect.info)))))))))
|
h_full(bold(true, fg_bg(fg, bg, origin_w(east(" ", name))))),
|
||||||
|
iter(
|
||||||
|
||connections.iter(),
|
||||||
|
move|connect: &'a Connect, index|iter_south(
|
||||||
|
index as u16,
|
||||||
|
1,
|
||||||
|
h_full(origin_w(bold(false, fg_bg(fg, bg, &connect.info))))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// CLI banner.
|
/// CLI banner.
|
||||||
|
|
@ -758,7 +769,7 @@ fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usu
|
||||||
Some("menu") => to.place(&if let Dialog::Menu(selected, items) = &state.dialog {
|
Some("menu") => to.place(&if let Dialog::Menu(selected, items) = &state.dialog {
|
||||||
let items = items.clone();
|
let items = items.clone();
|
||||||
let selected = selected;
|
let selected = selected;
|
||||||
Some(wh_full(Thunk::new(move|to: &mut Tui|{
|
Some(wh_full(thunk(move|to: &mut Tui|{
|
||||||
for (index, MenuItem(item, _)) in items.0.iter().enumerate() {
|
for (index, MenuItem(item, _)) in items.0.iter().enumerate() {
|
||||||
to.place(&y_push((2 * index) as u16,
|
to.place(&y_push((2 * index) as u16,
|
||||||
fg_bg(
|
fg_bg(
|
||||||
|
|
@ -776,7 +787,7 @@ fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usu
|
||||||
Some(":templates") => to.place(&{
|
Some(":templates") => to.place(&{
|
||||||
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::new(move |to: &mut Tui|{
|
h_exact(height, w_min(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>");
|
||||||
|
|
@ -792,7 +803,7 @@ fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usu
|
||||||
}
|
}
|
||||||
})))
|
})))
|
||||||
}),
|
}),
|
||||||
Some(":sessions") => to.place(&h_exact(6, w_min(30, Thunk::new(|to: &mut Tui|{
|
Some(":sessions") => to.place(&h_exact(6, w_min(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) };
|
||||||
|
|
@ -811,7 +822,7 @@ fn app_understand_word (state: &App, to: &mut Tui, dsl: &impl Expression) -> Usu
|
||||||
}, w_shrink(3, h_exact(1, fg(g(96), x_repeat("🭻")))))))),
|
}, w_shrink(3, h_exact(1, fg(g(96), x_repeat("🭻")))))))),
|
||||||
Some(":device") => {
|
Some(":device") => {
|
||||||
let selected = state.dialog.device_kind().unwrap();
|
let selected = state.dialog.device_kind().unwrap();
|
||||||
to.place(&south(bold(true, "Add device"), iter_south(1,
|
to.place(&south(bold(true, "Add device"), iter_south(
|
||||||
move||device_kinds().iter(),
|
move||device_kinds().iter(),
|
||||||
move|_label: &&'static str, i|{
|
move|_label: &&'static str, i|{
|
||||||
let bg = if i == selected { Rgb(64,128,32) } else { Rgb(0,0,0) };
|
let bg = if i == selected { Rgb(64,128,32) } else { Rgb(0,0,0) };
|
||||||
|
|
@ -957,7 +968,7 @@ impl App {
|
||||||
impl Draw<Tui> for App {
|
impl Draw<Tui> for App {
|
||||||
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
fn draw (self, to: &mut Tui) -> Usually<XYWH<u16>> {
|
||||||
if let Some(e) = self.error.read().unwrap().as_ref() {
|
if let Some(e) = self.error.read().unwrap().as_ref() {
|
||||||
to.place_at(to.area(), e);
|
to.place_at(to.area().into(), e.as_ref());
|
||||||
}
|
}
|
||||||
for (index, dsl) in self.mode.view.iter().enumerate() {
|
for (index, dsl) in self.mode.view.iter().enumerate() {
|
||||||
if let Err(e) = self.understand(to, dsl) {
|
if let Err(e) = self.understand(to, dsl) {
|
||||||
|
|
@ -974,3 +985,9 @@ primitive!(u8: try_to_u8);
|
||||||
primitive!(u16: try_to_u16);
|
primitive!(u16: try_to_u16);
|
||||||
primitive!(usize: try_to_usize);
|
primitive!(usize: try_to_usize);
|
||||||
primitive!(isize: try_to_isize);
|
primitive!(isize: try_to_isize);
|
||||||
|
|
||||||
|
fn field_h <T> (theme: ItemTheme, head: impl Draw<T>, body: impl Draw<T>) -> impl Draw<T> {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn field_v <T> (theme: ItemTheme, head: impl Draw<T>, body: impl Draw<T>) -> impl Draw<T> {
|
||||||
|
}
|
||||||
|
|
|
||||||
2
tengri
2
tengri
|
|
@ -1 +1 @@
|
||||||
Subproject commit a93fe92a596b8a9bcec898e228fca909c0e2e9f4
|
Subproject commit c9b9ff15191ec3a37e8da35f382ce0d4af74d0d8
|
||||||
Loading…
Add table
Add a link
Reference in a new issue