mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-02 09:40:15 +00:00
ncplane_reparent: extract from z-axis #1078
This commit is contained in:
parent
43ddfd11c6
commit
a6101d4fa2
@ -10,8 +10,8 @@ ncpile_debug(const ncpile* p, FILE* debugfp){
|
||||
fprintf(debugfp, "%04d off y: %3d x: %3d geom y: %3d x: %3d curs y: %3d x: %3d %p %.8s\n",
|
||||
planeidx, n->absy, n->absx, n->leny, n->lenx, n->y, n->x, n, n->name);
|
||||
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);
|
||||
fprintf(debugfp, " bound %p ← %p → %p binds %p\n",
|
||||
n->boundto, n->bprev, n->bnext, n->blist);
|
||||
}
|
||||
if(n->bprev && (*n->bprev != n)){
|
||||
fprintf(stderr, " WARNING: expected *->bprev %p, got %p\n", n, *n->bprev);
|
||||
@ -37,7 +37,11 @@ void notcurses_debug(notcurses* nc, FILE* debugfp){
|
||||
const ncpile* p0 = p;
|
||||
do{
|
||||
ncpile_debug(p0, debugfp);
|
||||
const ncpile* prev = p0;
|
||||
p0 = p0->next;
|
||||
if(p0->prev != prev){
|
||||
fprintf(stderr, "WARNING: expected ->prev %p, got %p\n", prev, p0->prev);
|
||||
}
|
||||
}while(p != p0);
|
||||
fprintf(debugfp, " ******************************************************************************\n");
|
||||
}
|
||||
|
@ -1148,6 +1148,7 @@ err:
|
||||
// updates *pile to point at (*pile)->next, frees all but standard pile/plane
|
||||
static void
|
||||
ncpile_drop(notcurses* nc, ncpile** pile){
|
||||
ncpile* next = (*pile)->next;
|
||||
ncplane* p = (*pile)->top;
|
||||
while(p){
|
||||
ncplane* tmp = p->below;
|
||||
@ -1156,11 +1157,7 @@ ncpile_drop(notcurses* nc, ncpile** pile){
|
||||
}
|
||||
p = tmp;
|
||||
}
|
||||
ncpile* tmp = (*pile)->next;
|
||||
if(*pile != ncplane_pile(nc->stdplane)){
|
||||
ncpile_destroy(*pile);
|
||||
}
|
||||
*pile = tmp;
|
||||
*pile = next;
|
||||
}
|
||||
|
||||
// drop all piles and all planes, save the standard plane and its pile
|
||||
@ -1980,10 +1977,16 @@ int ncplane_move_yx(ncplane* n, int y, int x){
|
||||
}
|
||||
|
||||
int ncplane_y(const ncplane* n){
|
||||
if(n->boundto == n){
|
||||
return n->absy - ncplane_notcurses_const(n)->margin_t;
|
||||
}
|
||||
return n->absy - n->boundto->absy;
|
||||
}
|
||||
|
||||
int ncplane_x(const ncplane* n){
|
||||
if(n->boundto == n){
|
||||
return n->absx - ncplane_notcurses_const(n)->margin_t;
|
||||
}
|
||||
return n->absx - n->boundto->absx;
|
||||
}
|
||||
|
||||
@ -2174,9 +2177,8 @@ int ncplane_resize_realign(ncplane* n){
|
||||
}
|
||||
|
||||
// The standard plane cannot be reparented; we return NULL in that case.
|
||||
// If provided a NULL |newparent|, we are moving |n| to its own stack. If |n|
|
||||
// is already root of its own stack in this case, we return NULL. If |n| is
|
||||
// already bound to |newparent|, this is a no-op, and we return |n|.
|
||||
// If provided |newparent|==|n|, we are moving |n| to its own stack. If |n|
|
||||
// is already bound to |newparent|, this is a no-op, and we return |n|.
|
||||
ncplane* ncplane_reparent(ncplane* n, ncplane* newparent){
|
||||
if(n == ncplane_notcurses(n)->stdplane){
|
||||
return NULL; // can't reparent standard plane
|
||||
@ -2208,30 +2210,59 @@ ncplane* ncplane_reparent_family(ncplane* n, ncplane* newparent){
|
||||
if(n->boundto == newparent){ // no-op
|
||||
return n;
|
||||
}
|
||||
// are we the sole member of our current pile? if so, destroy it.
|
||||
if(n->boundto == n && n->blist == NULL && n->bprev == NULL){
|
||||
pthread_mutex_lock(&ncplane_notcurses(n)->pilelock);
|
||||
ncpile_destroy(ncplane_pile(n));
|
||||
pthread_mutex_unlock(&ncplane_notcurses(n)->pilelock);
|
||||
// if we are not a root plane, adjust our origin
|
||||
if(n->boundto != n){
|
||||
n->absx -= n->boundto->absx;
|
||||
n->absy -= n->boundto->absy;
|
||||
}
|
||||
if(n->bprev){ // extract from sibling list
|
||||
if( (*n->bprev = n->bnext) ){
|
||||
n->bnext->bprev = n->bprev;
|
||||
}
|
||||
}
|
||||
// if leaving a pile, extract n from the old zaxis
|
||||
if(n == newparent || ncplane_pile(n) != ncplane_pile(newparent)){
|
||||
// FIXME need remove full family from z-axis, not just n!
|
||||
if(ncplane_pile(n)->top == n){
|
||||
ncplane_pile(n)->top = n->below;
|
||||
}else{
|
||||
n->above->below = n->below;
|
||||
}
|
||||
if(ncplane_pile(n)->bottom == n){
|
||||
ncplane_pile(n)->bottom = n->above;
|
||||
}else{
|
||||
n->below->above = n->above;
|
||||
}
|
||||
}
|
||||
n->boundto = newparent;
|
||||
if(n == n->boundto){ // we're a new root plane
|
||||
n->bnext = NULL;
|
||||
n->bprev = NULL;
|
||||
pthread_mutex_lock(&ncplane_notcurses(n)->pilelock);
|
||||
if(ncplane_pile(n)->top == NULL){ // did we just empty our pile?
|
||||
ncpile_destroy(ncplane_pile(n));
|
||||
}
|
||||
make_ncpile(ncplane_notcurses(n), n);
|
||||
pthread_mutex_unlock(&ncplane_notcurses(n)->pilelock);
|
||||
}else{ // establish ourselves as a sibling of new parent's children
|
||||
n->absx += n->boundto->absx;
|
||||
n->absy += n->boundto->absy;
|
||||
if( (n->bnext = newparent->blist) ){
|
||||
n->bnext->bprev = &n->bnext;
|
||||
}
|
||||
n->bprev = &newparent->blist;
|
||||
newparent->blist = n;
|
||||
// place it immediately above the new binding plane if crossing piles
|
||||
if(n->pile != ncplane_pile(n->boundto)){
|
||||
n->pile = ncplane_pile(n->boundto);
|
||||
if((n->above = n->boundto->above) == NULL){
|
||||
n->pile->top = n;
|
||||
}else{
|
||||
n->boundto->above->below = n;
|
||||
}
|
||||
n->below = n->boundto;
|
||||
n->boundto->above = n;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
@ -551,6 +551,7 @@ TEST_CASE("NCPlane") {
|
||||
CHECK(0 == testcell.gcluster);
|
||||
CHECK(0 == testcell.stylemask);
|
||||
CHECK(0 == testcell.channels);
|
||||
cell_release(n_, &testcell);
|
||||
int dimy, dimx;
|
||||
ncplane_dim_yx(n_, &dimy, &dimx);
|
||||
REQUIRE(0 == ncplane_cursor_move_yx(n_, 1, dimx - strlen(STR2)));
|
||||
@ -588,6 +589,7 @@ TEST_CASE("NCPlane") {
|
||||
CHECK(0 == testcell.gcluster);
|
||||
CHECK(0 == testcell.stylemask);
|
||||
CHECK(0 == testcell.channels);
|
||||
cell_release(n_, &testcell);
|
||||
int dimy, dimx;
|
||||
ncplane_dim_yx(n_, &dimy, &dimx);
|
||||
REQUIRE(0 == ncplane_cursor_move_yx(n_, 1, dimx - mbstowcs(nullptr, STR2, 0)));
|
||||
@ -897,11 +899,14 @@ TEST_CASE("NCPlane") {
|
||||
.x = 1,
|
||||
.rows = 2,
|
||||
.cols = 2,
|
||||
nullptr, nullptr, nullptr, 0,
|
||||
nullptr, "ndom", nullptr, 0,
|
||||
};
|
||||
struct ncplane* ndom = ncplane_create(n_, &nopts);
|
||||
CHECK(ncplane_pile(ndom) == ncplane_pile(n_));
|
||||
REQUIRE(ndom);
|
||||
nopts.name = "sub";
|
||||
struct ncplane* nsub = ncplane_create(ndom, &nopts);
|
||||
CHECK(ncplane_pile(nsub) == ncplane_pile(ndom));
|
||||
REQUIRE(nsub);
|
||||
int absy, absx;
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
@ -909,13 +914,14 @@ TEST_CASE("NCPlane") {
|
||||
CHECK(1 == absy); // actually at 2, 2
|
||||
CHECK(1 == absx);
|
||||
ncplane_reparent(nsub, nsub);
|
||||
CHECK(ncplane_pile(nsub) != ncplane_pile(ndom));
|
||||
ncplane_yx(nsub, &absy, &absx);
|
||||
CHECK(2 == absy); // now we recognize 2, 2
|
||||
CHECK(2 == absx);
|
||||
CHECK(1 == absy); // now truly at 1, 1
|
||||
CHECK(1 == absx);
|
||||
CHECK(0 == ncplane_move_yx(ndom, 0, 0));
|
||||
ncplane_yx(nsub, &absy, &absx);
|
||||
CHECK(2 == absy); // still at 2, 2
|
||||
CHECK(2 == absx);
|
||||
CHECK(1 == absy); // still at 1, 1
|
||||
CHECK(1 == absx);
|
||||
}
|
||||
|
||||
SUBCASE("NoReparentStdPlane") {
|
||||
|
Loading…
Reference in New Issue
Block a user