Skip to content

Commit b7fbb15

Browse files
committed
#78 fix text_editor panic
Also improve behavior of up arrow near the end of the text.
1 parent cbcf581 commit b7fbb15

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

src/views/text_editor.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@ struct TextEditorState {
88
}
99

1010
impl TextEditorState {
11+
/// Returns the position of the cursor in local coordinates.
12+
fn cursor_pos(&self) -> LocalPoint {
13+
if self.cursor == self.glyph_rects.len() {
14+
if let Some(r) = self.glyph_rects.last() {
15+
[r.origin.x + r.size.width, r.origin.y].into()
16+
} else {
17+
[0.0, -20.0].into()
18+
}
19+
} else {
20+
self.glyph_rects[self.cursor].origin
21+
}
22+
}
23+
1124
fn fwd(&mut self, len: usize) {
1225
self.cursor += 1;
1326
if self.cursor > len {
@@ -28,6 +41,8 @@ impl TextEditorState {
2841
}
2942
i += 1;
3043
}
44+
// Ensure we don't go out of bounds.
45+
i = i.min(self.lines.len() - 1);
3146
i
3247
}
3348

@@ -40,7 +55,7 @@ impl TextEditorState {
4055
let mut d = std::f32::MAX;
4156
let mut closest = 0;
4257
for i in range {
43-
let dp = rects[i].center().distance_to(p);
58+
let dp = rects[i].origin.distance_to(p);
4459
if dp < d {
4560
closest = i;
4661
d = dp;
@@ -50,7 +65,7 @@ impl TextEditorState {
5065
}
5166

5267
fn down(&mut self) {
53-
let p = self.glyph_rects[self.cursor].center();
68+
let p = self.cursor_pos();
5469

5570
let line = self.find_line() + 1;
5671
if line < self.lines.len() {
@@ -61,7 +76,7 @@ impl TextEditorState {
6176
}
6277

6378
fn up(&mut self) {
64-
let p = self.glyph_rects[self.cursor].center();
79+
let p = self.cursor_pos();
6580

6681
let line = self.find_line();
6782
if line > 0 {
@@ -140,8 +155,7 @@ impl TextEditorState {
140155
/// state can be created from more atomic Views.
141156
pub fn text_editor(text: impl Binding<String>) -> impl View {
142157
focus(move |has_focus| {
143-
state(TextEditorState::new, move |state, cx| {
144-
let cursor = cx[state].cursor;
158+
state(TextEditorState::new, move |state, _| {
145159
canvas(move |cx, rect, vger| {
146160
vger.translate([0.0, rect.height()]);
147161
let font_size = 18;
@@ -153,19 +167,12 @@ pub fn text_editor(text: impl Binding<String>) -> impl View {
153167
let rects = vger.glyph_positions(text.get(cx), font_size, break_width);
154168
let lines = vger.line_metrics(text.get(cx), font_size, break_width);
155169
let glyph_rect_paint = vger.color_paint(vger::Color::MAGENTA);
156-
let p = if cursor == rects.len() {
157-
if let Some(r) = rects.last() {
158-
[r.origin.x + r.size.width, r.origin.y].into()
159-
} else {
160-
[0.0, -20.0].into()
161-
}
162-
} else {
163-
rects[cursor].origin
164-
};
165-
vger.fill_rect(LocalRect::new(p, [2.0, 20.0].into()), 0.0, glyph_rect_paint);
166170

167171
cx[state].glyph_rects = rects;
168172
cx[state].lines = lines;
173+
174+
let p = cx[state].cursor_pos();
175+
vger.fill_rect(LocalRect::new(p, [2.0, 20.0].into()), 0.0, glyph_rect_paint);
169176
}
170177
})
171178
.key(move |cx, k| {

0 commit comments

Comments
 (0)