shithub: libnate

ref: c04fd4ce67a03c04b342c38185523bb834f4e0b7
dir: /n_hbox.c/

View raw version
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include "nate_construct.h"
#include "n_hbox.h"

#define N_TYPE NHBox_Type
char* NHBox_Type = "NHBox";

Point currentsize;
Image* currentscreen;

void
hbox_childsize(Nelem* nelem, int)
{
	Point p = ncallcalcsize(nelem, currentscreen);
	currentsize.x += p.x;
	currentsize.y = currentsize.y > p.y ? currentsize.y : p.y;
}

Point
hbox_calcsize(Nelem* nelem, Image* screen)
{
	NHBox* b = (NHBox*)nelem;
	GUARD(b);
	
	currentsize = Pt(0, 0);
	currentscreen = screen;
	
	lforeach(&b->children, hbox_childsize);

	return currentsize;
}

Rectangle currentrect;
Image* currentimg;

void
hbox_childdraw(Nelem* elem, int)
{
	Point p = ncallcalcsize(elem, currentimg);
	currentrect.max.x = currentrect.min.x + p.x;
	ncalldraw(elem, currentimg, currentrect);
	currentrect.min.x = currentrect.max.x;
}

void
hbox_draw(Nelem* nelem, Image* img, Rectangle r)
{
	NHBox* b = (NHBox*)nelem;
	GUARD(b);

	if (b->sizetocontent) {
		r.max = addpt(r.min, ncallcalcsize(b, img));
	}
	
	currentrect = r;
	currentimg = img;
	lforeach(&b->children, hbox_childdraw);
}

Nelem* ch_ret;
Image* ch_screen;
Rectangle ch_rect;
Mouse ch_mouse;

void
hbox_fe_checkhit(Nelem* nelem, int)
{
	Point s;
	Nelem* e;
	Rectangle r;
	
	s = ncallcalcsize(nelem, ch_screen);
	r.min = ch_rect.min;
	r.max = addpt(r.min, s);
	
	if (!ptinrect(ch_mouse.xy, r)) {
		ch_rect.min.x += s.x;
		return;
	}
	
	e = ncallcheckhit(nelem, ch_screen, r, ch_mouse);
	ch_rect.min.x += s.x;
	if (e) {
		ch_ret = e;
	}
}

Nelem*
hbox_checkhit(Nelem* nelem, Image* screen, Rectangle r, Mouse m)
{
	NHBox* b = (NHBox*)nelem;
	GUARD(b);
	
	ch_ret = nil;
	ch_screen = screen;
	ch_rect = r;
	ch_mouse = m;
	
	ch_rect.max.x = ch_rect.min.x;
	
	lforeach(&b->children, hbox_fe_checkhit);
	return ch_ret;
}

int
hbox_hit(Nelem* nelem, Mouse m)
{
	GUARD(nelem);
	return -1;
}

void
hbox_free(Nelem* nelem)
{
	NHBox* b = (NHBox*)nelem;
	if (nisroot(b))
		return;
	
	lfreelist(&b->children);
	free(b);
}

Nlist*
hbox_getchildren(Nelem* nelem)
{
	NHBox* b = (NHBox*)nelem;
	GUARD(b);
	return &b->children;
}

static Nelemfunctions Nhboxfunctions = {
	.calcsize = hbox_calcsize,
	.draw = hbox_draw,
	.checkhit = hbox_checkhit,
	.hit = hbox_hit,
	.free = hbox_free,
	.getchildren = hbox_getchildren,
};

NHBox*
hbox_slot(Nelem* child)
{
	if (child == nc_get()) {
		nc_pop();
	}
	NHBox* b = (NHBox*)nc_get();
	GUARD(b);
	
	ladd(&b->children, child);
	return b;
}

NHBox*
hbox_sizetocontent(int stc)
{
	NHBox* b = (NHBox*)nc_get();
	GUARD(b);
	b->sizetocontent = stc;
	return b;
}

NHBox*
New_HBox(void)
{
	NHBox* b = malloc(sizeof(NHBox));
	assert(b);
	
	b->type = NHBox_Type;
	b->funcs = &Nhboxfunctions;
	
	b->Slot = hbox_slot;
	b->SizeToContent = hbox_sizetocontent;
	
	linit(&b->children);
	b->sizetocontent = 0;
	nc_push(b);
	return b;
}