From 4600bca8d3061f636a7907f3235ea303c372b76a Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 29 Apr 2016 10:48:39 -0400 Subject: [PATCH] Migrated box.cpp. Now we can migrate the other controls, since we have a better idea of what we're doing. --- windows/box.cpp | 357 ++++++++++++++++++++++++------------------------ 1 file changed, 179 insertions(+), 178 deletions(-) diff --git a/windows/box.cpp b/windows/box.cpp index 95fd991d..e3705d96 100644 --- a/windows/box.cpp +++ b/windows/box.cpp @@ -1,47 +1,155 @@ // 7 april 2015 #include "uipriv_windows.hpp" -// TODO C++-ize +struct boxChild { + uiControl *c; + int stretchy; + intmax_t width; + intmax_t height; +}; struct uiBox { uiWindowsControl c; HWND hwnd; - struct ptrArray *controls; + std::vector *controls; int vertical; int padded; }; -#define ctrlStretchy(child) childFlag(child) -#define ctrlSetStretchy(child, stretchy) childSetFlag(child, stretchy) -// both used by resize(); preallocated to save time and reduce risk of failure -#define ctrlWidth(child) childIntmax(child, 0) -#define ctrlSetWidth(child, w) childSetIntmax(child, 0, w) -#define ctrlHeight(child) childIntmax(child, 1) -#define ctrlSetHeight(child, h) childSetIntmax(child, 1, h) - -static void onDestroy(uiBox *); - -uiWindowsDefineControlWithOnDestroy( - uiBox, // type name - onDestroy(me); // on destroy -) - -static void onDestroy(uiBox *b) +static void boxPadding(uiBox *b, int *xpadding, int *ypadding) { - struct child *bc; - - while (b->controls->len != 0) { - bc = ptrArrayIndex(b->controls, struct child *, 0); - ptrArrayDelete(b->controls, 0); - childDestroy(bc); + *xpadding = 0; + *ypadding = 0; + if (b->padded) { + uiWindowsGetSizing(b->hwnd, &sizing); + uiWindowsSizingStandardPadding(&sizing, xpadding, ypadding); } - ptrArrayDestroy(b->controls); } -static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height) +static void boxRelayout(uiBox *b) +{ + RECT r; + intmax_t x, y, width, height; + int xpadding, ypadding; + uintmax_t nStretchy; + intmax_t stretchywid, stretchyht; + uintmax_t i; + intmax_t minimumWidth, minimumHeight; + uiWindowsSizing *d; + + if (b->controls->size() == 0) + return; + + uiWindowsEnsureGetClientRect(b->hwnd, &r); + x = r.left; + y = r.top; + width = r.right - r.left; + height = r.bottom - r.top; + + // -1) get this Box's padding + boxPadding(b, &xpadding, &ypadding); + + // 0) inset the available rect by the needed padding + // TODO this is incorrect if any controls are hidden + if (b->vertical) + height -= (b->controls->size() - 1) * ypadding; + else + width -= (b->controls->size() - 1) * xpadding; + + // 1) get width and height of non-stretchy controls + // this will tell us how much space will be left for stretchy controls + stretchywid = width; + stretchyht = height; + nStretchy = 0; + for (struct boxChild &bc : *(b->controls)) { + if (!uiControlVisible(bc.c)) + continue; + if (bc.stretchy) { + nStretchy++; + continue; + } + uiWindowsControlMinimumSize(uiWindowsControl(bc.c), &minimumWidth, &minimumHeight); + if (b->vertical) { // all controls have same width + bc.width = width; + bc.height = minimumHeight; + stretchyht -= minimumHeight; + } else { // all controls have same height + bc.width = minimumWidth; + bc.height = height; + stretchywid -= minimumWidth; + } + } + + // 2) now get the size of stretchy controls + if (nStretchy != 0) + if (b->vertical) + stretchyht /= nStretchy; + else + stretchywid /= nStretchy; + // TODO put this in the above if + for (struct boxChild &bc : *(b->controls)) { + if (!uiControlVisible(bc.c)) + continue; + if (bc.stretchy) { + bc.width = stretchywid; + bc.height = stretchyht; + } + } + + // 3) now we can position controls + // first, make relative to the top-left corner of the container + x = 0; + y = 0; + for (const struct boxChild &bc : *(b->controls)) { + if (!uiControlVisible(bc.c)) + continue; + uiWindowsEnsureMoveWIndowDuringResize((HWND) uiControlHandle(bc.c), x, y, bc.width, bc.height); + if (b->vertical) + y += bc.height + ypadding; + else + x += bc.width + xpadding; + } +} + +static void uiBoxDestroy(uiControl *c) +{ + uiBox *b = uiBox(c); + + for (const struct boxChild &bc : *(b->controls)) { + uiControlSetParent(bc.c, NULL); + uiControlDestroy(bc.c); + } + delete b->controls; + uiWindowsEnsureDestroyWindow(b->hwnd); + uiFreeControl(uiControl(b)); +} + +uiWindowsControlDefaultHandle(uiBox) +uiWindowsControlDefaultParent(uiBox) +uiWindowsControlDefaultSetParent(uiBox) +uiWindowsControlDefaultToplevel(uiBox) +uiWindowsControlDefaultVisible(uiBox) +uiWindowsControlDefaultShow(uiBox) +uiWindowsControlDefaultHide(uiBox) +uiWindowsControlDefaultEnabled(uiBox) +uiWindowsControlDefaultEnable(uiBox) +uiWindowsControlDefaultDisable(uiBox) + +static void uiBoxSyncEnableState(uiWindowsControl *c, int enabled) +{ + uiBox *b = uiBox(c); + + if (uiWindowsShouldStopSyncEnableState(uiWindowsControl(b), enabled)) + return; + for (const struct boxChild &bc : *(b->controls)) + uiWindowsControlSyncEnableState(uiWindowsControl(bc.c), enabled); +} + +uiWindowsControlDefaultSetParentHWND(uiBox) + +static void uiBoxMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) { uiBox *b = uiBox(c); - struct child *bc; int xpadding, ypadding; uintmax_t nStretchy; // these two contain the largest minimum width and height of all stretchy controls in the box @@ -49,41 +157,33 @@ static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width intmax_t maxStretchyWidth, maxStretchyHeight; uintmax_t i; intmax_t minimumWidth, minimumHeight; - uiWindowsSizing *dself; + uiWindowsSizing sizing; *width = 0; *height = 0; - if (b->controls->len == 0) + if (b->controls->size() == 0) return; - dself = uiWindowsNewSizing(b->hwnd); - // 0) get this Box's padding - xpadding = 0; - ypadding = 0; - if (b->padded) { - xpadding = d->XPadding; - ypadding = d->YPadding; - } + boxPadding(b, &xpadding, &ypadding); // 1) initialize the desired rect with the needed padding // TODO this is wrong if any controls are hidden if (b->vertical) - *height = (b->controls->len - 1) * ypadding; + *height = (b->controls->size() - 1) * ypadding; else - *width = (b->controls->len - 1) * xpadding; + *width = (b->controls->size() - 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 nStretchy = 0; maxStretchyWidth = 0; maxStretchyHeight = 0; - for (i = 0; i < b->controls->len; i++) { - bc = ptrArrayIndex(b->controls, struct child *, i); - if (!childVisible(bc)) + for (const struct boxChild &bc : *(b->controls)) { + if (!uiControlVisible(bc.c)) continue; - childMinimumSize(bc, dself, &minimumWidth, &minimumHeight); - if (ctrlStretchy(bc)) { + uiWindowsControlMinimumSize(uiWindowsControl(bc.c), &minimumWidth, &minimumHeight); + if (bc.stretchy) { nStretchy++; if (maxStretchyWidth < minimumWidth) maxStretchyWidth = minimumWidth; @@ -93,10 +193,10 @@ static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width if (b->vertical) { if (*width < minimumWidth) *width = minimumWidth; - if (!ctrlStretchy(bc)) + if (!bc.stretchy) *height += minimumHeight; } else { - if (!ctrlStretchy(bc)) + if (!bc.stretchy) *width += minimumWidth; if (*height < minimumHeight) *height = minimumHeight; @@ -108,156 +208,57 @@ static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width *height += nStretchy * maxStretchyHeight; else *width += nStretchy * maxStretchyWidth; - - uiWindowsFreeSizing(dself); } -static void boxRelayout(uiWindowsControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height) +static void uiBoxMinimumSizeChanged(uiWindowsControl *c) { - uiBox *b = uiBox(c); - struct child *bc; - int xpadding, ypadding; - uintmax_t nStretchy; - intmax_t stretchywid, stretchyht; - uintmax_t i; - intmax_t minimumWidth, minimumHeight; - uiWindowsSizing *d; + uiBox *t = uiBox(c); - uiWindowsEnsureMoveWindowDuringResize(b->hwnd, x, y, width, height); - - if (b->controls->len == 0) + if (uiWindowsControlTooSmall(uiWindowsControl(b))) { + uiWindowsControlContinueMinimumSizeChanged(uiWindowsControl(b)); return; - - d = uiWindowsNewSizing(b->hwnd); - - // -1) get this Box's padding - xpadding = 0; - ypadding = 0; - if (b->padded) { - xpadding = d->XPadding; - ypadding = d->YPadding; } - - // 0) inset the available rect by the needed padding - // TODO this is incorrect if any controls are hidden - if (b->vertical) - height -= (b->controls->len - 1) * ypadding; - else - width -= (b->controls->len - 1) * xpadding; - - // 1) get width and height of non-stretchy controls - // this will tell us how much space will be left for stretchy controls - stretchywid = width; - stretchyht = height; - nStretchy = 0; - for (i = 0; i < b->controls->len; i++) { - bc = ptrArrayIndex(b->controls, struct child *, i); - if (!childVisible(bc)) - continue; - if (ctrlStretchy(bc)) { - nStretchy++; - continue; - } - childMinimumSize(bc, d, &minimumWidth, &minimumHeight); - if (b->vertical) { // all controls have same width - ctrlSetWidth(bc, width); - ctrlSetHeight(bc, minimumHeight); - stretchyht -= minimumHeight; - } else { // all controls have same height - ctrlSetWidth(bc, minimumWidth); - ctrlSetHeight(bc, height); - stretchywid -= minimumWidth; - } - } - - // 2) now get the size of stretchy controls - if (nStretchy != 0) - if (b->vertical) - stretchyht /= nStretchy; - else - stretchywid /= nStretchy; - for (i = 0; i < b->controls->len; i++) { - bc = ptrArrayIndex(b->controls, struct child *, i); - if (!childVisible(bc)) - continue; - if (ctrlStretchy(bc)) { - ctrlSetWidth(bc, stretchywid); - ctrlSetHeight(bc, stretchyht); - } - } - - // 3) now we can position controls - // first, make relative to the top-left corner of the container - x = 0; - y = 0; - for (i = 0; i < b->controls->len; i++) { - bc = ptrArrayIndex(b->controls, struct child *, i); - if (!childVisible(bc)) - continue; - childRelayout(bc, x, y, ctrlWidth(bc), ctrlHeight(bc)); - if (b->vertical) - y += ctrlHeight(bc) + ypadding; - else - x += ctrlWidth(bc) + xpadding; - } - - uiWindowsFreeSizing(d); + boxRelayout(b); } -static void boxContainerUpdateState(uiControl *c) -{ - uiBox *b = uiBox(c); - struct child *bc; - uintmax_t i; +uiWindowsControlDefaultLayoutRect(uiBox) +uiWindowsControlDefaultAssignControlIDZorder(uiBox) - for (i = 0; i < b->controls->len; i++) { - bc = ptrArrayIndex(b->controls, struct child *, i); - childUpdateState(bc); - } -} - -static void redoControlIDsZOrder(uiBox *b) +static void boxArrangeChildren(uiBox *b) { - struct child *bc; LONG_PTR controlID; HWND insertAfter; uintmax_t i; controlID = 100; insertAfter = NULL; - for (i = 0; i < b->controls->len; i++) { - bc = ptrArrayIndex(b->controls, struct child *, i); - childAssignControlIDZOrder(bc, &controlID, &insertAfter); - } -} - -static void boxArrangeChildrenControlIDsZOrder(uiWindowsControl *c) -{ - uiBox *b = uiBox(c); - - redoControlIDsZOrder(b); + for (const struct boxChild &bc : *(b->controls)) + uiWindowsControlAssignControlIDZOrder(uiWindwsControl(bc.c), &controlID, &insertAfter); } void uiBoxAppend(uiBox *b, uiControl *c, int stretchy) { - struct child *bc; + struct boxChild bc; - bc = newChild(c, uiControl(b), b->hwnd); - ctrlSetStretchy(bc, stretchy); - ptrArrayAppend(b->controls, bc); - redoControlIDsZOrder(b); - uiWindowsControlQueueRelayout(uiWindowsControl(b)); + bc.c = c; + bc.stretchy = stretchy; + uiControlSetParent(bc.c, uiControl(b)); + uiWindowsControlSetParentHWND(uiWindowsControl(bc.c), b->hwnd); + b->controls->push_back(bc); + boxArrangeChildren(b); + uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); } void uiBoxDelete(uiBox *b, uintmax_t index) { - struct child *bc; + uiControl *c; - bc = ptrArrayIndex(b->controls, struct child *, index); - ptrArrayDelete(b->controls, index); - childRemove(bc); - redoControlIDsZOrder(b); - uiWindowsControlQueueRelayout(uiWindowsControl(b)); + c = (*(b->controls))[index].c; + uiControlSetParent(c, NULL); + uiWindowsControlSetParentHWND(uiWindowsControl(c), NULL); + b->controls->erase(b->controls->begin() + Index); + boxArrangeChildren(b); + uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); } int uiBoxPadded(uiBox *b) @@ -268,25 +269,25 @@ int uiBoxPadded(uiBox *b) void uiBoxSetPadded(uiBox *b, int padded) { b->padded = padded; - uiWindowsControlQueueRelayout(uiWindowsControl(b)); + uiWindowsControlMinimumSizeChanged(uiWindowsControl(b)); +} + +static void onResize(uiControl *c) +{ + boxRelayout(uiBox(c)); } static uiBox *finishNewBox(int vertical) { uiBox *b; - b = (uiBox *) uiNewControl(uiBox); + uiWindowsNewControl(uiBox, b); - b->hwnd = newContainer(); + b->hwnd = uiWIndowsMakeContainer(uiControl(b), onResize); b->vertical = vertical; b->controls = newPtrArray(); - uiWindowsFinishNewControl(b, uiBox); - uiControl(b)->ContainerUpdateState = boxContainerUpdateState; - uiWindowsControl(b)->Relayout = boxRelayout; - uiWindowsControl(b)->ArrangeChildrenControlIDsZOrder = boxArrangeChildrenControlIDsZOrder; - return b; }