mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
ncplane_move_family_{below, above}() with unit tests #2232
This commit is contained in:
parent
2b9765e945
commit
e613b81b82
@ -1629,6 +1629,22 @@ ncplane_descendant_p(const struct ncplane* n, const struct ncplane* ancestor){
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Splice ncplane 'n' out of the z-buffer, and reinsert it above 'above'.
|
||||||
|
// Returns non-zero if 'n' is already in the desired location. 'n' and
|
||||||
|
// 'above' must not be the same plane. If 'above' is NULL, 'n' is moved
|
||||||
|
// to the bottom of its pile.
|
||||||
|
API int ncplane_move_above(struct ncplane* RESTRICT n,
|
||||||
|
struct ncplane* RESTRICT above)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
|
// Splice ncplane 'n' out of the z-buffer, and reinsert it below 'below'.
|
||||||
|
// Returns non-zero if 'n' is already in the desired location. 'n' and
|
||||||
|
// 'below' must not be the same plane. If 'below' is NULL, 'n' is moved to
|
||||||
|
// the top of its pile.
|
||||||
|
API int ncplane_move_below(struct ncplane* RESTRICT n,
|
||||||
|
struct ncplane* RESTRICT below)
|
||||||
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Splice ncplane 'n' out of the z-buffer, and reinsert it at the top or
|
// Splice ncplane 'n' out of the z-buffer, and reinsert it at the top or
|
||||||
// bottom. FIXME these both become static inline wrappers around
|
// bottom. FIXME these both become static inline wrappers around
|
||||||
// ncplane_move_below() and ncplane_move_above() in ABI3.
|
// ncplane_move_below() and ncplane_move_above() in ABI3.
|
||||||
@ -1638,38 +1654,27 @@ API void ncplane_move_bottom(struct ncplane* n)
|
|||||||
__attribute__ ((nonnull (1)));
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Splice ncplane 'n' and its bound planes out of the z-buffer, and reinsert
|
// Splice ncplane 'n' and its bound planes out of the z-buffer, and reinsert
|
||||||
// them at the top or bottom. Relative order will be maintained between the
|
// them above or below 'targ'. Relative order will be maintained between the
|
||||||
// reinserted planes. For a plane E bound to C, with z-ordering A B C D E,
|
// reinserted planes. For a plane E bound to C, with z-ordering A B C D E,
|
||||||
// moving the C family to the top results in C E A B D, while moving it to
|
// moving the C family to the top results in C E A B D, while moving it to
|
||||||
// the bottom results in A B D C E.
|
// the bottom results in A B D C E.
|
||||||
API void ncplane_move_family_top(struct ncplane* n)
|
API void ncplane_move_family_above(struct ncplane* n, struct ncplane* targ)
|
||||||
__attribute__ ((nonnull (1)));
|
|
||||||
API void ncplane_move_family_bottom(struct ncplane* n)
|
|
||||||
__attribute__ ((nonnull (1)));
|
__attribute__ ((nonnull (1)));
|
||||||
|
|
||||||
// Splice ncplane 'n' out of the z-buffer, and reinsert it above 'above'.
|
API void ncplane_move_family_below(struct ncplane* n, struct ncplane* targ)
|
||||||
// Returns non-zero if 'n' is already in the desired location. 'n' and
|
__attribute__ ((nonnull (1)));
|
||||||
// 'above' must not be the same plane. If 'above' is NULL, 'n' is moved
|
|
||||||
// to the bottom of its pile.
|
|
||||||
API int ncplane_move_above(struct ncplane* RESTRICT n,
|
|
||||||
struct ncplane* RESTRICT above)
|
|
||||||
__attribute__ ((nonnull (1, 2)));
|
|
||||||
|
|
||||||
// Splice ncplane 'n' out of the z-buffer, and reinsert it below 'below'.
|
__attribute__ ((nonnull (1)))
|
||||||
// Returns non-zero if 'n' is already in the desired location. 'n' and
|
static inline void
|
||||||
// 'below' must not be the same plane. If 'below' is NULL, 'n' is moved to
|
ncplane_move_family_top(struct ncplane* n){
|
||||||
// the top of its pile.
|
ncplane_move_family_below(n, NULL);
|
||||||
API int ncplane_move_below(struct ncplane* RESTRICT n,
|
}
|
||||||
struct ncplane* RESTRICT below)
|
|
||||||
__attribute__ ((nonnull (1, 2)));
|
|
||||||
|
|
||||||
API void ncplane_move_family_above(struct ncplane* RESTRICT n,
|
__attribute__ ((nonnull (1)))
|
||||||
struct ncplane* RESTRICT above)
|
static inline void
|
||||||
__attribute__ ((nonnull (1, 2)));
|
ncplane_move_family_bottom(struct ncplane* n){
|
||||||
|
ncplane_move_family_above(n, NULL);
|
||||||
API void ncplane_move_family_below(struct ncplane* RESTRICT n,
|
}
|
||||||
struct ncplane* RESTRICT below)
|
|
||||||
__attribute__ ((nonnull (1, 2)));
|
|
||||||
|
|
||||||
// Return the plane below this one, or NULL if this is at the bottom.
|
// Return the plane below this one, or NULL if this is at the bottom.
|
||||||
API struct ncplane* ncplane_below(struct ncplane* n)
|
API struct ncplane* ncplane_below(struct ncplane* n)
|
||||||
|
@ -1358,6 +1358,10 @@ int ncplane_move_above(ncplane* restrict n, ncplane* restrict above){
|
|||||||
if(n == above){
|
if(n == above){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if(above == NULL){
|
||||||
|
ncplane_move_bottom(n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if(ncplane_pile(n) != ncplane_pile(above)){ // can't move among piles
|
if(ncplane_pile(n) != ncplane_pile(above)){ // can't move among piles
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1389,6 +1393,10 @@ int ncplane_move_below(ncplane* restrict n, ncplane* restrict below){
|
|||||||
if(n == below){
|
if(n == below){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
if(below == NULL){
|
||||||
|
ncplane_move_top(n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if(ncplane_pile(n) != ncplane_pile(below)){ // can't move among piles
|
if(ncplane_pile(n) != ncplane_pile(below)){ // can't move among piles
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1444,39 +1452,10 @@ void ncplane_move_bottom(ncplane* n){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ncplane_move_family_top(ncplane* n){
|
// if above is NULL, we're moving to the bottom
|
||||||
ncplane* below = ncplane_below(n);
|
void ncplane_move_family_above(ncplane* restrict n, ncplane* restrict bpoint){
|
||||||
ncplane_move_top(n);
|
|
||||||
// traverse the planes below n, until we hit NULL. do the planes below n
|
|
||||||
// first, so that we know the bottommost element of our new ensplicification.
|
|
||||||
// at this point, n is the topmost plane, and we're inserting below it.
|
|
||||||
ncplane* targ = n;
|
|
||||||
while(below){
|
|
||||||
ncplane* tmp = ncplane_below(below);
|
|
||||||
if(ncplane_descendant_p(below, n)){
|
|
||||||
ncplane_move_below(below, targ);
|
|
||||||
targ = below;
|
|
||||||
}
|
|
||||||
below = tmp;
|
|
||||||
}
|
|
||||||
// n remains the topmost plane, and we're inserting above it. we have to be
|
|
||||||
// careful this time not to cross into any we moved below n.
|
|
||||||
const ncplane* bottommost = targ;
|
|
||||||
targ = n;
|
|
||||||
ncplane* above = ncplane_above(n);
|
ncplane* above = ncplane_above(n);
|
||||||
while(above && above != bottommost){
|
ncplane_move_above(n, bpoint);
|
||||||
ncplane* tmp = ncplane_above(above);
|
|
||||||
if(ncplane_descendant_p(above, n)){
|
|
||||||
ncplane_move_above(above, targ);
|
|
||||||
targ = above;
|
|
||||||
}
|
|
||||||
above = tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ncplane_move_family_bottom(ncplane* n){
|
|
||||||
ncplane* above = ncplane_above(n);
|
|
||||||
ncplane_move_bottom(n);
|
|
||||||
// traverse the planes above n, until we hit NULL. do the planes above n
|
// traverse the planes above n, until we hit NULL. do the planes above n
|
||||||
// first, so that we know the topmost element of our new ensplicification.
|
// first, so that we know the topmost element of our new ensplicification.
|
||||||
// at this point, n is the bottommost plane, and we're inserting above it.
|
// at this point, n is the bottommost plane, and we're inserting above it.
|
||||||
@ -1504,14 +1483,35 @@ void ncplane_move_family_bottom(ncplane* n){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ncplane_move_family_above(ncplane* restrict n, ncplane* restrict above){
|
// if below is NULL, we're moving to the top
|
||||||
ncplane_move_above(n, above);
|
void ncplane_move_family_below(ncplane* restrict n, ncplane* restrict bpoint){
|
||||||
// FIXME walk above and below, moving descendants
|
ncplane* below = ncplane_below(n);
|
||||||
}
|
ncplane_move_below(n, bpoint);
|
||||||
|
// traverse the planes below n, until we hit NULL. do the planes below n
|
||||||
void ncplane_move_family_below(ncplane* restrict n, ncplane* restrict below){
|
// first, so that we know the bottommost element of our new ensplicification.
|
||||||
ncplane_move_below(n, below);
|
// we're inserting below n...
|
||||||
// FIXME walk above and below, moving descendants
|
ncplane* targ = n;
|
||||||
|
while(below){
|
||||||
|
ncplane* tmp = ncplane_below(below);
|
||||||
|
if(ncplane_descendant_p(below, n)){
|
||||||
|
ncplane_move_below(below, targ);
|
||||||
|
targ = below;
|
||||||
|
}
|
||||||
|
below = tmp;
|
||||||
|
}
|
||||||
|
// n remains the topmost plane, and we're inserting above it. we have to be
|
||||||
|
// careful this time not to cross into any we moved below n.
|
||||||
|
const ncplane* bottommost = targ;
|
||||||
|
targ = n;
|
||||||
|
ncplane* above = ncplane_above(n);
|
||||||
|
while(above && above != bottommost){
|
||||||
|
ncplane* tmp = ncplane_above(above);
|
||||||
|
if(ncplane_descendant_p(above, n)){
|
||||||
|
ncplane_move_above(above, targ);
|
||||||
|
targ = above;
|
||||||
|
}
|
||||||
|
above = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ncplane_cursor_yx(const ncplane* n, int* y, int* x){
|
void ncplane_cursor_yx(const ncplane* n, int* y, int* x){
|
||||||
|
@ -168,5 +168,72 @@ TEST_CASE("ZAxis") {
|
|||||||
CHECK(0 == notcurses_render(nc_));
|
CHECK(0 == notcurses_render(nc_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SUBCASE("FamilyTop") {
|
||||||
|
struct ncplane_options nopts{};
|
||||||
|
nopts.rows = nopts.cols = 1;
|
||||||
|
auto a = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != a);
|
||||||
|
auto b = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != b);
|
||||||
|
auto c = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != c);
|
||||||
|
auto d = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != d);
|
||||||
|
auto e = ncplane_create(c, &nopts);
|
||||||
|
REQUIRE(nullptr != e);
|
||||||
|
ncplane_move_below(b, a);
|
||||||
|
ncplane_move_below(c, b);
|
||||||
|
ncplane_move_below(d, c);
|
||||||
|
ncplane_move_below(e, d);
|
||||||
|
CHECK(ncpile_top(n_) == a);
|
||||||
|
CHECK(ncplane_below(a) == b);
|
||||||
|
CHECK(ncplane_below(b) == c);
|
||||||
|
CHECK(ncplane_below(c) == d);
|
||||||
|
CHECK(ncplane_below(d) == e);
|
||||||
|
ncplane_move_family_top(c);
|
||||||
|
CHECK(ncpile_top(n_) == c);
|
||||||
|
CHECK(ncplane_below(c) == e);
|
||||||
|
CHECK(ncplane_below(e) == a);
|
||||||
|
CHECK(ncplane_below(a) == b);
|
||||||
|
CHECK(ncplane_below(b) == d);
|
||||||
|
CHECK(ncpile_bottom(n_) == n_);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBCASE("FamilyBottom") {
|
||||||
|
struct ncplane_options nopts{};
|
||||||
|
nopts.rows = nopts.cols = 1;
|
||||||
|
auto a = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != a);
|
||||||
|
auto b = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != b);
|
||||||
|
auto c = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != c);
|
||||||
|
auto d = ncplane_create(n_, &nopts);
|
||||||
|
REQUIRE(nullptr != d);
|
||||||
|
auto e = ncplane_create(c, &nopts);
|
||||||
|
REQUIRE(nullptr != e);
|
||||||
|
ncplane_move_below(b, a);
|
||||||
|
ncplane_move_below(c, b);
|
||||||
|
ncplane_move_below(d, c);
|
||||||
|
ncplane_move_below(e, d);
|
||||||
|
// ABCDEs, E is bound to C
|
||||||
|
CHECK(ncpile_top(n_) == a);
|
||||||
|
CHECK(ncplane_below(a) == b);
|
||||||
|
CHECK(ncplane_below(b) == c);
|
||||||
|
CHECK(ncplane_below(c) == d);
|
||||||
|
CHECK(ncplane_below(d) == e);
|
||||||
|
CHECK(ncplane_below(e) == n_);
|
||||||
|
CHECK(ncplane_bottom(n_) == n_);
|
||||||
|
ncplane_move_family_bottom(c);
|
||||||
|
// ABDsCE, E is bound to C (FIXME have ABDEsC)
|
||||||
|
CHECK(ncpile_top(n_) == a);
|
||||||
|
CHECK(ncplane_below(a) == b);
|
||||||
|
CHECK(ncplane_below(b) == d);
|
||||||
|
CHECK(ncplane_below(d) == e);
|
||||||
|
CHECK(ncplane_below(e) == n_);
|
||||||
|
CHECK(ncplane_below(n_) == c);
|
||||||
|
CHECK(ncpile_bottom(n_) == c);
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(0 == notcurses_stop(nc_));
|
CHECK(0 == notcurses_stop(nc_));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user