Started reworking window.cpp to get a feel for what's going to happen. This is a mess...

This commit is contained in:
Pietro Gagliardi 2016-04-26 22:44:40 -04:00
parent dd1d5c871e
commit 78b49ae04d
2 changed files with 112 additions and 57 deletions

View File

@ -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,
}; };

View File

@ -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)
{ {