Do not use start/end for TextCursor, only index
This commit is contained in:
parent
eacd09b167
commit
784215e490
1 changed files with 31 additions and 47 deletions
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue