mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56: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:
|
||||
pub(crate) use microxdg::XdgApp;
|
||||
pub(crate) use ratatui::prelude::*;
|
||||
pub(crate) use midly::{MidiMessage, live::LiveEvent, num::u7};
|
||||
pub(crate) use crossterm::{ExecutableCommand};
|
||||
pub(crate) use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
use crate::core::*;
|
||||
pub(crate) use ratatui::prelude::*;
|
||||
use ratatui::buffer::Cell;
|
||||
use ratatui::widgets::WidgetRef;
|
||||
|
||||
pub trait Blit {
|
||||
|
|
@ -80,3 +82,92 @@ impl WidgetRef for dyn Render {
|
|||
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> {
|
||||
fn render (&self, buf: &mut Buffer, area: Rect) -> Usually<Rect> {
|
||||
let Rect { x, y, width, .. } = area;
|
||||
draw_play_stop(buf, x + 1, y, &self.playing);
|
||||
if width > 100 {
|
||||
draw_play_stop(buf, x + 1, y, &self.playing);
|
||||
draw_rec(buf, x + 12, y, self.record);
|
||||
draw_dub(buf, x + 19, y, self.overdub);
|
||||
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 })
|
||||
} else {
|
||||
draw_play_stop(buf, x + 1, y, &self.playing);
|
||||
draw_bpm(buf, x + 12, y, self.timebase.bpm() as usize, self.quant);
|
||||
draw_timer(buf, x + width - 1, y,
|
||||
self.timebase.ppq() as usize,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue