From fa88467609ae7e12a8df1af6b54ae1bba7016325 Mon Sep 17 00:00:00 2001 From: Pietro Gagliardi Date: Fri, 29 Apr 2016 14:12:01 -0400 Subject: [PATCH] Migrated the rest of the controls. Ready for this build to completely fall apart? --- windows/radiobuttons.cpp | 82 +++++++++++++++++++-------------- windows/separator.cpp | 19 ++++---- windows/slider.cpp | 34 +++++++++----- windows/spinbox.cpp | 99 ++++++++++++++++++++++------------------ 4 files changed, 135 insertions(+), 99 deletions(-) diff --git a/windows/radiobuttons.cpp b/windows/radiobuttons.cpp index bac1998d..50bff56b 100644 --- a/windows/radiobuttons.cpp +++ b/windows/radiobuttons.cpp @@ -14,13 +14,6 @@ struct uiRadioButtons { std::vector *hwnds; // of the buttons }; -static void onDestroy(uiRadioButtons *); - -uiWindowsDefineControlWithOnDestroy( - uiRadioButtons, // type name - onDestroy(me); // on destroy -) - static BOOL onWM_COMMAND(uiControl *c, HWND clicked, WORD code, LRESULT *lResult) { uiRadioButtons *r = uiRadioButtons(c); @@ -39,49 +32,71 @@ static BOOL onWM_COMMAND(uiControl *c, HWND clicked, WORD code, LRESULT *lResult return TRUE; } -static void onDestroy(uiRadioButtons *r) +static void uiRadioButtonsDestroy(uiControl *c) { + uiRadioButtons *r = uiRadioButtons(c); + for (const HWND &hwnd : *(r->hwnds)) { uiWindowsUnregisterWM_COMMANDHandler(hwnd); uiWindowsEnsureDestroyWindow(hwnd); } delete r->hwnds; + uiWindowsEnsureDestroyWindow(r->hwnd); + uiFreeControl(uiControl(r)); } +// TODO SyncEnableState +uiWindowsControlAllDefaultsExceptDestroy(uiRadioButtons) + // from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing #define radiobuttonHeight 10 // from http://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx #define radiobuttonXFromLeftOfBoxToLeftOfLabel 12 -static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height) +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; } - *width = uiWindowsDlgUnitsToX(radiobuttonXFromLeftOfBoxToLeftOfLabel, d->BaseX) + maxwid; - *height = uiWindowsDlgUnitsToY(radiobuttonHeight, d->BaseY) * r->hwnds->size(); + + 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 radiobuttonsRelayout(uiWindowsControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height) +static void radiobuttonsRelayout(uiRadioButtons *r) { - uiRadioButtons *r = uiRadioButtons(c); - uiWindowsSizing *d; + RECT client; intmax_t height1; intmax_t h; + intmax_t x, y, width, height; - uiWindowsEnsureMoveWindowDuringResize(r->hwnd, x, y, width, height); - - x = 0; - y = 0; - d = uiWindowsNewSizing(r->hwnd); - height1 = uiWindowsDlgUnitsToY(radiobuttonHeight, d->BaseY); - uiWindowsFreeSizing(d); + uiWindowsEnsureGetClientRect(r->hwnd, &client); + x = client.left; + y = client.top; + width = client.right - client.left; + height = client.bottom - client.top; + // TODO compute the real height1 + height1 = 25; for (const HWND &hwnd : *(r->hwnds)) { h = height1; if (h > height) // clip to height @@ -96,20 +111,15 @@ static void radiobuttonsRelayout(uiWindowsControl *c, intmax_t x, intmax_t y, in } } -// TODO commit enable/disable - -static void redoControlIDsZOrder(uiRadioButtons *r) +static void radiobuttonsArrangeChildren(uiRadioButtons *r) { LONG_PTR controlID; HWND insertAfter; controlID = 100; insertAfter = NULL; - for (const HWND &hwnd : *(r->hwnds)) { - uiWindowsEnsureAssignControlIDZOrder(hwnd, controlID, insertAfter); - controlID++; - insertAfter = hwnd; - } + for (const HWND &hwnd : *(r->hwnds)) + uiWindowsEnsureAssignControlIDZOrder(hwnd, &controlID, &insertAfter); } void uiRadioButtonsAppend(uiRadioButtons *r, const char *text) @@ -134,22 +144,24 @@ void uiRadioButtonsAppend(uiRadioButtons *r, const char *text) uiWindowsEnsureSetParent(hwnd, r->hwnd); uiWindowsRegisterWM_COMMANDHandler(hwnd, onWM_COMMAND, uiControl(r)); r->hwnds->push_back(hwnd); - redoControlIDsZOrder(r); + radiobuttonsArrangeChildren(r); uiWindowsControlMinimumSizeChanged(uiWindowsControl(r)); } +static void onResize(uiControl *c) +{ + radiobuttonsRelayout(uiRadioButtons(c)); +} + uiRadioButtons *uiNewRadioButtons(void) { uiRadioButtons *r; - r = (uiRadioButtons *) uiNewControl(uiRadioButtons); + uiWindowsNewControl(uiRadioButtons, r); - r->hwnd = newContainer(); + r->hwnd = uiWindowsMakeContainer(uiControl(r), onResize); r->hwnds = new std::vector; - uiWindowsFinishNewControl(r, uiRadioButtons); - uiWindowsControl(r)->Relayout = radiobuttonsRelayout; - return r; } diff --git a/windows/separator.cpp b/windows/separator.cpp index d3c03fae..9c4be072 100644 --- a/windows/separator.cpp +++ b/windows/separator.cpp @@ -10,24 +10,29 @@ struct uiSeparator { HWND hwnd; }; -uiWindowsDefineControl( - uiSeparator // type name -) +uiWindowsControlAllDefaults(uiSeparator) // via https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx #define separatorHeight 1 -static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height) +static void uiSeparatorMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) { + uiSeparator *s = uiSeparator(c); + uiWindowsSizing sizing; + int y; + *width = 1; // TODO - *height = uiWindowsDlgUnitsToY(separatorHeight, d->BaseY); + y = separatorHeight; + uiWindowsGetSizing(s->hwnd, &sizing); + uiWindowsSizingDlgUnitsToPixels(&sizing, NULL, &y); + *height = y; } uiSeparator *uiNewHorizontalSeparator(void) { uiSeparator *s; - s = (uiSeparator *) uiNewControl(uiSeparator); + uiWindowsNewControl(uiSeparator, s); s->hwnd = uiWindowsEnsureCreateControlHWND(0, L"static", L"", @@ -35,7 +40,5 @@ uiSeparator *uiNewHorizontalSeparator(void) hInstance, NULL, TRUE); - uiWindowsFinishNewControl(s, uiSeparator); - return s; } diff --git a/windows/slider.cpp b/windows/slider.cpp index f76664f8..cc9aacb6 100644 --- a/windows/slider.cpp +++ b/windows/slider.cpp @@ -8,11 +8,6 @@ struct uiSlider { void *onChangedData; }; -uiWindowsDefineControlWithOnDestroy( - uiSlider, // type name - uiWindowsUnregisterWM_HSCROLLHandler(me->hwnd); // on destroy -) - static BOOL onWM_HSCROLL(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) { uiSlider *s = uiSlider(c); @@ -22,14 +17,33 @@ static BOOL onWM_HSCROLL(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) return TRUE; } +static void uiSliderDestroy(uiControl *s) +{ + uiSlider *s = uiSlider(c); + + uiWindowsUnregisterWM_HSCROLLHandler(s->hwnd); + uiWindowsEnsureDestroyWindow(s->hwnd); + uiFreeControl(uiControl(s)); +} + +uiWindowsControlAllDefaultsExceptDestroy(uiSlider); + // from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing #define sliderWidth 107 /* this is actually the shorter progress bar width, but Microsoft doesn't indicate a width */ #define sliderHeight 15 -static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height) +static void uiSliderMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) { - *width = uiWindowsDlgUnitsToX(sliderWidth, d->BaseX); - *height = uiWindowsDlgUnitsToY(sliderHeight, d->BaseY); + uiSlider *s = uiSlider(c); + uiWindowsSizing sizing; + int x, y; + + x = sliderWidth; + y = sliderHeight; + uiWindowsGetSizing(s->hwnd, &sizing); + uiWindowsSizingDlgUnitsToPixels(&sizing, &x, &y); + *width = x; + *height = y; } static void defaultOnChanged(uiSlider *s, void *data) @@ -58,7 +72,7 @@ uiSlider *uiNewSlider(intmax_t min, intmax_t max) { uiSlider *s; - s = (uiSlider *) uiNewControl(uiSlider); + uiSliderNewControl(uiSlider, s); s->hwnd = uiWindowsEnsureCreateControlHWND(0, TRACKBAR_CLASSW, L"", @@ -73,7 +87,5 @@ uiSlider *uiNewSlider(intmax_t min, intmax_t max) SendMessageW(s->hwnd, TBM_SETRANGEMAX, (WPARAM) TRUE, (LPARAM) max); SendMessageW(s->hwnd, TBM_SETPOS, (WPARAM) TRUE, (LPARAM) min); - uiWindowsFinishNewControl(s, uiSlider); - return s; } diff --git a/windows/spinbox.cpp b/windows/spinbox.cpp index fc986ec8..fc9a4779 100644 --- a/windows/spinbox.cpp +++ b/windows/spinbox.cpp @@ -4,20 +4,13 @@ struct uiSpinbox { uiWindowsControl c; HWND hwnd; + HWND edit; HWND updown; void (*onChanged)(uiSpinbox *, void *); void *onChangedData; BOOL inhibitChanged; - HWND parent; }; -static void onDestroy(uiSpinbox *); - -uiWindowsDefineControlWithOnDestroy( - uiSpinbox, // type name - onDestroy(me); // on destroy -) - // utility functions static intmax_t value(uiSpinbox *s) @@ -52,7 +45,7 @@ static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) // However, if we just have the code below, the up-down will catch the bare - and reject it. // Let's fix that. // This won't handle leading spaces, but spaces aren't allowed *anyway*. - wtext = windowText(s->hwnd); + wtext = windowText(s->edit); if (wcscmp(wtext, L"-") == 0) { uiFree(wtext); return TRUE; @@ -64,29 +57,49 @@ static BOOL onWM_COMMAND(uiControl *c, HWND hwnd, WORD code, LRESULT *lResult) return TRUE; } -static void onDestroy(uiSpinbox *s) -{ - uiWindowsUnregisterWM_COMMANDHandler(s->hwnd); - uiWindowsEnsureDestroyWindow(s->updown); -} - -static void spinboxCommitSetParent(uiWindowsControl *c, HWND parent) +static void uiSpinboxDestroy(uiControl *c) { uiSpinbox *s = uiSpinbox(c); - s->parent = parent; - uiWindowsEnsureSetParent(s->hwnd, s->parent); - uiWindowsEnsureSetParent(s->updown, s->parent); + uiWindowsUnregisterWM_COMMANDHandler(s->hwnd); + uiWindowsEnsureDestroyWindow(s->updown); + uiWindowsEnsureDestroyWindow(s->edit); + uiWindowsEnsureDestroyWindow(s->hwnd); + uiFreeControl(uiControl(s)); } +// TODO SyncEnableState +uiWindowsControlAllDefaultsExceptDestroy(uiSpinbox) + // from http://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing +// TODO reduce this? #define entryWidth 107 /* this is actually the shorter progress bar width, but Microsoft only indicates as wide as necessary */ #define entryHeight 14 -static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height) +static void uiSpinboxMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) { - *width = uiWindowsDlgUnitsToX(entryWidth, d->BaseX); - *height = uiWindowsDlgUnitsToY(entryHeight, d->BaseY); + 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 spinboxArrangeChildren(uiSpinbox *s) +{ + LONG_PTR controlID; + HWND insertAfter; + + controlID = 100; + insertAfter = NULL; + uiWindowsEnsureAssignControlIDZOrder(s->edit, &controlID, &insertAfter); + uiWindowsEnsureAssignControlIDZOrder(s->updown, &controlID, &insertAfter); } // an up-down control will only properly position itself the first time @@ -113,39 +126,32 @@ static void recreateUpDown(uiSpinbox *s) WS_CHILD | UDS_ALIGNRIGHT | UDS_ARROWKEYS | UDS_HOTTRACK | UDS_NOTHOUSANDS | UDS_SETBUDDYINT, // this is important; it's necessary for autosizing to work 0, 0, 0, 0, - s->parent, NULL, hInstance, NULL); + s->hwnd, NULL, hInstance, NULL); if (s->updown == NULL) logLastError(L"error creating updown"); - SendMessageW(s->updown, UDM_SETBUDDY, (WPARAM) (s->hwnd), 0); + SendMessageW(s->updown, UDM_SETBUDDY, (WPARAM) (s->edit), 0); if (preserve) { SendMessageW(s->updown, UDM_SETRANGE32, (WPARAM) min, (LPARAM) max); SendMessageW(s->updown, UDM_SETPOS32, 0, (LPARAM) current); } - // preserve the z-order - uiWindowsRearrangeControlIDsZOrder(uiControl(s)); + // preserve the Z-order + spinboxArrangeChildren(s); // TODO properly show/enable ShowWindow(s->updown, SW_SHOW); s->inhibitChanged = FALSE; } -static void spinboxRelayout(uiWindowsControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height) +static void spinboxRelayout(uiSpinbox *s) { uiSpinbox *s = uiSpinbox(c); + RECT r; - uiWindowsEnsureMoveWindowDuringResize(s->hwnd, x, y, width, height); + // make the edit fill the container first; the new updown will resize it + uiWindowsEnsureGetClientRect(s->hwnd, &r); + uiWindowsEnsureMoveWindowDuringResize(s->edit, r.left, r.top, r.right - r.left, r.bottom - r.top); recreateUpDown(s); } -static void spinboxAssignControlIDZOrder(uiWindowsControl *c, LONG_PTR *controlID, HWND *insertAfter) -{ - uiSpinbox *s = uiSpinbox(c); - - uiWindowsEnsureAssignControlIDZOrder(s->hwnd, *controlID, *insertAfter); - uiWindowsEnsureAssignControlIDZOrder(s->updown, *controlID + 1, s->hwnd); - *controlID += 2; - *insertAfter = s->updown; -} - static void defaultOnChanged(uiSpinbox *s, void *data) { // do nothing @@ -169,6 +175,11 @@ void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *, void *), void *data s->onChangedData = data; } +static void onResize(uiControl *c) +{ + spinboxRelayout(uiSpinbox(c)); +} + uiSpinbox *uiNewSpinbox(intmax_t min, intmax_t max) { uiSpinbox *s; @@ -176,14 +187,17 @@ uiSpinbox *uiNewSpinbox(intmax_t min, intmax_t max) if (min >= max) complain("error: min >= max in uiNewSpinbox()"); - s = (uiSpinbox *) uiNewControl(uiSpinbox); + uiWindowsNewControl(uiSpinbox, s); - s->hwnd = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, + s->hwnd = uiWindowsMakeContainer(uiControl(s), onResize); + + s->edit = uiWindowsEnsureCreateControlHWND(WS_EX_CLIENTEDGE, L"edit", L"", // don't use ES_NUMBER; it doesn't allow typing in a leading - ES_AUTOHSCROLL | ES_LEFT | ES_NOHIDESEL | WS_TABSTOP, hInstance, NULL, TRUE); + uiWindowsEnsureSetParent(s->edit, s->hwnd); uiWindowsRegisterWM_COMMANDHandler(s->hwnd, onWM_COMMAND, uiControl(s)); uiSpinboxOnChanged(s, defaultOnChanged, NULL); @@ -195,10 +209,5 @@ uiSpinbox *uiNewSpinbox(intmax_t min, intmax_t max) SendMessageW(s->updown, UDM_SETPOS32, 0, (LPARAM) min); s->inhibitChanged = FALSE; - uiWindowsFinishNewControl(s, uiSpinbox); - uiWindowsControl(s)->CommitSetParent = spinboxCommitSetParent; - uiWindowsControl(s)->Relayout = spinboxRelayout; - uiWindowsControl(s)->AssignControlIDZOrder = spinboxAssignControlIDZOrder; - return s; }