mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 03:36:41 +01:00
ohh why did i begin this refactor. e57
This commit is contained in:
parent
83eb9dd2fa
commit
49adf34b02
6 changed files with 46 additions and 41 deletions
|
|
@ -18,29 +18,30 @@ pub trait Output<E: Engine> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Content<E: Engine>: Send + Sync {
|
pub trait Content<E: Engine>: Send + Sync {
|
||||||
fn content (&self) -> Option<impl Content<E>> {
|
fn content (&self) -> impl Content<E> {
|
||||||
None::<()>
|
()
|
||||||
}
|
}
|
||||||
fn area (&self, area: E::Area) -> E::Area {
|
fn area (&self, area: E::Area) -> E::Area {
|
||||||
if let Some(content) = self.content() {
|
self.content().area(area)
|
||||||
content.area(area)
|
|
||||||
} else {
|
|
||||||
[0.into(), 0.into(), 0.into(), 0.into()].into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
fn render (&self, output: &mut E::Output) {
|
fn render (&self, output: &mut E::Output) {
|
||||||
if let Some(content) = self.content() {
|
self.content().render(output)
|
||||||
output.place(self.area(output.area()), &content)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: Engine> Content<E> for () {}
|
impl<E: Engine> Content<E> for () {
|
||||||
|
fn area (&self, area: E::Area) -> E::Area {
|
||||||
|
[0.into(), 0.into(), 0.into(), 0.into()].into()
|
||||||
|
}
|
||||||
|
fn render (&self, output: &mut E::Output) {}
|
||||||
|
}
|
||||||
|
|
||||||
impl<E: Engine, T: Content<E>> Content<E> for &T {}
|
impl<E: Engine, T: Content<E>> Content<E> for &T {}
|
||||||
|
|
||||||
impl<E: Engine, T: Content<E>> Content<E> for Option<T> {}
|
impl<E: Engine, T: Content<E>> Content<E> for Option<T> {}
|
||||||
|
|
||||||
|
impl<E: Engine, T: Content<E>> Content<E> for Vec<T> {}
|
||||||
|
|
||||||
#[macro_export] macro_rules! render {
|
#[macro_export] macro_rules! render {
|
||||||
(($self:ident:$Struct:ty) => $content:expr) => {
|
(($self:ident:$Struct:ty) => $content:expr) => {
|
||||||
impl <E: Engine> Content<E> for $Struct {
|
impl <E: Engine> Content<E> for $Struct {
|
||||||
|
|
|
||||||
|
|
@ -175,11 +175,10 @@ fn align<E: Engine, T: Content<E>, N: Coordinate, R: Area<N> + From<[N;4]>> (ali
|
||||||
impl<E: Engine, T: Content<E>> Content<E> for Align<E, T> {
|
impl<E: Engine, T: Content<E>> Content<E> for Align<E, T> {
|
||||||
fn render (&self, to: &mut E::Output) {
|
fn render (&self, to: &mut E::Output) {
|
||||||
let outer_area = to.area();
|
let outer_area = to.area();
|
||||||
if let Some(content) = self.content() {
|
let content = self.content();
|
||||||
let inner_area = content.area(outer_area);
|
let inner_area = content.area(outer_area);
|
||||||
if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) {
|
if let Some(aligned) = align(&self, outer_area.into(), inner_area.into()) {
|
||||||
to.place(aligned, &content)
|
to.place(aligned, &content)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -102,23 +102,25 @@ impl ArrangerTui {
|
||||||
render!(Tui: (self: ArrangerTui) => {
|
render!(Tui: (self: ArrangerTui) => {
|
||||||
let play = PlayPause(self.clock.is_rolling());
|
let play = PlayPause(self.clock.is_rolling());
|
||||||
let transport = TransportView::new(self, Some(ItemPalette::from(TuiTheme::g(96))), true);
|
let transport = TransportView::new(self, Some(ItemPalette::from(TuiTheme::g(96))), true);
|
||||||
let with_transport = |x|col!(row!(&play, &transport), &x);
|
|
||||||
let pool_size = if self.phrases.visible { self.splits[1] } else { 0 };
|
let pool_size = if self.phrases.visible { self.splits[1] } else { 0 };
|
||||||
let with_pool = |x|Split::w(false, pool_size, PoolView(&self.phrases), x);
|
let with_pool = |x|Split::w(false, pool_size, PoolView(&self.phrases), x);
|
||||||
let status = ArrangerStatus::from(self);
|
let status = ArrangerStatus::from(self);
|
||||||
let with_editbar = |x|Split::n(false, 1, MidiEditStatus(&self.editor), x);
|
let with_editbar = |x|Split::n(false, 1, MidiEditStatus(&self.editor), x);
|
||||||
let with_status = |x|Split::n(false, 2, status, x);
|
let with_status = |x|Split::n(false, 2, status, x);
|
||||||
let with_size = |x|lay!(&self.size, x);
|
let with_size = |x|lay!(&self.size, x);
|
||||||
let arranger = ||lay!(|add|{
|
let arranger = ||{
|
||||||
let color = self.color;
|
let color = self.color;
|
||||||
add(&Fill::xy(Tui::bg(color.darkest.rgb, "")))?;
|
lay!(
|
||||||
add(&Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))))?;
|
Fill::xy(Tui::bg(color.darkest.rgb, "")),
|
||||||
add(&Self::render_mode(self))
|
Fill::xy(Outer(Style::default().fg(color.dark.rgb).bg(color.darkest.rgb))),
|
||||||
});
|
Self::render_mode(self),
|
||||||
with_size(with_status(with_editbar(with_pool(with_transport(col!(
|
)
|
||||||
|
};
|
||||||
|
with_size(with_status(with_editbar(with_pool(col!(
|
||||||
|
row!(play, transport),
|
||||||
Fill::x(Fixed::y(20, arranger())),
|
Fill::x(Fixed::y(20, arranger())),
|
||||||
Fill::xy(&self.editor),
|
Fill::xy(&self.editor),
|
||||||
))))))
|
)))))
|
||||||
});
|
});
|
||||||
audio!(|self: ArrangerTui, client, scope|{
|
audio!(|self: ArrangerTui, client, scope|{
|
||||||
// Start profiling cycle
|
// Start profiling cycle
|
||||||
|
|
|
||||||
|
|
@ -17,12 +17,11 @@ impl<'a> ArrangerVClips<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a, E: Engine> Content<E> for ArrangerVClips<'a> {
|
impl<'a> Content<Tui> for ArrangerVClips<'a> {
|
||||||
fn content (&self) -> Option<impl Content<E>> {
|
fn content (&self) -> impl Content<Tui> {
|
||||||
let iter = self.scenes.iter().zip(self.rows.iter().map(|row|row.0));
|
let iter = self.scenes.iter().zip(self.rows.iter().map(|row|row.0));
|
||||||
let col = Coll::map(self.scenes.iter().zip(self.rows.iter().map(|row|row.0)), |(scene, pulses), i|
|
let col = Coll::map(iter, |(scene, pulses), i|Self::format_scene(self.tracks, scene, pulses));
|
||||||
Self::format_scene(self.tracks, scene, pulses));
|
Fill::xy(col)
|
||||||
Some(Fill::xy(col))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> ArrangerVClips<'a> {
|
impl<'a> ArrangerVClips<'a> {
|
||||||
|
|
@ -30,15 +29,19 @@ impl<'a> ArrangerVClips<'a> {
|
||||||
fn format_scene (
|
fn format_scene (
|
||||||
tracks: &'a [ArrangerTrack], scene: &'a ArrangerScene, pulses: usize
|
tracks: &'a [ArrangerTrack], scene: &'a ArrangerScene, pulses: usize
|
||||||
) -> impl Content<Tui> + use<'a> {
|
) -> impl Content<Tui> + use<'a> {
|
||||||
let height = 1.max((pulses / PPQ) as u16);
|
let height = 1.max((pulses / PPQ) as u16);
|
||||||
let playing = scene.is_playing(tracks);
|
let playing = scene.is_playing(tracks);
|
||||||
Fixed::y(height, row!(
|
let icon = Tui::bg(
|
||||||
Tui::bg(scene.color.base.rgb,
|
scene.color.base.rgb, if playing { "▶ " } else { " " }
|
||||||
if playing { "▶ " } else { " " }),
|
);
|
||||||
Tui::fg_bg(scene.color.lightest.rgb, scene.color.base.rgb,
|
let name = Tui::fg_bg(scene.color.lightest.rgb, scene.color.base.rgb,
|
||||||
Expand::x(1, Tui::bold(true, scene.name.read().unwrap().as_str()))),
|
Expand::x(1, Tui::bold(true, scene.name.read().unwrap().clone()))
|
||||||
Coll::map(ArrangerTrack::with_widths(tracks), |(index, track, x1, x2), _|
|
);
|
||||||
Push::x(Self::format_clip(scene, index, track, (x2 - x1) as u16, height)))))}
|
let clips = Coll::map(ArrangerTrack::with_widths(tracks), move|(index, track, x1, x2), _|
|
||||||
|
Push::x((x2 - x1) as u16, Self::format_clip(scene, index, track, (x2 - x1) as u16, height))
|
||||||
|
);
|
||||||
|
Fixed::y(height, row!(icon, name, clips))
|
||||||
|
}
|
||||||
|
|
||||||
fn format_clip (
|
fn format_clip (
|
||||||
scene: &'a ArrangerScene, index: usize, track: &'a ArrangerTrack, w: u16, h: u16
|
scene: &'a ArrangerScene, index: usize, track: &'a ArrangerTrack, w: u16, h: u16
|
||||||
|
|
|
||||||
|
|
@ -13,12 +13,12 @@ from!(|state:&ArrangerTui|ArrangerVColSep = Self {
|
||||||
});
|
});
|
||||||
render!(Tui: |self: ArrangerVColSep, to| {
|
render!(Tui: |self: ArrangerVColSep, to| {
|
||||||
let style = Some(Style::default().fg(self.fg));
|
let style = Some(Style::default().fg(self.fg));
|
||||||
Ok(for x in self.cols.iter().map(|col|col.1) {
|
for x in self.cols.iter().map(|col|col.1) {
|
||||||
let x = self.scenes_w + to.area().x() + x as u16;
|
let x = self.scenes_w + to.area().x() + x as u16;
|
||||||
for y in to.area().y()..to.area().y2() {
|
for y in to.area().y()..to.area().y2() {
|
||||||
to.blit(&"▎", x, y, style);
|
to.blit(&"▎", x, y, style);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
pub struct ArrangerVRowSep {
|
pub struct ArrangerVRowSep {
|
||||||
|
|
|
||||||
|
|
@ -119,7 +119,7 @@ render!(Tui: (self: MidiEditor) => {
|
||||||
|
|
||||||
//render!(<Tui>|self: MidiEditor|lay!(|add|{add(&self.size)?;add(self.mode)}));//bollocks
|
//render!(<Tui>|self: MidiEditor|lay!(|add|{add(&self.size)?;add(self.mode)}));//bollocks
|
||||||
|
|
||||||
pub trait PhraseViewMode: Content<Tui> + HasSize<Tui> + MidiRange + MidiPoint + Debug + Send + Sync {
|
pub trait PhraseViewMode: HasSize<Tui> + MidiRange + MidiPoint + Debug + Send + Sync {
|
||||||
fn buffer_size (&self, phrase: &MidiClip) -> (usize, usize);
|
fn buffer_size (&self, phrase: &MidiClip) -> (usize, usize);
|
||||||
fn redraw (&mut self);
|
fn redraw (&mut self);
|
||||||
fn phrase (&self) -> &Option<Arc<RwLock<MidiClip>>>;
|
fn phrase (&self) -> &Option<Arc<RwLock<MidiClip>>>;
|
||||||
|
|
@ -131,7 +131,7 @@ pub trait PhraseViewMode: Content<Tui> + HasSize<Tui> + MidiRange + MidiPoint +
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Content<Tui> for Box<dyn PhraseViewMode> {
|
impl Content<Tui> for Box<dyn PhraseViewMode> {
|
||||||
fn content (&self) -> Option<impl Content<Tui>> {
|
fn content (&self) -> impl Content<Tui> {
|
||||||
Some(&(*self))
|
Some(&(*self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue