1
1
use crate :: {
2
2
ansi:: { self , EraseMode , Op , OpStr } ,
3
3
color:: Rgb3 ,
4
- display:: { self , TextDisplay , ROWS } ,
4
+ display:: { self , TextDisplay , ROWS , COLUMNS } ,
5
5
CHARACTER_DRAW_CYCLES ,
6
6
} ;
7
7
use alloc:: string:: String ;
8
8
use embedded_graphics:: prelude:: DrawTarget ;
9
9
use esp32c3_hal:: systimer:: SystemTimer ;
10
- use esp_println:: println;
11
10
12
11
pub const IROWS : isize = display:: ROWS as isize ;
13
12
pub const ICOLS : isize = display:: COLUMNS as isize ;
@@ -63,6 +62,18 @@ impl CursorPos {
63
62
}
64
63
}
65
64
65
+ enum VerticalLocation {
66
+ Middle ,
67
+ Top ,
68
+ Bottom
69
+ }
70
+
71
+ enum HorizontalLocation {
72
+ Middle ,
73
+ Left ,
74
+ Right
75
+ }
76
+
66
77
#[ derive( Debug , Clone , Copy ) ]
67
78
pub struct Cursor {
68
79
pub pos : CursorPos ,
@@ -91,8 +102,20 @@ impl Cursor {
91
102
* self
92
103
}
93
104
94
- fn is_at_bottom ( & self ) -> bool {
95
- self . pos . row ( ) == ROWS - 1
105
+ fn location ( & self ) -> ( VerticalLocation , HorizontalLocation ) {
106
+ const BOT : usize = ROWS - 1 ;
107
+ const RIGHT : usize = COLUMNS - 1 ;
108
+ let vert = match self . pos . row ( ) {
109
+ BOT => VerticalLocation :: Bottom ,
110
+ 0 => VerticalLocation :: Top ,
111
+ _ => VerticalLocation :: Middle ,
112
+ } ;
113
+ let horz = match self . pos . col ( ) {
114
+ RIGHT => HorizontalLocation :: Right ,
115
+ 0 => HorizontalLocation :: Left ,
116
+ _ => HorizontalLocation :: Middle ,
117
+ } ;
118
+ ( vert, horz)
96
119
}
97
120
98
121
fn set_highlight ( & self , text : & mut TextDisplay ) {
@@ -217,27 +240,43 @@ impl TextField {
217
240
self . move_cursor ( 0 , 1 ) ;
218
241
}
219
242
'\n' => {
220
- if self . cursor . is_at_bottom ( ) {
221
- self . cursor . unset_highlight ( & mut self . text ) ;
222
- self . text . scroll_down ( 1 ) ;
223
- self . move_cursor ( 0 , -( self . cursor . pos . col ( ) as isize ) )
224
- } else {
225
- self . move_cursor ( 1 , -( self . cursor . pos . col ( ) as isize ) )
243
+ match self . cursor . location ( ) {
244
+ ( VerticalLocation :: Bottom , _) => {
245
+ self . cursor . unset_highlight ( & mut self . text ) ;
246
+ self . text . scroll_down ( 1 ) ;
247
+ self . move_cursor ( 0 , -( self . cursor . pos . col ( ) as isize ) )
248
+ } ,
249
+ _ => {
250
+ self . move_cursor ( 1 , -( self . cursor . pos . col ( ) as isize ) )
251
+ }
226
252
}
227
253
}
228
254
'\r' => self . move_cursor ( 0 , -( self . cursor . pos . col ( ) as isize ) ) ,
229
255
_ => {
230
256
for c in t. escape_default ( ) {
231
257
self . text . write ( self . cursor . pos . 0 , self . cursor . pos . 1 , c) ;
232
- self . move_cursor ( 0 , 1 ) ;
258
+ match self . cursor . location ( ) {
259
+ ( _, HorizontalLocation :: Left | HorizontalLocation :: Middle ) => {
260
+ self . move_cursor ( 0 , 1 ) ;
261
+ } ,
262
+ ( VerticalLocation :: Top | VerticalLocation :: Middle , HorizontalLocation :: Right ) => {
263
+ self . move_cursor ( 1 , -( self . cursor . pos . col ( ) as isize ) )
264
+ } ,
265
+ ( VerticalLocation :: Bottom , HorizontalLocation :: Right ) => {
266
+ self . cursor . unset_highlight ( & mut self . text ) ;
267
+ self . text . scroll_down ( 1 ) ;
268
+ self . cursor . set_highlight ( & mut self . text ) ;
269
+ self . move_cursor ( 0 , -( self . cursor . pos . col ( ) as isize ) ) ;
270
+ }
271
+ }
233
272
}
234
273
}
235
274
}
236
275
}
237
276
238
277
fn handle_op ( & mut self , op : Op ) {
239
278
use Op :: * ;
240
- println ! ( "{:?}" , op) ;
279
+ // println!("{:?}", op);
241
280
match op {
242
281
MoveCursorAbs { x, y } => {
243
282
self . move_cursor (
@@ -249,7 +288,11 @@ impl TextField {
249
288
self . move_cursor ( 0 , x as isize - self . cursor . pos . col ( ) as isize ) ;
250
289
}
251
290
MoveCursorDelta { dx, dy } => {
252
- self . move_cursor ( dy, dx) ;
291
+ // Constrain dx and dy so that the result added to the current position
292
+ // stays within the window
293
+ let x = ( self . cursor . pos . col ( ) as isize + dx) . clamp ( 0 , COLUMNS as isize - 1 ) - self . cursor . pos . col ( ) as isize ;
294
+ let y = ( self . cursor . pos . row ( ) as isize + dy) . clamp ( 0 , ROWS as isize - 1 ) - self . cursor . pos . row ( ) as isize ;
295
+ self . move_cursor ( y, x) ;
253
296
}
254
297
MoveCursorBeginningAndLine { dy } => {
255
298
self . move_cursor ( dy, -( self . cursor . pos . col ( ) as isize ) ) ;
0 commit comments