[ncplane_erase_region] generalize #2181

This commit is contained in:
nick black 2021-09-20 21:13:50 -04:00 committed by nick black
parent 9733835673
commit 72757044da
5 changed files with 110 additions and 20 deletions

View File

@ -900,10 +900,26 @@ int ncplane_mergedown_simple(struct ncplane* restrict src,
void ncplane_erase(struct ncplane* n);
// Erase every cell in the region starting at {ystart, xstart} and having size
// {ylen, xlen}. It is an error if any of ystart, xstart, ylen, or xlen is
// negative. A value of 0 may be provided for ylen and/or xlen, meaning to
// erase everything along that dimension. It is an error if ystart + ylen
// or xstart + xlen is not in the plane.
// {|ylen|x|xlen|} for non-zero lengths. If ystart and/or xstart are -1, the current
// cursor position along that axis is used; other negative values are an error. A
// negative ylen means to move up from the origin, and a negative xlen means to move
// left from the origin. A positive ylen moves down, and a positive xlen moves right.
// A value of 0 for the length erases everything along that dimension. It is an error
// if the starting coordinate is not in the plane, but the ending coordinate may be
// outside the plane.
//
// For example, on a plane of 20 rows and 10 columns, with the cursor at row 10 and
// column 5, the following would hold:
//
// (-1, -1, 0, 1): clears the column to the right of the cursor (column 6)
// (-1, -1, 0, -1): clears the column to the left of the cursor (column 4)
// (-1, -1, INT_MAX, 0): clears all rows with or below the cursor (rows 10--19)
// (-1, -1, -INT_MAX, 0): clears all rows with or above the cursor (rows 0--10)
// (-1, 4, 3, 3): clears from row 10, column 4 through row 12, column 6
// (-1, 4, 3, 3): clears from row 10, column 4 through row 8, column 2
// (4, -1, 0, 3): clears columns 5, 6, and 7
// (-1, -1, 0, 0): clears the plane *if the cursor is in a legal position*
// (0, 0, 0, 0): clears the plane in all cases
int ncplane_erase_region(struct ncplane* n, int ystart, int xstart,
int ylen, int xlen);
```

View File

@ -320,7 +320,11 @@ might see changes. It is an error to merge a plane onto itself.
homes the cursor. The base cell is preserved, as are the active attributes.
**ncplane_erase_region** does the same for a subregion of the plane. For the
latter, supply 0 for ***ylen*** and/or ***xlen*** to erase through that
dimension, starting at the specified point. See [BUGS][] below.
dimension, starting at the specified point. Supply -1 for ***ystart*** and/or
***xstart*** to use the cursor's current position along that axis for a starting
point. Negative ***ylen*** and ***xlen*** move up and to the left from the starting
coordinate; positive ***ylen*** and ***xlen*** move down and to the right from same.
See [BUGS][] below.
When a plane is resized (whether by **ncplane_resize**, **SIGWINCH**, or any
other mechanism), a depth-first recursion is performed on its children.
@ -444,8 +448,8 @@ plane is destroyed. The caller should release this **nccell** with
**ncplane_as_rgba** returns a heap-allocated array of **uint32_t** values,
each representing a single RGBA pixel, or **NULL** on failure.
**ncplane_erase_region** returns -1 if any of its parameters are negative, or
if they specify any area beyond the plane.
**ncplane_erase_region** returns -1 if **ystart** or **xstart** are less than -1,
or outside the plane.
**ncplane_cursor_move_yx** returns -1 if the coordinates are beyond the
dimensions of the specified plane (except for the special value -1).
@ -480,6 +484,12 @@ ncplane_set_base(notcurses_stdplane(nc), " ", 0, 0);
notcurses_render(nc);
```
or simply:
```c
notcurses_refresh(nc);
```
# SEE ALSO
**notcurses(3)**,

View File

@ -2231,10 +2231,26 @@ API int ncplane_mergedown(struct ncplane* RESTRICT src,
API void ncplane_erase(struct ncplane* n);
// Erase every cell in the region starting at {ystart, xstart} and having size
// {ylen, xlen}. It is an error if any of ystart, xstart, ylen, or xlen is
// negative. A value of 0 may be provided for ylen and/or xlen, meaning to
// erase everything along that dimension. It is an error if ystart + ylen
// or xstart + xlen is not in the plane.
// {|ylen|x|xlen|} for non-zero lengths. If ystart and/or xstart are -1, the current
// cursor position along that axis is used; other negative values are an error. A
// negative ylen means to move up from the origin, and a negative xlen means to move
// left from the origin. A positive ylen moves down, and a positive xlen moves right.
// A value of 0 for the length erases everything along that dimension. It is an error
// if the starting coordinate is not in the plane, but the ending coordinate may be
// outside the plane.
//
// For example, on a plane of 20 rows and 10 columns, with the cursor at row 10 and
// column 5, the following would hold:
//
// (-1, -1, 0, 1): clears the column to the right of the cursor (column 6)
// (-1, -1, 0, -1): clears the column to the left of the cursor (column 4)
// (-1, -1, INT_MAX, 0): clears all rows with or below the cursor (rows 10--19)
// (-1, -1, -INT_MAX, 0): clears all rows with or above the cursor (rows 0--10)
// (-1, 4, 3, 3): clears from row 10, column 4 through row 12, column 6
// (-1, 4, 3, 3): clears from row 10, column 4 through row 8, column 2
// (4, -1, 0, 3): clears columns 5, 6, and 7
// (-1, -1, 0, 0): clears the plane *if the cursor is in a legal position*
// (0, 0, 0, 0): clears the plane in all cases
API int ncplane_erase_region(struct ncplane* n, int ystart, int xstart,
int ylen, int xlen)
__attribute__ ((nonnull (1)));

View File

@ -2122,27 +2122,44 @@ void ncplane_erase(ncplane* n){
}
int ncplane_erase_region(ncplane* n, int ystart, int xstart, int ylen, int xlen){
if(ylen < 0 || xlen < 0){
logerror("Won't erase section of negative length (%d, %d)\n", ylen, xlen);
return -1;
if(ystart == -1){
ystart = n->y;
}
if(xstart == -1){
xstart = n->x;
}
if(ystart < 0 || xstart < 0){
logerror("Illegal start of erase (%d, %d)\n", ystart, xstart);
return -1;
}
if(ystart >= ncplane_dim_y(n) || ystart + ylen > ncplane_dim_y(n)){
logerror("Illegal y spec for erase (%d, %d)\n", ystart, ylen);
if(ystart >= ncplane_dim_y(n) || xstart >= ncplane_dim_x(n)){
logerror("Illegal start of erase (%d, %d)\n", ystart, xstart);
return -1;
}
if(ylen == 0){
ylen = ncplane_dim_y(n) - ystart;
ystart = 0;
ylen = ncplane_dim_y(n);
}
if(xstart >= ncplane_dim_x(n) || xstart + xlen > ncplane_dim_x(n)){
logerror("Illegal x spec for erase (%d, %d)\n", xstart, xlen);
if(ystart + ylen > ncplane_dim_y(n) || ystart + ylen < -1){
logerror("Illegal y spec for erase (%d, %d)\n", ystart, ylen);
return -1;
}
if(xlen == 0){
xlen = ncplane_dim_x(n) - xstart;
xstart = 0;
xlen = ncplane_dim_x(n);
}
if(xstart + xlen > ncplane_dim_x(n) || xstart + xlen < -1){
logerror("Illegal x spec for erase (%d, %d)\n", xstart, xlen);
return -1;
}
if(xlen < 0){
xstart = xstart + xlen;
xlen = -xlen;
}
if(ylen < 0){
ystart = ystart + ylen;
ylen = -ylen;
>>>>>>> 4e10ad795 ([ncplane_erase_region] generalize #2181)
}
for(int y = ystart ; y < ystart + ylen ; ++y){
for(int x = xstart ; x < xstart + xlen ; ++x){

31
src/tests/erase.cpp Normal file
View File

@ -0,0 +1,31 @@
#include <array>
#include <cstdlib>
#include "main.h"
TEST_CASE("Erase") {
auto nc_ = testing_notcurses();
if(!nc_){
return;
}
struct ncplane* n_ = notcurses_stdplane(nc_);
REQUIRE(n_);
// clear all columns to the left of cursor, inclusive
SUBCASE("EraseColumnsLeft") {
}
// clear all columns to the right of cursor, inclusive
SUBCASE("EraseColumnsRight") {
}
// clear all rows above cursor, inclusive
SUBCASE("EraseRowsLeft") {
}
// clear all rows below cursor, inclusive
SUBCASE("EraseRowsBelow") {
}
CHECK(0 == notcurses_stop(nc_));
}