ref: aab184987c79fc7a8e5467200f9ac448700b797f
dir: /nate_construct.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <event.h> #include "nate.h" #include "nate_construct.h" typedef struct NCelem NCelem; struct NCelem { Nelem* elem; NCelem* next; }; static NCelem* nc_stack = nil; void nc_init() { nc_stack = nil; } void nc_push(Nelem* nelem) { NCelem *n; if (!nc_stack) { nc_stack = malloc(sizeof(NCelem)); assert(nc_stack); nc_stack->next = nil; nc_stack->elem = nelem; } else { n = malloc(sizeof(NCelem)); assert(n); n->next = nc_stack; n->elem = nelem; nc_stack = n; } } void nc_pop() { if (!nc_stack) return; NCelem *nc = nc_stack; nc_stack = nc->next; free(nc); } Nelem* nc_get() { return nc_stack ? nc_stack->elem : nil; } typedef struct chparams chparams; struct chparams { Nelem *retelem; Image *screen; Mouse mouse; }; static void fe_checkhit(Nelem* elem, int, void *aux) { chparams *p = (chparams*)aux; Rectangle r; Nelem* e; if (p->retelem) return; if (!ptinrect(p->mouse.xy, elem->slot.r)) return; e = ncallcheckhit(elem, p->screen, p->mouse); nctracehitlevel--; if (e) { p->retelem = e; } } Nelem* nd_checkhit(Nelem* nelem, Image* screen, Mouse m) { chparams params; Nlist* l = ncallgetchildren(nelem); if (!l) return nil; params.retelem = nil; params.screen = screen; params.mouse = m; lforeach(l, fe_checkhit, ¶ms); return params.retelem; } void nd_free(Nelem *el) { if (nisroot(el)) return; lfreelist(&el->children); free(el); } Nelem* makenelem(long size, char *type, Nelemfunctions *funcs, Nelemaccessors *accs, char *name, int nchildren) { Nelem *nel = mallocz(size, 1); if (!nel) sysfatal("oom: creating nelem %s", type); accs->type = type; nel->type = type; nel->name = name; nel->funcs = funcs; nel->accs = accs; nel->nchildren = nchildren; linit(&nel->children); return nel; } void nc_addchild(Nelem *parent, Nelem *child) { if (parent->nchildren < 0) goto Add; if (!parent->nchildren) { sysfatal("invalid add to parent: %s is leaf", parent->type); } if (parent->children.num + 1 > parent->nchildren) { sysfatal("children count exhausted: parent %s supports %d children", parent->type, parent->nchildren); } Add: ladd(&parent->children, child); } int nctracehitlevel = 0; void nctracehit(Nelem *el, int pt) { char *name; if (natedebugfd < 0) return; if (nctracehitlevel < 0) return; if (el->funcs && el->funcs->getname) name = el->funcs->getname(el); else name = el->name; fprint(natedebugfd, "HIT: %*s%c%s%c %c%s%c\n", nctracehitlevel * 3, nctracehitlevel?"↘":"", /* indent */ pt ? '(' : ' ', el->type, pt ? ')' : ' ', /* Nelem type */ name?'\"':' ', name ? name : "", name?'\"':' '); /* name */ }