mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 03:36:41 +01:00
sensible arranger entrypoint! now let's see whats up with the align modifiers
This commit is contained in:
parent
0ee3059cf8
commit
f052891473
7 changed files with 180 additions and 105 deletions
|
|
@ -20,6 +20,7 @@ impl<'a, E: Output> Content<E> for &RenderDyn<'a, E> where Self: Sized {
|
|||
pub type RenderBox<'a, E: Output> = Box<RenderDyn<'a, E>>;
|
||||
impl<'a, E: Output> Content<E> for RenderBox<'a, E> {
|
||||
fn content (&self) -> impl Render<E> { self.deref() }
|
||||
//fn boxed <'b> (self) -> RenderBox<'b, E> where Self: Sized + 'b { self }
|
||||
}
|
||||
|
||||
impl<E: Output, C: Content<E>> Render<E> for C {
|
||||
|
|
|
|||
|
|
@ -4,12 +4,34 @@ use std::marker::PhantomData;
|
|||
/// Lazily-evaluated [Render]able.
|
||||
pub struct Thunk<E: Output, T: Render<E>, F: Fn()->T + Send + Sync>(PhantomData<E>, F);
|
||||
impl<E: Output, T: Render<E>, F: Fn()->T + Send + Sync> Thunk<E, T, F> {
|
||||
pub fn new (thunk: F) -> Self { Self(Default::default(), thunk) }
|
||||
pub fn new (thunk: F) -> Self {
|
||||
Self(Default::default(), thunk)
|
||||
}
|
||||
}
|
||||
impl<E: Output, T: Render<E>, F: Fn()->T + Send + Sync> Content<E> for Thunk<E, T, F> {
|
||||
fn content (&self) -> impl Render<E> { (self.1)() }
|
||||
}
|
||||
|
||||
pub struct BoxThunk<'a, E: Output>(PhantomData<E>, Box<dyn Fn()->Box<dyn Render<E> + 'a> + Send + Sync + 'a>);
|
||||
impl<'a, E: Output> BoxThunk<'a, E> {
|
||||
pub fn new (thunk: Box<dyn Fn()->Box<dyn Render<E> + 'a> + Send + Sync + 'a>) -> Self {
|
||||
Self(Default::default(), thunk)
|
||||
}
|
||||
}
|
||||
impl<'a, E: Output> Content<E> for BoxThunk<'a, E> {
|
||||
fn content (&self) -> impl Render<E> { (self.1)() }
|
||||
}
|
||||
impl<'a, E: Output, F: Fn()->T + Send + Sync + 'a, T: Render<E> + Send + Sync + 'a> From<F> for BoxThunk<'a, E> {
|
||||
fn from (f: F) -> Self {
|
||||
Self(Default::default(), Box::new(move||f().boxed()))
|
||||
}
|
||||
}
|
||||
//impl<'a, E: Output, F: Fn()->Box<dyn Render<E> + 'a> + Send + Sync + 'a> From<F> for BoxThunk<'a, E> {
|
||||
//fn from (f: F) -> Self {
|
||||
//Self(Default::default(), Box::new(f))
|
||||
//}
|
||||
//}
|
||||
|
||||
pub struct RenderThunk<E: Output, F: Fn(&mut E) + Send + Sync>(PhantomData<E>, F);
|
||||
impl<E: Output, F: Fn(&mut E) + Send + Sync> RenderThunk<E, F> {
|
||||
pub fn new (render: F) -> Self { Self(Default::default(), render) }
|
||||
|
|
|
|||
|
|
@ -9,9 +9,6 @@ mod arranger_tui; pub(crate) use self::arranger_tui::*;
|
|||
mod arranger_mode; pub(crate) use self::arranger_mode::*;
|
||||
mod arranger_h;
|
||||
|
||||
pub(crate) const HEADER_H: u16 = 0; // 5
|
||||
pub(crate) const SCENES_W_OFFSET: u16 = 3;
|
||||
|
||||
/// Root view for standalone `tek_arranger`
|
||||
pub struct Arranger {
|
||||
jack: Arc<RwLock<JackConnection>>,
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ impl Arranger {
|
|||
todo!("delete scene");
|
||||
}
|
||||
fn scene_default_name (&self) -> String {
|
||||
format!("S{:3>}", self.scenes.len() + 1)
|
||||
format!("Sc{:3>}", self.scenes.len() + 1)
|
||||
}
|
||||
pub fn selected_scene (&self) -> Option<&ArrangerScene> {
|
||||
self.selected.scene().and_then(|s|self.scenes.get(s))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use crate::*;
|
||||
impl Arranger {
|
||||
pub fn track_next_name (&self) -> String {
|
||||
format!("T{}", self.tracks.len() + 1)
|
||||
format!("Tr{}", self.tracks.len() + 1)
|
||||
}
|
||||
pub fn track_add (&mut self, name: Option<&str>, color: Option<ItemPalette>)
|
||||
-> Usually<&mut ArrangerTrack>
|
||||
|
|
|
|||
|
|
@ -7,46 +7,18 @@ render!(TuiOut: (self: Arranger) => {
|
|||
let scene_heights = Arranger::scene_heights(scenes, 1);
|
||||
let border_style_1 = Style::default().fg(Color::Rgb(48,48,48));
|
||||
let border_style_2 = Style::default().fg(Color::Rgb(72,72,72));
|
||||
let frame = Bsp::s(self.track_column_headers(),
|
||||
Bsp::n(self.track_column_inputs(),
|
||||
Bsp::s(self.track_column_outputs(),
|
||||
Bsp::b(self.track_column_separators(), ""))));
|
||||
let arranger = Bsp::n(
|
||||
Fixed::y(20, Outer(border_style_2).enclose(&self.editor)),
|
||||
Outer(border_style_1).enclose(Bsp::w(frame,
|
||||
Bsp::s(Fixed::y(1, Tui::bold(true, Tui::fg(TuiTheme::g(128), "Track"))),
|
||||
Bsp::s(Fixed::y(1, Tui::bold(true, Tui::fg(TuiTheme::g(128), "Playing"))),
|
||||
Bsp::s(Fixed::y(1, Tui::bold(true, Tui::fg(TuiTheme::g(128), "Next"))),
|
||||
Bsp::s(Fixed::y(1, Tui::bold(true, Tui::fg(TuiTheme::g(128), "Out 1: NI"))),
|
||||
Bsp::n(Fixed::y(1, Tui::bold(true, Tui::fg(TuiTheme::g(128), "In 1: Korg"))),
|
||||
Fixed::x(scenes_w, self.scene_row_headers())))))))));
|
||||
self.size.of(
|
||||
Bsp::s(self.toolbar_view(),
|
||||
Bsp::n(self.status_view(),
|
||||
Bsp::w(self.pool_view(),
|
||||
Bsp::n(self.editor_status_view(),
|
||||
arranger)))))
|
||||
//Outer(border_style).enclose(Tui::bg(Color::Rgb(0,32,0), self.track_column_headers())))))))) [>Align::nw(Fill::xy(Bsp::s(
|
||||
//Align::w(Fill::x(
|
||||
//Bsp::s(Align::w(Fixed::y(3, self.track_column_headers())),
|
||||
//Bsp::s(Fixed::y(1, self.ins()), Fill::x(Fixed::y(1, self.outs()))))
|
||||
//)),*/
|
||||
//""
|
||||
//Bsp::a(
|
||||
//Bsp::a(
|
||||
//Map::new(
|
||||
//move||scenes.iter(),//.zip(scene_heights.iter().map(|row|row.0)),
|
||||
//move|scene, i|Arranger::cell_scene(&self.tracks, scene, scene_heights[i].0)
|
||||
//),
|
||||
//self.cursor(),
|
||||
//),
|
||||
//Bsp::a(
|
||||
//Fill::xy(self.scene_row_sep()),
|
||||
//""
|
||||
////Fill::xy(ArrangerVColSep::from(self))
|
||||
//)
|
||||
//)
|
||||
//)))))))))))
|
||||
let toolbar = |x|Bsp::s(self.toolbar_view(), x);
|
||||
let status = |x|Bsp::n(self.status_view(), x);
|
||||
let pool = |x|Bsp::w(self.pool_view(), x);
|
||||
let editing = |x|Bsp::n(self.editor_status_view(), x);
|
||||
let editor = Fixed::y(20, Outer(border_style_2).enclose(&self.editor));
|
||||
let arrrrrr = Fixed::y(20, Map::new(
|
||||
move||self.grid_rows(),
|
||||
move|(height, header, cells), index|map_south(
|
||||
index as u16, height, Fill::x(Align::w(Bsp::e(
|
||||
Fixed::x(scenes_w, header),
|
||||
cells))))));
|
||||
self.size.of(toolbar(status(pool(editing(Bsp::n(editor, arrrrrr))))))
|
||||
});
|
||||
pub struct ArrangerVClips<'a> {
|
||||
size: &'a Measure<TuiOut>,
|
||||
|
|
@ -64,12 +36,129 @@ impl<'a> ArrangerVClips<'a> {
|
|||
}
|
||||
}
|
||||
}
|
||||
fn row <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
||||
Tui::fg_bg(color.lightest.rgb, color.base.rgb, Fixed::y(1, field))
|
||||
}
|
||||
impl Arranger {
|
||||
pub const LEFT_SEP: char = '▎';
|
||||
pub const TRACK_MIN_WIDTH: usize = 4;
|
||||
|
||||
fn grid_rows <'a> (&'a self) -> impl Iterator<Item=(u16, BoxThunk<'a, TuiOut>, BoxThunk<'a, TuiOut>)> + 'a {
|
||||
[
|
||||
(2, self.output_row_header(), self.output_row_cells()),
|
||||
(2, self.elapsed_row_header(), self.elapsed_row_cells()),
|
||||
(2, self.next_row_header(), self.next_row_cells()),
|
||||
(2, self.track_row_header(), self.track_row_cells()),
|
||||
(2, self.input_row_header(), self.input_row_cells()),
|
||||
(2 * (self.scenes.len() as u16 + 1), self.scene_row_headers(), self.scene_row_cells()),
|
||||
].into_iter()
|
||||
}
|
||||
|
||||
/// A 1-row cell.
|
||||
fn cell <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
||||
Tui::fg_bg(color.lightest.rgb, color.base.rgb, Fixed::y(1, field))
|
||||
}
|
||||
|
||||
/// A cell that is 3-row on its own, but stacks, giving (N+1)*2 rows per N cells.
|
||||
fn phat_cell <T: Content<TuiOut>> (color: ItemPalette, last: ItemPalette, field: T) -> impl Content<TuiOut> {
|
||||
Bsp::s(
|
||||
Fixed::y(1, Tui::fg_bg(color.base.rgb, last.base.rgb, RepeatH(&"▄"))),
|
||||
Bsp::s(
|
||||
Fixed::y(1, Fill::x(Tui::fg_bg(color.lightest.rgb, color.base.rgb, field))),
|
||||
Fixed::y(1, Tui::fg_bg(color.base.rgb, Color::Reset, RepeatH(&"▀"))),
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
fn track_row_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
(||Tui::bold(true, Tui::fg(TuiTheme::g(128), "Track")).boxed()).into()
|
||||
}
|
||||
fn track_row_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
(move||Fixed::y(1, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let color = track.color();
|
||||
Push::x(scenes_w, Tui::bg(color.base.rgb, map_east(x1 as u16, (x2 - x1) as u16,
|
||||
Tui::fg_bg(color.lightest.rgb, color.base.rgb,
|
||||
Self::cell(color, Tui::bold(true, format!("{}", track.name.read().unwrap())))))))
|
||||
})).boxed()).into()
|
||||
}
|
||||
|
||||
fn elapsed_row_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
(||Tui::bold(true, Tui::fg(TuiTheme::g(128), "Playing")).boxed()).into()
|
||||
}
|
||||
fn elapsed_row_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
(move||Fixed::y(1, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let color = track.color();
|
||||
Push::x(scenes_w, Tui::bg(color.base.rgb, map_east(x1 as u16, (x2 - x1) as u16,
|
||||
Tui::fg_bg(color.lightest.rgb, color.base.rgb, Self::cell_elapsed(track, self.clock().timebase())))))
|
||||
})).boxed()).into()
|
||||
}
|
||||
|
||||
fn next_row_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
(||Tui::bold(true, Tui::fg(TuiTheme::g(128), "Next")).boxed()).into()
|
||||
}
|
||||
fn next_row_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
(move||Fixed::y(1, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let color: ItemPalette = track.color();
|
||||
Push::x(scenes_w, Tui::bg(color.base.rgb, map_east(x1 as u16, (x2 - x1) as u16,
|
||||
Tui::fg_bg(color.lightest.rgb, color.base.rgb, Self::cell(color, Tui::bold(true, Self::cell_until_next(track, &self.clock().playhead)))))))
|
||||
})).boxed()).into()
|
||||
}
|
||||
|
||||
fn input_row_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
(||Fill::x(Tui::bold(true, Tui::fg_bg(TuiTheme::g(0), TuiTheme::g(200), "[ ] In 1: Korg"))).boxed()).into()
|
||||
}
|
||||
fn input_row_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
(move||Fixed::y(1, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let w = (x2 - x1) as u16;
|
||||
let cell = Self::cell_input(track).ok();
|
||||
let color: ItemPalette = track.color().dark.into();
|
||||
Push::x(scenes_w, map_east(x1 as u16, w, Fixed::x(w, Fixed::y(1, Self::cell(color, cell)))))
|
||||
})).boxed()).into()
|
||||
}
|
||||
fn cell_input (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
||||
Ok(format!("RecMon"))/*, track.player.midi_ins().first().map(|port|port.short_name())
|
||||
.transpose()?.unwrap_or("?".into())))*/
|
||||
}
|
||||
|
||||
fn output_row_header <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
(||Fill::x(Tui::bold(true, Tui::fg_bg(TuiTheme::g(0), TuiTheme::g(200), "[ ] Out 1: NI"))).boxed()).into()
|
||||
}
|
||||
fn output_row_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
(move||Fixed::y(1, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let w = (x2 - x1) as u16;
|
||||
let cell = Self::cell_output(track).ok();
|
||||
let color: ItemPalette = track.color().dark.into();
|
||||
Push::x(scenes_w, map_east(x1 as u16, w, Fixed::x(w, Fixed::y(1, Self::cell(color, cell)))))
|
||||
})).boxed()).into()
|
||||
}
|
||||
/// output port
|
||||
fn cell_output (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
||||
Ok(format!("MutSol"))/*, track.player.midi_outs().first().map(|port|port.short_name())
|
||||
.transpose()?.unwrap_or("?".into())))*/
|
||||
}
|
||||
|
||||
fn scene_row_headers <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
(||{
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
let last_color = Arc::new(RwLock::new(ItemPalette::from(Color::Rgb(0, 0, 0))));
|
||||
Tui::bg(Color::Rgb(0,0,0), Fill::y(Map::new(
|
||||
||self.scenes_with_heights(2),
|
||||
move|(_, scene, y1, y2), i| {
|
||||
let h = (y2 - y1) as u16;
|
||||
let color = scene.color();
|
||||
let cell = Self::phat_cell(color, *last_color.read().unwrap(), scene.name.read().unwrap().clone());
|
||||
*last_color.write().unwrap() = color;
|
||||
map_south(y1 as u16, 2, Fill::x(cell))
|
||||
}
|
||||
))).boxed()
|
||||
}).into()
|
||||
}
|
||||
fn scene_row_cells <'a> (&'a self) -> BoxThunk<'a, TuiOut> {
|
||||
(||"".boxed()).into()
|
||||
}
|
||||
|
||||
pub fn tracks_with_widths (&self)
|
||||
-> impl Iterator<Item = (usize, &ArrangerTrack, usize, usize)>
|
||||
{
|
||||
|
|
@ -93,51 +182,11 @@ impl Arranger {
|
|||
Fixed::x((x2 - x1) as u16, Tui::fg(fg, RepeatV(&"·")))))
|
||||
})
|
||||
}
|
||||
fn track_column_headers (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
Fixed::y(3, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let color = track.color();
|
||||
Push::x(scenes_w, Tui::bg(color.base.rgb, map_east(x1 as u16, (x2 - x1) as u16,
|
||||
Tui::fg_bg(color.lightest.rgb, color.base.rgb,
|
||||
Bsp::s(row(color, Tui::bold(true, format!("{}", track.name.read().unwrap()))),
|
||||
Bsp::s(
|
||||
row(color, Self::cell_elapsed(track, self.clock().timebase())),
|
||||
row(color, Self::cell_until_next(track, &self.clock().playhead))
|
||||
))))))
|
||||
}))
|
||||
}
|
||||
fn track_column_inputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
Fixed::y(1, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let w = (x2 - x1) as u16;
|
||||
let color = track.color();
|
||||
let cell = Self::cell_input(track).ok();
|
||||
Push::x(scenes_w, map_east(x1 as u16, w, Fixed::x(w, Fixed::y(1, row(color, cell)))))
|
||||
}))
|
||||
}
|
||||
fn track_column_outputs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
Fixed::y(1, Map::new(||self.tracks_with_widths(), move|(_, track, x1, x2), i| {
|
||||
let w = (x2 - x1) as u16;
|
||||
let color = track.color();
|
||||
let cell = Self::cell_output(track).ok();
|
||||
Push::x(scenes_w, map_east(x1 as u16, w, Fixed::x(w, Fixed::y(1, row(color, cell)))))
|
||||
}))
|
||||
}
|
||||
/// name and width of track
|
||||
fn cell_name (track: &ArrangerTrack, _w: usize) -> impl Content<TuiOut> {
|
||||
let name = track.name().read().unwrap().clone();
|
||||
Tui::bold(true, Tui::fg(track.color.lightest.rgb, name))
|
||||
}
|
||||
fn cell_input (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
||||
Ok(format!("⦗R⦘⦗M⦘"))/*, track.player.midi_ins().first().map(|port|port.short_name())
|
||||
.transpose()?.unwrap_or("?".into())))*/
|
||||
}
|
||||
/// output port
|
||||
fn cell_output (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
||||
Ok(format!("⦗M⦘⦗S⦘"))/*, track.player.midi_outs().first().map(|port|port.short_name())
|
||||
.transpose()?.unwrap_or("?".into())))*/
|
||||
}
|
||||
/// beats elapsed
|
||||
fn cell_elapsed (track: &ArrangerTrack, timebase: &Arc<Timebase>) -> impl Content<TuiOut> {
|
||||
let mut result = String::new();
|
||||
|
|
@ -164,29 +213,20 @@ impl Arranger {
|
|||
Some(result)
|
||||
}
|
||||
|
||||
pub fn scenes_with_heights (&self) -> impl Iterator<Item = (usize, &ArrangerScene, usize, usize)> {
|
||||
pub fn scenes_with_heights (&self, h: usize) -> impl Iterator<Item = (usize, &ArrangerScene, usize, usize)> {
|
||||
let mut y = 0;
|
||||
self.scenes.iter().enumerate().map(move|(index, scene)|{
|
||||
let data = (index, scene, y, y + 1);
|
||||
y += 1;
|
||||
let data = (index, scene, y, y + h);
|
||||
y += h;
|
||||
data
|
||||
})
|
||||
}
|
||||
fn scene_row_headers (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
Fill::y(Map::new(||self.scenes_with_heights(), move|(_, scene, y1, y2), i| {
|
||||
let h = (y2 - y1) as u16;
|
||||
let color = scene.color();
|
||||
let cell = row(color, scene.name.read().unwrap().clone());
|
||||
map_south(y1 as u16, 1, cell)
|
||||
}))
|
||||
}
|
||||
fn scene_rows (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||
Map::new(||self.scenes_with_heights(), move|(_, scene, y1, y2), i| {
|
||||
Map::new(||self.scenes_with_heights(1), move|(_, scene, y1, y2), i| {
|
||||
let h = (y2 - y1) as u16;
|
||||
let color = scene.color();
|
||||
let cell = Fixed::y(h, Fixed::x(scenes_w, row(color, scene.name.read().unwrap().clone())));
|
||||
let cell = Fixed::y(h, Fixed::x(scenes_w, Self::cell(color, scene.name.read().unwrap().clone())));
|
||||
map_south(y1 as u16, 1, cell)
|
||||
})
|
||||
}
|
||||
|
|
@ -279,7 +319,7 @@ impl Arranger {
|
|||
|
||||
fn scene_row_sep <'a> (&'a self) -> impl Content<TuiOut> + 'a {
|
||||
let fg = Color::Rgb(255,255,255);
|
||||
Map::new(move||self.scenes_with_heights(), |_, _|"")
|
||||
Map::new(move||self.scenes_with_heights(1), |_, _|"")
|
||||
//Map(||rows.iter(), |(_n, _scene, y1, _y2), _i| {
|
||||
//let y = to.area().y() + (y / PPQ) as u16 + 1;
|
||||
//if y >= to.buffer.area.height { break }
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ impl Content<TuiOut> for RepeatV<'_> {
|
|||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x, y, w, h] = to.area().xywh();
|
||||
let a = self.0.len();
|
||||
for y in y..y+h {
|
||||
if let Some(cell) = to.buffer.cell_mut(ratatui::prelude::Position::from((x, y))) {
|
||||
cell.set_symbol(&self.0);
|
||||
|
|
@ -54,3 +53,19 @@ impl Content<TuiOut> for RepeatV<'_> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RepeatH<'a>(pub &'a str);
|
||||
|
||||
impl Content<TuiOut> for RepeatH<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
to
|
||||
}
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x, y, w, h] = to.area().xywh();
|
||||
for x in x..x+w {
|
||||
if let Some(cell) = to.buffer.cell_mut(ratatui::prelude::Position::from((x, y))) {
|
||||
cell.set_symbol(&self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue