replace old Split component

This commit is contained in:
🪞👃🪞 2024-09-10 23:12:02 +03:00
parent e845d252b7
commit 60406e1d32
9 changed files with 141 additions and 107 deletions

View file

@ -52,6 +52,29 @@ impl<'a, E: Engine> Collect<'a, E> for Collection<'a, E> {
} }
} }
pub struct Split<
E: Engine,
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
>(pub F, pub Direction, PhantomData<E>);
impl<
E: Engine,
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
> Split<E, F> {
#[inline]
pub fn new (direction: Direction, build: F) -> Self {
Self(build, direction, Default::default())
}
#[inline]
pub fn right (build: F) -> Self {
Self::new(Direction::Right, build)
}
#[inline]
pub fn down (build: F) -> Self {
Self::new(Direction::Down, build)
}
}
pub struct Layers< pub struct Layers<
E: Engine, E: Engine,
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()> F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
@ -61,6 +84,7 @@ impl<
E: Engine, E: Engine,
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()> F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = E>)->Usually<()>)->Usually<()>
> Layers<E, F> { > Layers<E, F> {
#[inline]
pub fn new (build: F) -> Self { pub fn new (build: F) -> Self {
Self(build, Default::default()) Self(build, Default::default())
} }
@ -83,43 +107,6 @@ impl Direction {
} }
} }
pub struct Split<'a, E: Engine> {
pub items: Collection<'a, E>,
pub direction: Direction,
pub focus: Option<usize>
}
impl<'a, E: Engine> Split<'a, E> {
pub fn new (direction: Direction) -> Self {
Self {
items: Collection::new(),
direction,
focus: None
}
}
pub fn down () -> Self {
Self::new(Direction::Down)
}
pub fn right () -> Self {
Self::new(Direction::Right)
}
pub fn focus (mut self, focus: Option<usize>) -> Self {
self.focus = focus;
self
}
}
impl<'a, E: Engine> Collect<'a, E> for Split<'a, E> {
fn add_box (mut self, item: Box<dyn Widget<Engine = E> + 'a>) -> Self {
self.items = self.items.add_box(item);
self
}
fn add_ref (mut self, item: &'a dyn Widget<Engine = E>) -> Self {
self.items = self.items.add_ref(item);
self
}
}
/// Override X and Y coordinates, aligning to corner, side, or center of area /// Override X and Y coordinates, aligning to corner, side, or center of area
pub enum Align<L> { pub enum Align<L> {
Center(L), Center(L),

View file

@ -1,55 +1,82 @@
use crate::*; use crate::*;
impl<'a> Widget for Split<'a, Tui> { impl<F> Widget for Split<Tui, F>
where
F: Send + Sync + Fn(&mut dyn FnMut(&dyn Widget<Engine = Tui>)->Usually<()>)->Usually<()>
{
type Engine = Tui; type Engine = Tui;
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { fn layout (&self, to: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
Ok(Some(self.render_areas(to)?.0))
}
}
// TODO
impl<'a> Split<'a, Tui> {
pub fn render_areas (&self, to: &mut Tui) -> Usually<([u16;4], Vec<Option<[u16;4]>>)> {
let area = to.area();
let mut w = 0; let mut w = 0;
let mut h = 0; let mut h = 0;
let mut areas = vec![]; match self.1 {
Ok((match self.direction {
Direction::Down => { Direction::Down => {
for component in self.items.0.iter() { (self.0)(&mut |component| {
if h >= area.h() { if h >= to.h() {
break return Ok(())
} }
let offset = Offset::Y(h, component as &dyn Widget<Engine = Tui>); if let Some([_, _, width, height]) = Offset::Y(
let result = offset.render(to)?; h, component as &dyn Widget<Engine = Tui>
areas.push(result); ).layout(to)? {
if let Some([_, _, width, height]) = result {
h += height; h += height;
w = w.max(width) w = w.max(width)
} }
} Ok(())
[area.x(), area.y(), w, h] })?;
}, },
Direction::Right => { Direction::Right => {
for component in self.items.0.iter() { (self.0)(&mut |component| {
if w >= area.x() { if w >= to.w() {
break return Ok(())
} }
let offset = Offset::X(w, component as &dyn Widget<Engine = Tui>); if let Some([_, _, width, height]) = Offset::X(
let result = offset.render(to)?; w, component as &dyn Widget<Engine = Tui>
areas.push(result); ).layout(to)? {
if let Some([_, _, width, height]) = result {
w += width; w += width;
h = h.max(height) h = h.max(height)
} }
} Ok(())
[area.x(), area.y(), w, h] })?;
}, },
_ => todo!() _ => todo!()
}, areas)) };
Ok(Some([to.x(), to.y(), w, h]))
}
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area();
let mut w = 0;
let mut h = 0;
match self.1 {
Direction::Down => {
(self.0)(&mut |component| {
if h >= area.h() {
return Ok(())
}
if let Some([_, _, width, height]) = Offset::Y(
h, component as &dyn Widget<Engine = Tui>
).render(to)? {
h += height;
w = w.max(width)
};
Ok(())
})?;
},
Direction::Right => {
(self.0)(&mut |component| {
if w >= area.w() {
return Ok(())
}
if let Some([_, _, width, height]) = Offset::X(
w, component as &dyn Widget<Engine = Tui>
).render(to)? {
w += width;
h = h.max(height)
};
Ok(())
})?;
},
_ => todo!()
};
Ok(Some([area.x(), area.y(), w, h]))
} }
} }

View file

@ -33,10 +33,11 @@ impl<E: Engine> Audio for Mixer<E> {
impl Content for Mixer<Tui> { impl Content for Mixer<Tui> {
type Engine = Tui; type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> { fn content (&self) -> impl Widget<Engine = Tui> {
let mut tracks = Split::right(); Split::right(|add| {
for channel in self.tracks.iter() { for channel in self.tracks.iter() {
tracks = tracks.add_ref(channel) add(channel)?;
} }
tracks Ok(())
})
} }
} }

View file

@ -82,10 +82,12 @@ impl Widget for ArrangerStandalone<Tui> {
let area = to.area(); let area = to.area();
let sequencer = self.arranger.sequencer() let sequencer = self.arranger.sequencer()
.map(|t|t as &dyn Widget<Engine = Tui>); .map(|t|t as &dyn Widget<Engine = Tui>);
let result = Split::down() let result = Split::down(|add|{
.add_ref(&self.transport) add(&self.transport)?;
.add_ref(&self.arranger) add(&self.arranger)?;
.add_ref(&sequencer) add(&sequencer)?;
Ok(())
})
//.focus(Some(self.focus)) //.focus(Some(self.focus))
.render(to)?; .render(to)?;
if let Some(ref modal) = self.arranger.modal { if let Some(ref modal) = self.arranger.modal {

View file

@ -6,14 +6,16 @@ pub fn draw (state: &Arranger<Tui>, to: &mut Tui) -> Perhaps<[u16;4]> {
let tracks = state.tracks.as_slice(); let tracks = state.tracks.as_slice();
Layers::new(|add|{ Layers::new(|add|{
add(&state.focused.then_some(FillBg(COLOR_BG0)))?; add(&state.focused.then_some(FillBg(COLOR_BG0)))?;
add(&Split::right() add(&Split::right(|add|{
.add(TrackNameColumn(tracks, state.selected)) add(&TrackNameColumn(tracks, state.selected))?;
.add(TrackMonitorColumn(tracks)) add(&TrackMonitorColumn(tracks))?;
.add(TrackRecordColumn(tracks)) add(&TrackRecordColumn(tracks))?;
.add(TrackOverdubColumn(tracks)) add(&TrackOverdubColumn(tracks))?;
.add(TrackEraseColumn(tracks)) add(&TrackEraseColumn(tracks))?;
.add(TrackGainColumn(tracks)) add(&TrackGainColumn(tracks))?;
.add(TrackScenesColumn(tracks, state.scenes.as_slice(), state.selected))) add(&TrackScenesColumn(tracks, state.scenes.as_slice(), state.selected))?;
Ok(())
}))
}).render(to.with_rect(area)) }).render(to.with_rect(area))
} }

View file

@ -43,9 +43,10 @@ pub fn draw <'a, 'b> (
add(&ColumnSeparators(offset, cols))?; add(&ColumnSeparators(offset, cols))?;
add(&RowSeparators(rows))?; add(&RowSeparators(rows))?;
add(&CursorFocus(state.selected, offset, cols, rows))?; add(&CursorFocus(state.selected, offset, cols, rows))?;
add(&Split::down() add(&Split::right(|add|{
.add_ref(&TracksHeader(offset, cols, tracks)) add(&TracksHeader(offset, cols, tracks))?;
.add_ref(&SceneRows(offset, cols, rows, tracks, scenes))) add(&SceneRows(offset, cols, rows, tracks, scenes))
}))
}).render(to.with_rect(area)) }).render(to.with_rect(area))
} }

View file

@ -6,12 +6,13 @@ impl Sequencer<Tui> {
pub(crate) fn horizontal_draw <'a> (&self, to: &mut Tui) -> Usually<()> { pub(crate) fn horizontal_draw <'a> (&self, to: &mut Tui) -> Usually<()> {
let area = to.area(); let area = to.area();
Split::down() Split::down(|add|{
.add_ref(&SequenceName(&self)) add(&SequenceName(&self))?;
.add_ref(&SequenceRange) add(&SequenceRange)?;
.add_ref(&SequenceLoopRange) add(&SequenceLoopRange)?;
.add_ref(&SequenceNoteRange) add(&SequenceNoteRange)?;
.render(to.with_area(area.x(), area.y(), 10, area.h()))?; Ok(())
}).render(to.with_area(area.x(), area.y(), 10, area.h()))?;
let area = [area.x() + 10, area.y(), area.w().saturating_sub(10), area.h().min(66)]; let area = [area.x() + 10, area.y(), area.w().saturating_sub(10), area.h().min(66)];
Lozenge(Style::default().fg(Nord::BG2)).draw(to.with_rect(area))?; Lozenge(Style::default().fg(Nord::BG2)).draw(to.with_rect(area))?;
let area = [area.x() + 1, area.y(), area.w().saturating_sub(1), area.h()]; let area = [area.x() + 1, area.y(), area.w().saturating_sub(1), area.h()];

View file

@ -5,12 +5,14 @@ const CORNERS: Corners = Corners(NOT_DIM_GREEN);
impl Content for TransportToolbar<Tui> { impl Content for TransportToolbar<Tui> {
type Engine = Tui; type Engine = Tui;
fn content (&self) -> impl Widget<Engine = Tui> { fn content (&self) -> impl Widget<Engine = Tui> {
Split::right() Split::right(|add|{
.add_ref(&self.playing) add(&self.playing)?;
.add_ref(&self.bpm) add(&self.bpm)?;
.add_ref(&self.quant) add(&self.quant)?;
.add_ref(&self.sync) add(&self.sync)?;
.add_ref(&self.clock) add(&self.clock)?;
Ok(())
})
} }
} }

View file

@ -40,10 +40,21 @@ impl Content for Demo<Tui> {
//Align::Center(&self.items[self.index] as &dyn Widget<Engine = Tui>) //Align::Center(&self.items[self.index] as &dyn Widget<Engine = Tui>)
Align::Center(Layers::new(|add|{ Align::Center(Layers::new(|add|{
add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,128))))?; add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,128))))?;
add(&Layers::new(|add|{ add(&Split::down(|add|{
add(&Align::Center("....."))?; add(&Layers::new(|add|{
add(&Align::Center("FOO"))?; add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,128,0))))?;
Ok(()) add(&Align::Center("55555"))?;
add(&Align::Center("FOO"))?;
//add(&FillBg(Color::Rgb(0,128,0)))?;
Ok(())
}))?;
add(&Layers::new(|add|{
add(&Outset::WH(1, 1, FillBg(Color::Rgb(0,0,128))))?;
add(&Align::Center("7777777"))?;
add(&Align::Center("BAR"))?;
//add(&FillBg(Color::Rgb(0,0,128)))?;
Ok(())
}))
})) }))
})) }))
} }