8000 Merge pull request #10110 from RetiredWizard/rangescroll · adafruit/circuitpython@e8de36a · GitHub
[go: up one dir, main page]

Skip to content

Commit e8de36a

Browse files
authored
Merge pull request #10110 from RetiredWizard/rangescroll
Add VT100 ranged scroll
2 parents 612d22c + f02a3dc commit e8de36a

File tree

5 files changed

+68
-30
lines changed

5 files changed

+68
-30
lines changed

ports/atmel-samd/boards/openbook_m4/mpconfigboard.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ CIRCUITPY_KEYPAD = 1
1414
CIRCUITPY_SYNTHIO = 0
1515
CIRCUITPY_JPEGIO = 0
1616
CIRCUITPY_FLOPPYIO = 0
17+
CIRCUITPY_TERMINALIO_VT100 = 0

ports/atmel-samd/boards/uartlogger2/mpconfigboard.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ LONGINT_IMPL = MPZ
1212
CIRCUITPY_SPITARGET = 0
1313
CIRCUITPY_SYNTHIO = 0
1414
CIRCUITPY_JPEGIO = 0
15+
CIRCUITPY_TERMINALIO_VT100 = 0

shared-bindings/terminalio/Terminal.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
//| * ``ESC [ H`` - Move the cursor to 0,0.
4040
//| * ``ESC M`` - Move the cursor up one line, scrolling if necessary.
4141
//| * ``ESC D`` - Move the cursor down one line, scrolling if necessary.
42+
//| * ``ESC [ r`` - Disable scrolling range (set to fullscreen).
43+
//| * ``ESC [ nnnn ; mmmm r`` - Set scrolling range between rows nnnn and mmmm.
4244
//| * ``ESC [ ## m`` - Set the terminal display attributes.
4345
//| * ``ESC [ ## ; ## m`` - Set the terminal display attributes.
4446
//| * ``ESC [ ## ; ## ; ## m`` - Set the terminal display attributes.

shared-module/terminalio/Terminal.c

Lines changed: 62 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
3333
self->status_x = 0;
3434
self->status_y = 0;
3535
self->first_row = 0;
36+
self->vt_scroll_top = 0;
37+
self->vt_scroll_end = self->scroll_area->height_in_tiles - 1;
3638
common_hal_displayio_tilegrid_set_all_tiles(self->scroll_area, 0);
3739
if (self->status_bar) {
3840
common_hal_displayio_tilegrid_set_all_tiles(self->status_bar, 0);
@@ -42,6 +44,8 @@ void common_hal_terminalio_terminal_construct(terminalio_terminal_obj_t *self,
4244
}
4345

4446
size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, const byte *data, size_t len, int *errcode) {
47+
#define SCRNMOD(x) (((x) + (self->scroll_area->top_left_y)) % (self->scroll_area->height_in_tiles))
48+
4549
// Make sure the terminal is initialized before we do anything with it.
4650
if (self->scroll_area == NULL) {
4751
return len;
@@ -114,7 +118,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
114118
}
115119
} else if (c == 0x1b) {
116120
// Handle commands of the form [ESC].<digits><command-char> where . is not yet known.
117-
uint8_t vt_args[3] = {0, -1, -1};
121+
int16_t vt_args[3] = {0, 0, 0};
118122
uint8_t j = 1;
119123
#if CIRCUITPY_TERMINALIO_VT100
120124
uint8_t n_args = 1;
@@ -158,8 +162,8 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
158162
#endif
159163
} else {
160164
if (c == 'K') {
161-
uint8_t clr_start = self->cursor_x;
162-
uint8_t clr_end = self->scroll_area->width_in_tiles;
165+
int16_t clr_start = self->cursor_x;
166+
int16_t clr_end = self->scroll_area->width_in_tiles;
163167
#if CIRCUITPY_TERMINALIO_VT100
164168
if (vt_args[0] == 1) {
165169
clr_start = 0;
@@ -188,9 +192,6 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
188192
if (vt_args[0] > 0) {
189193
vt_args[0]--;
190194
}
191-
if (vt_args[1] == -1) {
192-
vt_args[1] = 0;
193-
}
194195
if (vt_args[1] > 0) {
195196
vt_args[1]--;
196197
}
@@ -200,7 +201,7 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
200201
if (vt_args[1] >= self->scroll_area->width_in_tiles) {
201202
vt_args[1] = self->scroll_area->width_in_tiles - 1;
202203
}
203-
vt_args[0] = (vt_args[0] + self->scroll_area->top_left_y) % self->scroll_area->height_in_tiles;
204+
vt_args[0] = SCRNMOD(vt_args[0]);
204205
self->cursor_x = vt_args[1];
205206
self->cursor_y = vt_args[0];
206207
start_y = self->cursor_y;
@@ -215,43 +216,58 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
215216
common_hal_displayio_palette_set_color(terminal_palette, 1, 0xffffff);
216217
}
217218
}
219+
} else if (c == 'r') {
220+
if (vt_args[0] < vt_args[1] && vt_args[0] >= 1 && vt_args[1] <= self->scroll_area->height_in_tiles) {
221+
self->vt_scroll_top = vt_args[0] - 1;
222+
self->vt_scroll_end = vt_args[1] - 1;
223+
} else {
224+
self->vt_scroll_top = 0;
225+
self->vt_scroll_end = self->scroll_area->height_in_tiles - 1;
226+
}
227+
self->cursor_x = 0;
228+
self->cursor_y = self->scroll_area->top_left_y % self->scroll_area->height_in_tiles;
229+
start_y = self->cursor_y;
218230
#endif
219231
}
220232
i += j + 1;
221233
}
222234
#if CIRCUITPY_TERMINALIO_VT100
223235
} else if (i[0] == 'M') {
224-
if (self->cursor_y != self->scroll_area->top_left_y) {
236+
if (self->cursor_y != SCRNMOD(self->vt_scroll_top)) {
225237
if (self->cursor_y > 0) {
226238
self->cursor_y = self->cursor_y - 1;
227239
} else {
228240
self->cursor_y = self->scroll_area->height_in_tiles - 1;
229241
}
230242
} else {
231-
if (self->cursor_y > 0) {
232-
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, self->cursor_y - 1);
243+
if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles) {
244+
// Scroll range defined, manually move tiles to perform scroll
245+
for (int16_t irow = self->vt_scroll_end - 1; irow >= self->vt_scroll_top; irow--) {
246+
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
247+
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, SCRNMOD(irow + 1), common_hal_displayio_tilegrid_get_tile(self->scroll_area, icol, SCRNMOD(irow)));
248+
}
249+
}
250+
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
251+
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->cursor_y, 0);
252+
}
233253
} else {
234-
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, self->scroll_area->height_in_tiles - 1);
235-
}
236-
for (uint8_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
237-
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->scroll_area->top_left_y, 0);
254+
// Full screen scroll, just set new top_y pointer and clear row
255+
if (self->cursor_y > 0) {
256+
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, self->cursor_y - 1);
257+
} else {
258+
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, self->scroll_area->height_in_tiles - 1);
259+
}
260+
for (uint16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
261+
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->scroll_area->top_left_y, 0);
262+
}
263+
self->cursor_y = self->scroll_area->top_left_y;
238264
}
239-
240265
self->cursor_x = 0;
241-
self->cursor_y = self->scroll_area->top_left_y;
242266
}
243267
start_y = self->cursor_y;
244268
i++;
245269
} else if (i[0] == 'D') {
246-
self->cursor_y = (self->cursor_y + 1) % self->scroll_area->height_in_tiles;
247-
if (self->cursor_y == self->scroll_area->top_left_y) {
248-
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, (self->cursor_y + 1) % self->scroll_area->height_in_tiles);
249-
for (uint8_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
250-
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->cursor_y, 0);
251-
}
252-
self->cursor_x = 0;
253-
}
254-
start_y = self->cursor_y;
270+
self->cursor_y++;
255271
i++;
256272
#endif
257273
} else if (i[0] == ']' && c == ';') {
@@ -276,12 +292,28 @@ size_t common_hal_terminalio_terminal_write(terminalio_terminal_obj_t *self, con
276292
self->cursor_y %= self->scroll_area->height_in_tiles;
277293
}
278294
if (self->cursor_y != start_y) {
279-
// clear the new row in case of scroll up
280-
if (self->cursor_y == self->scroll_area->top_left_y) {
281-
for (uint16_t j = 0; j < self->scroll_area->width_in_tiles; j++) {
282-
common_hal_displayio_tilegrid_set_tile(self->scroll_area, j, self->cursor_y, 0);
295+
if (((self->cursor_y + self->scroll_area->height_in_tiles) - 1) % self->scroll_area->height_in_tiles == SCRNMOD(self->vt_scroll_end)) {
296+
#if CIRCUITPY_TERMINALIO_VT100
297+
if (self->vt_scroll_top != 0 || self->vt_scroll_end != self->scroll_area->height_in_tiles) {
298+
// Scroll range defined, manually move tiles to perform scroll
299+
self->cursor_y = SCRNMOD(self->vt_scroll_end);
300+
301+
for (int16_t irow = self->vt_scroll_top; irow < self->vt_scroll_end; irow++) {
302+
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
303+
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, SCRNMOD(irow), common_hal_displayio_tilegrid_get_tile(self->scroll_area, icol, SCRNMOD(irow + 1)));
304+
}
305+
}
306+
}
307+
#endif
308+
if (self->vt_scroll_top == 0 && self->vt_scroll_end == self->scroll_area->height_in_tiles) {
309+
// Full screen scroll, just set new top_y pointer
310+
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, (self->cursor_y + self->scroll_area->height_in_tiles + 1) % self->scroll_area->height_in_tiles);
311+
}
312+
// clear the new row in case of scroll up
313+
for (int16_t icol = 0; icol < self->scroll_area->width_in_tiles; icol++) {
314+
common_hal_displayio_tilegrid_set_tile(self->scroll_area, icol, self->cursor_y, 0);
283315
}
284-
common_hal_displayio_tilegrid_set_top_left(self->scroll_area, 0, (self->cursor_y + self->scroll_area->height_in_tiles + 1) % self->scroll_area->height_in_tiles);
316+
self->cursor_x = 0;
285317
}
286318
start_y = self->cursor_y;
287319
}

shared-module/terminalio/Terminal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ typedef struct {
2323
uint16_t status_x;
2424
uint16_t status_y;
2525
uint16_t first_row;
26+
uint16_t vt_scroll_top;
27+
uint16_t vt_scroll_end;
2628
uint16_t osc_command;
2729
bool in_osc_command;
2830
} terminalio_terminal_obj_t;

0 commit comments

Comments
 (0)
0