use crate::segment::Segment;
use crate::cursor::CursorPosition;
use crate::update::UpdateStep;
use crate::interface::TTYInterface;
use crate::utility::{move_cursor_exact, render_line, move_cursor_by, clear_line};
use crate::result::{Result, TTYError};
pub struct Line {
pub(crate) segments: Vec<Segment>,
}
impl Line {
pub fn new(segments: Vec<Segment>) -> Line {
Line { segments }
}
pub(crate) fn get_segment_start(&self, segment_index: usize) -> u16 {
let mut segment_start = 0;
for i in 0..segment_index {
segment_start += self.segments[i].text.len();
}
segment_start as u16
}
}
pub(crate) struct SetLineStep {
pub(crate) line_index: usize,
pub(crate) line: Option<Line>,
}
impl UpdateStep for SetLineStep {
fn do_update(&mut self, interface: &mut TTYInterface, update_cursor: &mut CursorPosition) -> Result<()> {
if self.line_index > interface.state.lines.len() {
return Err(TTYError::LineOutOfBounds);
}
let line = self.line.take().expect("SetLineStep is missing a Line");
if self.line_index == interface.state.lines.len() {
interface.state.lines.push(line);
} else {
interface.state.lines[self.line_index] = line;
}
move_cursor_exact(interface.writer, update_cursor, 0, self.line_index as u16)?;
render_line(interface.writer, update_cursor, &interface.state.lines[self.line_index])?;
Ok(())
}
}
pub(crate) struct DeleteLineStep {
pub(crate) line_index: usize,
}
impl UpdateStep for DeleteLineStep {
fn do_update(&mut self, interface: &mut TTYInterface, update_cursor: &mut CursorPosition) -> Result<()> {
if self.line_index > interface.state.lines.len() - 1 {
return Err(TTYError::LineOutOfBounds);
}
let line_y: u16 = self.line_index as u16;
if update_cursor.y != line_y {
move_cursor_exact(interface.writer, update_cursor, 0, line_y)?;
}
interface.state.lines.remove(self.line_index);
for i in self.line_index..interface.state.lines.len() {
render_line(interface.writer, update_cursor, &interface.state.lines[i])?;
move_cursor_by(interface.writer, update_cursor, 0, 1)?;
}
clear_line(interface.writer)?;
Ok(())
}
}