ref: c04fd4ce67a03c04b342c38185523bb834f4e0b7
dir: /n_hbox.c/
#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;
}