Started a newer, better system for propagating layout changes. This relies on WM_GETMINMAXINFO, at least...

This commit is contained in:
Pietro Gagliardi 2016-04-28 16:59:26 -04:00
parent 56853c5d86
commit c457d9bf00
16 changed files with 71 additions and 53 deletions

View File

@ -22,7 +22,8 @@ struct uiWindowsControl {
void (*SyncEnableState)(uiWindowsControl *, int);
void (*SetParentHWND)(uiWindowsControl *, HWND);
void (*MinimumSize)(uiWindowsControl *, intmax_t *, intmax_t *);
void (*ChildMinimumSizeChanged)(uiWIndowsControl *);
void (*MinimumSizeChanged)(uiWIndowsControl *);
void (*LayoutRect)(uiWindowsControl *c, RECT *r);
void (*AssignControlIDZOrder)(uiWindowsControl *, LONG_PTR *, HWND *);
};
#define uiWindowsControl(this) ((uiWindowsControl *) (this))
@ -30,7 +31,8 @@ struct uiWindowsControl {
_UI_EXTERN void uiWindowsControlSyncEnableState(uiWindowsControl *, int);
_UI_EXTERN void uiWindowsControlSetParentHWND(uiWindowsControl *, HWND);
_UI_EXTERN void uiWindowsControlMinimumSize(uiWindowsControl *, intmax_t *, intmax_t *);
_UI_EXTERN void uiWindowsControlChildMinimumSizeChanged(uiWindowsControl *);
_UI_EXTERN void uiWindowsControlMinimumSizeChanged(uiWindowsControl *);
_UI_EXTERN void uiWindowsControlLayoutRect(uiWindowsControl *, RECT *);
_UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_PTR *, HWND *);
// TODO document
@ -109,12 +111,20 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
uiWindowsEnsureSetParentHWND(type(c)->hwnd, parent); \
}
// note that there is no uiWindowsControlDefaultMinimumSize(); you MUST define this yourself!
#define uiWindowsDefaultChildMinimumSizeChanged(type) \
static void type ## ChildMinimumSizeChanged)(uiWIndowsControl *c) \
#define uiWindowsControlDefaultMinimumSizeChanged(type) \
static void type ## MinimumSizeChanged)(uiWIndowsControl *c) \
{ \
/* do nothing; default has no children */ \
if (uiWindowsControlTooSmall(c)) \
uiWindowsControlMinimumSizeChanged(uiWindowsControl(c->parent)); \
/* otherwise do nothing; we have no children */ \
}
#define uiWindowsDefaultAssignControlIDZorder(type) \
#define uiWindowsControlDefaultLayoutRect(type) \
static void type ## LayoutRect(uiWindowsControl *c, RECT *r) \
{ \
/* use the window rect as we include the non-client area in the sizes */ \
uiWindowsEnsureGetWindowRect(type(c)->hwnd, r); \
}
#define uiWindowsControlDefaultAssignControlIDZorder(type) \
static void type ## AssignControlIDZOrder)(uiWindowsControl *c, LONG_PTR *controlID, HWND *insertAfter) \
{ \
uiWindowsEnsureAssignControlIDZOrder(c, controlID, insertAfter); \
@ -133,8 +143,9 @@ _UI_EXTERN void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *, LONG_P
uiWindowsControlDefaultDisable(type) \
uiWindowsControlDefaultSyncEnableState(type) \
uiWindowsControlDefaultSetParentHWND(type) \
uiWindowsDefaultChildMinimumSizeChanged(type) \
uiWindowsDefaultAssignControlIDZorder(type)
uiWindowsControlDefaultMinimumSizeChanged(type) \
uiWindowsControlDefaultLayoutRect(type) \
uiWindowsControlDefaultAssignControlIDZorder(type)
#define uiWindowsControlAllDefaults(type) \
uiWindowsControlDefaultDestroy(type) \
@ -177,6 +188,10 @@ _UI_EXTERN void uiWindowsEnsureSetParentHWND(HWND hwnd, HWND parent);
// TODO document
_UI_EXTERN void uiWindowsEnsureAssignControlIDZOrder(HWND hwnd, LONG_PTR *controlID, HWND *insertAfter);
// TODO document
_UI_EXTERN void uiWindowsEnsureGetClientRect(HWND hwnd, RECT *r);
_UI_EXTERN void uiWindowsEnsureGetWindowRect(HWND hwnd, RECT *r);
// TODO document
_UI_EXTERN char *uiWindowsWindowText(HWND hwnd);
_UI_EXTERN void uiWindowsSetWindowText(HWND hwnd, const char *text);
@ -219,7 +234,7 @@ _UI_EXTERN void uiWindowsSizingStandardPadding(uiWindowsSizing *sizing, int *x,
_UI_EXTERN HWND uiWindowsMakeContainer(void (*onResize)(void *data), void *data);
// TODO document
_UI_EXTERN void uiWindowsControlNotifyMinimumSizeChanged(uiWindowsControl *);
_UI_EXTERN BOOL uiWindowsControlTooSmall(uiWindowsControl *c);
// TODO document
_UI_EXTERN void uiWindowsControlAssignSoleControlIDZOrder(uiWindowsControl *);

View File

@ -36,7 +36,7 @@ static LRESULT CALLBACK areaWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM
if (uMsg == WM_WINDOWPOSCHANGED) {
if ((wp->flags & SWP_NOSIZE) != 0)
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
if (getClientRect(a->hwnd, &client) == 0)
if (uiWindowsEnsureGetClientRect(a->hwnd, &client) == 0)
logLastError(L"error getting client rect of uiArea for WM_WINDOWPOSCHANGED handling");
areaDrawOnResize(a, &client);
areaScrollOnResize(a, &client);

View File

@ -94,7 +94,7 @@ static void onWM_PRINTCLIENT(uiArea *a)
{
RECT client;
if (getClientRect(a->hwnd, &client) == 0)
if (uiWindowsEnsureGetClientRect(a->hwnd, &client) == 0)
logLastError(L"error getting client rect");
//TODO doPaint(a, (HDC) wParam, &client);
}

View File

@ -85,7 +85,7 @@ static void areaMouseEvent(uiArea *a, uintmax_t down, uintmax_t up, WPARAM wPar
if (a->capturing) {
clientpt.x = GET_X_LPARAM(lParam);
clientpt.y = GET_Y_LPARAM(lParam);
if (getClientRect(a->hwnd, &client) == 0)
if (uiWindowsEnsureGetClientRect(a->hwnd, &client) == 0)
logLastError(L"error getting uiAreaclient rect for mouse crossing on capture on drag");
inClient = PtInRect(&client, clientpt);
if (inClient && !a->inside) {

View File

@ -128,7 +128,7 @@ static void hscrollParams(uiArea *a, struct scrollParams *p)
ZeroMemory(p, sizeof (struct scrollParams));
p->pos = &(a->hscrollpos);
// TODO get rid of these and replace with points
if (getClientRect(a->hwnd, &r) == 0)
if (uiWindowsEnsureGetClientRect(a->hwnd, &r) == 0)
logLastError(L"error getting area client rect");
p->pagesize = r.right - r.left;
p->length = a->scrollWidth;
@ -174,7 +174,7 @@ static void vscrollParams(uiArea *a, struct scrollParams *p)
ZeroMemory(p, sizeof (struct scrollParams));
p->pos = &(a->vscrollpos);
if (getClientRect(a->hwnd, &r) == 0)
if (uiWindowsEnsureGetClientRect(a->hwnd, &r) == 0)
logLastError(L"error getting area client rect");
p->pagesize = r.bottom - r.top;
p->length = a->scrollHeight;

View File

@ -50,7 +50,7 @@ static LRESULT CALLBACK containerWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LP
return 0;
// tab controls use this to draw the background of the tab area
case WM_PRINTCLIENT:
if (getClientRect(hwnd, &r) == 0) {
if (uiWindowsEnsureGetClientRect(hwnd, &r) == 0) {
logLastError(L"error getting client rect");
// likewise
break;

View File

@ -16,9 +16,14 @@ void uiWindowsControlMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t
(*(c->MinimumSize))(c, widdth, height);
}
void uiWindowsControlChildMinimumSizeChanged(uiWIndowsControl *c)
void uiWindowsControlMinimumSizeChanged(uiWIndowsControl *c)
{
(*(c->ChildMinimumSizeChanged))(c);
(*(c->MinimumSizeChanged))(c);
}
void uiWindowsControlLayoutRect(uiWindowsControl *c, RECT *r)
{
(*(c->LayoutRect))(c, r);
}
void uiWindowsControlAssignControlIDZOrder(uiWindowsControl *c, LONG_PTR *controlID, HWND *insertAfter)

View File

@ -51,7 +51,7 @@ ID2D1HwndRenderTarget *makeHWNDRenderTarget(HWND hwnd)
if (ReleaseDC(hwnd, dc) == 0)
logLastError(L"error releasing DC for finding DPI");
if (getClientRect(hwnd, &r) == 0)
if (uiWindowsEnsureGetClientRect(hwnd, &r) == 0)
logLastError(L"error getting current size of window");
ZeroMemory(&hprops, sizeof (D2D1_HWND_RENDER_TARGET_PROPERTIES));

View File

@ -495,7 +495,7 @@ static struct fontDialog *beginFontDialog(HWND hwnd, LPARAM lParam)
samplePlacement = GetDlgItem(f->hwnd, rcFontSamplePlacement);
if (samplePlacement == NULL)
logLastError(L"error getting sample placement static control handle");
if (getWindowRect(samplePlacement, &(f->sampleRect)) == 0)
if (uiWindowsEnsureGetWindowRect(samplePlacement, &(f->sampleRect)) == 0)
logLastError(L"error getting sample placement");
mapWindowRect(NULL, f->hwnd, &(f->sampleRect));
uiWindowsEnsureDestroyWindow(samplePlacement);

View File

@ -33,7 +33,7 @@ static HRESULT parentDraw(HDC dc, HWND parent, struct parentDraw *pd)
{
RECT r;
if (getClientRect(parent, &r) == 0)
if (uiWindowsEnsureGetClientRect(parent, &r) == 0)
return logLastError(L"error getting parent's client rect");
pd->cdc = CreateCompatibleDC(dc);
if (pd->cdc == NULL)
@ -86,7 +86,7 @@ static HBRUSH getControlBackgroundBrush(HWND hwnd, HDC dc)
// now figure out where the control is relative to the parent so we can align the brush properly
// if anything fails, give up and return the brush as-is
if (getWindowRect(hwnd, &hwndScreenRect) == 0) {
if (uiWindowsEnsureGetWindowRect(hwnd, &hwndScreenRect) == 0) {
logLastError(L"error getting control window rect");
return brush;
}

View File

@ -32,7 +32,7 @@ static void tabPageRect(uiTab *t, RECT *r)
// this rect needs to be in parent window coordinates, but TCM_ADJUSTRECT wants a window rect, which is screen coordinates
// because we have each page as a sibling of the tab, use the tab's own rect as the input rect
getWindowRect(t->tabHWND, &r);
uiWindowsEnsureGetWindowRect(t->tabHWND, &r);
SendMessageW(t->tabHWND, TCM_ADJUSTRECT, (WPARAM) FALSE, (LPARAM) (&r));
// and get it in terms of the container instead of the screen
mapWindowRect(NULL, t->hwnd, &r);

View File

@ -28,7 +28,7 @@ static void tabRelayout(struct tabPage *tp)
if (tp->child == NULL)
return;
getClientRect(tp->hwnd, &r);
uiWindowsEnsureGetClientRect(tp->hwnd, &r);
tabPageMargins(tp, &mx, &my);
r.left += mx;
r.right += my;

View File

@ -67,8 +67,6 @@ extern void clientSizeToWindowSize(HWND hwnd, intmax_t *width, intmax_t *height,
extern HWND parentOf(HWND child);
extern HWND parentToplevel(HWND child);
extern void setWindowInsertAfter(HWND hwnd, HWND insertAfter);
extern void getClientRect(HWND, RECT *);
extern void getWindowRect(HWND, RECT *);
// text.cpp
extern WCHAR *windowTextAndLen(HWND hwnd, LRESULT *len);

View File

@ -46,7 +46,7 @@ static void windowRelayout(uiWindow *w)
return;
x = 0;
y = 0;
getClientRect(w->hwnd, &r);
uiWindowsEnsureGetClientRect(w->hwnd, &r);
width = r.right - r.left;
height = r.bottom - r.top;
windowMargins(w, &mx, &my);
@ -239,7 +239,7 @@ static void uiWindowChildMinimumSizeChanged(uiWindowsControl *c)
int mx, my;
uiWindowsControlMinimumSize(uiWindowsControl(w->child), &width, &height);
getClientRect(w->hwnd, &r);
uiWindowsEnsureGetClientRect(w->hwnd, &r);
windowMargins(w, &mx, &my);
needsGrowing = FALSE;
// subtract margins so we only care about the area that's used
@ -374,7 +374,7 @@ void ensureMinimumWindowSize(uiWindow *w)
RECT r;
uiWindowsControlMinimumSize(uiWindowsControl(w), &width, &height);
getClientRect(w->hwnd, &r);
uiWindowsEnsureGetClientRect(w->hwnd, &r);
if (width < (r.right - r.left)) // preserve width if larger
width = r.right - r.left;
if (height < (r.bottom - r.top)) // preserve height if larger

View File

@ -34,3 +34,28 @@ void uiWindowsEnsureMoveWindowDuringResize(HWND hwnd, intmax_t x, intmax_t y, in
if (SetWindowPos(hwnd, NULL, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER) == 0)
logLastError(L"error moving window");
}
// do these function even error out in any case other than invalid parameters?! I thought all windows had rects
void uiWindowsEnsureGetClientRect(HWND hwnd, RECT *r)
{
if (GetClientRect(hwnd, r) == 0) {
logLastError(L"error getting window client rect");
// zero out the rect on error just to be safe
r->left = 0;
r->top = 0;
r->right = 0;
r->bottom = 0;
}
}
void uiWindowsEnsureGetWindowRect(HWND hwnd, RECT *r)
{
if (GetWindowRect(hwnd, r) == 0) {
logLastError(L"error getting window rect");
// zero out the rect on error just to be safe
r->left = 0;
r->top = 0;
r->right = 0;
r->bottom = 0;
}
}

View File

@ -120,28 +120,3 @@ void setWindowInsertAfter(HWND hwnd, HWND insertAfter)
if (SetWindowPos(hwnd, insertAfter, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE) == 0)
logLastError(L"error reordering window");
}
// do these function even error out in any case other than invalid parameters?! I thought all windows had rects
void getClientRect(HWND hwnd, RECT *r)
{
if (GetClientRect(hwnd, r) == 0) {
logLastError(L"error getting window client rect");
// zero out the rect on error just to be safe
r->left = 0;
r->top = 0;
r->right = 0;
r->bottom = 0;
}
}
void getWindowRect(HWND hwnd, RECT *r)
{
if (GetWindowRect(hwnd, r) == 0) {
logLastError(L"error getting window rect");
// zero out the rect on error just to be safe
r->left = 0;
r->top = 0;
r->right = 0;
r->bottom = 0;
}
}