mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-02 09:40:15 +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;
|
||||
}
|
||||
|
||||
// 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
|
||||
// bottom. FIXME these both become static inline wrappers around
|
||||
// ncplane_move_below() and ncplane_move_above() in ABI3.
|
||||
@ -1638,38 +1654,27 @@ API void ncplane_move_bottom(struct ncplane* n)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// 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,
|
||||
// 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.
|
||||
API void ncplane_move_family_top(struct ncplane* n)
|
||||
__attribute__ ((nonnull (1)));
|
||||
API void ncplane_move_family_bottom(struct ncplane* n)
|
||||
API void ncplane_move_family_above(struct ncplane* n, struct ncplane* targ)
|
||||
__attribute__ ((nonnull (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, 2)));
|
||||
API void ncplane_move_family_below(struct ncplane* n, struct ncplane* targ)
|
||||
__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, 2)));
|
||||
__attribute__ ((nonnull (1)))
|
||||
static inline void
|
||||
ncplane_move_family_top(struct ncplane* n){
|
||||
ncplane_move_family_below(n, NULL);
|
||||
}
|
||||
|
||||
API void ncplane_move_family_above(struct ncplane* RESTRICT n,
|
||||
struct ncplane* RESTRICT above)
|
||||
__attribute__ ((nonnull (1, 2)));
|
||||
|
||||
API void ncplane_move_family_below(struct ncplane* RESTRICT n,
|
||||
struct ncplane* RESTRICT below)
|
||||
__attribute__ ((nonnull (1, 2)));
|
||||
__attribute__ ((nonnull (1)))
|
||||
static inline void
|
||||
ncplane_move_family_bottom(struct ncplane* n){
|
||||
ncplane_move_family_above(n, NULL);
|
||||
}
|
||||
|
||||
// Return the plane below this one, or NULL if this is at the bottom.
|
||||
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){
|
||||
return -1;
|
||||
}
|
||||
if(above == NULL){
|
||||
ncplane_move_bottom(n);
|
||||
return 0;
|
||||
}
|
||||
if(ncplane_pile(n) != ncplane_pile(above)){ // can't move among piles
|
||||
return -1;
|
||||
}
|
||||
@ -1389,6 +1393,10 @@ int ncplane_move_below(ncplane* restrict n, ncplane* restrict below){
|
||||
if(n == below){
|
||||
return -1;
|
||||
}
|
||||
if(below == NULL){
|
||||
ncplane_move_top(n);
|
||||
return 0;
|
||||
}
|
||||
if(ncplane_pile(n) != ncplane_pile(below)){ // can't move among piles
|
||||
return -1;
|
||||
}
|
||||
@ -1444,39 +1452,10 @@ void ncplane_move_bottom(ncplane* n){
|
||||
}
|
||||
}
|
||||
|
||||
void ncplane_move_family_top(ncplane* n){
|
||||
ncplane* below = ncplane_below(n);
|
||||
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;
|
||||
// if above is NULL, we're moving to the bottom
|
||||
void ncplane_move_family_above(ncplane* restrict n, ncplane* restrict bpoint){
|
||||
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_move_family_bottom(ncplane* n){
|
||||
ncplane* above = ncplane_above(n);
|
||||
ncplane_move_bottom(n);
|
||||
ncplane_move_above(n, bpoint);
|
||||
// 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.
|
||||
// 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){
|
||||
ncplane_move_above(n, above);
|
||||
// FIXME walk above and below, moving descendants
|
||||
}
|
||||
|
||||
void ncplane_move_family_below(ncplane* restrict n, ncplane* restrict below){
|
||||
ncplane_move_below(n, below);
|
||||
// FIXME walk above and below, moving descendants
|
||||
// if below is NULL, we're moving to the top
|
||||
void ncplane_move_family_below(ncplane* restrict n, ncplane* restrict bpoint){
|
||||
ncplane* below = ncplane_below(n);
|
||||
ncplane_move_below(n, bpoint);
|
||||
// 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.
|
||||
// we're inserting below n...
|
||||
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){
|
||||
|
@ -168,5 +168,72 @@ TEST_CASE("ZAxis") {
|
||||
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_));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user