// TODO check widths static void uiColorButtonMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) { uiColorButton *b = uiColorButton(c); SIZE size; uiWindowsSizing sizing; int y; // try the comctl32 version 6 way size.cx = 0; // explicitly ask for ideal size size.cy = 0; if (SendMessageW(b->hwnd, BCM_GETIDEALSIZE, 0, (LPARAM) (&size)) != FALSE) { *width = size.cx; *height = size.cy; return; } // that didn't work; fall back to using Microsoft's metrics // Microsoft says to use a fixed width for all buttons; this isn't good enough // use the text width instead, with some edge padding *width = uiWindowsWindowTextWidth(b->hwnd) + (2 * GetSystemMetrics(SM_CXEDGE)); y = buttonHeight; uiWindowsGetSizing(b->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); *height = y; }
static void uiRadioButtonsMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) { uiRadioButtons *r = uiRadioButtons(c); intmax_t wid, maxwid; uiWindowsSizing sizing; int x, y; if (r->hwnds->size() == 0) { *width = 0; *height = 0; return; } maxwid = 0; for (const HWND &hwnd : *(r->hwnds)) { wid = uiWindowsWindowTextWidth(hwnd); if (maxwid < wid) maxwid = wid; } x = radiobuttonXFromLeftOfBoxToLeftOfLabel; y = radiobuttonHeight; // get it for the radio button itself since that's what counts // TODO for all of them? uiWindowsGetSizing((*(r->hwnds))[0], &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); *width = x + maxwid; *height = y * r->hwnds->size(); }
static void uiFormMinimumSize(uiWindowsControl *c, int *width, int *height) { uiForm *f = uiForm(c); int xpadding, ypadding; int nStretchy; // these two contain the largest minimum width and height of all stretchy controls in the form // all stretchy controls will use this value to determine the final minimum size int maxLabelWidth, maxControlWidth; int maxStretchyHeight; int labelwid; int i; int minimumWidth, minimumHeight; int nVisible; uiWindowsSizing sizing; *width = 0; *height = 0; if (f->controls->size() == 0) return; // 0) get this Form's padding formPadding(f, &xpadding, &ypadding); // 1) determine the longest width of all controls and labels; add in the height of non-stretchy controls and get (but not add in) the largest heights of stretchy controls // we still add in like direction of stretchy controls nStretchy = 0; maxLabelWidth = 0; maxControlWidth = 0; maxStretchyHeight = 0; nVisible = 0; for (const struct formChild &fc : *(f->controls)) { if (!uiControlVisible(fc.c)) continue; nVisible++; labelwid = uiWindowsWindowTextWidth(fc.label); if (maxLabelWidth < labelwid) maxLabelWidth = labelwid; uiWindowsControlMinimumSize(uiWindowsControl(fc.c), &minimumWidth, &minimumHeight); if (fc.stretchy) { nStretchy++; if (maxStretchyHeight < minimumHeight) maxStretchyHeight = minimumHeight; } if (maxControlWidth < minimumWidth) maxControlWidth = minimumWidth; if (!fc.stretchy) *height += minimumHeight; } if (nVisible == 0) // nothing to show; return 0x0 return; *width += maxLabelWidth + maxControlWidth; // 2) outset the desired rect with the needed padding *width += xpadding; *height += (nVisible - 1) * ypadding; // 3) and now we can add in stretchy controls *height += nStretchy * maxStretchyHeight; }
static void uiCheckboxMinimumSize(uiWindowsControl *cc, intmax_t *width, intmax_t *height) { uiCheckbox *c = uiCheckbox(cc); uiWindowsSizing sizing; int x, y; x = checkboxXFromLeftOfBoxToLeftOfLabel; y = checkboxHeight; uiWindowsGetSizing(c->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); *width = x + uiWindowsWindowTextWidth(c->hwnd); *height = y; }
static void uiGroupMinimumSize(uiWindowsControl *c, int *width, int *height) { uiGroup *g = uiGroup(c); int mx, mtop, mbottom; int labelWidth; *width = 0; *height = 0; if (g->child != NULL) uiWindowsControlMinimumSize(uiWindowsControl(g->child), width, height); labelWidth = uiWindowsWindowTextWidth(g->hwnd); if (*width < labelWidth) // don't clip the label; it doesn't ellipsize *width = labelWidth; groupMargins(g, &mx, &mtop, &mbottom); *width += 2 * mx; *height += mtop + mbottom; }
static void formRelayout(uiForm *f) { RECT r; int x, y, width, height; int xpadding, ypadding; int nStretchy; int labelwid, stretchyht; int thiswid; int i; int minimumWidth, minimumHeight; uiWindowsSizing sizing; int labelht, labelyoff; int nVisible; if (f->controls->size() == 0) return; uiWindowsEnsureGetClientRect(f->hwnd, &r); x = r.left; y = r.top; width = r.right - r.left; height = r.bottom - r.top; // 0) get this Form's padding formPadding(f, &xpadding, &ypadding); // 1) get width of labels and height of non-stretchy controls // this will tell us how much space will be left for controls labelwid = 0; stretchyht = height; nStretchy = 0; nVisible = 0; for (struct formChild &fc : *(f->controls)) { if (!uiControlVisible(fc.c)) { ShowWindow(fc.label, SW_HIDE); continue; } ShowWindow(fc.label, SW_SHOW); nVisible++; thiswid = uiWindowsWindowTextWidth(fc.label); if (labelwid < thiswid) labelwid = thiswid; if (fc.stretchy) { nStretchy++; continue; } uiWindowsControlMinimumSize(uiWindowsControl(fc.c), &minimumWidth, &minimumHeight); fc.height = minimumHeight; stretchyht -= minimumHeight; } if (nVisible == 0) // nothing to do return; // 2) inset the available rect by the needed padding width -= xpadding; height -= (nVisible - 1) * ypadding; stretchyht -= (nVisible - 1) * ypadding; // 3) now get the width of controls and the height of stretchy controls width -= labelwid; if (nStretchy != 0) { stretchyht /= nStretchy; for (struct formChild &fc : *(f->controls)) { if (!uiControlVisible(fc.c)) continue; if (fc.stretchy) fc.height = stretchyht; } } // 4) get the y offset labelyoff = labelYOffset; uiWindowsGetSizing(f->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &labelyoff); // 5) now we can position controls // first, make relative to the top-left corner of the container // also prefer left alignment on Windows x = labelwid + xpadding; y = 0; for (const struct formChild &fc : *(f->controls)) { if (!uiControlVisible(fc.c)) continue; labelht = labelHeight; uiWindowsGetSizing(f->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &labelht); uiWindowsEnsureMoveWindowDuringResize(fc.label, 0, y + labelyoff - sizing.InternalLeading, labelwid, labelht); uiWindowsEnsureMoveWindowDuringResize((HWND) uiControlHandle(fc.c), x, y, width, fc.height); y += fc.height + ypadding; } }