// 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 groupMargins(uiGroup *g, int *mx, int *mtop, int *mbottom) { uiWindowsSizing sizing; *mx = groupUnmarginedXMargin; *mtop = groupUnmarginedYMarginTop; *mbottom = groupUnmarginedYMarginBottom; if (g->margined) { *mx = groupXMargin; *mtop = groupYMarginTop; *mbottom = groupYMarginBottom; } uiWindowsGetSizing(g->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, mx, mtop); uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, mbottom); }
static BOOL onWM_NOTIFY(uiControl *c, HWND hwnd, NMHDR *nmhdr, LRESULT *lResult) { uiColorButton *b = uiColorButton(c); NMCUSTOMDRAW *nm = (NMCUSTOMDRAW *) nmhdr; RECT r; uiWindowsSizing sizing; int x, y; if (nmhdr->code != NM_CUSTOMDRAW) return FALSE; // and allow the button to draw its background if (nm->dwDrawStage != CDDS_PREPAINT) return FALSE; // TODO use Direct2D? either way, draw alpha uiWindowsEnsureGetClientRect(b->hwnd, &r); uiWindowsGetSizing(b->hwnd, &sizing); x = 3; // should be enough y = 3; uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); r.left += x; r.top += y; r.right -= x; r.bottom -= y; // TODO error check #define comp(x) ((BYTE) (x * 255)) // TODO free brush FillRect(nm->hdc, &r, CreateSolidBrush(RGB(comp(b->r), comp(b->g), comp(b->b)))); #undef comp // skip default processing (don't draw text) *lResult = CDRF_SKIPDEFAULT; return TRUE; }
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 uiMultilineEntryMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) { uiMultilineEntry *e = uiMultilineEntry(c); uiWindowsSizing sizing; int x, y; x = entryWidth; y = entryHeight; uiWindowsGetSizing(e->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); *width = x; *height = y; }
static void uiEditableComboboxMinimumSize(uiWindowsControl *cc, int *width, int *height) { uiEditableCombobox *c = uiEditableCombobox(cc); uiWindowsSizing sizing; int x, y; x = comboboxWidth; y = comboboxHeight; uiWindowsGetSizing(c->hwnd, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); *width = x; *height = y; }
static void windowMargins(uiWindow *w, int *mx, int *my) { uiWindowsSizing sizing; *mx = 0; *my = 0; if (!w->margined) return; uiWindowsGetSizing(w->hwnd, &sizing); *mx = windowMargin; *my = windowMargin; uiWindowsSizingDlgUnitsToPixels(&sizing, mx, my); }
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 uiSpinboxMinimumSize(uiWindowsControl *c, int *width, int *height) { uiSpinbox *s = uiSpinbox(c); uiWindowsSizing sizing; int x, y; x = entryWidth; y = entryHeight; // note that we go by the edit here uiWindowsGetSizing(s->edit, &sizing); uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); *width = x; *height = y; }
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; } }