diff --git a/cli/main.c b/cli/main.c index 00662e5..cd79176 100644 --- a/cli/main.c +++ b/cli/main.c @@ -5,12 +5,6 @@ #include #include "cursetree.h" -#include "surface.h" - -#define nprintsfdims(nout, i, label, nin) \ - (mvwprintw((nout)->surface->win, (i), 0, "%s@(%d,%d) %dx%d", (label), \ - (nin)->surface->dims->x, (nin)->surface->dims->y, \ - (nin)->surface->dims->width, (nin)->surface->dims->height)) int main(int argc, char **argv) { struct ct_tree *tree; @@ -18,48 +12,32 @@ 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); - init_pair(4, COLOR_BLACK, COLOR_MAGENTA); - init_pair(5, COLOR_BLACK, COLOR_YELLOW); + + // 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); - struct ct_node *const child4 = new_node(bounds_none(), tree->root); - struct ct_node *const child5 = new_node(bounds_none(), tree->root); append_child_node(tree->root, child1); append_child_node(tree->root, child2); - append_child_node(tree->root, child3); - append_child_node(tree->root, child4); - append_child_node(tree->root, child5); wbkgd(child1->surface->win, COLOR_PAIR(1)); wbkgd(child2->surface->win, COLOR_PAIR(2)); - wbkgd(child3->surface->win, COLOR_PAIR(3)); - wbkgd(child4->surface->win, COLOR_PAIR(4)); - wbkgd(child5->surface->win, COLOR_PAIR(5)); - child3->axis = AXIS_Y; - struct ct_node *const child3_1 = new_node(bounds_none(), child3); - struct ct_node *const child3_2 = new_node(bounds_none(), child3); - append_child_node(child3, child3_1); - append_child_node(child3, child3_2); - wbkgd(child3_1->surface->win, COLOR_PAIR(1)); - wbkgd(child3_2->surface->win, COLOR_PAIR(5)); + // wrefresh(child1->surface->win); + + mvwprintw(child2->surface->win, 0, 0, "1@(%d,%d) %dx%d\n", + child1->surface->dims->x, child1->surface->dims->y, + child1->surface->dims->width, child1->surface->dims->height); + 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); + while (1) { - nprintsfdims(child2, 0, "R", tree->root); - nprintsfdims(child2, 1, "1", child1); - nprintsfdims(child2, 2, "2", child2); - nprintsfdims(child2, 3, "3", child3); - nprintsfdims(child2, 4, "4", child4); - nprintsfdims(child2, 5, "5", child5); - - nprintsfdims(child2, 7, "3_1", child3_1); - nprintsfdims(child2, 8, "3_2", child3_2); - - ct_update(tree); + napms(100); } destroy_tree(tree); diff --git a/cursetree/cursetree.c b/cursetree/cursetree.c index 47cef7a..5c79652 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,63 +13,44 @@ 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 int __update_rec(struct ct_node *const node) { - int result = 0; - struct ct_dims *dims; - +static void __update_rec(struct ct_node *const node) { if (node->flags & NFLAG_RESIZE) { /* TODO: the child has requested a resizing, but resize_node() * TODO: wastes CPU time resizing itself! */ - dims = IS_ROOT_NODE(node) ? termdims() : dup_dims(node->surface->dims); - resize_node(node, dims); - result = 1; + resize_node(node, dup_dims(node->surface->dims)); } - if (node->surface->updatereq) { - sfflush(node->surface); + for (int i=0; i < node->cindex; i++) { + __update_rec(node->child[i]); } - - 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: - tree->root->flags |= NFLAG_RESIZE; + resize_tree(tree, termdims()); + // flush ncurses virtual screen -> physical screen + doupdate(); 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; } - if (__update_rec(tree->root)) { - ct_redraw(); - } + __update_rec(tree->root); } diff --git a/cursetree/dims.c b/cursetree/dims.c index 771c68a..f0bb0ef 100644 --- a/cursetree/dims.c +++ b/cursetree/dims.c @@ -86,3 +86,37 @@ struct ct_bounds *dup_bounds(const struct ct_bounds *const bounds) { return dup; } + +/* Calculate the dimensions for nodes resulting from a bifurcation. + * Returns 0 on success, and 1 on failure if any width/height are 0 characters. + * WARNING: This function does not guarantee the x,y positions returned + * WARNING: are valid screen coordinates. + */ +// int bifurcate_dims(const struct ct_dims *const parent_dims, +// const enum ct_axis axis, const float ratio, +// struct ct_dims **const dims0, struct ct_dims **const +// dims1) { +// assert(0 < ratio && ratio < 1); +// struct ct_dims *_dims0, *_dims1; + +// _dims0 = dup_dims(parent_dims); +// _dims1 = dup_dims(parent_dims); + +// if (axis == AXIS_X) { +// _dims0->width *= ratio; +// _dims1->width -= _dims0->width; +// _dims1->x += _dims0->width; +// } else { +// _dims0->height *= ratio; +// _dims1->height -= _dims0->height; +// _dims1->y += _dims0->height; +// } + +// if (!_dims0->width || !_dims0->height || !_dims1->width || !_dims1->height) +// return 1; + +// // propagate bifurcated dimensions +// *dims0 = _dims0; +// *dims1 = _dims1; +// return 0; +// } diff --git a/cursetree/node.c b/cursetree/node.c index d3c4422..3f1abaf 100644 --- a/cursetree/node.c +++ b/cursetree/node.c @@ -1,6 +1,5 @@ #include #include -#include #include #include @@ -103,37 +102,43 @@ int resize_node(struct ct_node *const node, struct ct_dims *dims) { } int axm_size, axm_free; - size_t bounds_axm_min_offset, bounds_axm_max_offset; - size_t dims_axm_pos_offset, dims_axm_size_offset; + /* DEBUG: WARNING :DEBUG */ + // size_t bounds_axm_min_offset, bounds_axm_max_offset; + // size_t dims_axm_pos_offset, dims_axm_size_offset; if (node->axis == AXIS_X) { axm_free = dims->width; axm_size = dims->width; - dims_axm_pos_offset = offsetof(struct ct_dims, x); - dims_axm_size_offset = offsetof(struct ct_dims, width); - bounds_axm_min_offset = offsetof(struct ct_bounds, wmin); - bounds_axm_max_offset = offsetof(struct ct_bounds, wmax); + /* DEBUG: WARNING :DEBUG */ + // dims_axm_pos_offset = offsetof(struct ct_dims, x); + // dims_axm_size_offset = offsetof(struct ct_dims, width); + // bounds_axm_min_offset = offsetof(struct ct_bounds, wmin); + // bounds_axm_max_offset = offsetof(struct ct_bounds, wmax); } else { assert(node->axis == AXIS_Y); axm_free = dims->height; axm_size = dims->height; - - dims_axm_pos_offset = offsetof(struct ct_dims, y); - dims_axm_size_offset = offsetof(struct ct_dims, height); - bounds_axm_min_offset = offsetof(struct ct_bounds, hmin); - bounds_axm_max_offset = offsetof(struct ct_bounds, hmax); + + /* DEBUG: WARNING :DEBUG */ + // dims_axm_pos_offset = offsetof(struct ct_dims, y); + // dims_axm_size_offset = offsetof(struct ct_dims, height); + // bounds_axm_min_offset = offsetof(struct ct_bounds, hmin); + // bounds_axm_max_offset = offsetof(struct ct_bounds, hmax); } struct ct_spdims cspdims[node->cindex]; cindex parts_n = node->cindex; memset(cspdims, 0, sizeof(struct ct_spdims) * node->cindex); for (int i = 0; i < node->cindex; i++) { - cspdims[i].min = *(int *)((char *)node->child[i]->surface->bounds + - bounds_axm_min_offset); - cspdims[i].max = *(int *)((char *)node->child[i]->surface->bounds + - bounds_axm_max_offset); - + /* DEBUG: WARNING :DEBUG */ + // cspdims[i].min = + // *(int *)(node->child[i]->surface->bounds + bounds_axm_min_offset); + // cspdims[i].max = + // *(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; @@ -143,15 +148,14 @@ int resize_node(struct ct_node *const node, struct ct_dims *dims) { } int split, new_size; - while (axm_free && parts_n) { - split = (axm_free > parts_n) ? (axm_free / parts_n) : 1; + while (parts_n) { + split = axm_free / parts_n; for (int i = 0; i < node->cindex; i++) { if (cspdims[i].fixed) continue; new_size = clampi(cspdims[i].axm_size + split, cspdims[i].min, cspdims[i].max); - if (new_size == cspdims[i].axm_size) { cspdims[i].fixed = true; parts_n--; @@ -160,23 +164,22 @@ int resize_node(struct ct_node *const node, struct ct_dims *dims) { axm_free -= (new_size - cspdims[i].axm_size); cspdims[i].axm_size = new_size; - - if (axm_free == 0) - break; } } struct ct_dims *cdims = dup_dims(dims); /* NOTE: the statements below are done implicitly by dup_dims */ - // *(int*)(cdims + dims_axm_pos_offset) = *(int*)(dims + - // dims_axm_pos_offset); - // *(int*)(cdims + dims_axo_pos_offset) = *(int*)(dims + - // dims_axo_pos_offset); + // *(int*)(cdims + dims_axm_pos_offset) = *(int*)(dims + dims_axm_pos_offset); + // *(int*)(cdims + dims_axo_pos_offset) = *(int*)(dims + dims_axo_pos_offset); // *(int*)(cdims + dims_axo_size_offset) = axo_size; for (int i = 0; i < node->cindex; i++) { - *(int *)((char *)cdims + dims_axm_size_offset) = cspdims[i].axm_size; + /* DEBUG: WARNING :DEBUG */ + // *(int *)(cdims + dims_axm_size_offset) = cspdims[i].axm_size; + cdims->width = cspdims[i].axm_size; resize_node(node->child[i], dup_dims(cdims)); - *(int *)((char *)cdims + dims_axm_pos_offset) += cspdims[i].axm_size; + /* DEBUG: WARNING :DEBUG */ + // *(int *)(cdims + dims_axm_pos_offset) += cspdims[i].axm_size; + cdims->x += cspdims[i].axm_size; } free(cdims); @@ -233,9 +236,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 - cindex new_csize = parent->csize * NODE_CHILDREN_GROWTH; - // check overflow - parent->csize = (parent->csize <= new_csize) ? new_csize : CINDEX_MAX; + parent->csize *= NODE_CHILDREN_GROWTH; + if (parent->csize > CINDEX_MAX) + parent->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 316b8e3..b62438b 100644 --- a/cursetree/node.h +++ b/cursetree/node.h @@ -40,7 +40,6 @@ 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 a028bc8..c003faa 100644 --- a/cursetree/surface.c +++ b/cursetree/surface.c @@ -3,7 +3,6 @@ #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, @@ -47,6 +46,10 @@ 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); } @@ -70,12 +73,3 @@ 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 c84f7ee..727c489 100644 --- a/cursetree/surface.h +++ b/cursetree/surface.h @@ -26,13 +26,10 @@ 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)) -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); +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); #endif /* CURSETREE_SURFACE_H */