ref: 69e287559e1faed50092d64659c5bc02f9bf395c
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"; typedef struct csizep csizep; struct csizep { Rectangle crect; Image *screen; int autoheight; int fillwidth; }; static void childsize(Nelem* nelem, int, void *aux) { Point pt; Rectangle r; csizep *p = (csizep*)aux; /* only call if no fill at all */ if (!nelem->slot.fill) pt = ncalldesiredsize(nelem, p->screen); if (nelem->slot.fill&FILLX) pt.x = p->fillwidth; if (nelem->slot.fill&FILLY) pt.y = p->autoheight; r = p->crect; r.max = addpt(r.min, pt); ncallcalcrect(nelem, p->screen, r); p->crect.min.y = r.max.y; } typedef struct dprepassp dprepassp; struct dprepassp { Image *screen; int numfill; int fixedheight; }; static void sizeprepass(Nelem *nelem, int, void *aux) { dprepassp *p = (dprepassp*)aux; if (nelem->slot.fill & FILLY) { p->numfill++; return; } Rectangle r = ncalldesiredsize(nelem, p->screen); p->fixedheight += Dy(r); } static Rectangle vbox_calcrect(Nelem* nelem, Image* img, Rectangle r) { csizep cp; dprepassp pp; NVBox* b = (NVBox*)nelem; GUARD(b); b->slot.r = r; pp.screen = screen; pp.numfill = 0; pp.fixedheight = 0; lforeach(&b->children, sizeprepass, &pp); cp.crect = r; cp.screen = img; cp.fillwidth = Dx(r); cp.autoheight = (Dy(r) - pp.fixedheight) / pp.numfill; lforeach(&b->children, childsize, &cp); return b->slot.r; } typedef struct cdsizep cdsizep; struct cdsizep { Image *screen; Point size; }; static void dsizechild(Nelem *el, int, void *aux) { Point t; cdsizep *p = (cdsizep*)aux; t = ncalldesiredsize(el, p->screen); if (t.x > p->size.x) p->size.x = t.x; p->size.y += t.y; } static Point vbox_desiredsize(Nelem *nelem, Image *screen) { cdsizep p; NVBox *b = (NVBox*)nelem; GUARD(b); p.screen = screen; p.size = ZP; lforeach(&b->children, dsizechild, &p); return p.size; } static void vbox_childdraw(Nelem* elem, int, void *aux) { ncalldraw(elem, (Image*)aux); } static void vbox_draw(Nelem* nelem, Image* img) { NVBox* b = (NVBox*)nelem; GUARD(b); lforeach(&b->children, vbox_childdraw, img); } static Nelemfunctions Nvboxfunctions = { .calcrect = vbox_calcrect, .desiredsize = vbox_desiredsize, .draw = vbox_draw, }; DEF_SLOTFUNC(NVBox, vbox_slot); DEF_ACCESSOR_OneParam(NVBox, vbox_autowidth, int, autowidth); NVBox* New_VBox(char *name) { NVBox *b = MakeNelem(NVBox, NVBox_Type, &Nvboxfunctions, name, -1); b->Slot = vbox_slot; b->AutoWidth = vbox_autowidth; linit(&b->children); b->autowidth = 0; nc_push(b); return b; }