shithub: libnate

ref: c9e889a6d73bcfcd63a93a8f74732411304ef257
dir: /n_vlist.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include "nate.h"
#include "nate_construct.h"
#include "n_vbox.h"
#include "n_vlist.h"

#define N_TYPE NVList_Type
char *NVList_Type = "NVList";

static void
updatechildren(NVList *l)
{
	Nelem *n;
	long i;
	uchar *it;
	Nlist *list;
	
	if (!(l && l->box))
		return;
	
	list = ncallgetchildren(l->box);
	if (!list)
		return;
	lfreelist(list);
	
	if (!l->items)
		return;
	if (!l->genwidget)
		return;
	
	it = l->items->data;
	for (i = 0; i < l->items->num; i++) {
		n = l->genwidget(&it[i * l->items->size], i, l->aux);
		if (n) {
			ladd(list, n);
		}
	}
	nsetdirty(l, DRAW);
}

static Rectangle
calcrect(Nelem *nel, Image *screen, Rectangle r)
{
	NVList *v = (NVList*)nel;
	GUARD(v);
	v->box->slot = v->slot;
	v->slot.r = ncallcalcrect(v->box, screen, r);
	return v->slot.r;
}

static Point
desiredsize(Nelem *nel, Image *screen)
{
	NVList *v = (NVList*)nel;
	GUARD(v);
	v->box->slot = v->slot;
	return ncalldesiredsize(v->box, screen);
}

static void
vdraw(Nelem *nel, Image *img)
{
	NVList *v = (NVList*)nel;
	GUARD(v);
	v->box->slot = v->slot;
	ncalldraw(v->box, img);
}

static Nelem*
checkhit(Nelem *nel, Image *screen, Mouse m)
{
	NVList *v = (NVList*)nel;
	GUARD(v);
	v->box->slot = v->slot;
	return ncallcheckhit(v->box, screen, m);
}

static void
vfree(Nelem *nel)
{
	NVList *v = (NVList*)nel;
	GUARD(v);
	if (nisroot(v) || nisroot(v->box))
		return;
	v->box->funcs->free(v->box);
	free(v);
}

static Nlist*
getchildren(Nelem *nel)
{
	NVList *v = (NVList*)nel;
	GUARD(v);
	return ncallgetchildren(v->box);
}

static Nelemfunctions Nvlistfunctions = {
	.calcrect = calcrect,
	.desiredsize = desiredsize,
	.draw = vdraw,
	.checkhit = checkhit,
	.free = vfree,
	.getchildren = getchildren,
};

#define NTYPE NVList
#define NACCS NVListAccessors

static NACCS*
vgenwidget(NelemGetter getter, void *aux)
{
	NVList *v = (NVList*)nc_get();
	GUARD(v);
	v->genwidget = getter;
	v->aux = aux;
	return (NACCS*)v->accs;
}

static NACCS*
vsource(NArray *arr)
{
	NVList *v = (NVList*)nc_get();
	GUARD(v);
	v->items = arr;
	return (NACCS*)v->accs;
}

static NACCS accs = {
	.GenerateWidget = vgenwidget,
	.Source = vsource,
};

static void
notifyupdate(NTYPE *v)
{
	updatechildren(v);
}

NACCS*
New_VList(char *name)
{
	NVList *v = MakeNelem(NVList, NVList_Type, &Nvlistfunctions, &accs, name, 0);
	
	NAssign(NVBoxAccessors, &v->box, New_VBox(name));
	nc_pop();
	
	v->notifyupdate = notifyupdate;
	
	nc_push(v);
	return &accs;
}