From 6b5bcff1a490b02a0bed8fe873cbea6aab3d954e Mon Sep 17 00:00:00 2001 From: Emile Clark-Boman Date: Mon, 15 Sep 2025 17:11:06 +1000 Subject: [PATCH] (UNDER CONSTRUCTION) implementing general child nodes bifurcation was limited and I needed something more powerful --- cursetree/node.c | 100 ++++++++++++++++++++++++++++++++++++++++++----- cursetree/node.h | 5 ++- cursetree/tree.c | 6 +-- 3 files changed, 97 insertions(+), 14 deletions(-) diff --git a/cursetree/node.c b/cursetree/node.c index 4251afd..bc198f9 100644 --- a/cursetree/node.c +++ b/cursetree/node.c @@ -1,5 +1,8 @@ #include +#include +#include #include +#include #include "dims.h" #include "node.h" @@ -71,25 +74,104 @@ void satisfy_node(struct ct_node *const node, struct ct_dims *const dims) { } } +struct ct_whdims { + // Main Axis & Orthogonal Axis Sizes + int axm_size, axo_size; + bool fixed; + int min, max; +}; + /* */ -void resize_node(struct ct_node *const node, struct ct_dims *const dims) { - int cwidth, cheight; // child dimensions - - if (IS_PARENT_NODE(node)) { - dims->width / node->cindex; - } +int resize_node(struct ct_node *const node, struct ct_dims *const dims) { + // if (IS_PARENT_NODE(node)) { + // dims->width / node->cindex; + // } resize_surface(node->surface, dims); - for (int j = 0; j < node->cindex; j++) { - /* TODO */ - resize_node(node->child[j], TODO); + if (node->cbounds.wmin_abs + node->cbounds.wmin_rel * dims->width > + dims->width || + node->cbounds.hmin_abs + node->cbounds.hmin_rel * dims->height > + dims->height) { + node->flags |= NFLAG_TOOSMALL; + return 1; } + + struct ct_whdims cwhdims[node->cindex]; + struct ct_whdims *const parts[node->cindex]; + int cunfixedn = node->cindex; // number of non-fixed children + memset(cwhdims, 0, sizeof(struct ct_whdims) * node->cindex); + + int axm_size, axm_free, axo_size; + size_t axm_min_offset, axm_max_offset; + if (node->axis == AXIS_X) { + axm_free = dims->width; + axm_size = dims->width; + axo_size = dims->height; + + axm_min_offset = offsetof(struct ct_bounds, wmin); + axm_max_offset = offsetof(struct ct_bounds, wmax); + } else { + assert(node->axis == AXIS_Y); + axm_free = dims->height; + axm_size = dims->height; + axo_size = dims->width; + + axm_min_offset = offsetof(struct ct_bounds, hmin); + axm_max_offset = offsetof(struct ct_bounds, hmax); + } + + int split = axm_free / node->cindex; + for (int j = 0; j < node->cindex; j++) { + cwhdims[j].min = *(int*)(node->child[j]->surface->bounds + axm_min_offset); + cwhdims[j].max = *(int*)(node->child[j]->surface->bounds + axm_max_offset); + if (node->child[j]->surface->bounds->type == BOUND_RELATIVE) { + cwhdims[j].min *= axm_size; + cwhdims[j].max *= axm_size; + } + + cwhdims[j].axm_size = fmax(fmin(split, cwhdims[j].max), cwhdims[j].min); + cwhdims[j].axo_size = axo_size; + + axm_free -= cwhdims[j].axm_size; + } + + int delta; + while (axm_free) { + if (axm_free < cunfixedn) { + int progress = 0; + for (int j = 0; j < node->cindex; j++) { + if (cwhdims[j].fixed) + continue; + cwhdims[j].axm_size--; + axm_free--; + } + } + + // split is guaranteed to be >0 + split = axm_free / node->cindex; + for (int j = 0; j < node->cindex; j++) { + if (cwhdims[j].fixed) + continue; + + delta = cwhdims[j].axm_size - fmax(cwhdims[j].axm_size - split, bounds->wmin); + if (delta == 0) { + cwhdims[j].fixed = true; + cunfixedn++; + continue; + } + + cwhdims[j].axm_size -= delta; + axm_free -= delta; + } + } + // bifurcate_dims(dims, node->axis, node->ratio, &dims0, &dims1); // resize_node(node->child[0], dims0); // resize_node(node->child[1], dims1); + return 0; } static int __set_cbounds(struct ct_node *const parent, diff --git a/cursetree/node.h b/cursetree/node.h index b9917fc..650f98f 100644 --- a/cursetree/node.h +++ b/cursetree/node.h @@ -13,8 +13,9 @@ typedef struct _win_st WINDOW; #define NODE_CHILDREN_GROWTH 1.5 #define CINDEX_MAX UCHAR_MAX -#define NFLAG_EMPTY (0) -#define NFLAG_RESIZE (1<<0) +#define NFLAG_EMPTY (0) +#define NFLAG_RESIZE (1<<0) +#define NFLAG_TOOSMALL (1<<1) /* Child Index */ typedef unsigned char cindex; diff --git a/cursetree/tree.c b/cursetree/tree.c index 6a91937..b0b3b1a 100644 --- a/cursetree/tree.c +++ b/cursetree/tree.c @@ -6,7 +6,7 @@ /* */ static inline struct ct_node *__root_node(void) { - return new_node(termdims(), NULL); + return new_node(termdims(), bounds_none(), NULL); } int init_tree(struct ct_tree **const tree) { @@ -27,8 +27,8 @@ void resize_tree(struct ct_tree *const tree, struct ct_dims *const dims) { void switch_nodes(struct ct_node **const node0, struct ct_node **const node1) { struct ct_node *const node0ptr = *node0; - struct ct_dims *const node0dims = dup_dims((*node0)->dims); - struct ct_dims *const node1dims = dup_dims((*node1)->dims); + struct ct_dims *const node0dims = dup_dims((*node0)->surface->dims); + struct ct_dims *const node1dims = dup_dims((*node1)->surface->dims); *node0 = *node1; resize_node(*node0, node1dims);