From 75f458d69a759b40ec94c4c7a713f2216c5f7b6b Mon Sep 17 00:00:00 2001 From: nick black Date: Wed, 3 Jun 2020 12:17:51 -0400 Subject: [PATCH] ncplane_yx: results are relative to bound plane --- src/lib/debug.c | 8 +++--- src/lib/internal.h | 5 ++-- src/lib/notcurses.c | 69 ++++++++++++++++++++++++++++++--------------- tests/ncplane.cpp | 33 ++++++++++++---------- 4 files changed, 71 insertions(+), 44 deletions(-) diff --git a/src/lib/debug.c b/src/lib/debug.c index 5bf70a7ee..28204c734 100644 --- a/src/lib/debug.c +++ b/src/lib/debug.c @@ -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)){ diff --git a/src/lib/internal.h b/src/lib/internal.h index 8bcf59364..0b703d472 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -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 diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index d5e5a77a2..6eefa15ef 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -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; } diff --git a/tests/ncplane.cpp b/tests/ncplane.cpp index 36a07e4a3..dee8004c8 100644 --- a/tests/ncplane.cpp +++ b/tests/ncplane.cpp @@ -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); }