wip: new old arranger scenes
Some checks are pending
/ build (push) Waiting to run

This commit is contained in:
🪞👃🪞 2025-05-15 23:06:15 +03:00
parent 4ba88bfd6d
commit 9aeb792f7d
6 changed files with 197 additions and 176 deletions

View file

@ -60,7 +60,7 @@ impl<'a> Content<TuiOut> for ArrangerView<'a> {
let bg = |x|Tui::bg(Reset, x);
//let track_scroll = |x|Bsp::s(&self.track_scroll, x);
//let scene_scroll = |x|Bsp::e(&self.scene_scroll, x);
self.arrangement.size.of(outs(tracks(devices(ins(bg(self.scenes(&None)))))))
self.arrangement.size.of(outs(tracks(devices(ins(bg(self.scenes_view(&None)))))))
}
}
@ -72,7 +72,6 @@ impl<'a> ArrangerView<'a> {
Bsp::s(self.input_routes(), self.input_ports()),
))
}
/// Render output matrix.
pub(crate) fn outputs (&'a self) -> impl Content<TuiOut> + 'a {
Tui::bg(Reset, Align::n(Bsp::s(
@ -80,14 +79,14 @@ impl<'a> ArrangerView<'a> {
Bsp::s(self.output_nexts(), self.output_froms()),
)))
}
/// Render track headers
pub(crate) fn tracks (&'a self) -> impl Content<TuiOut> + 'a {
let Self { width_side, width_mid, track_selected, is_editing, .. } = self;
Tryptich::center(3)
.left(*width_side, button_3("t", "track", format!("{}", self.arrangement.tracks.len()), *is_editing))
.left(*width_side,
button_3("t", "track", format!("{}", self.arrangement.tracks.len()), *is_editing))
.right(*width_side, button_2("T", "add track", *is_editing))
.middle(*width_mid, per_track(*width_mid, ||self.tracks_with_sizes_scrolled(),
.middle(*width_mid, per_track(||self.tracks_with_sizes_scrolled(),
|index, track|wrap(
if *track_selected == Some(index) {
track.color.light
@ -98,14 +97,13 @@ impl<'a> ArrangerView<'a> {
Tui::bold(true, Fill::xy(Align::nw(&track.name)))
)))
}
/// Render device switches.
pub(crate) fn devices (&'a self) -> impl Content<TuiOut> + 'a {
let Self { width_side, width_mid, track_selected, is_editing, .. } = self;
Tryptich::top(1)
.left(*width_side, button_3("d", "devices", format!("{}", 0), *is_editing))
.right(*width_side, button_2("D", "add device", *is_editing))
.middle(*width_mid, per_track_top(*width_mid, ||self.tracks_with_sizes_scrolled(),
.middle(*width_mid, per_track_top(||self.tracks_with_sizes_scrolled(),
move|index, track|{
let bg = if *track_selected == Some(index) {
track.color.light
@ -116,138 +114,9 @@ impl<'a> ArrangerView<'a> {
track.devices.get(0).map(|device|wrap(bg.rgb, fg, device.name()))
}))
}
/// Default scene height.
pub(crate) const H_SCENE: usize = 2;
/// Default editor height.
pub(crate) const H_EDITOR: usize = 15;
/// Render scenes with clips
pub(crate) fn scenes (&'a self, editor: &'a Option<MidiEditor>) -> impl Content<TuiOut> + 'a {
/// A scene with size and color.
type SceneWithColor<'a> = (usize, &'a Scene, usize, usize, Option<ItemTheme>);
let Self {
arrangement,
width, width_side, width_mid,
scenes_height, scene_last, scene_selected,
track_selected, is_editing, ..
} = self;
let selection = Has::<Selection>::get(self.arrangement);
let selected_track = selection.track();
let selected_scene = selection.scene();
Tryptich::center(*scenes_height)
.left(*width_side, Map::new(
move||arrangement.scenes_with_sizes(
*is_editing, Self::H_SCENE, Self::H_EDITOR, selected_track, selected_scene,
).map_while(|(s, scene, y1, y2)|if y2 as u16 > *scenes_height {
None
} else {
Some((s, scene, y1, y2, if s == 0 {
None
} else {
Some(arrangement.scenes()[s-1].color)
}))
}),
move |(s, scene, y1, y2, previous): SceneWithColor, _|{
let height = (1 + y2 - y1) as u16;
let name = Some(scene.name.clone());
let content = Fill::x(Align::w(Tui::bold(true, Bsp::e("", name))));
let same_track = true;
let selected = same_track && *scene_selected == Some(s);
let neighbor = same_track && s > 0 && *scene_selected == Some(s - 1);
let is_last = *scene_last == s;
let theme = scene.color;
let fg = theme.lightest.rgb;
let bg = if selected { theme.light } else { theme.base }.rgb;
let hi = if let Some(previous) = previous {
if neighbor {
previous.light.rgb
} else {
previous.base.rgb
}
} else {
Reset
};
let lo = if is_last {
Reset
} else if selected {
theme.light.rgb
} else {
theme.base.rgb
};
Fill::x(map_south(y1 as u16, height, Fixed::y(height, Phat {
width: 0, height: 0, content, colors: [fg, bg, hi, lo]
})))
}))
.middle(*width_mid, per_track(
*width_mid,
||self.tracks_with_sizes_scrolled(),
move|track_index, track|Map::new(
move||arrangement.scenes_with_sizes(
self.is_editing,
Self::H_SCENE,
Self::H_EDITOR,
selected_track,
selected_scene,
).map_while(move|(s, scene, y1, y2)|if y2 as u16 > self.scenes_height {
None
} else {
Some((s, scene, y1, y2, if s == 0 {
None
} else {
Some(self.arrangement.scenes[s-1].clips[track_index].as_ref()
.map(|c|c.read().unwrap().color)
.unwrap_or(ItemTheme::G[32]))
}))
}),
move|(s, scene, y1, y2, previous): SceneWithColor<'a>, _|{
let (name, theme) = if let Some(clip) = &scene.clips[track_index] {
let clip = clip.read().unwrap();
(Some(clip.name.clone()), clip.color)
} else {
(None, ItemTheme::G[32])
};
let height = (1 + y2 - y1) as u16;
let content = Fill::x(Align::w(Tui::bold(true, Bsp::e("", name))));
let same_track = *track_selected == Some(track_index);
let selected = same_track && *scene_selected == Some(s);
let neighbor = same_track && s > 0 && *scene_selected == Some(s - 1);
let is_last = *scene_last == s;
let fg = theme.lightest.rgb;
let bg = if selected { theme.light } else { theme.base }.rgb;
let hi = if let Some(previous) = previous {
if neighbor {
previous.light.rgb
} else {
previous.base.rgb
}
} else {
Reset
};
let lo = if is_last {
Reset
} else if selected {
theme.light.rgb
} else {
theme.base.rgb
};
map_south(y1 as u16, height, Bsp::b(Fixed::y(height, Phat {
width: 0, height: 0, content, colors: [fg, bg, hi, lo]
}), When(
*is_editing && same_track && *scene_selected == Some(s),
editor
)))
})))
}
}
pub(crate) fn per_track_top <'a, T: Content<TuiOut> + 'a, U: TracksSizes<'a>> (
width: u16,
tracks: impl Fn() -> U + Send + Sync + 'a,
callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a
) -> impl Content<TuiOut> + 'a {
@ -261,13 +130,8 @@ pub(crate) fn per_track_top <'a, T: Content<TuiOut> + 'a, U: TracksSizes<'a>> (
}
pub(crate) fn per_track <'a, T: Content<TuiOut> + 'a, U: TracksSizes<'a>> (
width: u16,
tracks: impl Fn() -> U + Send + Sync + 'a,
callback: impl Fn(usize, &'a Track)->T + Send + Sync + 'a
) -> impl Content<TuiOut> + 'a {
per_track_top(
width,
tracks,
move|index, track|Fill::y(Align::y(callback(index, track)))
)
per_track_top(tracks, move|index, track|Fill::y(Align::y(callback(index, track))))
}