mirror of
https://codeberg.org/unspeaker/tek.git
synced 2026-08-28 21:06:56 +02:00
This commit is contained in:
parent
d9e17cd348
commit
e50c4a5eef
7 changed files with 479 additions and 146 deletions
|
|
@ -54,8 +54,6 @@ impl Arrangement {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T: TracksView + ScenesView + Send + Sync> ClipsView for T {}
|
||||
|
||||
pub trait HasClipsSize {
|
||||
fn clips_size (&self) -> &Sizer;
|
||||
}
|
||||
|
|
@ -68,98 +66,98 @@ impl HasClipsSize for Arrangement {
|
|||
fn clips_size (&self) -> &Sizer { &self.size_inner }
|
||||
}
|
||||
|
||||
impl<T: TracksView + ScenesView + Send + Sync> ClipsView for T {}
|
||||
|
||||
pub trait ClipsView: TracksView + ScenesView {
|
||||
/// Draw clips per scene
|
||||
fn view_scenes_clips <'a> (&'a self) -> impl Draw<Tui> + 'a {
|
||||
view_scenes_clips(
|
||||
||self.scenes_with_sizes(),
|
||||
self.tracks_with_sizes(),
|
||||
self.selection(),
|
||||
self.editor(),
|
||||
self.clips_size(),
|
||||
self.is_editing(),
|
||||
)
|
||||
fn view_scenes_clips (&self) -> impl Draw<Tui> {
|
||||
let select = self.selection();
|
||||
let editor = self.editor();
|
||||
let size = self.clips_size();
|
||||
let editing = self.is_editing();
|
||||
return size.of(
|
||||
above(
|
||||
fg(Green, format!("{}x{}", size.w(), size.h())).align_se().full_wh(),
|
||||
iter_east(move||self.tracks_with_sizes().map(move|(
|
||||
track_index, track, _, _
|
||||
)| {
|
||||
iter_south(move||self.scenes_with_sizes().map(move|(
|
||||
scene_index, scene, _, _
|
||||
)| {
|
||||
let (name, theme): (Arc<str>, ItemTheme) = view_scene_name_theme(scene, track_index);
|
||||
let f = theme.lightest.term;
|
||||
let (b, o) = view_scene_bg(
|
||||
theme, select, track_index, scene_index
|
||||
);
|
||||
let w = view_scene_w(
|
||||
track, select, track_index, editor
|
||||
);
|
||||
let y = view_scene_y(
|
||||
select, scene_index, editor
|
||||
);
|
||||
let is_selected = view_scene_sel(
|
||||
select, track_index, scene_index, editing
|
||||
);
|
||||
below(
|
||||
Outer(true, Style::default().fg(o)).full_wh(),
|
||||
below(
|
||||
below(
|
||||
fg_bg(o, b, "".full_wh()),
|
||||
fg_bg(f, b, bold(true, name)).align_nw().full_wh(),
|
||||
),
|
||||
when(is_selected, editor.map(|e|e.view())).full_wh()
|
||||
).full_wh()
|
||||
).exact_wh(w, y)
|
||||
})).full_h().exact_w(track.width as u16)
|
||||
}))
|
||||
).full_wh());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn view_scenes_clips <'a, S: ScenesSizes<'a>> (
|
||||
scenes: impl Fn()->S,
|
||||
tracks: impl TracksSizes<'a>,
|
||||
select: &Selection,
|
||||
editor: Option<&MidiEditor>,
|
||||
size: &Sizer,
|
||||
editing: bool,
|
||||
) -> impl Draw<Tui> {
|
||||
let status = fg(Green, format!("{}x{}", size.w(), size.h())).align_se().full_wh();
|
||||
let tracks = iter_once(tracks, move|(track_index, track, _, _), _| {
|
||||
let scenes = iter_once(scenes(), move|(scene_index, scene, _, _), _| {
|
||||
let (name, theme): (Arc<str>, ItemTheme) = scene_name_theme(scene, track_index);
|
||||
let f = theme.lightest.term;
|
||||
let (b, o) = scene_bg(theme, select, track_index, scene_index);
|
||||
let w = scene_w(track, select, track_index, editor);
|
||||
let y = scene_y(select, scene_index, editor);
|
||||
let is_selected = scene_sel(select, track_index, scene_index, editing);
|
||||
below(
|
||||
Outer(true, Style::default().fg(o)).full_wh(),
|
||||
below(
|
||||
below(
|
||||
fg_bg(o, b, "".full_wh()),
|
||||
fg_bg(f, b, bold(true, name)).align_nw().full_wh(),
|
||||
),
|
||||
when(is_selected, editor.map(|e|e.view())).full_wh()
|
||||
).full_wh()
|
||||
).exact_wh(w, y)
|
||||
});
|
||||
scenes.full_h().exact_w(track.width as u16)
|
||||
});
|
||||
|
||||
return size.of(above(status, tracks).full_wh());
|
||||
|
||||
fn scene_name_theme (scene: &Scene, track_index: usize) -> (Arc<str>, ItemTheme) {
|
||||
if let Some(Some(clip)) = &scene.clips.get(track_index) {
|
||||
let clip = clip.read().unwrap();
|
||||
(format!(" ⏹ {}", &clip.name).into(), clip.color)
|
||||
} else {
|
||||
(" ⏹ -- ".into(), ItemTheme::G[32])
|
||||
}
|
||||
}
|
||||
|
||||
fn scene_bg (
|
||||
theme: ItemTheme, select: &Selection, track_index: usize, scene_index: usize
|
||||
) -> (Color, Color) {
|
||||
let mut outline = theme.base.term;
|
||||
(if select.track() == Some(track_index) && select.scene() == Some(scene_index) {
|
||||
outline = theme.lighter.term;
|
||||
theme.light.term
|
||||
} else if select.track() == Some(track_index) || select.scene() == Some(scene_index) {
|
||||
outline = theme.darkest.term;
|
||||
theme.base.term
|
||||
} else {
|
||||
theme.dark.term
|
||||
}, outline)
|
||||
}
|
||||
|
||||
fn scene_w (
|
||||
track: &Track, select: &Selection, track_index: usize, editor: Option<&MidiEditor>
|
||||
) -> u16 {
|
||||
if select.track() == Some(track_index) && let Some(editor) = editor {
|
||||
(editor.size.w() as usize).max(24).max(track.width) as u16
|
||||
} else {
|
||||
track.width as u16
|
||||
}
|
||||
}
|
||||
|
||||
fn scene_y (
|
||||
select: &Selection, scene_index: usize, editor: Option<&MidiEditor>
|
||||
) -> u16 {
|
||||
if select.scene() == Some(scene_index) && let Some(editor) = editor {
|
||||
editor.size.h().max(12)
|
||||
} else {
|
||||
Scene::DEFAULT_HEIGHT as u16
|
||||
}
|
||||
}
|
||||
|
||||
fn scene_sel (select: &Selection, track_index: usize, scene_index: usize, editing: bool) -> bool {
|
||||
editing && select.track() == Some(track_index) && select.scene() == Some(scene_index)
|
||||
fn view_scene_name_theme (scene: &Scene, track_index: usize) -> (Arc<str>, ItemTheme) {
|
||||
if let Some(Some(clip)) = &scene.clips.get(track_index) {
|
||||
let clip = clip.read().unwrap();
|
||||
(format!(" ⏹ {}", &clip.name).into(), clip.color)
|
||||
} else {
|
||||
(" ⏹ -- ".into(), ItemTheme::G[32])
|
||||
}
|
||||
}
|
||||
|
||||
fn view_scene_bg (
|
||||
theme: ItemTheme, select: &Selection, track_index: usize, scene_index: usize
|
||||
) -> (Color, Color) {
|
||||
let mut outline = theme.base.term;
|
||||
(if select.track() == Some(track_index) && select.scene() == Some(scene_index) {
|
||||
outline = theme.lighter.term;
|
||||
theme.light.term
|
||||
} else if select.track() == Some(track_index) || select.scene() == Some(scene_index) {
|
||||
outline = theme.darkest.term;
|
||||
theme.base.term
|
||||
} else {
|
||||
theme.dark.term
|
||||
}, outline)
|
||||
}
|
||||
|
||||
fn view_scene_w (
|
||||
track: &Track, select: &Selection, track_index: usize, editor: Option<&MidiEditor>
|
||||
) -> u16 {
|
||||
if select.track() == Some(track_index) && let Some(editor) = editor {
|
||||
(editor.size.w() as usize).max(24).max(track.width) as u16
|
||||
} else {
|
||||
track.width as u16
|
||||
}
|
||||
}
|
||||
|
||||
fn view_scene_y (
|
||||
select: &Selection, scene_index: usize, editor: Option<&MidiEditor>
|
||||
) -> u16 {
|
||||
if select.scene() == Some(scene_index) && let Some(editor) = editor {
|
||||
editor.size.h().max(12)
|
||||
} else {
|
||||
Scene::DEFAULT_HEIGHT as u16
|
||||
}
|
||||
}
|
||||
|
||||
fn view_scene_sel (select: &Selection, track_index: usize, scene_index: usize, editing: bool) -> bool {
|
||||
editing && select.track() == Some(track_index) && select.scene() == Some(scene_index)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ impl Track {
|
|||
name: name.as_ref().into(),
|
||||
color: color.unwrap_or_default(),
|
||||
sequencer: Sequencer::new(
|
||||
format!("{}/sequencer", name.as_ref()), jack, clock, clip, midi_from, midi_to
|
||||
format!("{}/sequencer", name.as_ref()),
|
||||
jack, clock, clip, midi_from, midi_to
|
||||
)?,
|
||||
..Default::default()
|
||||
})
|
||||
|
|
@ -224,7 +225,7 @@ pub trait HasTracks: AsRef<Vec<Track>> + AsMut<Vec<Track>> + HasClock + HasTrack
|
|||
where Self: HasJack<'static> + HasScenes
|
||||
{
|
||||
let name: Arc<str> = name.map_or_else(
|
||||
||format!("trk{:02}", self.tracks_last()).into(),
|
||||
||format!("trk{}", self.tracks_last()).into(),
|
||||
|x|x.to_string().into()
|
||||
);
|
||||
*self.tracks_last_mut() += 1;
|
||||
|
|
@ -232,7 +233,7 @@ pub trait HasTracks: AsRef<Vec<Track>> + AsMut<Vec<Track>> + HasClock + HasTrack
|
|||
width: (name.len() + 2).max(12),
|
||||
color: color.unwrap_or_else(ItemTheme::random),
|
||||
sequencer: Sequencer::new(
|
||||
&format!("{name}"),
|
||||
&name,
|
||||
self.jack(),
|
||||
Some(self.clock()),
|
||||
None,
|
||||
|
|
@ -282,7 +283,6 @@ pub trait TracksController: HasTracks
|
|||
+ Namespace<Option<Arc<[Connect]>>>
|
||||
+ Namespace<Option<Vec<Option<Arc<RwLock<MidiClip>>>>>>
|
||||
{
|
||||
|
||||
#[command(Stop = "stop")]
|
||||
/// Stop all playing clips
|
||||
fn tracks_stop_all (&mut self) -> Perhaps<TracksCommand> {
|
||||
|
|
@ -344,35 +344,55 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
|||
|
||||
/// Draw name of each track
|
||||
fn view_track_names (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||
let track_count = self.tracks().len();
|
||||
let scene_count = self.scenes().len();
|
||||
let selected = self.selection();
|
||||
let button = south(
|
||||
button_3("t", "rack ", format!("{}{track_count}", selected.track()
|
||||
.map(|track|format!("{track}/")).unwrap_or_default()), false),
|
||||
button_3("s", "cene ", format!("{}{scene_count}", selected.scene()
|
||||
.map(|scene|format!("{scene}/")).unwrap_or_default()), false));
|
||||
let button_2 = south(
|
||||
button_2("T", "+", false),
|
||||
button_2("S", "+", false));
|
||||
view_track_row_section(theme, button, button_2, bg(theme.darker.term,
|
||||
draw(|to: &mut Tui|{
|
||||
for (index, track, x1, _x2) in self.tracks_with_sizes() {
|
||||
east(
|
||||
south(
|
||||
button_3(
|
||||
"t",
|
||||
"rack ",
|
||||
east(
|
||||
selected.track().map(|track|east(track, "/")),
|
||||
self.tracks().len()
|
||||
),
|
||||
false
|
||||
),
|
||||
button_3(
|
||||
"s",
|
||||
"cene ",
|
||||
east(
|
||||
selected.scene().map(|scene|east(scene, "/")),
|
||||
self.scenes().len()
|
||||
),
|
||||
false
|
||||
)
|
||||
),
|
||||
west(
|
||||
south(
|
||||
button_2("T", "+", false),
|
||||
button_2("S", "+", false),
|
||||
),
|
||||
bg(theme.darker.term, iter_east(||self.tracks_with_sizes().map(|(index, track, x1, _x2)|{
|
||||
let b = if selected.track() == Some(index) {
|
||||
track.color.light.term
|
||||
} else {
|
||||
track.color.base.term
|
||||
};
|
||||
bg(b, south(east(
|
||||
format!("·t{index:02} "),
|
||||
fg(Rgb(255, 255, 255), bold(true, &track.name))
|
||||
).align_nw().full_w(), ""))
|
||||
bg(b, south(
|
||||
east!(
|
||||
"·t",
|
||||
index,
|
||||
" ",
|
||||
fg(Rgb(255, 255, 255), bold(true, &track.name))
|
||||
)
|
||||
.align_nw()
|
||||
.full_w(),
|
||||
""
|
||||
))
|
||||
.exact_w(track_width(index, track))
|
||||
.push_x(x1 as u16)
|
||||
.draw(to)?;
|
||||
}
|
||||
Ok(Some(XYWH(0, 0, 0, 0)))
|
||||
}).exact_h(2)))
|
||||
.exact_h(2)
|
||||
})))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/// Draw outputs per track
|
||||
|
|
@ -391,9 +411,20 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
|||
let f = Rgb(255, 255, 255);
|
||||
let b = track.color.dark.term;
|
||||
iter_south(||track.sequencer.midi_outs.iter().map(|port: &MidiOutput|{
|
||||
fg(f, bg(b, format!("·o{index:02} {}", port.port_name()).full_w().align_w()).exact_h(1))
|
||||
fg(f, bg(b, east!(
|
||||
"·o",
|
||||
index,
|
||||
" ",
|
||||
port.port_name()
|
||||
)
|
||||
.full_w()
|
||||
.align_w()
|
||||
).exact_h(1))
|
||||
}))
|
||||
.full_h().align_nw().exact_w(track_width(index, track)).draw(to)?;
|
||||
.full_h()
|
||||
.align_nw()
|
||||
.exact_w(track_width(index, track))
|
||||
.draw(to)?;
|
||||
}
|
||||
Ok(Some(XYWH(0, 0, 0, 0)))
|
||||
}).align_w()))
|
||||
|
|
@ -416,7 +447,12 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
|||
either(track.sequencer.overdub, fg(Yellow, "●dub "), "·dub "),
|
||||
).align_w().full_w()),
|
||||
iter_south(||track.sequencer.midi_ins.iter().map(|port|fg_bg(Rgb(255, 255, 255), track.color.dark.term,
|
||||
format!("·i{index:02} {}", port.port_name()).align_w().full_w())))
|
||||
east!(
|
||||
"·i",
|
||||
index,
|
||||
" ",
|
||||
port.port_name()
|
||||
).align_w().full_w())))
|
||||
).align_nw().exact_wh(track_width(index, track), height + 1).draw(to)?;
|
||||
}
|
||||
Ok(Some(XYWH(0, 0, 0, 0)))
|
||||
|
|
@ -425,7 +461,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
|||
|
||||
fn view_track_devices (&self, theme: ItemTheme) -> impl Draw<Tui> {
|
||||
let height = self.tracks_devices_height();
|
||||
let btn1 = button_3("d", "evice", format!("{}", self.track().map(|t|t.devices.len()).unwrap_or(0)), false);
|
||||
let btn1 = button_3("d", "evice", self.track().map(|t|t.devices.len()).unwrap_or(0), false);
|
||||
let btn2 = button_2("D", "+", false);
|
||||
view_track_row_section(theme, btn1, btn2, iter_east(move||self.tracks_with_sizes()
|
||||
.enumerate()
|
||||
|
|
@ -434,7 +470,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
|||
iter_south(move||(0..height).map(|_|fg_bg(
|
||||
ItemTheme::G[32].lightest.term,
|
||||
ItemTheme::G[32].dark.term,
|
||||
format!(" · {}", "--").align_nw()
|
||||
" · --".align_nw()
|
||||
).exact_wh(track.width as u16, 2)))
|
||||
.align_nw()
|
||||
)
|
||||
|
|
@ -453,7 +489,7 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
|||
}
|
||||
|
||||
fn view_inputs (&self, _theme: ItemTheme) -> impl Draw<Tui> + '_ {
|
||||
let title_1 = button_3("i", "nput ", format!("{}", self.midi_ins().len()), false).align_w().exact_wh(20, 1);
|
||||
let title_1 = button_3("i", "nput ", self.midi_ins().len(), false).align_w().exact_wh(20, 1);
|
||||
let title_2 = button_2("I", "+", false).exact_wh(4, 1);
|
||||
east(title_1, west(title_2, draw(move|to: &mut Tui|{
|
||||
for (_index, track, x1, _x2) in self.tracks_with_sizes() {
|
||||
|
|
@ -500,17 +536,27 @@ pub trait TracksView: HasTracks + ScenesView + HasMidiIns + HasMidiOuts + HasTra
|
|||
let height = self.outputs_height();
|
||||
let list = south(
|
||||
button_3(
|
||||
"o", "utput", format!("{}", self.midi_outs().len()), false
|
||||
"o", "utput", self.midi_outs().len(), false
|
||||
).align_w().full_w().exact_h(1),
|
||||
draw(|to: &mut Tui|{
|
||||
for (_index, port) in self.midi_outs().iter().enumerate() {
|
||||
east(
|
||||
east(" ● ", fg(Rgb(255,255,255), bold(true, port.port_name()))).align_w(),
|
||||
format!("{}/{} ",
|
||||
east(
|
||||
" ● ",
|
||||
fg(Rgb(255,255,255), bold(true, port.port_name()))
|
||||
).align_w(),
|
||||
east!(
|
||||
port.port().get_connections().len(),
|
||||
port.connections.len()).align_e().full_w().exact_h(1)).full_w().draw(to)?;
|
||||
"/",
|
||||
port.connections.len(),
|
||||
" "
|
||||
).align_e().full_w().exact_h(1)).full_w().draw(to)?;
|
||||
for (index, conn) in port.connections.iter().enumerate() {
|
||||
format!(" c{index:02}{}", conn.info()).align_w().full_w().exact_h(1).draw(to)?;
|
||||
east!(
|
||||
" c",
|
||||
index,
|
||||
conn.info()
|
||||
).align_w().full_w().exact_h(1).draw(to)?;
|
||||
}
|
||||
}
|
||||
todo!();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue