shithub: libnate

ref: 812d84e15bf64b6bdad838401acd8c8bbf25342b
dir: /nate_construct.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.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;
	
	border(p->screen, r, 1, ncolor.green, ZP);
	
	if (!ptinrect(p->mouse.xy, elem->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, &params);
	
	return params.retelem;
}

Nelem*
makenelem(long size, char *type, Nelemfunctions *funcs, char *name)
{
	Nelem *nel = mallocz(size, 1);
	if (!nel)
		sysfatal("oom: creating nelem %s", type);
	nel->type = type;
	nel->name = name;
	nel->funcs = funcs;
	return nel;
}

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 */
}