mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
This commit is contained in:
parent
4ba88bfd6d
commit
9aeb792f7d
6 changed files with 197 additions and 176 deletions
|
|
@ -1,5 +1,156 @@
|
|||
use crate::*;
|
||||
|
||||
pub type SceneWith<'a, T: Send + Sync> = (usize, &'a Scene, usize, usize, T);
|
||||
|
||||
pub trait ArrangerSceneRows: Send + Sync {
|
||||
/// Default scene height.
|
||||
const H_SCENE: usize = 2;
|
||||
/// Default editor height.
|
||||
const H_EDITOR: usize = 15;
|
||||
/// Render scenes with clips
|
||||
fn scenes_view <'a> (&'a self, editor: &'a Option<MidiEditor>) -> impl Content<TuiOut> + 'a {
|
||||
Tryptich::center(self.scenes_height())
|
||||
.left(self.width_side(), self.scenes_names())
|
||||
.middle(self.width_mid(), self.scenes_clips(editor))
|
||||
}
|
||||
fn is_editing (&self) -> bool;
|
||||
fn arrangement (&self) -> &Arrangement;
|
||||
fn scene_last (&self) -> usize;
|
||||
fn scene_selected (&self) -> Option<usize>;
|
||||
fn track_selected (&self) -> Option<usize>;
|
||||
fn scenes_height (&self) -> u16;
|
||||
fn width_side (&self) -> u16;
|
||||
fn width_mid (&self) -> u16;
|
||||
fn scenes_names (&self) -> impl Content<TuiOut> {
|
||||
Map::new(move||self.scenes_with_prev_color(),
|
||||
move|(s, scene, y1, y2, previous): SceneWith<'_, Option<ItemTheme>>, _|{
|
||||
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 selected = self.scene_selected() == Some(s);
|
||||
let neighbor = s > 0 && self.scene_selected() == Some(s - 1);
|
||||
let is_last = self.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]
|
||||
})))
|
||||
})
|
||||
}
|
||||
fn scenes_with_prev_color (&self) -> impl Iterator<Item=SceneWith<Option<ItemTheme>>> + Send + Sync {
|
||||
self.scenes_iter().map(|(s, scene, y1, y2)|(s, scene, y1, y2,
|
||||
(s>0).then_some(self.arrangement().scenes()[s-1].color)))
|
||||
}
|
||||
fn scenes_clips <'a> (&'a self, editor: &'a Option<MidiEditor>)
|
||||
-> impl Content<TuiOut> + 'a
|
||||
{
|
||||
per_track(||self.tracks_with_sizes_scrolled(),
|
||||
move|track_index, track|Map::new(move||self.scenes_with_clip(track_index),
|
||||
move|(s, scene, y1, y2, previous): SceneWith<'_, Option<ItemTheme>>, _|{
|
||||
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 = self.track_selected() == Some(track_index);
|
||||
let selected = same_track && self.scene_selected() == Some(s);
|
||||
let neighbor = same_track && s > 0 && self.scene_selected() == Some(s - 1);
|
||||
let is_last = self.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(
|
||||
self.is_editing() && same_track && self.scene_selected() == Some(s),
|
||||
editor
|
||||
)))
|
||||
}))
|
||||
}
|
||||
fn scenes_with_clip (&self, track_index: usize) -> impl Iterator<Item=SceneWith<'_, Option<ItemTheme>>> + Send + Sync {
|
||||
self.scenes_iter().map(move|(s, scene, y1, y2)|(s, scene, y1, y2,
|
||||
(s>0).then_some(self.arrangement().scenes()[s-1].clips[track_index].as_ref()
|
||||
.map(|c|c.read().unwrap().color)
|
||||
.unwrap_or(ItemTheme::G[32]))))
|
||||
}
|
||||
/// A scene with size and color.
|
||||
fn scenes_iter (&self) -> impl Iterator<Item=(usize, &Scene, usize, usize,)> + Send + Sync {
|
||||
let selection = Has::<Selection>::get(self.arrangement());
|
||||
self.arrangement().scenes_with_sizes(
|
||||
self.is_editing(),
|
||||
Self::H_SCENE, Self::H_EDITOR,
|
||||
selection.track(), selection.scene(),
|
||||
).map_while(|(s, scene, y1, y2)|(y2<=self.scenes_height() as usize)
|
||||
.then_some((s, scene, y1, y2)))
|
||||
}
|
||||
fn tracks_with_sizes_scrolled <'t> (&'t self) -> impl TracksSizes<'t> {
|
||||
self.arrangement()
|
||||
.tracks_with_sizes(
|
||||
&self.arrangement().selection(),
|
||||
self.is_editing().then_some(20/*FIXME*/)
|
||||
)
|
||||
.map_while(move|(t, track, x1, x2)|{
|
||||
(self.width_mid() > x2 as u16).then_some((t, track, x1, x2))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> ArrangerSceneRows for ArrangerView<'a> {
|
||||
fn arrangement (&self) -> &Arrangement {
|
||||
self.arrangement
|
||||
}
|
||||
fn scenes_height (&self) -> u16 {
|
||||
self.scenes_height
|
||||
}
|
||||
fn width_side (&self) -> u16 {
|
||||
self.width_side
|
||||
}
|
||||
fn width_mid (&self) -> u16 {
|
||||
self.width_mid
|
||||
}
|
||||
fn scene_selected (&self) -> Option<usize> {
|
||||
self.arrangement.selection.scene()
|
||||
}
|
||||
fn scene_last (&self) -> usize {
|
||||
self.scene_last
|
||||
}
|
||||
fn track_selected (&self) -> Option<usize> {
|
||||
self.arrangement.selection.track()
|
||||
}
|
||||
fn is_editing (&self) -> bool {
|
||||
self.is_editing
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Has<Vec<Scene>> + Send + Sync> HasScenes for T {}
|
||||
|
||||
pub trait HasScenes: Has<Vec<Scene>> + Send + Sync {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue