ncplane_yx: results are relative to bound plane

This commit is contained in:
nick black 2020-06-03 12:17:51 -04:00
parent 6d5e027be9
commit 75f458d69a
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC
4 changed files with 71 additions and 44 deletions

View File

@ -9,11 +9,11 @@ void notcurses_debug(notcurses* nc, FILE* debugfp){
fprintf(debugfp, "%04d off y: %3d x: %3d geom y: %3d x: %3d curs y: %3d x: %3d %s %p\n",
planeidx, n->absy, n->absx, n->leny, n->lenx, n->y, n->x,
n == notcurses_stdplane_const(nc) ? "std" : " ", n);
if(n->bound || n->bnext || n->bprev){
fprintf(debugfp, " bound to %p, next bound %p, bind %p\n",
n->bound, n->bnext, n->bprev);
if(n->boundto || n->bnext || n->bprev || n->blist){
fprintf(debugfp, " bound %p -> %p <- %p binds %p\n",
n->boundto, n->bnext, n->bprev, n->blist);
}
if(n->bnext == n || n->bound == n){
if(n->bnext == n || n->boundto == n || n->blist == n){
fprintf(debugfp, "WARNING: bound pointers target self\n");
}
if(n->bprev && (*n->bprev != n)){

View File

@ -72,8 +72,9 @@ typedef struct ncplane {
struct ncplane* above; // plane above us, NULL if we're on top
struct ncplane* below; // plane below us, NULL if we're on bottom
struct ncplane* bnext; // next in the bound list of plane to which we are bound
struct ncplane** bprev;// link to us if we're bound
struct ncplane* bound; // plane to which we are bound, if any
struct ncplane** bprev;// link to us iff we're bound, NULL otherwise
struct ncplane* blist; // head of list of bound planes
struct ncplane* boundto; // plane to which we are bound, if any
egcpool pool; // attached storage pool for UTF-8 EGCs
uint64_t channels; // works the same way as cells
uint32_t attrword; // same deal as in a cell

View File

@ -277,15 +277,15 @@ ncplane_create(notcurses* nc, ncplane* n, int rows, int cols,
p->lenx = cols;
p->x = p->y = 0;
p->logrow = 0;
p->bound = NULL;
if(n){
p->blist = NULL;
if( (p->boundto = n) ){
p->absx = xoff + n->absx;
p->absy = yoff + n->absy;
if( (p->bnext = n->bound) ){
n->bound->bprev = &p->bnext;
if( (p->bnext = n->blist) ){
n->blist->bprev = &p->bnext;
}
n->bound = p;
p->bprev = &n->bound;
p->bprev = &n->blist;
*p->bprev = p;
}else{
p->absx = xoff + nc->margin_l;
p->absy = yoff + nc->margin_t;
@ -337,7 +337,7 @@ ncplane* ncplane_bound(ncplane* n, int rows, int cols, int yoff, int xoff, void*
ncplane* ncplane_aligned(ncplane* n, int rows, int cols, int yoff,
ncalign_e align, void* opaque){
return ncplane_create(n->nc, NULL, rows, cols, yoff, ncplane_align(n, align, cols), opaque);
return ncplane_create(n->nc, n, rows, cols, yoff, ncplane_align(n, align, cols), opaque);
}
inline int ncplane_cursor_move_yx(ncplane* n, int y, int x){
@ -370,7 +370,7 @@ ncplane* ncplane_dup(const ncplane* n, void* opaque){
int dimx = n->lenx;
uint32_t attr = ncplane_attr(n);
uint64_t chan = ncplane_channels(n);
ncplane* newn = ncplane_create(n->nc, n->bound, dimy, dimx, n->absy, n->absx, opaque);
ncplane* newn = ncplane_create(n->nc, n->boundto, dimy, dimx, n->absy, n->absx, opaque);
if(newn){
if(egcpool_dup(&newn->pool, &n->pool)){
ncplane_destroy(newn);
@ -509,10 +509,14 @@ int ncplane_destroy(ncplane* ncp){
ncp->nc->bottom = ncp->above;
}
if(ncp->bprev){
*ncp->bprev = ncp->bnext;
if( (*ncp->bprev = ncp->bnext) ){
ncp->bnext->bprev = ncp->bprev;
}
}
if(ncp->bound){
ncp->bound->bprev = NULL;
if(ncp->blist){
// FIXME need unlink all on list
ncp->blist->bprev = NULL;
ncp->blist->bnext = NULL;
}
free_plane(ncp);
return 0;
@ -1656,7 +1660,7 @@ move_bound_planes(ncplane* n, int dy, int dx){
while(n){
n->absy += dy;
n->absx += dx;
move_bound_planes(n->bound, dy, dx);
move_bound_planes(n->blist, dy, dx);
n = n->bnext;
}
}
@ -1666,25 +1670,33 @@ int ncplane_move_yx(ncplane* n, int y, int x){
return -1;
}
int dy, dx; // amount moved
if(n->bound){
dy = (n->bound->absy + y) - n->absy;
dx = (n->bound->absx + x) - n->absx;
if(n->boundto){
dy = (n->boundto->absy + y) - n->absy;
dx = (n->boundto->absx + x) - n->absx;
}else{
dy = (n->nc->stdscr->absy + y) - n->absy;
dx = (n->nc->stdscr->absx + x) - n->absx;
}
n->absx += dx;
n->absy += dy;
move_bound_planes(n->bound, dy, dx);
move_bound_planes(n->blist, dy, dx);
return 0;
}
void ncplane_yx(const ncplane* n, int* y, int* x){
if(y){
*y = n->absy - n->nc->stdscr->absy;
if(n->boundto == NULL){
*y = n->absy - n->nc->stdscr->absy;
}else{
*y = n->absy - n->boundto->absy;
}
}
if(x){
*x = n->absx - n->nc->stdscr->absx;
if(n->boundto == NULL){
*x = n->absx - n->nc->stdscr->absx;
}else{
*x = n->absx - n->boundto->absx;
}
}
}
@ -1834,14 +1846,25 @@ ncplane* ncplane_reparent(ncplane* n, ncplane* newparent){
if(n == n->nc->stdscr){
return NULL; // can't reparent standard plane
}
if( (*n->bprev = n->bnext) ){
n->bnext->bprev = n->bprev;
if(n->boundto == newparent){
return n;
}
if( (n->bnext = newparent->bound) ){
if(n->bprev){
if( (*n->bprev = n->bnext) ){
n->bnext->bprev = n->bprev;
}
}
n->boundto = newparent;
if(newparent == NULL){
n->bnext = NULL;
n->bprev = NULL;
return n;
}
if( (n->bnext = newparent->blist) ){
n->bnext->bprev = &n->bnext;
}
n->bprev = &newparent->bound;
newparent->bound = n;
n->bprev = &newparent->blist;
newparent->blist = n;
return n;
}

View File

@ -769,13 +769,13 @@ TEST_CASE("NCPlane") {
REQUIRE(nsub);
int absy, absx;
ncplane_yx(nsub, &absy, &absx);
// we ought be at 2,2 despite supplying 1,1
CHECK(2 == absy);
CHECK(2 == absx);
CHECK(0 == ncplane_move_yx(nsub, -1, -1)); // moving to -1, -1 ought be 0, 0
CHECK(0 == notcurses_render(nc_));
CHECK(1 == absy); // actually at 2, 2
CHECK(1 == absx);
CHECK(0 == ncplane_move_yx(nsub, -1, -1));
ncplane_yx(nsub, &absy, &absx);
CHECK(0 == absy);
CHECK(0 == absx);
CHECK(-1 == absy); // actually at 0, 0
CHECK(-1 == absx);
}
SUBCASE("BoundToPlaneMoves") { // bound plane ought move along with plane
@ -785,10 +785,10 @@ TEST_CASE("NCPlane") {
REQUIRE(nsub);
int absy, absx;
ncplane_yx(nsub, &absy, &absx);
// we ought be at 2,2 despite supplying 1,1
CHECK(2 == absy);
CHECK(2 == absx);
CHECK(0 == ncplane_move_yx(ndom, 0, 0)); // move to 0, 0 places it at 1, 1
CHECK(0 == notcurses_render(nc_));
CHECK(1 == absy); // actually at 2, 2
CHECK(1 == absx);
CHECK(0 == ncplane_move_yx(ndom, 0, 0));
ncplane_yx(nsub, &absy, &absx);
CHECK(1 == absy);
CHECK(1 == absx);
@ -800,14 +800,17 @@ TEST_CASE("NCPlane") {
struct ncplane* nsub = ncplane_bound(ndom, 2, 2, 1, 1, nullptr);
REQUIRE(nsub);
int absy, absx;
CHECK(0 == notcurses_render(nc_));
ncplane_yx(nsub, &absy, &absx);
// we ought be at 2,2 despite supplying 1,1
CHECK(2 == absy);
CHECK(2 == absx);
CHECK(1 == absy); // actually at 2, 2
CHECK(1 == absx);
ncplane_reparent(nsub, nullptr);
CHECK(0 == ncplane_move_yx(ndom, 0, 0)); // move to 0, 0 places it at 1, 1
ncplane_yx(nsub, &absy, &absx);
CHECK(2 == absy);
CHECK(2 == absy); // now we recognize 2, 2
CHECK(2 == absx);
CHECK(0 == ncplane_move_yx(ndom, 0, 0));
ncplane_yx(nsub, &absy, &absx);
CHECK(2 == absy); // still at 2, 2
CHECK(2 == absx);
}