ref: a0b15f88e6274b4892061a7dfe790d85eb211078
dir: /n_vbox.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include "nate_construct.h"
#include "n_vbox.h"
#define N_TYPE NVBox_Type
char* NVBox_Type = "NVBox";
Point currentsize;
Image* currentscreen;
void
vbox_childsize(Nelem* nelem, int)
{
Point p = ncallcalcsize(nelem, currentscreen);
currentsize.x = currentsize.x > p.x ? currentsize.x : p.x;
currentsize.y += p.y;
}
Point
vbox_calcsize(Nelem* nelem, Image* screen)
{
NVBox* b = (NVBox*)nelem;
GUARD(b);
currentsize = Pt(0, 0);
currentscreen = screen;
lforeach(&b->children, vbox_childsize);
return currentsize;
}
Rectangle currentrect;
Image* currentimg;
void
vbox_childdraw(Nelem* elem, int)
{
Point p = ncallcalcsize(elem, currentimg);
currentrect.max.y = currentrect.min.y + p.y;
ncalldraw(elem, currentimg, currentrect);
currentrect.min.y = currentrect.max.y;
}
void
vbox_draw(Nelem* nelem, Image* img, Rectangle r)
{
NVBox* b = (NVBox*)nelem;
GUARD(b);
if (b->sizetocontent) {
r.max = addpt(r.min, ncallcalcsize(b, img));
}
currentrect = r;
currentimg = img;
lforeach(&b->children, vbox_childdraw);
}
Nelem* ch_ret;
Image* ch_screen;
Rectangle ch_rect;
Mouse ch_mouse;
void
vbox_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.y += s.y;
return;
}
e = ncallcheckhit(nelem, ch_screen, r, ch_mouse);
ch_rect.min.y += s.y;
if (e) {
ch_ret = e;
}
}
Nelem*
vbox_checkhit(Nelem* nelem, Image* screen, Rectangle r, Mouse m)
{
NVBox* b = (NVBox*)nelem;
GUARD(b);
ch_ret = nil;
ch_screen = screen;
ch_rect = r;
ch_mouse = m;
ch_rect.max.y = ch_rect.min.y;
lforeach(&b->children, vbox_fe_checkhit);
return ch_ret;
}
int
vbox_hit(Nelem* nelem, Mouse m)
{
GUARD(nelem);
return -1;
}
void
vbox_free(Nelem* nelem)
{
NVBox* b = (NVBox*)nelem;
if (nisroot(b))
return;
lfreelist(&b->children);
free(b);
}
Nlist*
vbox_getchildren(Nelem* nelem)
{
NVBox* b = (NVBox*)nelem;
GUARD(b);
return &b->children;
}
static Nelemfunctions Nvboxfunctions = {
.calcsize = vbox_calcsize,
.draw = vbox_draw,
.checkhit = vbox_checkhit,
.hit = vbox_hit,
.free = vbox_free,
.getchildren = vbox_getchildren,
};
NVBox*
vbox_slot(Nelem* child)
{
if (child == nc_get()) {
nc_pop();
}
NVBox* b = (NVBox*)nc_get();
GUARD(b);
ladd(&b->children, child);
return b;
}
NVBox*
vbox_sizetocontent(int stc)
{
NVBox* b = (NVBox*)nc_get();
GUARD(b);
b->sizetocontent = stc;
return b;
}
NVBox*
New_VBox(void)
{
NVBox* b = malloc(sizeof(NVBox));
assert(b);
b->type = NVBox_Type;
b->funcs = &Nvboxfunctions;
b->Slot = vbox_slot;
b->SizeToContent = vbox_sizetocontent;
linit(&b->children);
b->sizetocontent = 0;
nc_push(b);
return b;
}