And added the new uiWindow methods on Windows.
This commit is contained in:
parent
48c13c738a
commit
c3777da0f4
|
@ -20,6 +20,7 @@ This README is being written.<br>
|
|||
|
||||
* **15 June 2016**
|
||||
* Added `uiFormDelete()`; thanks to @emersion.
|
||||
* Added `uiWindowPosition()`, `uiWindowSetPosition()`, `uiWindowCenter()`, and `uiWindowOnPositionChanged()`, methods for manipulating uiWindow position.
|
||||
|
||||
* **14 June 2016**
|
||||
* uiDarwinControl now has a `ChildVisibilityChanged()` method and a corresponding `NotifyVisibilityChanged()` function that is called by the default show/hide handlers. This is used to make visibility changes work on OS X; uiBox, uiForm, and uiGrid all respect these now.
|
||||
|
|
|
@ -14,6 +14,9 @@ struct uiWindow {
|
|||
void *onClosingData;
|
||||
int margined;
|
||||
BOOL hasMenubar;
|
||||
void (*onPositionChanged)(uiWindow *, void *);
|
||||
void *onPositionChangedData;
|
||||
BOOL changingPosition;
|
||||
};
|
||||
|
||||
// from https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486.aspx#sizingandspacing
|
||||
|
@ -87,6 +90,10 @@ static LRESULT CALLBACK windowWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARA
|
|||
runMenuEvent(LOWORD(wParam), uiWindow(w));
|
||||
return 0;
|
||||
case WM_WINDOWPOSCHANGED:
|
||||
if ((wp->flags & SWP_NOMOVE) == 0)
|
||||
if (!w->changingPosition)
|
||||
(*(w->onPositionChanged))(w, w->onPositionChangedData);
|
||||
// and continue anyway
|
||||
if ((wp->flags & SWP_NOSIZE) != 0)
|
||||
break;
|
||||
windowRelayout(w);
|
||||
|
@ -138,6 +145,11 @@ static int defaultOnClosing(uiWindow *w, void *data)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void defaultOnPositionChanged(uiWindow *w, void *data)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
static std::map<uiWindow *, bool> windows;
|
||||
|
||||
static void uiWindowDestroy(uiControl *c)
|
||||
|
@ -277,6 +289,74 @@ void uiWindowSetTitle(uiWindow *w, const char *title)
|
|||
// don't queue resize; the caption isn't part of what affects layout and sizing of the client area (it'll be ellipsized if too long)
|
||||
}
|
||||
|
||||
void uiWindowPosition(uiWindow *w, int *x, int *y)
|
||||
{
|
||||
RECT r;
|
||||
|
||||
uiWindowsEnsureGetWindowRect(w->hwnd, &r);
|
||||
*x = r.left;
|
||||
*y = r.top;
|
||||
}
|
||||
|
||||
void uiWindowSetPosition(uiWindow *w, int x, int y)
|
||||
{
|
||||
w->changingPosition = TRUE;
|
||||
if (SetWindowPos(w->hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER) == 0)
|
||||
logLastError(L"error moving window");
|
||||
w->changingPosition = FALSE;
|
||||
}
|
||||
|
||||
// this is used for both fullscreening and centering
|
||||
// see also https://blogs.msdn.microsoft.com/oldnewthing/20100412-00/?p=14353 and https://blogs.msdn.microsoft.com/oldnewthing/20050505-04/?p=35703
|
||||
static void windowMonitorRect(HWND hwnd, RECT *r)
|
||||
{
|
||||
HMONITOR monitor;
|
||||
MONITORINFO mi;
|
||||
|
||||
monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
|
||||
ZeroMemory(&mi, sizeof (MONITORINFO));
|
||||
mi.cbSize = sizeof (MONITORINFO);
|
||||
if (GetMonitorInfoW(monitor, &mi) == 0) {
|
||||
logLastError(L"error getting window monitor rect");
|
||||
// default to SM_CXSCREEN x SM_CYSCREEN to be safe
|
||||
r->left = 0;
|
||||
r->top = 0;
|
||||
r->right = GetSystemMetrics(SM_CXSCREEN);
|
||||
r->bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||
return;
|
||||
}
|
||||
*r = mi.rcMonitor;
|
||||
}
|
||||
|
||||
// TODO use the work rect instead?
|
||||
void uiWindowCenter(uiWindow *w)
|
||||
{
|
||||
RECT wr, mr;
|
||||
int x, y;
|
||||
LONG wwid, mwid;
|
||||
LONG wht, mht;
|
||||
|
||||
uiWindowsEnsureGetWindowRect(w->hwnd, &wr);
|
||||
windowMonitorRect(w->hwnd, &mr);
|
||||
wwid = wr.right - wr.left;
|
||||
mwid = mr.right - mr.left;
|
||||
x = (mwid - wwid) / 2;
|
||||
wht = wr.bottom - wr.top;
|
||||
mht = mr.bottom - mr.top;
|
||||
y = (mht - wht) / 2;
|
||||
// y is now evenly divided, however https://msdn.microsoft.com/en-us/library/windows/desktop/dn742502(v=vs.85).aspx says that 45% should go above and 55% should go below
|
||||
// so just move 5% of the way up
|
||||
// TODO is this correct?
|
||||
y -= y / 20;
|
||||
uiWindowSetPosition(w, x, y);
|
||||
}
|
||||
|
||||
void uiWindowOnPositionChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data)
|
||||
{
|
||||
w->onPositionChanged = f;
|
||||
w->onPositionChangedData = data;
|
||||
}
|
||||
|
||||
void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
|
||||
{
|
||||
w->onClosing = f;
|
||||
|
@ -373,6 +453,7 @@ uiWindow *uiNewWindow(const char *title, int width, int height, int hasMenubar)
|
|||
setClientSize(w, width, height, hasMenubarBOOL, style, exstyle);
|
||||
|
||||
uiWindowOnClosing(w, defaultOnClosing, NULL);
|
||||
uiWindowOnPositionChanged(w, defaultOnPositionChanged, NULL);
|
||||
|
||||
windows[w] = true;
|
||||
return w;
|
||||
|
|
Loading…
Reference in New Issue