mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
replace old Split component
This commit is contained in:
parent
e845d252b7
commit
60406e1d32
9 changed files with 141 additions and 107 deletions
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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()];
|
||||||
|
|
|
||||||
|
|
@ -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(())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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(())
|
||||||
|
}))
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue