From 8c4f288a972c63f72ee00884448b71d818cff2ae Mon Sep 17 00:00:00 2001 From: Emile Clark-Boman Date: Thu, 11 Sep 2025 17:41:14 +1000 Subject: [PATCH] finish bulk of tree.* implementation --- Makefile | 10 ++-- cli/main.c | 25 +++++++- cli/tree.c | 166 +++++++++++++++++++++++++++++++++++++++++++++-------- cli/tree.h | 23 ++++---- 4 files changed, 181 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index a755c16..5c16f0d 100644 --- a/Makefile +++ b/Makefile @@ -33,18 +33,18 @@ $(BIN)/shfx: shfx/main.c $(CC) $(CFLAGS) -o $(BUILD)/shfx.o -c $^ $(CLD) $(CLDFLAGS) -lncurses -o $@ $(BUILD)/shfx.o -$(BIN)/dorne: $(addprefix $(BUILD)/,dorne.o epty.o) - $(CLD) $(CLDFLAGS) -o $@ $^ +$(BIN)/dorne: $(addprefix $(BUILD)/,dorne.o ilovecurses.o) + $(CLD) $(CLDFLAGS) -lncurses -o $@ $^ $(BUILD) $(BIN): mkdir -p $@ $(BUILD)/dorne.o: $(addprefix $(CLI)/, main.c) $(mkobj) -$(BUILD)/epty.o: $(addprefix $(CLI)/, epty.c _pty.c) +$(BUILD)/ilovecurses.o: $(addprefix $(CLI)/, tree.c curse.c) + $(mkobj) +$(BUILD)/epty.o: $(addprefix $(CLI)/, child.c epty.c _pty.c) $(mkobj) - -# $1/%.o: $1/%.c # === DEVELOPMENT TARGETS === .PHONY: debug run test diff --git a/cli/main.c b/cli/main.c index af57f88..2b5ab1e 100644 --- a/cli/main.c +++ b/cli/main.c @@ -2,7 +2,10 @@ #include #include -#include "child.h" +#include + +// #include "child.h" +#include "tree.h" // struct d_window { // int ptmx; // fd @@ -15,7 +18,23 @@ // } int main(int argc, char **argv) { - struct d_child child; - spawnchild(&child); + // struct d_child child; + // spawnchild(&child); + + struct crs_tree *tree; + init_tree(&tree); + + init_pair(1, COLOR_BLACK, COLOR_CYAN); + init_pair(2, COLOR_BLACK, COLOR_RED); + + // bifurcate_window_node(&tree->root, AXIS_X, FALSE, 0.5); + + // wbkgd(tree->root->child[0]->win, COLOR_PAIR(1)); + // wbkgd(tree->root->child[1]->win, COLOR_PAIR(1)); + + // sleep(3); + + destroy_tree(tree); + return EXIT_SUCCESS; } diff --git a/cli/tree.c b/cli/tree.c index 04922e6..41ae103 100644 --- a/cli/tree.c +++ b/cli/tree.c @@ -1,5 +1,6 @@ #include #include +#include #include "curse.h" #include "tree.h" @@ -14,21 +15,30 @@ static inline struct crs_node *__alloc_node(const enum crs_nodetype type) { /* Construct a new window node (crs_node of type NODE_WIN). */ -static struct crs_node *init_node_window(WINDOW *win) { +static struct crs_node *init_window_node(WINDOW *const win) { struct crs_node *node = __alloc_node(NODE_WINDOW); node->win = win; return node; } -static struct crs_node *init_node_abstract(struct crs_node *node1, - struct crs_node *node2, - float ratio) { - struct crs_node *node = __alloc_node(NODE_ABSTRACT); - node->ratio = ratio; +static struct crs_node *auto_window_node(const struct crs_nodedims *dims) { + WINDOW *win = newwin(dims->height, dims->width, dims->y, dims->x); + return init_window_node(win); +} - node->child[0] = node1; - node->child[1] = node2; +static struct crs_node *init_abstract_node(struct crs_node *node0, + struct crs_node *node1, + const enum crs_axis axis, + const float ratio, + struct crs_nodedims *dims) { + struct crs_node *node = __alloc_node(NODE_ABSTRACT); + node->axis = axis; + node->ratio = ratio; + node->dims = dims; + + node->child[0] = node0; + node->child[1] = node1; return node; } @@ -39,35 +49,138 @@ static void destroy_node(struct crs_node *node) { goto end; } /* Abstract Node */ + assert(node->type == NODE_ABSTRACT); destroy_node(node->child[0]); destroy_node(node->child[1]); + free(node->dims); end: free(node); } +static inline struct crs_nodedims *__dup_dims(const struct crs_nodedims *dims) { + struct crs_nodedims *dup; + dup = (struct crs_nodedims *)malloc(sizeof(struct crs_nodedims)); + memcpy(dup, dims, sizeof(struct crs_nodedims)); + + return dup; +} + +static struct crs_nodedims *get_dims(const struct crs_node *node) { + struct crs_nodedims *dims; + if (node->type == NODE_WINDOW) { + /* Window Node */ + dims = (struct crs_nodedims *)malloc(sizeof(struct crs_nodedims)); + // GET_WNODEDIMS(); + getbegyx(node->win, dims->y, dims->x); + getmaxyx(node->win, dims->height, dims->width); + printf("getx: %d\n", dims->x); + printf("gety: %d\n", dims->y); + printf("getwidth: %d\n", dims->width); + printf("getheight: %d\n", dims->height); + } else { + /* Abstract Node */ + assert(node->type == NODE_ABSTRACT); + dims = __dup_dims(node->dims); + } + + return dims; +} + +/* 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. + */ +static int bifurcate_dims(const struct crs_node *parent, + const enum crs_axis axis, const float ratio, + struct crs_nodedims **dims0, + struct crs_nodedims **dims1) { + assert(0 < ratio && ratio < 1); + struct crs_nodedims *_dims0, *_dims1; + + _dims0 = get_dims(parent); + _dims1 = __dup_dims(_dims0); + + printf("widthP: %d\n", _dims0->width); + printf("heightP: %d\n", _dims0->height); + + 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 += _dims1->height; + } + + if (!_dims0->width || !_dims0->height || !_dims1->width || !_dims1->height) { + printf("width0: %d\n", _dims0->width); + printf("height0: %d\n", _dims0->height); + printf("width1: %d\n", _dims1->width); + printf("height1: %d\n", _dims1->height); + return 1; + } + + // propagate bifurcated dimensions + *dims0 = _dims0; + *dims1 = _dims1; + return 0; +} + +static void resize_node(struct crs_node *node, struct crs_nodedims *new_dims) { + if (node->type == NODE_WINDOW) { + /* Window Node */ + resizemv_window(new_dims->x, new_dims->y, new_dims->width, new_dims->height, + node->win); + free(new_dims); + } else { + /* Abstract Node */ + assert(node->type == NODE_ABSTRACT); + struct crs_nodedims *dims0, *dims1; + + free(node->dims); + node->dims = new_dims; + bifurcate_dims(node, node->axis, node->ratio, &dims0, &dims1); + + resize_node(node->child[0], dims0); + resize_node(node->child[1], dims1); + } +} + /* Subdivide a window node's allocated region into two window nodes * replacing the original node with an abstract node. * Parameters: * axis - controls which direction the subdivision occurs - * invert - invert index of the original node in the new abstract node + * invert_axis - invert index of the original node in the new abstract node */ -static void bifurcate_window_node(struct crs_node **node, enum crs_axis axis, - int invert, float ratio) { - assert((*node)->type == NODE_ABSTRACT); +void bifurcate_window_node(struct crs_node **node, + const enum crs_axis axis, + const int invert_axis, const float ratio) { + assert((*node)->type == NODE_WINDOW); + struct crs_nodedims *dims0, *dims1; + struct crs_node *node0, *node1; - struct crs_node *original_node = *node; - struct crs_node *bi_node = init_node_window(); // WARNING: TODO - - if (!invert) { + + if (bifurcate_dims(*node, axis, ratio, &dims0, &dims1)) { + printf("FAILED TERRIBLY THE FUCK\n"); + exit(1); + return; + } + if (invert_axis) { /* Inverted Bifurcation */ - *node = init_node_abstract(bi_node, original_node, ratio); + node0 = auto_window_node(dims0); + node1 = *node; + resize_node(node1, dims1); } else { /* Non-Inverted Bifurcation */ - *node = init_node_abstract(original_node, bi_node, ratio); + node0 = *node; + node1 = auto_window_node(dims1); + resize_node(node0, dims0); } - resize_abstract_node(*node); + *node = init_abstract_node(node0, node1, axis, ratio, (*node)->dims); } /* Collapse an abstract node, killing one child node and resizing @@ -89,17 +202,15 @@ static void collapse_abstract_node(struct crs_node **node, /* */ static struct crs_node *init_root_node(void) { - WINDOW *rootwin = newwin(0, 0, 0, 0); - return init_node_window(rootwin); + return init_window_node(root_window()); } -int init_tree(struct crs_tree **tree) { +int init_tree(struct crs_tree **const tree) { *tree = (struct crs_tree *)malloc(sizeof(struct crs_tree)); /* Initialise NCurses Library & Standard Screen */ - crs_init(&(*tree)->stdscr); + init_ncurses(); - /* */ (*tree)->root = init_root_node(); // (*tree)->root = __alloc_node(NODE_WINDOW); @@ -108,9 +219,14 @@ int init_tree(struct crs_tree **tree) { return EXIT_SUCCESS; } -void destroy_tree(struct crs_tree *tree) { +void destroy_tree(struct crs_tree *const tree) { /* WARNING: is it ok to delwin(stdscr) ?? */ destroy_node(tree->root); endwin(); + free(tree); +} + +void resize_tree(struct crs_tree *const tree, struct crs_nodedims *const dims) { + resize_node(tree->root, dims); } diff --git a/cli/tree.h b/cli/tree.h index d5ba171..c2263f1 100644 --- a/cli/tree.h +++ b/cli/tree.h @@ -1,16 +1,19 @@ #ifndef DORNE_TREE_H #define DORNE_TREE_H -# ifndef __NCURSES_H +#ifndef __NCURSES_H typedef struct _win_st WINDOW; -# endif /* __NCURSES_H */ +#endif /* __NCURSES_H */ #define NODE_CHILD_N 2 /* MACRO: + * Get widnow node start x,y coordinates, width, & height. * void NODEDIMS(struct crs_node *node, struct crs_nodedims dims); */ -#define NODEDIMS(node, dims) (getbegyx(dims.y, dims.x); getmaxyx(dims.y, dims.x)) +#define GET_WNODEDIMS(dims, node) \ + (getbegyx((node)->win, dims.y, dims.x)); \ + getmaxyx((node)->win, dims.y, dims.x) enum crs_nodetype { NODE_WINDOW, @@ -35,24 +38,24 @@ struct crs_node { union { WINDOW *win; struct { + enum crs_axis axis; float ratio; + struct crs_nodedims *dims; struct crs_node *child[NODE_CHILD_N]; }; }; }; struct crs_tree { - WINDOW *stdscr; struct crs_node *root; }; /* === External Interface === */ -// struct crs_node *init_node_window(void); -// struct crs_node *init_node_abstract(void); -// void destroy_node(struct crs_node *node); +int init_tree(struct crs_tree **const tree); +void destroy_tree(struct crs_tree *const tree); +void resize_tree(struct crs_tree *const tree, struct crs_nodedims *const dims); -int init_tree(struct crs_tree **tree); -void update_tree(struct crs_tree *tree); -void destroy_tree(struct crs_tree *tree); +void bifurcate_window_node(struct crs_node **node, const enum crs_axis axis, + const int invert_axis, const float ratio); #endif /* DORNE_TREE_H */