diff --git a/stack.c b/stack.c index 80c2d75c..f65e0d74 100644 --- a/stack.c +++ b/stack.c @@ -1,13 +1,17 @@ // 7 april 2015 #include "uipriv.h" +// TODO +// - use stackControl +// - change prefwid/prefht to preferredWidth/preferredHeight + typedef struct stack stack; +typedef struct stackControl stackControl; struct stack { - uiControl control; uiControl **controls; int *stretchy; - intmax_t *width; // both used by resize(); preallocated to save time and reduce risk of failure + intmax_t *width; intmax_t *height; uintmax_t len; uintmax_t cap; @@ -16,20 +20,26 @@ struct stack { int padded; }; -#define S(c) ((stack *) (c)) +struct stackControl { + uiControl *control; + int stretchy; + intmax_t width; // both used by resize(); preallocated to save time and reduce risk of failure + intmax_t height; +}; static void stackDestroy(uiControl *c) { - stack *s = (stack *) c; + stack *s = (stack *) (c->data); uintmax_t i; - for (i = 0; i < S(c)->len; i++) + for (i = 0; i < s->len; i++) uiControlDestroy(s->controls[i]); uiFree(s->controls); uiFree(s->stretchy); uiFree(s->width); uiFree(s->height); uiFree(s); + uiFree(c); } static uintptr_t stackHandle(uiControl *c) @@ -39,56 +49,55 @@ static uintptr_t stackHandle(uiControl *c) static void stackSetParent(uiControl *c, uintptr_t parent) { - stack *s = S(c); + stack *s = (stack *) (c->data); uintmax_t i; s->parent = parent; - for (i = 0; i < S(c)->len; i++) - (*(s->controls[i]->setParent))(s->controls[i], s->parent); + for (i = 0; i < s->len; i++) + uiControlSetParent(s->controls[i], s->parent); updateParent(s->parent); } static void stackRemoveParent(uiControl *c) { - stack *s = S(c); + stack *s = (stack *) (c->data); uintmax_t i; uintptr_t oldparent; oldparent = s->parent; s->parent = 0; - for (i = 0; i < S(c)->len; i++) - (*(s->controls[i]->removeParent))(s->controls[i]); + for (i = 0; i < s->len; i++) + uiControlRemoveParent(s->controls[i]); updateParent(oldparent); } -static uiSize stackPreferredSize(uiControl *c, uiSizing *d) +static void stackPreferredSize(uiControl *c, uiSizing *d, intmax_t *width, intmax_t *height) { - stack *s = S(c); + stack *s = (stack *) (c->data); int xpadding, ypadding; uintmax_t nStretchy; intmax_t maxswid, maxsht; uintmax_t i; - uiSize size, preferred; - uiSizingComm *dd = (uiSizingComm *) d; + intmax_t prefwid, prefht; - size.width = 0; - size.height = 0; + *width = 0; + *height = 0; if (s->len == 0) - return size; + return; // 0) get this Stack's padding xpadding = 0; ypadding = 0; if (s->padded) { - xpadding = dd->xPadding; - ypadding = dd->yPadding; + xpadding = d->xPadding; + ypadding = d->yPadding; } // 1) initialize the desired rect with the needed padding if (s->vertical) - size.height = (s->len - 1) * ypadding; + *height = (s->len - 1) * ypadding; else - size.width = (s->len - 1) * xpadding; + *width = (s->len - 1) * xpadding; // 2) add in the size of non-stretchy controls and get (but not add in) the largest widths and heights of stretchy controls // we still add in like direction of stretchy controls @@ -96,45 +105,42 @@ static uiSize stackPreferredSize(uiControl *c, uiSizing *d) maxswid = 0; maxsht = 0; for (i = 0; i < s->len; i++) { - preferred = (*(s->controls[i]->preferredSize))(s->controls[i], d); + uiControlPreferredSize(s->controls[i], d, &prefwid, &prefht); if (s->stretchy[i]) { nStretchy++; - if (maxswid < preferred.width) - maxswid = preferred.width; - if (maxsht < preferred.height) - maxsht = preferred.height; + if (maxswid < prefwid) + maxswid = prefwid; + if (maxsht < prefht) + maxsht = prefht; } if (s->vertical) { - if (size.width < preferred.width) - size.width = preferred.width; + if (*width < prefwid) + *width = prefwid; if (!s->stretchy[i]) - size.height += preferred.height; + *height += prefht; } else { if (!s->stretchy[i]) - size.width += preferred.width; - if (size.height < preferred.height) - size.height = preferred.height; + *width += prefwid; + if (*height < prefht) + *height = prefht; } } // 3) and now we can add in stretchy controls if (s->vertical) - size.height += nStretchy * maxsht; + *height += nStretchy * maxsht; else - size.width += nStretchy * maxswid; - - return size; + *width += nStretchy * maxswid; } static void stackResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height, uiSizing *d) { - stack *s = S(c); + stack *s = (stack *) (c->data); int xpadding, ypadding; uintmax_t nStretchy; intmax_t stretchywid, stretchyht; uintmax_t i; - uiSize preferred; - uiSizingComm *dd = (uiSizingComm *) d; + intmax_t prefwid, prefht; if (s->len == 0) return; @@ -143,8 +149,8 @@ static void stackResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, in xpadding = 0; ypadding = 0; if (s->padded) { - xpadding = dd->xPadding; - ypadding = dd->yPadding; + xpadding = d->xPadding; + ypadding = d->yPadding; } // 0) inset the available rect by the needed padding @@ -164,15 +170,15 @@ static void stackResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, in continue; } c = s->controls[i]; - preferred = (*(s->controls[i]->preferredSize))(s->controls[i], d); + uiControlPreferredSize(s->controls[i], d, &prefwid, &prefht); if (s->vertical) { // all controls have same width s->width[i] = width; - s->height[i] = preferred.height; - stretchyht -= preferred.height; + s->height[i] = prefht; + stretchyht -= prefht; } else { // all controls have same height - s->width[i] = preferred.width; + s->width[i] = prefwid; s->height[i] = height; - stretchywid -= preferred.width; + stretchywid -= prefwid; } } @@ -190,7 +196,7 @@ static void stackResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, in // 3) now we can position controls for (i = 0; i < s->len; i++) { - (*(s->controls[i]->resize))(s->controls[i], x, y, s->width[i], s->height[i], d); + uiControlResize(s->controls[i], x, y, s->width[i], s->height[i], d); if (s->vertical) y += s->height[i] + ypadding; else @@ -200,26 +206,31 @@ static void stackResize(uiControl *c, intmax_t x, intmax_t y, intmax_t width, in uiControl *uiNewHorizontalStack(void) { + uiControl *c; stack *s; + c = uiNew(uiControl); s = uiNew(stack); - s->control.destroy = stackDestroy; - s->control.handle = stackHandle; - s->control.setParent = stackSetParent; - s->control.removeParent = stackRemoveParent; - s->control.preferredSize = stackPreferredSize; - s->control.resize = stackResize; + c->data = s; + c->destroy = stackDestroy; + c->handle = stackHandle; + c->setParent = stackSetParent; + c->removeParent = stackRemoveParent; + c->preferredSize = stackPreferredSize; + c->resize = stackResize; - return (uiControl *) s; + return c; } uiControl *uiNewVerticalStack(void) { uiControl *c; + stack *s; c = uiNewHorizontalStack(); - S(c)->vertical = 1; + s = (stack *) (c->data); + s->vertical = 1; return c; } @@ -227,7 +238,7 @@ uiControl *uiNewVerticalStack(void) void uiStackAdd(uiControl *st, uiControl *c, int stretchy) { - stack *s = S(st); + stack *s = (stack *) (st->data); if (s->len >= s->cap) { s->cap += stackCapGrow; @@ -246,9 +257,9 @@ void uiStackAdd(uiControl *st, uiControl *c, int stretchy) // TODO get padded -void uiStackSetPadded(uiControl *st, int padded) +void uiStackSetPadded(uiControl *c, int padded) { - stack *s = S(st); + stack *s = (stack *) (c->data); s->padded = padded; updateParent(s->parent);