ref: 6ff9ef0c4bef23bfd91f33f0c2f5cab0b88c0307
dir: /n_box.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <event.h> #include "nate_construct.h" #include "n_box.h" #define N_TYPE NBox_Type char* NBox_Type = "NBox"; Point box_calcsize(Nelem* nelem, Image* screen) { NBox* b = (NBox*)nelem; GUARD(b); if (!lgetfirst(&b->child)) { return Pt(0, 0); } Point csize = ncallcalcsize(lgetfirst(&b->child), screen); Point ssize = Pt(b->borderwidth, b->borderwidth); csize = addpt(csize, addpt(ssize, ssize)); return csize; } void box_draw(Nelem* nelem, Image* img, Rectangle r) { Nelem* f; NBox* b = (NBox*)nelem; GUARD(b); f = lgetfirst(&b->child); if (!f) return; if (b->sizetocontent) { r.max = addpt(r.min, ncallcalcsize(nelem, img)); } border(img, r, b->borderwidth, b->bordercolor, ZP); ncalldraw(f, img, insetrect(r, b->borderwidth)); } Nelem* box_checkhit(Nelem* nelem, Image* screen, Rectangle rect, Mouse m) { NBox* b = (NBox*)nelem; Nelem* r; Nelem* ch; Point size; Rectangle cr; GUARD(b); if (!(ch = lgetfirst(&b->child))) { if (m.buttons&1 && b->hitfunc) { return b; } return nil; } size = ncallcalcsize(ch, screen); cr.min = rect.min; cr.max = addpt(cr.min, size); if (ptinrect(m.xy, cr)) { r = ncallcheckhit(ch, screen, cr, m); if (r) return r; } if (m.buttons&1 && b->hitfunc) { return b; } return nil; } int box_hit(Nelem* nelem, Mouse m) { NBox* b = (NBox*)nelem; GUARD(b); if (b->hitfunc) return b->hitfunc(m, b, b->hitaux); return 0; } void box_free(Nelem* nelem) { Nelem* ch; NBox* b = (NBox*)nelem; if (nisroot(b)) return; if ((ch = lgetfirst(&b->child))) ncallfree(ch); free(b); } Nlist* box_getchildren(Nelem* nelem) { NBox* b = (NBox*)nelem; GUARD(b); return &b->child; } static Nelemfunctions Nboxfunctions = { .calcsize = box_calcsize, .draw = box_draw, .checkhit = box_checkhit, .hit = box_hit, .free = box_free, .getchildren = box_getchildren, }; NBox* box_slot(Nelem* child) { if (child == nc_get()) { nc_pop(); } NBox* b = (NBox*)nc_get(); GUARD(b); // TODO: potential leak! lsetfirst(&b->child, child); return b; } NBox* box_border(int bwidth, Image* col) { NBox* b = (NBox*)nc_get(); GUARD(b); b->borderwidth = bwidth; if (col) b->bordercolor = col; return b; } NBox* box_sizetocontent(int stc) { NBox* b = (NBox*)nc_get(); GUARD(b); b->sizetocontent = stc; return b; } NBox* box_onclick(int (*f)(Mouse, Nelem*, void*), void* aux) { NBox* b = (NBox*)nc_get(); GUARD(b); b->hitfunc = f; b->hitaux = aux; return b; } NBox* New_Box(void) { NBox* b = malloc(sizeof(NBox)); assert(b); b->type = NBox_Type; b->funcs = &Nboxfunctions; b->Slot = box_slot; b->Border = box_border; b->SizeToContent = box_sizetocontent; b->OnClick = box_onclick; linit(&b->child); b->sizetocontent = 0; b->hitfunc = nil; b->hitaux = nil; b->borderwidth = 0; b->bordercolor = display->black; nc_push(b); return b; }