shithub: libnate

ref: aab184987c79fc7a8e5467200f9ac448700b797f
dir: /n_button.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_box.h"
#include "n_label.h"
#include "n_button.h"

#define N_TYPE NButton_Type
char *NButton_Type = "NButton";

static Rectangle
button_calcrect(Nelem *nelem, Image *screen, Rectangle r)
{
	NButton *b = (NButton*)nelem;
	GUARD(b);
	b->box->slot = b->slot;
	b->slot.r = ncallcalcrect(b->box, screen, r);
	return b->slot.r;
}

static Point
button_desiredsize(Nelem *nelem, Image *screen)
{
	NButton *b = (NButton*)nelem;
	GUARD(b);
	b->box->slot = b->slot;
	return ncalldesiredsize(b->box, screen);
}

static void
button_draw(Nelem *nelem, Image *img)
{
	NButton *b = (NButton*)nelem;
	GUARD(b);
	b->box->slot = b->slot;
	ncalldraw(b->box, img);
}

static Nelem*
button_checkhit(Nelem *nelem, Image *screen, Mouse m)
{
	NButton *b = (NButton*)nelem;
	GUARD(b);
	b->box->slot = b->slot;
	return ncallcheckhit(b->box, screen, m);
}

static void
button_free(Nelem *nelem)
{
	NButton *b = (NButton*)nelem;
	GUARD(b);
	if (nisroot(b) || nisroot(b->box))
		return;
	b->box->funcs->free(b->box);
	free(b);
}

static Nlist*
button_getchildren(Nelem *nelem)
{
	NButton *b = (NButton*)nelem;
	GUARD(b);
	return ncallgetchildren(b->box);
}

static Nelemfunctions Nbuttonfunctions = {
	.calcrect = button_calcrect,
	.desiredsize = button_desiredsize,
	.draw = button_draw,
	.checkhit = button_checkhit,
	.free = button_free,
	.getchildren = button_getchildren,
};

#define NTYPE NButton
#define NACCS NButtonAccessors

static NACCS*
button_slot(Nslot info, Nelemaccessors *a)
{
	NButton *c;
	Nelem *child = nc_get();
	if (a->type != child->type)
		sysfatal("invalid child type in slot");
	nc_pop();
	c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->box);
	NCACCS(NBoxAccessors, c->box)->Slot(info, a);
	nc_pop();
	return (NACCS*)c->accs;
}

static NACCS*
button_border(int w, Image *i)
{
	NButton *c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->box);
	NCACCS(NBoxAccessors, c->box)->Border(w, i);
	nc_pop();
	return (NACCS*)c->accs;
}

static NACCS*
button_autosize(int n)
{
	NButton *c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->box);
	NCACCS(NBoxAccessors, c->box)->AutoSize(n);
	nc_pop();
	return (NACCS*)c->accs;
}

static NACCS*
button_onclick(OnclickHandler f, void *aux)
{
	NButton *c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->box);
	NCACCS(NBoxAccessors, c->box)->OnClick(f, aux);
	nc_pop();
	return NCACCS(NACCS, c);
}

static NACCS*
button_label(char *l)
{
	NButton *c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->label);
	NCACCS(NLabelAccessors, c->label)->Label(l);
	nc_pop();
	return (NACCS*)c->accs;
}

static NACCS*
button_labelfunc(StringGetter f)
{
	NButton *c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->label);
	NCACCS(NLabelAccessors, c->label)->LabelFunc(f);
	nc_pop();
	return (NACCS*)c->accs;
}

static NACCS*
button_font(Font *f)
{
	NButton *c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->label);
	NCACCS(NLabelAccessors, c->label)->Font(f);
	nc_pop();
	return (NACCS*)c->accs;
}

static NACCS*
button_color(Image *i)
{
	NButton *c = (NButton*)nc_get();
	GUARD(c);
	nc_push(c->label);
	NCACCS(NLabelAccessors, c->label)->Color(i);
	nc_pop();
	return (NACCS*)c->accs;
}

static NACCS accs = {
	.Slot = button_slot,
	.Border = button_border,
	.AutoSize = button_autosize,
	.OnClick = button_onclick,
	.Label = button_label,
	.LabelFunc = button_labelfunc,
	.Font = button_font,
	.Color = button_color,
};

NACCS*
New_Button(char *name)
{
	NButton *b = MakeNelem(NButton, NButton_Type, &Nbuttonfunctions, &accs, name, 0);
	
	NAssign(NBoxAccessors, &b->box, New_Box(name))
		->Slot(NSlot(),
			NAssign(NLabelAccessors, &b->label, New_Label(nil))
			->Margin(NMargin2(5, 2))
		);
	/* pop box from stack */
	nc_pop();
	
	nc_push(b);
	return &accs;
}