mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-05-02 14:50:14 +02:00
implement scrollbar components
This commit is contained in:
parent
357efeea3e
commit
6755f972f3
|
@ -20,7 +20,6 @@ view!(TuiOut: |self: Tek| self.size.of(View(self, self.view)); {
|
|||
":sampler" => ().boxed(),//self.view_sampler(self.is_editing(), &self.editor).boxed(),
|
||||
":scene-add" => self.view_scene_add().boxed(),
|
||||
":scenes" => self.view_scenes().boxed(),
|
||||
":toolbar" => self.view_clock().boxed(),
|
||||
":transport" => self.view_transport().boxed(),
|
||||
":status" => self.view_status().boxed(),
|
||||
":tracks" => self.view_tracks().boxed(),
|
||||
|
|
|
@ -29,23 +29,6 @@ impl Tek {
|
|||
fmtd.bpm.update(None, rewrite!(buf, "---.---"));
|
||||
}
|
||||
}
|
||||
pub(crate) fn view_clock (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
self.update_clock();
|
||||
let theme = ItemPalette::G[96];
|
||||
let fmtd = self.fmtd.read().unwrap();
|
||||
Bsp::a(
|
||||
Fill::xy(Align::w(self.view_play_pause())),
|
||||
Fill::xy(Align::e(row!(
|
||||
FieldH(theme, "Sel", self.selected.describe(&self.tracks, &self.scenes)),
|
||||
FieldH(theme, "SR", fmtd.sr.view.clone()),
|
||||
FieldH(theme, "Buf", fmtd.buf.view.clone()),
|
||||
FieldH(theme, "Lat", fmtd.lat.view.clone()),
|
||||
FieldH(theme, "BPM", fmtd.bpm.view.clone()),
|
||||
FieldH(theme, "Beat", fmtd.beat.view.clone()),
|
||||
FieldH(theme, "Time", fmtd.time.view.clone())
|
||||
)))
|
||||
)
|
||||
}
|
||||
pub(crate) fn view_status (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
self.update_clock();
|
||||
let theme = ItemPalette::G[96];
|
||||
|
@ -66,9 +49,9 @@ impl Tek {
|
|||
Tui::bg(Black, row!(Bsp::a(
|
||||
Fill::xy(Align::w(FieldH(theme, "Selected", self.selected.describe(&self.tracks, &self.scenes)))),
|
||||
Fill::xy(Align::e(row!(
|
||||
FieldH(theme, "SR", fmtd.sr.view.clone()),
|
||||
FieldH(theme, "Buf", fmtd.buf.view.clone()),
|
||||
FieldH(theme, "Lat", fmtd.lat.view.clone()),
|
||||
FieldH(theme, "SR", fmtd.sr.view.clone()),
|
||||
FieldH(theme, "Buf", fmtd.buf.view.clone()),
|
||||
FieldH(theme, "Lat", fmtd.lat.view.clone()),
|
||||
)))
|
||||
)))
|
||||
}
|
||||
|
|
|
@ -19,17 +19,19 @@ impl Tek {
|
|||
y += height;
|
||||
data})}
|
||||
fn scene_scrollbar (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
Bsp::s(Tui::fg_bg(Rgb(255,255,255), Rgb(0,0,0),"▲"),
|
||||
Bsp::n(Tui::fg_bg(Rgb(255,255,255), Rgb(0,0,0),"▼"), Bsp::a(
|
||||
Fill::y(Align::nw(Fixed::xy(1, 1, Tui::fg(Rgb(255,255,255), "┃")))),
|
||||
Fill::y(Fixed::x(1, Tui::fg(Rgb(0,0,0), RepeatV("┊")))),
|
||||
))) }
|
||||
Fill::y(Fixed::x(1, ScrollbarV {
|
||||
offset: self.scene_scroll,
|
||||
length: 0,
|
||||
total: self.tracks.len()
|
||||
}))
|
||||
}
|
||||
fn track_scrollbar (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
Bsp::e(Tui::fg_bg(Rgb(255,255,255), Rgb(0,0,0), "🞀"),
|
||||
Bsp::w(Tui::fg_bg(Rgb(255,255,255), Rgb(0,0,0), "🞂"), Bsp::a(
|
||||
Fill::x(Align::nw(Fixed::xy(1, 1, Tui::fg(Rgb(255,255,255), "━")))),
|
||||
Fill::x(Fixed::y(1, Tui::fg(Rgb(0,0,0), RepeatH("┈")))),
|
||||
))) }
|
||||
Fill::x(Fixed::y(1, ScrollbarH {
|
||||
offset: self.track_scroll,
|
||||
length: 0,// self.view_track_count(),
|
||||
total: self.tracks.len()
|
||||
}))
|
||||
}
|
||||
pub fn view_scenes (&self) -> impl Content<TuiOut> + use<'_> {
|
||||
let w_full = self.w();
|
||||
let w = self.w_tracks_area();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::*;
|
||||
use crate::Color::*;
|
||||
use ratatui::prelude::Position;
|
||||
macro_rules! impl_content_layout_render {
|
||||
($Output:ty: |$self:ident: $Struct:ty, $to:ident| layout = $layout:expr; render = $render:expr) => {
|
||||
impl Content<$Output> for $Struct {
|
||||
|
@ -34,7 +35,6 @@ impl<T: Content<TuiOut>> Content<TuiOut> for std::sync::Arc<T> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub struct FieldH<T, U>(pub ItemPalette, pub T, pub U);
|
||||
impl<T: Content<TuiOut>, U: Content<TuiOut>> Content<TuiOut> for FieldH<T, U> {
|
||||
fn content (&self) -> impl Render<TuiOut> {
|
||||
|
@ -62,15 +62,13 @@ impl<T: Content<TuiOut>, U: Content<TuiOut>> Content<TuiOut> for FieldV<T, U> {
|
|||
|
||||
pub struct Repeat<'a>(pub &'a str);
|
||||
impl Content<TuiOut> for Repeat<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
to
|
||||
}
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] { to }
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x, y, w, h] = to.area().xywh();
|
||||
let a = self.0.len();
|
||||
for (_v, y) in (y..y+h).enumerate() {
|
||||
for (u, x) in (x..x+w).enumerate() {
|
||||
if let Some(cell) = to.buffer.cell_mut(ratatui::prelude::Position::from((x, y))) {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
let u = u % a;
|
||||
cell.set_symbol(&self.0[u..u+1]);
|
||||
}
|
||||
|
@ -81,13 +79,11 @@ impl Content<TuiOut> for Repeat<'_> {
|
|||
|
||||
pub struct RepeatV<'a>(pub &'a str);
|
||||
impl Content<TuiOut> for RepeatV<'_> {
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] {
|
||||
to
|
||||
}
|
||||
fn layout (&self, to: [u16;4]) -> [u16;4] { to }
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x, y, _w, h] = to.area().xywh();
|
||||
for y in y..y+h {
|
||||
if let Some(cell) = to.buffer.cell_mut(ratatui::prelude::Position::from((x, y))) {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
cell.set_symbol(&self.0);
|
||||
}
|
||||
}
|
||||
|
@ -96,19 +92,83 @@ 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 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))) {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
cell.set_symbol(&self.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScrollbarV {
|
||||
pub offset: usize,
|
||||
pub length: usize,
|
||||
pub total: usize,
|
||||
}
|
||||
impl ScrollbarV {
|
||||
const ICON_DEC: &[char] = &['▲'];
|
||||
const ICON_INC: &[char] = &['▼'];
|
||||
}
|
||||
impl Content<TuiOut> for ScrollbarV {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x, y1, _w, h] = to.area().xywh();
|
||||
let y2 = y1 + h;
|
||||
for (i, y) in (y1..=y2).enumerate() {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
if (i as usize) < (Self::ICON_DEC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_DEC[i as usize]);
|
||||
} else if (i as usize) > (h as usize - Self::ICON_INC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_INC[h as usize - i]);
|
||||
} else {
|
||||
cell.set_fg(Rgb(0, 0, 0));
|
||||
cell.set_bg(Reset);
|
||||
cell.set_char('╎'); // ━
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScrollbarH {
|
||||
pub offset: usize,
|
||||
pub length: usize,
|
||||
pub total: usize,
|
||||
}
|
||||
impl ScrollbarH {
|
||||
const ICON_DEC: &[char] = &[' ', '🞀', ' '];
|
||||
const ICON_INC: &[char] = &[' ', '🞂', ' '];
|
||||
}
|
||||
impl Content<TuiOut> for ScrollbarH {
|
||||
fn render (&self, to: &mut TuiOut) {
|
||||
let [x1, y, w, _h] = to.area().xywh();
|
||||
let x2 = x1 + w;
|
||||
for (i, x) in (x1..=x2).enumerate() {
|
||||
if let Some(cell) = to.buffer.cell_mut(Position::from((x, y))) {
|
||||
if i < (Self::ICON_DEC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_DEC[x as usize]);
|
||||
} else if i > (w as usize - Self::ICON_INC.len()) {
|
||||
cell.set_fg(Rgb(255, 255, 255));
|
||||
cell.set_bg(Rgb(0, 0, 0));
|
||||
cell.set_char(Self::ICON_INC[w as usize - i]);
|
||||
} else {
|
||||
cell.set_fg(Rgb(0, 0, 0));
|
||||
cell.set_bg(Reset);
|
||||
cell.set_char('╌'); // ━
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A cell that takes up 3 rows on its own,
|
||||
/// but stacks, giving (N+1)*2 rows per N cells.
|
||||
pub struct Phat<T> {
|
||||
|
@ -445,25 +505,6 @@ border! {
|
|||
}
|
||||
}
|
||||
|
||||
//pub trait TuiStyle: Render<TuiOut> + Sized {
|
||||
//fn fg (self, color: Color) -> impl Render<TuiOut> {
|
||||
//Layers::new(move |add|{ add(&Foreground(color))?; add(&self) })
|
||||
//}
|
||||
//fn bg (self, color: Color) -> impl Render<TuiOut> {
|
||||
//Layers::new(move |add|{ add(&Background(color))?; add(&self) })
|
||||
//}
|
||||
//fn bold (self, on: bool) -> impl Render<TuiOut> {
|
||||
//Layers::new(move |add|{ add(&Bold(on))?; add(&self) })
|
||||
//}
|
||||
//fn border <S: BorderStyle> (self, style: S) -> impl Render<TuiOut> {
|
||||
//Bordered(style, self)
|
||||
//}
|
||||
//}
|
||||
|
||||
//impl<R: Content<TuiOut>> TuiStyle for R {}
|
||||
|
||||
//impl<S: BorderStyle> Content<TuiOut> for Border<S> {
|
||||
//}
|
||||
|
||||
//impl<S: BorderStyle, R: Content<TuiOut>> Content<TuiOut> for Bordered<S, R> {
|
||||
//fn content (&self) -> impl Render<TuiOut> {
|
||||
|
|
Loading…
Reference in a new issue