Started a newer, better system for propagating layout changes. This relies on WM_GETMINMAXINFO, at least...
This commit is contained in:
parent
56853c5d86
commit
c457d9bf00
33
ui_windows.h
33
ui_windows.h
|
@ -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 *);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue