use std::{fmt::Debug, vec::IntoIter};
use unicode_width::UnicodeWidthChar;
#[derive(Debug)]
pub(crate) struct CursorPos {
x_left: usize,
y_top: usize,
x_right: usize,
y_bottom: usize,
x: usize,
y: usize,
lines_omitted: usize,
codepoints: Vec<char>,
}
impl CursorPos {
pub(crate) fn new(
x_left: usize,
y_top: usize,
x_right: usize,
y_bottom: usize,
codepoints: &Vec<char>,
offset: usize,
) -> Self {
let mut pos = Self {
x_left,
y_top,
x_right,
y_bottom,
x: x_left,
y: y_top,
lines_omitted: 0,
codepoints: codepoints.clone(),
};
let mut index = 0;
for i in codepoints {
if index < offset {
pos.next(i);
index += 1;
}
}
pos
}
pub(crate) fn x(&self) -> usize {
self.x
}
pub(crate) fn y(&self) -> usize {
self.y
}
fn next(&mut self, c: &char) {
match c {
'\n' => self.newline(),
' '.. => {
self.x += match c.width() {
Some(n) => n,
None => 0,
}
}
_ => (),
}
if self.x_right < self.x {
self.x = self.x_left;
self.y += 1;
}
if (self.y_bottom / 2) < self.y {
self.y = self.y_bottom / 2;
self.lines_omitted += 1;
}
}
fn newline(&mut self) {
self.y += 1;
self.x = self.x_left;
}
}
pub(crate) struct CharPositions {
v: Vec<CharPos>,
}
impl CharPositions {
pub(crate) fn new(cursor_pos: &CursorPos) -> CharPositions {
let mut cp = CharPositions { v: Vec::new() };
let mut lines_ommitted = 0;
let mut x = cursor_pos.x_left;
let mut y = cursor_pos.y_top;
for c in &cursor_pos.codepoints {
if y > cursor_pos.y_bottom {
break;
}
match c {
'\n' => {
if cursor_pos.lines_omitted > lines_ommitted {
lines_ommitted += 1;
cp.v = Vec::new()
} else {
y += 1;
x = cursor_pos.x_left;
}
}
' '.. => {
if x > cursor_pos.x_right {
if cursor_pos.lines_omitted > lines_ommitted {
lines_ommitted += 1;
cp.v = Vec::new();
} else {
x = cursor_pos.x_left;
y += 1;
}
} else {
cp.v.push(CharPos { x, y, c: *c });
x += 1;
}
}
_ => (),
}
}
cp
}
}
impl IntoIterator for CharPositions {
type Item = CharPos;
type IntoIter = IntoIter<Self::Item>;
fn into_iter(self) -> Self::IntoIter {
IntoIterator::into_iter(self.v)
}
}
pub(crate) struct CharPos {
pub(self) x: usize,
pub(self) y: usize,
pub(self) c: char,
}
impl CharPos {
pub fn x(&self) -> usize {
self.x
}
pub fn y(&self) -> usize {
self.y
}
pub fn c(&self) -> char {
self.c
}
}