diff --git a/common/uipriv.h b/common/uipriv.h index 38a546ca..bb6e8b38 100644 --- a/common/uipriv.h +++ b/common/uipriv.h @@ -16,9 +16,6 @@ extern void uiFree(void *); extern void complain(const char *, ...); -extern void osCommitEnable(uiControl *); -extern void osCommitDisable(uiControl *); - // control.c extern uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr); diff --git a/ui_windows.h b/ui_windows.h index 3f2cbd6c..2722d04f 100644 --- a/ui_windows.h +++ b/ui_windows.h @@ -211,10 +211,8 @@ struct uiWindowsSizing { LONG InternalLeading; }; _UI_EXTERN void uiWindowsGetSizing(HWND hwnd, uiWindowsSizing *sizing); -_UI_EXTERN void uiWindowsSizingDlgUnitsToPixels(HWND hwnd, uiWindowsSIzing *sizing, int *x, int *y); -// TODO make private -#define uiWindowsDlgUnitsToX(dlg, baseX) MulDiv((dlg), baseX, 4) -#define uiWindowsDlgUnitsToY(dlg, baseY) MulDiv((dlg), baseY, 8) +_UI_EXTERN void uiWindowsSizingDlgUnitsToPixels(uiWindowsSIzing *sizing, int *x, int *y); +_UI_EXTERN void uiWindowsSizingStandardPadding(uiWindowsSizing *sizing, int *x, int *y); // TODO document _UI_EXTERN HWND uiWindowsMakeContainer(void (*onResize)(void *data), void *data); diff --git a/windows/GNUfiles.mk b/windows/GNUfiles.mk index a539d768..d88d7486 100644 --- a/windows/GNUfiles.mk +++ b/windows/GNUfiles.mk @@ -33,8 +33,8 @@ CXXFILES += \ windows/parent.cpp \ windows/progressbar.cpp \ windows/radiobuttons.cpp \ - windows/resize.cpp \ windows/separator.cpp \ + windows/sizing.cpp \ windows/slider.cpp \ windows/spinbox.cpp \ windows/stddialogs.cpp \ diff --git a/windows/control.cpp b/windows/control.cpp index f35b794a..aa67fdb1 100644 --- a/windows/control.cpp +++ b/windows/control.cpp @@ -1,6 +1,32 @@ // 16 august 2015 #include "uipriv_windows.hpp" +void uiWindowsControlSyncEnableState(uiWindowsControl *c, int enabled) +{ + (*(c->SyncEnableState))(c, enabled); +} + +void uiWindowsControlSetParentHWND(uiWindowsControl *c, HWND parent) +{ + (*(c->SetParentHWND))(c, parent); +} + +void uiWindowsControlMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height) +{ + (*(c->MinimumSize))(c, widdth, height); +} + +void uiWindowsControlChildMinimumSizeChanged(uiWIndowsControl *c) +{ + (*(c->ChildMinimumSizeChanged))(c); +} + +// TODO get the correct argument names from existing implemenations for here and ui_windows.h +void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *c, LONG_PTR *cid, HWND *zorder) +{ + (*(c->AssignControlIDZorder))(c, cID, zorder); +} + HWND uiWindowsEnsureCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCWSTR lpWindowName, DWORD dwStyle, HINSTANCE hInstance, LPVOID lpParam, BOOL useStandardControlFont) { HWND hwnd; @@ -24,43 +50,6 @@ HWND uiWindowsEnsureCreateControlHWND(DWORD dwExStyle, LPCWSTR lpClassName, LPCW return hwnd; } -static void defaultCommitShow(uiControl *c) -{ - ShowWindow((HWND) uiControlHandle(c), SW_SHOW); -} - -static void defaultCommitHide(uiControl *c) -{ - ShowWindow((HWND) uiControlHandle(c), SW_HIDE); -} - -void osCommitEnable(uiControl *c) -{ - EnableWindow((HWND) uiControlHandle(c), TRUE); -} - -void osCommitDisable(uiControl *c) -{ - EnableWindow((HWND) uiControlHandle(c), FALSE); -} - -void uiWindowsFinishControl(uiControl *c) -{ - c->CommitShow = defaultCommitShow; - c->CommitHide = defaultCommitHide; -} - -void uiWindowsRearrangeControlIDsZOrder(uiControl *c) -{ - uiWindowsControl *wc; - - c = uiControlParent(c); - if (c == NULL) - return; - wc = uiWindowsControl(c); - (*(wc->ArrangeChildrenControlIDsZOrder))(wc); -} - // choose a value distinct from uiWindowSignature #define uiWindowsControlSignature 0x4D53576E @@ -68,3 +57,12 @@ uiWindowsControl *uiWindowsNewControl(size_t n, uint32_t typesig, const char *ty { return uiWindowsControl(uiAllocControl(n, uiWindowsControlSignature, typesig, typenamestr)); } + +void uiWindowsControlNotifyMinimumSizeChanged(uiWindowsControl *c) +{ + uiControl *parent; + + parent = uiControlParent(uiControl(c)); + if (parent != NULL) + uiWindowsControlChildMinimumSizeChanged(uiWindowsControl(parent)); +} diff --git a/windows/resize.cpp b/windows/resize.cpp deleted file mode 100644 index da8bd06d..00000000 --- a/windows/resize.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// 14 may 2015 -#include "uipriv_windows.hpp" - -static std::map resizes; - -// TODO clicking buttons doesn't get rid of anything? -void uiWindowsControlQueueRelayout(uiWindowsControl *c) -{ - HWND hwnd; - HWND parent; - uintmax_t i; - - // resizing a control requires us to reocmpute the sizes of everything in the top-level window - hwnd = (HWND) uiControlHandle(uiControl(c)); - // TODO what if this is toplevel - parent = parentToplevel(hwnd); - if (parent == utilWindow) // not in a parent - return; - c = uiWindowsControl(SendMessageW(parent, msgGetuiWindow, 0, 0)); - resizes[c] = true; -} - -void doResizes(void) -{ - uiWindowsControl *w; - HWND hwnd; - RECT r; - - for (const auto &iter : resizes) { - w = iter.first; - // don't clip content if content dynamically changed (tab page changed, etc.) - // do this BEFORE removing w from the queue list to avoid double queueing - ensureMinimumWindowSize(uiWindow(w)); - hwnd = (HWND) uiControlHandle(uiControl(w)); - if (GetClientRect(hwnd, &r) == 0) { - logLastError(L"error getting uiWindow client rect"); - // give up on this one; move on to the next one - continue; - } - (*(w->Relayout))(w, r.left, r.top, r.right - r.left, r.bottom - r.top); - // we used SWP_NOREDRAW; we need to queue a redraw ourselves - // force all controls to be redrawn; this fixes things like the date-time picker's up-down not showing up until hovered over (and bypasses complications caused by WS_CLIPCHILDREN and WS_CLIPSIBLINGS, which we don't use but other controls might) - if (RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN) == 0) - logLastError(L"error redrawing controls after a resize"); // and keep going anyway - } - // and wipe the list - resizes.clear(); -} - -/////////////////////// -// TODO REEVALUATE EVERYTHING BEYOND THIS POINT -// if we do have to keep, verify the error handling -/////////////////////// - -// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing and https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx -// this X value is really only for buttons but I don't see a better one :/ -#define winXPadding 4 -#define winYPadding 4 - -uiWindowsSizing *uiWindowsNewSizing(HWND hwnd) -{ - uiWindowsSizing *d; - HDC dc; - HFONT prevfont; - TEXTMETRICW tm; - SIZE size; - - d = uiNew(uiWindowsSizing); - - dc = GetDC(hwnd); - if (dc == NULL) - logLastError(L"error getting DC"); - prevfont = (HFONT) SelectObject(dc, hMessageFont); - if (prevfont == NULL) - logLastError(L"error loading control font into device context"); - - ZeroMemory(&tm, sizeof (TEXTMETRICW)); - if (GetTextMetricsW(dc, &tm) == 0) - logLastError(L"error getting text metrics"); - if (GetTextExtentPoint32W(dc, L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &size) == 0) - logLastError(L"error getting text extent point"); - - d->BaseX = (int) ((size.cx / 26 + 1) / 2); - d->BaseY = (int) tm.tmHeight; - d->InternalLeading = tm.tmInternalLeading; - - if (SelectObject(dc, prevfont) != hMessageFont) - logLastError(L"error restoring previous font into device context"); - if (ReleaseDC(hwnd, dc) == 0) - logLastError(L"error releasing DC"); - - d->XPadding = uiWindowsDlgUnitsToX(winXPadding, d->BaseX); - d->YPadding = uiWindowsDlgUnitsToY(winYPadding, d->BaseY); - - return d; -} - -void uiWindowsFreeSizing(uiWindowsSizing *d) -{ - uiFree(d); -} diff --git a/windows/sizing.cpp b/windows/sizing.cpp new file mode 100644 index 00000000..a5079575 --- /dev/null +++ b/windows/sizing.cpp @@ -0,0 +1,55 @@ +// 14 may 2015 +#include "uipriv_windows.hpp" + +// TODO rework the error handling +void uiWindowsGetSizing(HWND hwnd, uiWindowsSizing *sizing); +{ + HDC dc; + HFONT prevfont; + TEXTMETRICW tm; + SIZE size; + + dc = GetDC(hwnd); + if (dc == NULL) + logLastError(L"error getting DC"); + prevfont = (HFONT) SelectObject(dc, hMessageFont); + if (prevfont == NULL) + logLastError(L"error loading control font into device context"); + + ZeroMemory(&tm, sizeof (TEXTMETRICW)); + if (GetTextMetricsW(dc, &tm) == 0) + logLastError(L"error getting text metrics"); + if (GetTextExtentPoint32W(dc, L"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", 52, &size) == 0) + logLastError(L"error getting text extent point"); + + d->BaseX = (int) ((size.cx / 26 + 1) / 2); + d->BaseY = (int) tm.tmHeight; + d->InternalLeading = tm.tmInternalLeading; + + if (SelectObject(dc, prevfont) != hMessageFont) + logLastError(L"error restoring previous font into device context"); + if (ReleaseDC(hwnd, dc) == 0) + logLastError(L"error releasing DC"); + + return d; +} + +#define dlgUnitsToX(dlg, baseX) MulDiv((dlg), (baseX), 4) +#define dlgUnitsToY(dlg, baseY) MulDiv((dlg), (baseY), 8) + +void uiWindowsSizingDlgUnitsToPixels(uiWindowsSIzing *sizing, int *x, int *y) +{ + *x = dlgUnitsToX(*x, sizing->BaseX); + *y = dlgUnitsToY(*y, sizing->BaseY); +} + +// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing and https://msdn.microsoft.com/en-us/library/windows/desktop/bb226818%28v=vs.85%29.aspx +// this X value is really only for buttons but I don't see a better one :/ +#define winXPadding 4 +#define winYPadding 4 + +void uiWindowsSizingStandardPadding(uiWindowsSizing *sizing, int *x, int *y) +{ + *x = dlgUnitsToX(winXPadding, sizing->BaseX); + *y = dlgUnitsToY(winYPadding, sizing->BaseY); +} diff --git a/windows/uipriv_windows.hpp b/windows/uipriv_windows.hpp index 48b772c9..85de595c 100644 --- a/windows/uipriv_windows.hpp +++ b/windows/uipriv_windows.hpp @@ -93,9 +93,6 @@ extern void unregisterMessageFilter(void); extern void paintContainerBackground(HWND hwnd, HDC dc, RECT *paintRect); extern BOOL handleParentMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *lResult); -// resize.cpp -extern void doResizes(void); - // d2dscratch.cpp extern ATOM registerD2DScratchClass(HICON hDefaultIcon, HCURSOR hDefaultCursor); extern void unregisterD2DScratchClass(void);