From dce97e6b3ebe30480cd2ae6247826cd1a5304ded Mon Sep 17 00:00:00 2001 From: Emile Clark-Boman Date: Tue, 16 Sep 2025 21:30:14 +1000 Subject: [PATCH] bug fixes + general X axis splitting! --- cli/main.c | 12 +++++++--- cursetree/cursetree.c | 51 +++++++++++++++++++++++++++++-------------- cursetree/node.c | 11 +++++----- cursetree/node.h | 1 + cursetree/surface.c | 14 ++++++++---- cursetree/surface.h | 13 ++++++----- 6 files changed, 69 insertions(+), 33 deletions(-) diff --git a/cli/main.c b/cli/main.c index cd79176..a140f0b 100644 --- a/cli/main.c +++ b/cli/main.c @@ -12,17 +12,22 @@ int main(int argc, char **argv) { init_pair(1, COLOR_BLACK, COLOR_CYAN); init_pair(2, COLOR_BLACK, COLOR_RED); + init_pair(3, COLOR_BLACK, COLOR_GREEN); + // wbkgd(tree->root->surface->win, COLOR_PAIR(1)); // wrefresh(tree->root->surface->win); struct ct_node *const child1 = new_node(bounds_none(), tree->root); struct ct_node *const child2 = new_node(bounds_none(), tree->root); + struct ct_node *const child3 = new_node(bounds_none(), tree->root); append_child_node(tree->root, child1); append_child_node(tree->root, child2); + append_child_node(tree->root, child3); wbkgd(child1->surface->win, COLOR_PAIR(1)); wbkgd(child2->surface->win, COLOR_PAIR(2)); + wbkgd(child3->surface->win, COLOR_PAIR(3)); // wrefresh(child1->surface->win); @@ -32,12 +37,13 @@ int main(int argc, char **argv) { mvwprintw(child2->surface->win, 1, 0, "2@(%d,%d) %dx%d\n", child2->surface->dims->x, child2->surface->dims->y, child2->surface->dims->width, child2->surface->dims->height); - wrefresh(child2->surface->win); - + mvwprintw(child2->surface->win, 1, 0, "2@(%d,%d) %dx%d\n", + child3->surface->dims->x, child3->surface->dims->y, + child3->surface->dims->width, child3->surface->dims->height); while (1) { ct_update(tree); - napms(100); + // napms(100); } destroy_tree(tree); diff --git a/cursetree/cursetree.c b/cursetree/cursetree.c index 5c79652..47cef7a 100644 --- a/cursetree/cursetree.c +++ b/cursetree/cursetree.c @@ -1,9 +1,9 @@ #include +#include "_ncurses.h" #include "ncrswrap.h" #include "node.h" #include "tree.h" -#include "_ncurses.h" int ct_init(struct ct_tree **const tree) { /* Initialise NCurses Library & Root Node */ @@ -13,44 +13,63 @@ int ct_init(struct ct_tree **const tree) { return EXIT_SUCCESS; } +void ct_redraw(void) { + /* TODO: hide doupdate() behind some other method */ + /* flush ncurses virtual screen -> physical screen */ + doupdate(); +} + /* Recursively search the tree for update requests. + * Returns: + * 0 - success (no action required) + * 1 - success (request: redraw the screen) */ -static void __update_rec(struct ct_node *const node) { +static int __update_rec(struct ct_node *const node) { + int result = 0; + struct ct_dims *dims; + if (node->flags & NFLAG_RESIZE) { /* TODO: the child has requested a resizing, but resize_node() * TODO: wastes CPU time resizing itself! */ - resize_node(node, dup_dims(node->surface->dims)); + dims = IS_ROOT_NODE(node) ? termdims() : dup_dims(node->surface->dims); + resize_node(node, dims); + result = 1; } - for (int i=0; i < node->cindex; i++) { - __update_rec(node->child[i]); + if (node->surface->updatereq) { + sfflush(node->surface); } + + for (int i = 0; i < node->cindex; i++) { + result |= __update_rec(node->child[i]); + } + return result; } void ct_update(struct ct_tree *const tree) { const int key = wgetch(curscr); /* ncurses binds a SIGWINCH handler if SIGWINCH has SIG_DFL disposition - * when initscr(3x) is called. This handler emits KEY_RESIZE (decimal 410) to stdin. - * REF: manpages -> resizeterm(3x) initscr(3x) wgetch(3x) + * when initscr(3x) is called. This handler emits KEY_RESIZE (decimal 410) to + * stdin. REF: manpages -> resizeterm(3x) initscr(3x) wgetch(3x) */ switch (key) { case -1: - wclear(tree->root->surface->win); - mvwprintw(tree->root->surface->win, 0, 0, " \r-1\n"); - wrefresh(tree->root->surface->win); + // wclear(tree->root->surface->win); + // mvwprintw(tree->root->surface->win, 0, 0, " \r-1\n"); + // wrefresh(tree->root->surface->win); return; case KEY_RESIZE: - resize_tree(tree, termdims()); - // flush ncurses virtual screen -> physical screen - doupdate(); + tree->root->flags |= NFLAG_RESIZE; break; default: // wclear(tree->root->surface->win); - mvwprintw(tree->root->surface->win, 0, 0, " \r%d\n", key); - wrefresh(tree->root->surface->win); + // mvwprintw(tree->root->surface->win, 0, 0, " \r%d\n", key); + // wrefresh(tree->root->surface->win); break; } - __update_rec(tree->root); + if (__update_rec(tree->root)) { + ct_redraw(); + } } diff --git a/cursetree/node.c b/cursetree/node.c index 3f1abaf..9fbcfeb 100644 --- a/cursetree/node.c +++ b/cursetree/node.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -119,7 +120,7 @@ int resize_node(struct ct_node *const node, struct ct_dims *dims) { assert(node->axis == AXIS_Y); axm_free = dims->height; axm_size = dims->height; - + /* DEBUG: WARNING :DEBUG */ // dims_axm_pos_offset = offsetof(struct ct_dims, y); // dims_axm_size_offset = offsetof(struct ct_dims, height); @@ -138,7 +139,7 @@ int resize_node(struct ct_node *const node, struct ct_dims *dims) { // *(int *)(node->child[i]->surface->bounds + bounds_axm_max_offset); cspdims[i].min = node->child[i]->surface->bounds->wmin; cspdims[i].max = node->child[i]->surface->bounds->wmax; - + if (node->child[i]->surface->bounds->type == BOUND_RELATIVE) { cspdims[i].min *= axm_size; cspdims[i].max *= axm_size; @@ -236,9 +237,9 @@ int insert_child_node(struct ct_node *const parent, struct ct_node *const child, return 2; else if (parent->cindex == parent->csize) { // grow child array size and clamp maximum - parent->csize *= NODE_CHILDREN_GROWTH; - if (parent->csize > CINDEX_MAX) - parent->csize = CINDEX_MAX; + cindex new_csize = parent->csize * NODE_CHILDREN_GROWTH; + // check overflow + parent->csize = (parent->csize <= new_csize) ? new_csize : CINDEX_MAX; parent->child = reallocarray(parent->child, parent->csize, sizeof(struct ct_node *)); diff --git a/cursetree/node.h b/cursetree/node.h index b62438b..316b8e3 100644 --- a/cursetree/node.h +++ b/cursetree/node.h @@ -40,6 +40,7 @@ struct ct_node { }; /* === External Interface === */ +#define IS_ROOT_NODE(node) (node->parent == NULL) #define IS_PARENT_NODE(node) (node->cindex != 0) struct ct_node *__node(struct ct_dims *const dims, diff --git a/cursetree/surface.c b/cursetree/surface.c index c003faa..a028bc8 100644 --- a/cursetree/surface.c +++ b/cursetree/surface.c @@ -3,6 +3,7 @@ #include "ncrswrap.h" #include "surface.h" #include "_ncurses.h" +#include "ncurses.h" static inline struct ct_surface *__surface(struct ct_dims *const dims, struct ct_bounds *const bounds, @@ -46,10 +47,6 @@ void rebind_surface(struct ct_surface *const surface, surface->bounds = bounds; } -void sfclear(struct ct_surface *const surface) { - wclear(surface->win); -} - int sfwidth(const struct ct_surface *const surface) { return getmaxx(surface->win); } @@ -73,3 +70,12 @@ struct ct_dims *sfdims(const struct ct_surface *const surface) { return new_dims(x, y, width, height); } +void sfclear(struct ct_surface *const surface) { + wclear(surface->win); + surface->updatereq = true; +} + +void sfflush(struct ct_surface *const surface) { + wnoutrefresh(surface->win); + surface->updatereq = false; +} diff --git a/cursetree/surface.h b/cursetree/surface.h index 727c489..c84f7ee 100644 --- a/cursetree/surface.h +++ b/cursetree/surface.h @@ -26,10 +26,13 @@ void rebind_surface(struct ct_surface *const surface, #define sfpos(surface, x, y) (x = sfposx(surface), y = sfposy(surface)) #define sfsize(surface, width, height) (width = sfwidth(surface), height = sfheight(surface)) -void sclear(struct ct_surface *const surface); -int swidth(const struct ct_surface *const surface); -int sheight(const struct ct_surface *const surface); -int sposx(const struct ct_surface *const surface); -int sposy(const struct ct_surface *const surface); +int sfwidth(const struct ct_surface *const surface); +int sfheight(const struct ct_surface *const surface); +int sfposx(const struct ct_surface *const surface); +int sfposy(const struct ct_surface *const surface); +struct ct_dims *sfdims(const struct ct_surface *const surface); + +void sfclear(struct ct_surface *const surface); +void sfflush(struct ct_surface *const surface); #endif /* CURSETREE_SURFACE_H */