mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
LineBuffer
This commit is contained in:
parent
61af72c281
commit
d75600188e
3 changed files with 92 additions and 3 deletions
|
|
@ -13,7 +13,6 @@ pub(crate) use std::sync::{
|
||||||
|
|
||||||
// Non-stdlib dependencies:
|
// Non-stdlib dependencies:
|
||||||
pub(crate) use microxdg::XdgApp;
|
pub(crate) use microxdg::XdgApp;
|
||||||
pub(crate) use ratatui::prelude::*;
|
|
||||||
pub(crate) use midly::{MidiMessage, live::LiveEvent, num::u7};
|
pub(crate) use midly::{MidiMessage, live::LiveEvent, num::u7};
|
||||||
pub(crate) use crossterm::{ExecutableCommand};
|
pub(crate) use crossterm::{ExecutableCommand};
|
||||||
pub(crate) use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers};
|
pub(crate) use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers};
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
use crate::core::*;
|
use crate::core::*;
|
||||||
|
pub(crate) use ratatui::prelude::*;
|
||||||
|
use ratatui::buffer::Cell;
|
||||||
use ratatui::widgets::WidgetRef;
|
use ratatui::widgets::WidgetRef;
|
||||||
|
|
||||||
pub trait Blit {
|
pub trait Blit {
|
||||||
|
|
@ -80,3 +82,92 @@ impl WidgetRef for dyn Render {
|
||||||
Render::render(self, buf, area).expect("Failed to render device.");
|
Render::render(self, buf, area).expect("Failed to render device.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct LineBuffer {
|
||||||
|
width: usize,
|
||||||
|
cells: Vec<Cell>,
|
||||||
|
style: Option<Style>,
|
||||||
|
bg: Cell,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LineBuffer {
|
||||||
|
pub fn new (bg: Cell, width: usize, height: usize) -> Self {
|
||||||
|
Self {
|
||||||
|
style: None,
|
||||||
|
width: width,
|
||||||
|
cells: vec![bg.clone();width*height],
|
||||||
|
bg,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn height (&self) -> usize {
|
||||||
|
self.cells.len() / self.width
|
||||||
|
}
|
||||||
|
pub fn style (&mut self, style: Style) -> &mut Self {
|
||||||
|
self.style = Some(style);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn no_style (&mut self) -> &mut Self {
|
||||||
|
self.style = None;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn put (&mut self, data: &str, x: usize, y: usize) -> &mut Self {
|
||||||
|
if x < self.width {
|
||||||
|
for (i, c) in data.chars().enumerate() {
|
||||||
|
if x + i >= self.width {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let index = y * self.width + x + i;
|
||||||
|
while index >= self.cells.len() {
|
||||||
|
self.cells.extend_from_slice(&vec![self.bg.clone();self.width]);
|
||||||
|
}
|
||||||
|
self.cells[index].set_char(c);
|
||||||
|
if let Some(s) = self.style {
|
||||||
|
self.cells[index].set_style(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self
|
||||||
|
}
|
||||||
|
pub fn show (&self, buf: &mut Buffer, area: Rect, offset: isize) -> Usually<Rect> {
|
||||||
|
let Rect { x, mut y, width, height } = area;
|
||||||
|
for row in offset..self.height() as isize {
|
||||||
|
let length = self.cells.len();
|
||||||
|
let start = ((row.max(0) as usize)*self.width).min(length);
|
||||||
|
let end = (((row + 1).max(0) as usize)*self.width).min(length);
|
||||||
|
for (column, cell) in self.cells[start..end].iter().enumerate() {
|
||||||
|
if column >= width as usize {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
*buf.get_mut(x + column as u16, y + row as u16) = cell.clone();
|
||||||
|
}
|
||||||
|
y = y + 1;
|
||||||
|
if y > height {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(area)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_line_buffer () {
|
||||||
|
let mut buffer = LineBuffer::new(Cell::default(), 12, 0);
|
||||||
|
assert_eq!(buffer.cells.len(), 0);
|
||||||
|
buffer.put("FOO", 0, 0);
|
||||||
|
assert_eq!(buffer.cells.len(), 12);
|
||||||
|
buffer.put("FOO", 6, 0);
|
||||||
|
assert_eq!(buffer.cells.len(), 12);
|
||||||
|
buffer.put("FOO", 11, 0);
|
||||||
|
assert_eq!(buffer.cells.len(), 12);
|
||||||
|
buffer.put("FOO", 12, 0);
|
||||||
|
assert_eq!(buffer.cells.len(), 12);
|
||||||
|
buffer.put("FOO", 24, 0);
|
||||||
|
assert_eq!(buffer.cells.len(), 12);
|
||||||
|
buffer.put("FOO", 0, 1);
|
||||||
|
assert_eq!(buffer.cells.len(), 24);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ pub struct TransportView<'a> {
|
||||||
impl<'a> Render for TransportView<'a> {
|
impl<'a> Render for TransportView<'a> {
|
||||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||||
let Rect { x, y, width, .. } = area;
|
let Rect { x, y, width, .. } = area;
|
||||||
|
draw_play_stop(buf, x + 1, y, &self.playing);
|
||||||
if width > 100 {
|
if width > 100 {
|
||||||
draw_play_stop(buf, x + 1, y, &self.playing);
|
|
||||||
draw_rec(buf, x + 12, y, self.record);
|
draw_rec(buf, x + 12, y, self.record);
|
||||||
draw_dub(buf, x + 19, y, self.overdub);
|
draw_dub(buf, x + 19, y, self.overdub);
|
||||||
draw_mon(buf, x + 26, y, self.monitor);
|
draw_mon(buf, x + 26, y, self.monitor);
|
||||||
|
|
@ -26,7 +26,6 @@ impl<'a> Render for TransportView<'a> {
|
||||||
);
|
);
|
||||||
Ok(Rect { x, y, width, height: 1 })
|
Ok(Rect { x, y, width, height: 1 })
|
||||||
} else {
|
} else {
|
||||||
draw_play_stop(buf, x + 1, y, &self.playing);
|
|
||||||
draw_bpm(buf, x + 12, y, self.timebase.bpm() as usize, self.quant);
|
draw_bpm(buf, x + 12, y, self.timebase.bpm() as usize, self.quant);
|
||||||
draw_timer(buf, x + width - 1, y,
|
draw_timer(buf, x + width - 1, y,
|
||||||
self.timebase.ppq() as usize,
|
self.timebase.ppq() as usize,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue