@@ -8,6 +8,19 @@ struct TextEditorState {
8
8
}
9
9
10
10
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
+
11
24
fn fwd ( & mut self , len : usize ) {
12
25
self . cursor += 1 ;
13
26
if self . cursor > len {
@@ -28,6 +41,8 @@ impl TextEditorState {
28
41
}
29
42
i += 1 ;
30
43
}
44
+ // Ensure we don't go out of bounds.
45
+ i = i. min ( self . lines . len ( ) - 1 ) ;
31
46
i
32
47
}
33
48
@@ -40,7 +55,7 @@ impl TextEditorState {
40
55
let mut d = std:: f32:: MAX ;
41
56
let mut closest = 0 ;
42
57
for i in range {
43
- let dp = rects[ i] . center ( ) . distance_to ( p) ;
58
+ let dp = rects[ i] . origin . distance_to ( p) ;
44
59
if dp < d {
45
60
closest = i;
46
61
d = dp;
@@ -50,7 +65,7 @@ impl TextEditorState {
50
65
}
51
66
52
67
fn down ( & mut self ) {
53
- let p = self . glyph_rects [ self . cursor ] . center ( ) ;
68
+ let p = self . cursor_pos ( ) ;
54
69
55
70
let line = self . find_line ( ) + 1 ;
56
71
if line < self . lines . len ( ) {
@@ -61,7 +76,7 @@ impl TextEditorState {
61
76
}
62
77
63
78
fn up ( & mut self ) {
64
- let p = self . glyph_rects [ self . cursor ] . center ( ) ;
79
+ let p = self . cursor_pos ( ) ;
65
80
66
81
let line = self . find_line ( ) ;
67
82
if line > 0 {
@@ -140,8 +155,7 @@ impl TextEditorState {
140
155
/// state can be created from more atomic Views.
141
156
pub fn text_editor ( text : impl Binding < String > ) -> impl View {
142
157
focus ( move |has_focus| {
143
- state ( TextEditorState :: new, move |state, cx| {
144
- let cursor = cx[ state] . cursor ;
158
+ state ( TextEditorState :: new, move |state, _| {
145
159
canvas ( move |cx, rect, vger| {
146
160
vger. translate ( [ 0.0 , rect. height ( ) ] ) ;
147
161
let font_size = 18 ;
@@ -153,19 +167,12 @@ pub fn text_editor(text: impl Binding<String>) -> impl View {
153
167
let rects = vger. glyph_positions ( text. get ( cx) , font_size, break_width) ;
154
168
let lines = vger. line_metrics ( text. get ( cx) , font_size, break_width) ;
155
169
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) ;
166
170
167
171
cx[ state] . glyph_rects = rects;
168
172
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) ;
169
176
}
170
177
} )
171
178
. key ( move |cx, k| {
0 commit comments