mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
wip: what is up with the arranger after all
This commit is contained in:
parent
abc1cc8fce
commit
7ff731133c
5 changed files with 156 additions and 124 deletions
134
src/arranger.rs
134
src/arranger.rs
|
|
@ -5,14 +5,14 @@ mod arranger_scene; pub(crate) use self::arranger_scene::*;
|
||||||
mod arranger_select; pub(crate) use self::arranger_select::*;
|
mod arranger_select; pub(crate) use self::arranger_select::*;
|
||||||
mod arranger_track; pub(crate) use self::arranger_track::*;
|
mod arranger_track; pub(crate) use self::arranger_track::*;
|
||||||
mod arranger_mode; pub(crate) use self::arranger_mode::*;
|
mod arranger_mode; pub(crate) use self::arranger_mode::*;
|
||||||
mod arranger_v; #[allow(unused)] pub(crate) use self::arranger_v::*;
|
|
||||||
mod arranger_h;
|
mod arranger_h;
|
||||||
mod arranger_v_clips; pub(crate) use self::arranger_v_clips::*;
|
mod arranger_v_clips; pub(crate) use self::arranger_v_clips::*;
|
||||||
mod arranger_v_cursor; pub(crate) use self::arranger_v_cursor::*;
|
mod arranger_v_cursor; pub(crate) use self::arranger_v_cursor::*;
|
||||||
mod arranger_v_head; pub(crate) use self::arranger_v_head::*;
|
|
||||||
mod arranger_v_io; pub(crate) use self::arranger_v_io::*;
|
|
||||||
mod arranger_v_sep; pub(crate) use self::arranger_v_sep::*;
|
mod arranger_v_sep; pub(crate) use self::arranger_v_sep::*;
|
||||||
|
|
||||||
|
pub(crate) const HEADER_H: u16 = 5;
|
||||||
|
pub(crate) const SCENES_W_OFFSET: u16 = 3;
|
||||||
|
|
||||||
/// Root view for standalone `tek_arranger`
|
/// Root view for standalone `tek_arranger`
|
||||||
pub struct Arranger {
|
pub struct Arranger {
|
||||||
jack: Arc<RwLock<JackConnection>>,
|
jack: Arc<RwLock<JackConnection>>,
|
||||||
|
|
@ -98,14 +98,14 @@ from_jack!(|jack| Arranger {
|
||||||
compact: false,
|
compact: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
impl Arranger {
|
//impl Arranger {
|
||||||
fn render_mode (state: &Self) -> impl Content<TuiOut> + use<'_> {
|
//fn render_mode (state: &Self) -> impl Content<TuiOut> + use<'_> {
|
||||||
match state.mode {
|
//match state.mode {
|
||||||
ArrangerMode::H => todo!("horizontal arranger"),
|
//ArrangerMode::H => todo!("horizontal arranger"),
|
||||||
ArrangerMode::V(factor) => Self::render_mode_v(state, factor),
|
//ArrangerMode::V(factor) => Self::render_mode_v(state, factor),
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
}
|
//}
|
||||||
//render!(TuiOut: (self: Arranger) => {
|
//render!(TuiOut: (self: Arranger) => {
|
||||||
//let pool_w = if self.pool.visible { self.splits[1] } else { 0 };
|
//let pool_w = if self.pool.visible { self.splits[1] } else { 0 };
|
||||||
//let color = self.color;
|
//let color = self.color;
|
||||||
|
|
@ -122,17 +122,38 @@ impl Arranger {
|
||||||
//});
|
//});
|
||||||
render!(TuiOut: (self: Arranger) => self.size.of(
|
render!(TuiOut: (self: Arranger) => self.size.of(
|
||||||
Bsp::s(self.toolbar_view(),
|
Bsp::s(self.toolbar_view(),
|
||||||
Bsp::n(self.selector_view(),
|
|
||||||
Bsp::n(self.status_view(),
|
Bsp::n(self.status_view(),
|
||||||
Bsp::w(self.pool_view(), Fill::xy(&self.editor)))))));
|
Bsp::n(self.selector_view(),
|
||||||
|
Bsp::s(Align::nw(Fill::x(Fixed::y(3, self.header()))),
|
||||||
|
Bsp::s(Align::nw(Fill::x(Fixed::y(1, self.ins()))),
|
||||||
|
Bsp::n(Align::nw(Fill::x(Fixed::y(1, self.outs()))),
|
||||||
|
Bsp::w(self.pool_view(), Fill::xy(lay!(
|
||||||
|
Align::nw(Fill::xy(Tui::bg(self.color.darkest.rgb, " "))),
|
||||||
|
Align::nw(Fill::xy(ArrangerVColSep::from(self))),
|
||||||
|
Align::nw(Fill::xy(ArrangerVRowSep::from((self, 1)))),
|
||||||
|
Align::nw(Fill::xy(ArrangerVCursor::from((self, 1)))),
|
||||||
|
Align::nw(Fill::xy(":")))))))))))));
|
||||||
|
//"todo:"))))))));
|
||||||
|
//Bsp::s(
|
||||||
|
//Align::nw(Fixed::y(1, Fill::x(ArrangerVIns::from(self)))),
|
||||||
|
//Bsp::s(
|
||||||
|
//Fixed::y(20, Align::nw(ArrangerVClips::new(self, 1))),
|
||||||
|
//Fill::x(Fixed::y(1, ArrangerVOuts::from(self)))))))))))));
|
||||||
|
//Bsp::s(
|
||||||
|
//Bsp::s(
|
||||||
|
//Bsp::s(
|
||||||
|
//Fill::xy(ArrangerVClips::new(self, 1)),
|
||||||
|
//Fill::x(ArrangerVOuts::from(self)))))
|
||||||
|
|
||||||
impl Arranger {
|
impl Arranger {
|
||||||
fn toolbar_view (&self) -> impl Content<TuiOut> + use<'_> {
|
fn toolbar_view (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
Fill::x(Fixed::y(2, Align::x(TransportView::new(true, &self.clock))))
|
Fill::x(Fixed::y(2, Align::x(TransportView::new(true, &self.clock))))
|
||||||
}
|
}
|
||||||
fn status_view (&self) -> impl Content<TuiOut> + use<'_> {
|
fn status_view (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
let edit_clip = MidiEditClip(&self.editor);
|
ArrangerStatus::from(self)
|
||||||
//let selectors = When(false, Bsp::e(ClipSelected::play_phrase(&self.player), ClipSelected::next_phrase(&self.player)));
|
//let edit_clip = MidiEditClip(&self.editor);
|
||||||
row!(/*selectors,*/ edit_clip, MidiEditStatus(&self.editor))
|
////let selectors = When(false, Bsp::e(ClipSelected::play_phrase(&self.player), ClipSelected::next_phrase(&self.player)));
|
||||||
|
//row!([>selectors,<] edit_clip, MidiEditStatus(&self.editor))
|
||||||
}
|
}
|
||||||
fn selector_view (&self) -> impl Content<TuiOut> + use<'_> {
|
fn selector_view (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
row!(
|
row!(
|
||||||
|
|
@ -149,6 +170,87 @@ impl Arranger {
|
||||||
let pool = Pull::y(1, Fill::y(Align::e(PoolView(self.pool.visible, &self.pool))));
|
let pool = Pull::y(1, Fill::y(Align::e(PoolView(self.pool.visible, &self.pool))));
|
||||||
Fixed::x(pool_w, Align::e(Fill::y(PoolView(self.compact, &self.pool))))
|
Fixed::x(pool_w, Align::e(Fill::y(PoolView(self.compact, &self.pool))))
|
||||||
}
|
}
|
||||||
|
fn header (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||||
|
fn row <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
||||||
|
row!(Tui::fg(color.light.rgb, "▎"), Tui::fg(color.lightest.rgb, field))
|
||||||
|
}
|
||||||
|
Push::x(scenes_w, Map(||ArrangerTrack::with_widths(self.tracks.as_slice()), |(_, track, x1, x2), i| {
|
||||||
|
let (w, h) = (ArrangerTrack::MIN_WIDTH.max(x2 - x1), HEADER_H);
|
||||||
|
let color = track.color();
|
||||||
|
Push::x(x1 as u16, Tui::bg(color.base.rgb, Min::xy(w as u16, h, Fixed::xy(w as u16, 5, col!(
|
||||||
|
row(color, Self::format_name(track, w)),
|
||||||
|
row(color, Self::format_elapsed(track, self.clock().timebase())),
|
||||||
|
row(color, Self::format_until_next(track, &self.clock().playhead)),
|
||||||
|
)))))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/// name and width of track
|
||||||
|
fn format_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))
|
||||||
|
}
|
||||||
|
/// beats elapsed
|
||||||
|
fn format_elapsed (track: &ArrangerTrack, timebase: &Arc<Timebase>) -> impl Content<TuiOut> {
|
||||||
|
let mut result = String::new();
|
||||||
|
if let Some((_, Some(phrase))) = track.player.play_phrase().as_ref() {
|
||||||
|
let length = phrase.read().unwrap().length;
|
||||||
|
let elapsed = track.player.pulses_since_start().unwrap();
|
||||||
|
let elapsed = timebase.format_beats_1_short(
|
||||||
|
(elapsed as usize % length) as f64
|
||||||
|
);
|
||||||
|
result = format!("+{elapsed:>}")
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
/// beats until switchover
|
||||||
|
fn format_until_next (track: &ArrangerTrack, current: &Arc<Moment>)
|
||||||
|
-> Option<impl Content<TuiOut>>
|
||||||
|
{
|
||||||
|
let timebase = ¤t.timebase;
|
||||||
|
let mut result = String::new();
|
||||||
|
if let Some((t, _)) = track.player.next_phrase().as_ref() {
|
||||||
|
let target = t.pulse.get();
|
||||||
|
let current = current.pulse.get();
|
||||||
|
if target > current {
|
||||||
|
let remaining = target - current;
|
||||||
|
result = format!("-{:>}", timebase.format_beats_0_short(remaining))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(result)
|
||||||
|
}
|
||||||
|
fn ins (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||||
|
fn row <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
||||||
|
row!(Tui::fg(color.light.rgb, "▎"), Tui::fg(color.lightest.rgb, field))
|
||||||
|
}
|
||||||
|
Push::x(scenes_w, Map(||ArrangerTrack::with_widths(self.tracks.as_slice()), |(_, track, x1, x2), i| {
|
||||||
|
let (w, h) = (ArrangerTrack::MIN_WIDTH.max(x2 - x1), HEADER_H);
|
||||||
|
let color = track.color();
|
||||||
|
let input = Self::format_input(track);
|
||||||
|
Push::x(x1 as u16, Tui::bg(color.base.rgb, Min::xy(w as u16, h, Fixed::xy(w as u16, 5, row(color, Self::format_input(track).ok())))))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
fn format_input (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
||||||
|
Ok(format!(">{}", track.player.midi_ins().first().map(|port|port.short_name())
|
||||||
|
.transpose()?.unwrap_or("?".into())))
|
||||||
|
}
|
||||||
|
fn outs (&self) -> impl Content<TuiOut> + use<'_> {
|
||||||
|
let scenes_w = SCENES_W_OFFSET + ArrangerScene::longest_name(&self.scenes) as u16;
|
||||||
|
fn row <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
||||||
|
row!(Tui::fg(color.light.rgb, "▎"), Tui::fg(color.lightest.rgb, field))
|
||||||
|
}
|
||||||
|
Push::x(scenes_w, Map(||ArrangerTrack::with_widths(self.tracks.as_slice()), |(_, track, x1, x2), i| {
|
||||||
|
let (w, h) = (ArrangerTrack::MIN_WIDTH.max(x2 - x1), HEADER_H);
|
||||||
|
let color = track.color();
|
||||||
|
Push::x(x2 as u16, Tui::bg(color.base.rgb, Min::xy(w as u16, h, Fixed::xy(w as u16, 5, row(color, Self::format_output(track).ok())))))
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
/// output port
|
||||||
|
fn format_output (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
||||||
|
Ok(format!("<{}", track.player.midi_outs().first().map(|port|port.short_name())
|
||||||
|
.transpose()?.unwrap_or("?".into())))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//render!(TuiOut: (self: Arranger) => {
|
//render!(TuiOut: (self: Arranger) => {
|
||||||
//let pool_w = if self.pool.visible { self.splits[1] } else { 0 };
|
//let pool_w = if self.pool.visible { self.splits[1] } else { 0 };
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,12 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
// egyptian snakes den
|
// egyptian snakes den
|
||||||
pub(crate) const HEADER_H: u16 = 5;
|
|
||||||
pub(crate) const SCENES_W_OFFSET: u16 = 3;
|
|
||||||
impl Arranger {
|
impl Arranger {
|
||||||
pub fn render_mode_v (state: &Arranger, factor: usize) -> impl Content<TuiOut> + use<'_> {
|
pub fn render_mode_v (state: &Arranger, factor: usize) -> impl Content<TuiOut> + use<'_> {
|
||||||
lay!(
|
lay!(
|
||||||
ArrangerVColSep::from(state),
|
ArrangerVColSep::from(state),
|
||||||
ArrangerVRowSep::from((state, factor)),
|
ArrangerVRowSep::from((state, factor)),
|
||||||
col!(
|
col!(
|
||||||
ArrangerVHead::from(state),
|
//ArrangerVHead::from(state),
|
||||||
ArrangerVIns::from(state),
|
ArrangerVIns::from(state),
|
||||||
ArrangerVClips::new(state, factor),
|
ArrangerVClips::new(state, factor),
|
||||||
ArrangerVOuts::from(state),
|
ArrangerVOuts::from(state),
|
||||||
|
|
|
||||||
|
|
@ -1,84 +1,41 @@
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub struct ArrangerVHead<'a> {
|
pub struct ArrangerVIns<'a> {
|
||||||
|
size: &'a Measure<TuiOut>,
|
||||||
|
tracks: &'a Vec<ArrangerTrack>,
|
||||||
scenes_w: u16,
|
scenes_w: u16,
|
||||||
timebase: &'a Arc<Timebase>,
|
|
||||||
current: &'a Arc<Moment>,
|
|
||||||
tracks: &'a [ArrangerTrack],
|
|
||||||
}
|
}
|
||||||
|
impl ArrangerVIns<'_> {
|
||||||
from!(<'a>|state: &'a Arranger|ArrangerVHead<'a> = Self { // A
|
|
||||||
tracks: &state.tracks,
|
|
||||||
timebase: state.clock().timebase(),
|
|
||||||
current: &state.clock().playhead,
|
|
||||||
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&state.scenes) as u16,
|
|
||||||
});
|
|
||||||
|
|
||||||
render!(TuiOut: (self: ArrangerVHead<'a>) => {
|
|
||||||
fn row <T: Content<TuiOut>> (color: ItemPalette, field: T) -> impl Content<TuiOut> {
|
|
||||||
row!(Tui::fg(color.light.rgb, "▎"), Tui::fg(color.lightest.rgb, field))
|
|
||||||
}
|
|
||||||
Some(Push::x(self.scenes_w,
|
|
||||||
Map(||ArrangerTrack::with_widths(self.tracks), |(_, track, x1, x2), i| {
|
|
||||||
let (w, h) = (ArrangerTrack::MIN_WIDTH.max(x2 - x1), HEADER_H);
|
|
||||||
let color = track.color();
|
|
||||||
let input = Self::format_input(track);
|
|
||||||
let output = Self::format_output(track);
|
|
||||||
Tui::bg(color.base.rgb, Min::xy(w as u16, h, Fixed::xy(w as u16, 5, col!(
|
|
||||||
row(color, Self::format_name(track, w)),
|
|
||||||
row(color, Self::format_input(track).ok()),
|
|
||||||
row(color, Self::format_output(track).ok()),
|
|
||||||
row(color, Self::format_elapsed(track, self.timebase)),
|
|
||||||
row(color, Self::format_until_next(track, self.current)),
|
|
||||||
))))
|
|
||||||
})
|
|
||||||
))
|
|
||||||
});
|
|
||||||
|
|
||||||
impl ArrangerVHead<'_> {
|
|
||||||
/// name and width of track
|
|
||||||
fn format_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))
|
|
||||||
}
|
|
||||||
/// input port
|
/// input port
|
||||||
fn format_input (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
fn format_input (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
||||||
Ok(format!(">{}", track.player.midi_ins().first().map(|port|port.short_name())
|
Ok(format!(">{}", track.player.midi_ins().first().map(|port|port.short_name())
|
||||||
.transpose()?.unwrap_or("?".into())))
|
.transpose()?.unwrap_or("?".into())))
|
||||||
}
|
}
|
||||||
/// output port
|
|
||||||
fn format_output (track: &ArrangerTrack) -> Usually<impl Content<TuiOut>> {
|
|
||||||
Ok(format!("<{}", track.player.midi_outs().first().map(|port|port.short_name())
|
|
||||||
.transpose()?.unwrap_or("?".into())))
|
|
||||||
}
|
|
||||||
/// beats elapsed
|
|
||||||
fn format_elapsed (track: &ArrangerTrack, timebase: &Arc<Timebase>) -> impl Content<TuiOut> {
|
|
||||||
let mut result = String::new();
|
|
||||||
if let Some((_, Some(phrase))) = track.player.play_phrase().as_ref() {
|
|
||||||
let length = phrase.read().unwrap().length;
|
|
||||||
let elapsed = track.player.pulses_since_start().unwrap();
|
|
||||||
let elapsed = timebase.format_beats_1_short(
|
|
||||||
(elapsed as usize % length) as f64
|
|
||||||
);
|
|
||||||
result = format!("+{elapsed:>}")
|
|
||||||
}
|
|
||||||
result
|
|
||||||
}
|
|
||||||
/// beats until switchover
|
|
||||||
fn format_until_next (track: &ArrangerTrack, current: &Arc<Moment>)
|
|
||||||
-> Option<impl Content<TuiOut>>
|
|
||||||
{
|
|
||||||
let timebase = ¤t.timebase;
|
|
||||||
let mut result = String::new();
|
|
||||||
if let Some((t, _)) = track.player.next_phrase().as_ref() {
|
|
||||||
let target = t.pulse.get();
|
|
||||||
let current = current.pulse.get();
|
|
||||||
if target > current {
|
|
||||||
let remaining = target - current;
|
|
||||||
result = format!("-{:>}", timebase.format_beats_0_short(remaining))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some(result)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
from!(<'a>|args: &'a Arranger|ArrangerVIns<'a> = Self {
|
||||||
|
size: &args.size,
|
||||||
|
tracks: &args.tracks,
|
||||||
|
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&args.scenes) as u16,
|
||||||
|
});
|
||||||
|
|
||||||
|
render!(TuiOut: (self: ArrangerVIns<'a>) => {
|
||||||
|
});
|
||||||
|
|
||||||
|
pub struct ArrangerVOuts<'a> {
|
||||||
|
size: &'a Measure<TuiOut>,
|
||||||
|
tracks: &'a Vec<ArrangerTrack>,
|
||||||
|
scenes_w: u16,
|
||||||
|
}
|
||||||
|
impl ArrangerVOuts<'_> {
|
||||||
|
}
|
||||||
|
|
||||||
|
from!(<'a>|args: &'a Arranger|ArrangerVOuts<'a> = Self {
|
||||||
|
size: &args.size,
|
||||||
|
tracks: &args.tracks,
|
||||||
|
scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&args.scenes) as u16,
|
||||||
|
});
|
||||||
|
|
||||||
|
render!(TuiOut: (self: ArrangerVOuts<'a>) => {
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
use crate::*;
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub struct ArrangerVIns<'a> {
|
|
||||||
size: &'a Measure<TuiOut>,
|
|
||||||
tracks: &'a Vec<ArrangerTrack>,
|
|
||||||
}
|
|
||||||
|
|
||||||
from!(<'a>|args: &'a Arranger|ArrangerVIns<'a> = Self {
|
|
||||||
size: &args.size,
|
|
||||||
tracks: &args.tracks,
|
|
||||||
});
|
|
||||||
|
|
||||||
render!(TuiOut: (self: ArrangerVIns<'a>) => "");
|
|
||||||
|
|
||||||
pub struct ArrangerVOuts<'a> {
|
|
||||||
size: &'a Measure<TuiOut>,
|
|
||||||
tracks: &'a Vec<ArrangerTrack>,
|
|
||||||
}
|
|
||||||
|
|
||||||
from!(<'a>|args: &'a Arranger|ArrangerVOuts<'a> = Self {
|
|
||||||
size: &args.size,
|
|
||||||
tracks: &args.tracks,
|
|
||||||
});
|
|
||||||
|
|
||||||
render!(TuiOut: (self: ArrangerVOuts<'a>) => "");
|
|
||||||
|
|
@ -26,17 +26,18 @@ pub struct ArrangerVRowSep {
|
||||||
rows: Vec<(usize, usize)>,
|
rows: Vec<(usize, usize)>,
|
||||||
}
|
}
|
||||||
from!(|args:(&Arranger, usize)|ArrangerVRowSep = Self {
|
from!(|args:(&Arranger, usize)|ArrangerVRowSep = Self {
|
||||||
fg: TuiTheme::separator_fg(false),
|
fg: Color::Rgb(255,255,255,),
|
||||||
rows: ArrangerScene::ppqs(&args.0.scenes, args.1),
|
rows: ArrangerScene::ppqs(&args.0.scenes, args.1),
|
||||||
});
|
});
|
||||||
render!(TuiOut: |self: ArrangerVRowSep, to|for y in self.rows.iter().map(|row|row.1) {
|
render!(TuiOut: |self: ArrangerVRowSep, to|for y in self.rows.iter().map(|row|row.1) {
|
||||||
let y = to.area().y() + (y / PPQ) as u16 + 1;
|
let y = to.area().y() + (y / PPQ) as u16 + 1;
|
||||||
if y >= to.buffer.area.height { break }
|
if y >= to.buffer.area.height { break }
|
||||||
for x in to.area().x()..to.area().x2().saturating_sub(2) {
|
for x in to.area().x()..to.area().x2().saturating_sub(2) {
|
||||||
if x < to.buffer.area.x && y < to.buffer.area.y {
|
//if x < to.buffer.area.x && y < to.buffer.area.y {
|
||||||
let cell = to.buffer.get_mut(x, y);
|
if let Some(cell) = to.buffer.cell_mut(ratatui::prelude::Position::from((x, y))) {
|
||||||
cell.modifier = Modifier::UNDERLINED;
|
cell.modifier = Modifier::UNDERLINED;
|
||||||
cell.underline_color = self.fg;
|
cell.underline_color = self.fg;
|
||||||
}
|
}
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue