#include "paint.h" Widget * mkwidget(Rectangle r, int (*mouse)(Widget *, Mousectl *), int (*sync)(Widget *), void (*redraw)(Widget *, RedrawMode), Rdims (*dims)(Widget *), void (*resize)(Widget *, Point), void (*free)(Widget *), void *aux ) { Widget *w; if((w = malloc(sizeof(Widget))) == nil) return nil; /* return the unmodified errstr */ *w = (Widget){r, mouse, sync, redraw, dims, resize, free, aux, nil, nil, nil, nil}; return w; } void freewidget(Widget *w) { Widget *c; for(c = w->children; c != nil; c = c->next) c->free(c); free(w); } void addchildwidget(Widget *p, Widget *c, Point pos) { c->next = p->children; p->children = c; c->up = p; movewidget(c, pos, nil); } void movewidget(Widget *w, Point p, Image *screen) { Point old; Rectangle r; Widget *c; old = w->r.min; r = rectsubpt(w->r, w->r.min); if(w->up) r = rectaddpt(r, w->up->r.min); r = rectaddpt(r, p); w->r = r; w->screen = screen; for(c = w->children; c != nil; c = c->next) movewidget(c, subpt(c->r.min, old), screen); } Widget * findrootwidget(Widget *w) { while(w->up != nil) w = w->up; return w; } int widgetmousenop(Widget *, Mousectl *) { return 0; } int widgetmousedescend(Widget *w, Mousectl *mctl) { int r; for(w = w->children; w != nil; w = w->next) { if(ptinrect(mctl->xy, w->r)) { if((r = w->mouse(w, mctl)) < 0) { while(ptinrect(mctl->xy, w->r)) readmouse(mctl); } return r; } } while(mctl->buttons) readmouse(mctl); return 0; } int widgetsyncnop(Widget *) { return 0; } void widgetredrawnop(Widget *, RedrawMode) { return; } void widgetredrawdescend(Widget *w, RedrawMode redrawmode) { for(w = w->children; w != nil; w = w->next) w->redraw(w, redrawmode); } Rdims widgetdimsnop(Widget *w) { Point d; d = rectdim(w->r); return (Rdims){d, d, d}; } Rdims widgetdimsdescend(Widget *w) { Rdims total; total = (Rdims){ZP, ZP, ZP}; for(w = w->children; w != nil; w = w->next) total = adddims(total, w->dims(w)); return total; } void widgetresizenop(Widget *, Point) { } void widgetresizedescend(Widget *w, Point dim) { Rdims d; for(w = w->children; w != nil; w = w->next) { d = w->dims(w); w->resize(w, clamppt(dim, Rpt(d.min, d.max))); } }