ref: 228a7b0eeda3531eb0bf0efa2211e4532af69681
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"; Rectangle box_calcsize(Nelem* nelem, Image* screen, Rectangle r) { NBox* b = (NBox*)nelem; GUARD(b); if (!b->sizetocontent) { r.max = addpt(r.min, b->size); b->r = r; return r; } if (!lgetfirst(&b->child)) { b->r = r; return r; } Rectangle csize = ncallcalcsize(lgetfirst(&b->child), screen, r); b->r = insetrect(csize, b->borderwidth); return b->r; } static void box_draw(Nelem* nelem, Image* img) { Nelem* f; Rectangle r; NBox* b = (NBox*)nelem; GUARD(b); f = lgetfirst(&b->child); if (!f) return; r = b->r; if (b->sizetocontent) { r = b->r; } else { r = b->r; r.max = addpt(r.min, b->size); } border(img, r, b->borderwidth, b->bordercolor, ZP); ncalldraw(f, img); if (nateborders) { border(img, r, 1, ncolor.red, ZP); } } static Nelem* box_checkhit(Nelem *nelem, Image *screen, Mouse m) { NBox *b = (NBox*)nelem; GUARD(b); if (!b->hitfunc) return nd_checkhit(nelem, screen, m); if (ptinrect(m.xy, b->r)) 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 char* box_getname(Nelem *nelem) { Nelem *ch; NBox *b = (NBox*)nelem; GUARD(b); ch = lgetfirst(&b->child); if (!(ch && ch->funcs && ch->funcs->getname)) return b->name; return ch->funcs->getname(ch); } static Nelemfunctions Nboxfunctions = { .calcsize = box_calcsize, .draw = box_draw, .checkhit = box_checkhit, .hit = box_hit, .free = box_free, .getchildren = box_getchildren, .getname = box_getname, }; 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; } DEF_ACCESSOR_TwoParams(NBox, box_border, int, borderwidth, Image*, bordercolor); DEF_ACCESSOR_OneParam(NBox, box_sizetocontent, int, sizetocontent); DEF_ACCESSOR_OneParam(NBox, box_size, Point, size); DEF_ACCESSOR_OneParam(NBox, box_padding, Nmargin, padding); DEF_ACCESSOR_TwoParams(NBox, box_onclick, OnclickHandler, hitfunc, void*, hitaux); NBox* New_Box(char *name) { NBox *b = MakeNelem(NBox, NBox_Type, &Nboxfunctions, name); b->Slot = box_slot; b->Border = box_border; b->SizeToContent = box_sizetocontent; b->Size = box_size; b->OnClick = box_onclick; b->Padding = box_padding; linit(&b->child); b->sizetocontent = 0; b->size = ZP; b->hitfunc = nil; b->hitaux = nil; b->borderwidth = 0; b->bordercolor = display->black; nc_push(b); return b; }