Do not use start/end for TextCursor, only index

This commit is contained in:
Jeremy Soller 2022-10-21 11:44:11 -06:00
parent eacd09b167
commit 784215e490
No known key found for this signature in database
GPG key ID: 87F211AF2BE4C2FE

View file

@ -46,15 +46,13 @@ pub enum TextAction {
pub struct TextCursor { pub struct TextCursor {
/// Text line the cursor is on /// Text line the cursor is on
pub line: TextLineIndex, pub line: TextLineIndex,
/// Start of glyph (behind cursor) /// Index of glyph at cursor (will insert behind this glyph)
pub start: usize, pub index: usize,
/// End of glyph (after cursor)
pub end: usize,
} }
impl TextCursor { impl TextCursor {
pub const fn new(line: TextLineIndex, start: usize, end: usize) -> Self { pub const fn new(line: TextLineIndex, index: usize) -> Self {
Self { line, start, end } Self { line, index }
} }
} }
@ -240,7 +238,7 @@ impl<'a> TextBuffer<'a> {
for layout_line in layout { for layout_line in layout {
let mut found = false; let mut found = false;
for glyph in layout_line.glyphs.iter() { for glyph in layout_line.glyphs.iter() {
if glyph.start <= self.cursor.end { if glyph.start <= self.cursor.index {
found = true; found = true;
break; break;
} }
@ -427,10 +425,9 @@ impl<'a> TextBuffer<'a> {
} else { } else {
let line = &mut self.lines[self.cursor.line.get()]; let line = &mut self.lines[self.cursor.line.get()];
line.reset(); line.reset();
line.text.insert(self.cursor.end, character); line.text.insert(self.cursor.index, character);
self.cursor.start = self.cursor.end; self.cursor.index += character.len_utf8();
self.cursor.end += character.len_utf8();
self.shape_until_cursor(CursorScroll::Bottom); self.shape_until_cursor(CursorScroll::Bottom);
}, },
@ -439,27 +436,29 @@ impl<'a> TextBuffer<'a> {
self.lines.insert(next_line, TextBufferLine::new(String::new())); self.lines.insert(next_line, TextBufferLine::new(String::new()));
self.cursor.line = TextLineIndex::new(next_line); self.cursor.line = TextLineIndex::new(next_line);
self.cursor.start = 0; self.cursor.index = 0;
self.cursor.end = 0;
self.shape_until_cursor(CursorScroll::Bottom); self.shape_until_cursor(CursorScroll::Bottom);
}, },
TextAction::Backspace => { TextAction::Backspace => {
if self.cursor.end > 0 { if self.cursor.index > 0 {
let line = &mut self.lines[self.cursor.line.get()]; let line = &mut self.lines[self.cursor.line.get()];
line.reset(); line.reset();
line.text.remove(self.cursor.start);
self.cursor.end = self.cursor.start; // Find previous character index
self.cursor.start = 0; let mut prev_index = 0;
for (i, _) in line.text.char_indices() { for (i, _) in line.text.char_indices() {
if i == self.cursor.end { if i < self.cursor.index {
break; prev_index = i;
} else { } else {
self.cursor.start = i; break;
} }
} }
self.cursor.index = prev_index;
line.text.remove(self.cursor.index);
self.shape_until_cursor(CursorScroll::Top); self.shape_until_cursor(CursorScroll::Top);
} else if self.cursor.line.get() > 0 { } else if self.cursor.line.get() > 0 {
let mut line_index = self.cursor.line.get(); let mut line_index = self.cursor.line.get();
@ -470,15 +469,7 @@ impl<'a> TextBuffer<'a> {
line.reset(); line.reset();
self.cursor.line = TextLineIndex::new(line_index); self.cursor.line = TextLineIndex::new(line_index);
self.cursor.end = line.text.len(); self.cursor.index = line.text.len();
self.cursor.start = 0;
for (i, _) in line.text.char_indices() {
if i == self.cursor.end {
break;
} else {
self.cursor.start = i;
}
}
line.text.push_str(&old_line.text); line.text.push_str(&old_line.text);
@ -559,23 +550,17 @@ impl<'a> TextBuffer<'a> {
} }
} }
let mut new_cursor = TextCursor::new( let mut new_cursor = TextCursor::new(TextLineIndex::new(line_i), 0);
TextLineIndex::new(line_i),
0,
0
);
match layout_line.glyphs.get(new_cursor_glyph) { match layout_line.glyphs.get(new_cursor_glyph) {
Some(glyph) => { Some(glyph) => {
// Position at glyph // Position at glyph
new_cursor.start = glyph.start; new_cursor.index = glyph.start;
new_cursor.end = glyph.end;
}, },
None => match layout_line.glyphs.last() { None => match layout_line.glyphs.last() {
Some(glyph) => { Some(glyph) => {
// Position at end of line // Position at end of line
new_cursor.start = glyph.end; new_cursor.index = glyph.end;
new_cursor.end = glyph.end;
}, },
None => { None => {
// Keep at start of empty line // Keep at start of empty line
@ -590,10 +575,9 @@ impl<'a> TextBuffer<'a> {
if let Some(glyph) = layout_line.glyphs.get(new_cursor_glyph) { if let Some(glyph) = layout_line.glyphs.get(new_cursor_glyph) {
let text_glyph = &line.text[glyph.start..glyph.end]; let text_glyph = &line.text[glyph.start..glyph.end];
log::debug!( log::debug!(
"{}, {}, {}: '{}' ('{}'): '{}' ({:?})", "{}, {}: '{}' ('{}'): '{}' ({:?})",
self.cursor.line.get(), self.cursor.line.get(),
self.cursor.start, self.cursor.index,
self.cursor.end,
glyph.font.info.family, glyph.font.info.family,
glyph.font.info.post_script_name, glyph.font.info.post_script_name,
text_glyph, text_glyph,
@ -648,9 +632,9 @@ impl<'a> TextBuffer<'a> {
let cursor_glyph_opt = |cursor: &TextCursor| -> Option<usize> { let cursor_glyph_opt = |cursor: &TextCursor| -> Option<usize> {
let mut glyph_i_opt = None; let mut glyph_i_opt = None;
for (glyph_i, glyph) in layout_line.glyphs.iter().enumerate() { for (glyph_i, glyph) in layout_line.glyphs.iter().enumerate() {
if cursor.start == glyph.start { if cursor.index == glyph.start {
glyph_i_opt = Some(glyph_i); glyph_i_opt = Some(glyph_i);
} else if cursor.start == glyph.end { } else if cursor.index == glyph.end {
glyph_i_opt = Some(glyph_i + 1); glyph_i_opt = Some(glyph_i + 1);
} }
} }
@ -665,10 +649,10 @@ impl<'a> TextBuffer<'a> {
(self.cursor, select) (self.cursor, select)
} else { } else {
/* select.line == self.cursor.line */ /* select.line == self.cursor.line */
if select.start < self.cursor.start { if select.index < self.cursor.index {
(select, self.cursor) (select, self.cursor)
} else { } else {
/* select.start >= self.cursor.start */ /* select.index >= self.cursor.index */
(self.cursor, select) (self.cursor, select)
} }
}; };
@ -682,7 +666,7 @@ impl<'a> TextBuffer<'a> {
if line_i == start.line.get() && line_i == end.line.get() { if line_i == start.line.get() && line_i == end.line.get() {
// On edge of start and end line, check if any contained glyphs are after start and before end // On edge of start and end line, check if any contained glyphs are after start and before end
for glyph in layout_line.glyphs.iter() { for glyph in layout_line.glyphs.iter() {
if glyph.start >= start.start && glyph.end <= end.end{ if glyph.start >= start.index && glyph.end <= end.index {
inside = true; inside = true;
break; break;
} }
@ -690,7 +674,7 @@ impl<'a> TextBuffer<'a> {
} else if line_i == start.line.get() { } else if line_i == start.line.get() {
// On edge of start line, check if any contained glyphs are after start // On edge of start line, check if any contained glyphs are after start
for glyph in layout_line.glyphs.iter() { for glyph in layout_line.glyphs.iter() {
if glyph.start >= start.start { if glyph.start >= start.index {
inside = true; inside = true;
break; break;
} }
@ -698,7 +682,7 @@ impl<'a> TextBuffer<'a> {
} else if line_i == end.line.get() { } else if line_i == end.line.get() {
// On edge of end line, check if any contained glyphs are before end // On edge of end line, check if any contained glyphs are before end
for glyph in layout_line.glyphs.iter() { for glyph in layout_line.glyphs.iter() {
if glyph.end <= end.end { if glyph.end <= end.index {
inside = true; inside = true;
break; break;
} }