Started reworking window.cpp to get a feel for what's going to happen. This is a mess...
This commit is contained in:
parent
dd1d5c871e
commit
78b49ae04d
|
@ -12,7 +12,6 @@ enum {
|
||||||
msgCOMMAND = WM_APP + 0x40, // start offset just to be safe
|
msgCOMMAND = WM_APP + 0x40, // start offset just to be safe
|
||||||
msgNOTIFY,
|
msgNOTIFY,
|
||||||
msgHSCROLL,
|
msgHSCROLL,
|
||||||
msgGetuiWindow,
|
|
||||||
msgQueued,
|
msgQueued,
|
||||||
msgD2DScratchPaint,
|
msgD2DScratchPaint,
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,20 +7,43 @@ struct uiWindow {
|
||||||
uiWindowsControl c;
|
uiWindowsControl c;
|
||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
HMENU menubar;
|
HMENU menubar;
|
||||||
struct child *child;
|
uiControl *child;
|
||||||
BOOL shownOnce;
|
BOOL shownOnce;
|
||||||
|
int visible;
|
||||||
int (*onClosing)(uiWindow *, void *);
|
int (*onClosing)(uiWindow *, void *);
|
||||||
void *onClosingData;
|
void *onClosingData;
|
||||||
int margined;
|
int margined;
|
||||||
BOOL hasMenubar;
|
BOOL hasMenubar;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void onDestroy(uiWindow *);
|
static void windowRelayout(uiWindow *w)
|
||||||
|
{
|
||||||
|
uiWindow *w = uiWindow(c);
|
||||||
|
uiWindowsSizing sizing;
|
||||||
|
int x, y, width, height;
|
||||||
|
RECT r;
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
uiWindowsDefineControlWithOnDestroy(
|
if (w->child == NULL)
|
||||||
uiWindow, // type name
|
return;
|
||||||
onDestroy(me); // on destroy
|
x = 0;
|
||||||
)
|
y = 0;
|
||||||
|
if (GetClientRect(w->hwnd, &r) == 0)
|
||||||
|
/* TODO */;
|
||||||
|
width = r.right - r.left;
|
||||||
|
height = r.bottom - r.top;
|
||||||
|
if (w->margined) {
|
||||||
|
uiWindowsGetSizing(w->hwnd, &sizing);
|
||||||
|
mx = windowMargin;
|
||||||
|
my = windowMargin;
|
||||||
|
uiWindowsSizingDlgUnitsToPixels(&sizing, &mx, &my);
|
||||||
|
x += mx;
|
||||||
|
y += my;
|
||||||
|
width -= 2 * mx;
|
||||||
|
height -= 2 * my;
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +52,6 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA
|
||||||
CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
|
CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
|
||||||
WINDOWPOS *wp = (WINDOWPOS *) lParam;
|
WINDOWPOS *wp = (WINDOWPOS *) lParam;
|
||||||
MINMAXINFO *mmi = (MINMAXINFO *) lParam;
|
MINMAXINFO *mmi = (MINMAXINFO *) lParam;
|
||||||
uiWindowsControl *c;
|
|
||||||
intmax_t width, height;
|
intmax_t width, height;
|
||||||
LRESULT lResult;
|
LRESULT lResult;
|
||||||
|
|
||||||
|
@ -44,8 +66,6 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA
|
||||||
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
if (handleParentMessages(hwnd, uMsg, wParam, lParam, &lResult) != FALSE)
|
||||||
return lResult;
|
return lResult;
|
||||||
switch (uMsg) {
|
switch (uMsg) {
|
||||||
case msgGetuiWindow:
|
|
||||||
return (LRESULT) w;
|
|
||||||
case WM_COMMAND:
|
case WM_COMMAND:
|
||||||
// not a menu
|
// not a menu
|
||||||
if (lParam != 0)
|
if (lParam != 0)
|
||||||
|
@ -57,17 +77,12 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA
|
||||||
case WM_WINDOWPOSCHANGED:
|
case WM_WINDOWPOSCHANGED:
|
||||||
if ((wp->flags & SWP_NOSIZE) != 0)
|
if ((wp->flags & SWP_NOSIZE) != 0)
|
||||||
break;
|
break;
|
||||||
if (w->child != NULL)
|
windowRelayout(w);
|
||||||
childQueueRelayout(w->child);
|
|
||||||
return 0;
|
return 0;
|
||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
// ensure the user cannot resize the window smaller than its minimum size
|
// ensure the user cannot resize the window smaller than its minimum size
|
||||||
lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
lResult = DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
c = uiWindowsControl(w);
|
uiWindowsControlMinimumSize(uiWindowsControl(w), &width, &height);
|
||||||
// TODO why is this message being sent too early?
|
|
||||||
if (c->MinimumSize == NULL)
|
|
||||||
return lResult;
|
|
||||||
(*(c->MinimumSize))(c, NULL, &width, &height);
|
|
||||||
// width and height are in client coordinates; ptMinTrackSize is in window coordinates
|
// width and height are in client coordinates; ptMinTrackSize is in window coordinates
|
||||||
clientSizeToWindowSize(w->hwnd, &width, &height, w->hasMenubar);
|
clientSizeToWindowSize(w->hwnd, &width, &height, w->hasMenubar);
|
||||||
mmi->ptMinTrackSize.x = width;
|
mmi->ptMinTrackSize.x = width;
|
||||||
|
@ -111,23 +126,52 @@ static int defaultOnClosing(uiWindow *w, void *data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onDestroy(uiWindow *w)
|
static void uiWindowDestroy(uiControl *c)
|
||||||
{
|
|
||||||
// first hide ourselves
|
|
||||||
ShowWindow(w->hwnd, SW_HIDE);
|
|
||||||
// now destroy the child
|
|
||||||
if (w->child != NULL)
|
|
||||||
childDestroy(w->child);
|
|
||||||
// now free the menubar, if any
|
|
||||||
if (w->menubar != NULL)
|
|
||||||
freeMenubar(w->menubar);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void windowCommitShow(uiControl *c)
|
|
||||||
{
|
{
|
||||||
uiWindow *w = uiWindow(c);
|
uiWindow *w = uiWindow(c);
|
||||||
|
|
||||||
|
// TODO make sure all ports have the necessary verifications
|
||||||
|
// first hide ourselves
|
||||||
|
ShowWindow(w->hwnd, SW_HIDE);
|
||||||
|
// now destroy the child
|
||||||
|
if (w->child != NULL) {
|
||||||
|
uiControlSetParent(w->child, NULL);
|
||||||
|
uiControlDestroy(w->child);
|
||||||
|
}
|
||||||
|
// now free the menubar, if any
|
||||||
|
if (w->menubar != NULL)
|
||||||
|
freeMenubar(w->menubar);
|
||||||
|
// and finally free ourselves
|
||||||
|
uiWindowsEnsureDestroyWindow(w->hwnd);
|
||||||
|
uiFreeControl(uiControl(w));
|
||||||
|
}
|
||||||
|
|
||||||
|
uiWindowsControlDefaultHandle(uiWindow)
|
||||||
|
// TODO?
|
||||||
|
uiWindowsControlDefaultParent(uiWindow)
|
||||||
|
uiWindowsControlDefaultSetParent(uiWindow)
|
||||||
|
// end TODO
|
||||||
|
|
||||||
|
static int uiWindowToplevel(uiControl *c)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO initial state of windows is hidden; ensure this here and make it so on other platforms
|
||||||
|
static int uiWindowVisible(uiControl *c)
|
||||||
|
{
|
||||||
|
uiWindow *w = uiWindow(c);
|
||||||
|
|
||||||
|
return w->visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uiWindowShow(uiControl *c)
|
||||||
|
{
|
||||||
|
uiWindow *w = uiWindow(c);
|
||||||
|
|
||||||
|
w->visible = 1;
|
||||||
// just in case this wasn't called already
|
// just in case this wasn't called already
|
||||||
|
// TODO is it needed?
|
||||||
ensureMinimumWindowSize(w);
|
ensureMinimumWindowSize(w);
|
||||||
if (w->shownOnce) {
|
if (w->shownOnce) {
|
||||||
ShowWindow(w->hwnd, SW_SHOW);
|
ShowWindow(w->hwnd, SW_SHOW);
|
||||||
|
@ -141,58 +185,70 @@ static void windowCommitShow(uiControl *c)
|
||||||
logLastError(L"error calling UpdateWindow() after showing uiWindow for the first time");
|
logLastError(L"error calling UpdateWindow() after showing uiWindow for the first time");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void windowContainerUpdateState(uiControl *c)
|
static void uiWindowHide(uiControl *c)
|
||||||
{
|
{
|
||||||
uiWindow *w = uiWindow(c);
|
uiWindow *w = uiWindow(c);
|
||||||
|
|
||||||
if (w->child != NULL)
|
w->visible = 0;
|
||||||
childUpdateState(w->child);
|
ShowWindow(w->hwnd, SW_HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO we don't want the window to be disabled completely; that would prevent it from being moved! ...would it?
|
||||||
|
uiWindowsControlDefaultEnabled(uiWindow)
|
||||||
|
uiWindowsControlDefaultEnable(uiWindow)
|
||||||
|
uiWindowsControlDefaultDisable(uiWindow)
|
||||||
|
// TODO we need to do something about undocumented fields in the OS control types
|
||||||
|
uiWindowsControlDefaultSyncEnableState(uiWindow)
|
||||||
|
// TODO
|
||||||
|
uiWindowsControlDefaultSetParentHWND(uiWindow)
|
||||||
|
|
||||||
// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||||
#define windowMargin 7
|
#define windowMargin 7
|
||||||
|
|
||||||
static void minimumSize(uiWindowsControl *c, uiWindowsSizing *d, intmax_t *width, intmax_t *height)
|
static void uiWindowMinimumSize(uiWindowsControl *c, intmax_t *width, intmax_t *height)
|
||||||
{
|
{
|
||||||
uiWindow *w = uiWindow(c);
|
uiWindow *w = uiWindow(c);
|
||||||
|
uiWindowsSizing sizing;
|
||||||
|
int mx, my;
|
||||||
|
|
||||||
*width = 0;
|
*width = 0;
|
||||||
*height = 0;
|
*height = 0;
|
||||||
d = uiWindowsNewSizing(w->hwnd);
|
|
||||||
if (w->child != NULL)
|
if (w->child != NULL)
|
||||||
childMinimumSize(w->child, d, width, height);
|
uiWindowsControlMinimumSize(uiWindowsControl(w->child), width, height);
|
||||||
if (w->margined) {
|
if (w->margined) {
|
||||||
*width += 2 * uiWindowsDlgUnitsToX(windowMargin, d->BaseX);
|
uiWindowsGetSizing(w->hwnd, &sizing);
|
||||||
*height += 2 * uiWindowsDlgUnitsToY(windowMargin, d->BaseY);
|
mx = windowMargin;
|
||||||
|
my = windowMargin;
|
||||||
|
uiWindowsSizingDlgUnitsToPixels(&sizing, &mx, &my);
|
||||||
|
*width += 2 * mx;
|
||||||
|
*height += 2 * my;
|
||||||
}
|
}
|
||||||
uiWindowsFreeSizing(d);
|
uiWindowsFreeSizing(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void windowRelayout(uiWindowsControl *c, intmax_t x, intmax_t y, intmax_t width, intmax_t height)
|
static void uiWindowChildMinimumSizeChanged(uiWindowsControl *c)
|
||||||
{
|
{
|
||||||
uiWindow *w = uiWindow(c);
|
uiWindow *w = uiWindow(c);
|
||||||
uiWindowsSizing *d;
|
intmax_t width, height;
|
||||||
|
RECT r;
|
||||||
|
BOOL needsGrowing;
|
||||||
|
|
||||||
if (w->child == NULL)
|
uiWindowsControlMinimumSize(uiWindowsControl(w->child), &width, &height);
|
||||||
return;
|
if (GetClientRect(w->hwnd, &r) == 0)
|
||||||
d = uiWindowsNewSizing(w->hwnd);
|
/* TODO */;
|
||||||
if (w->margined) {
|
// TODO discount margins
|
||||||
x += uiWindowsDlgUnitsToX(windowMargin, d->BaseX);
|
needsGrowing = FALSE;
|
||||||
y += uiWindowsDlgUnitsToY(windowMargin, d->BaseY);
|
if ((r.right - r.left) < width)
|
||||||
width -= 2 * uiWindowsDlgUnitsToX(windowMargin, d->BaseX);
|
needsGrowing = TRUE;
|
||||||
height -= 2 * uiWindowsDlgUnitsToY(windowMargin, d->BaseY);
|
if ((r.bottom - r.top) < height)
|
||||||
}
|
needsGrowing = TRUE;
|
||||||
childRelayout(w->child, x, y, width, height);
|
if (needsGrowing)
|
||||||
uiWindowsFreeSizing(d);
|
/* TODO */;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void windowArrangeChildrenControlIDsZOrder(uiWindowsControl *c)
|
uiWindowsDefaultAssignControlIDZorder(uiWindow)
|
||||||
{
|
|
||||||
uiWindow *w = uiWindow(c);
|
|
||||||
|
|
||||||
if (w->child != NULL)
|
///////// TODO CONTINUE HERE
|
||||||
childSetSoleControlID(w->child);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *uiWindowTitle(uiWindow *w)
|
char *uiWindowTitle(uiWindow *w)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue