Implement Mouse Enter/Leave Events

This commit is contained in:
Phillip 2015-11-06 23:49:53 -08:00
parent 9fc3810015
commit 0f057a3713
2 changed files with 109 additions and 29 deletions

View File

@ -234,7 +234,8 @@ public:
case WM_DEVICECHANGE:
return DeviceFinder::winDevChangedHandler(wParam, lParam);
case WM_SIZE:
case WM_SIZING:
case WM_MOVING:
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
case WM_SYSKEYUP:
@ -248,6 +249,10 @@ public:
case WM_XBUTTONDOWN:
case WM_XBUTTONUP:
case WM_MOUSEMOVE:
case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE:
case WM_MOUSEHOVER:
case WM_NCMOUSEHOVER:
window->_incomingEvent(&HWNDEvent(uMsg, wParam, lParam));
default:

View File

@ -420,14 +420,14 @@ class WindowWin32 : public IWindow
HWND m_hwnd;
std::unique_ptr<GraphicsContextWin32> m_gfxCtx;
IWindowCallback* m_callback = nullptr;
public:
WindowWin32(const SystemString& title, Boo3DAppContext& b3dCtx)
{
m_hwnd = CreateWindowW(L"BooWindow", title.c_str(), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, NULL, NULL);
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, NULL, NULL);
IGraphicsContext::EGraphicsAPI api = IGraphicsContext::API_D3D11;
#if _WIN32_WINNT_WIN10
if (b3dCtx.m_ctx12.m_dev)
@ -440,39 +440,39 @@ public:
}
m_gfxCtx.reset(new GraphicsContextWin32D3D(api, this, m_hwnd, b3dCtx));
}
~WindowWin32()
{
}
void setCallback(IWindowCallback* cb)
{
m_callback = cb;
}
void showWindow()
{
ShowWindow(m_hwnd, SW_SHOW);
}
void hideWindow()
{
ShowWindow(m_hwnd, SW_HIDE);
}
SystemString getTitle()
{
wchar_t title[256];
int c = GetWindowTextW(m_hwnd, title, 256);
return SystemString(title, c);
wchar_t title[256];
int c = GetWindowTextW(m_hwnd, title, 256);
return SystemString(title, c);
}
void setTitle(const SystemString& title)
{
SetWindowTextW(m_hwnd, title.c_str());
}
void setWindowFrameDefault()
{
MONITORINFO monInfo;
@ -481,13 +481,17 @@ public:
genFrameDefault(&monInfo, x, y, w, h);
setWindowFrame(x, y, w, h);
}
void getWindowFrame(float& xOut, float& yOut, float& wOut, float& hOut) const
{
RECT rct;
GetClientRect(m_hwnd, &rct);
xOut = rct.left;
yOut = rct.top;
POINT pt;
pt.x = rct.left;
pt.y = rct.top;
MapWindowPoints(m_hwnd, HWND_DESKTOP, &pt, 1);
xOut = pt.x;
yOut = pt.y;
wOut = rct.right;
hOut = rct.bottom;
}
@ -496,12 +500,16 @@ public:
{
RECT rct;
GetClientRect(m_hwnd, &rct);
xOut = rct.left;
yOut = rct.top;
POINT pt;
pt.x = rct.left;
pt.y = rct.top;
MapWindowPoints(m_hwnd, HWND_DESKTOP, &pt, 1);
xOut = pt.x;
yOut = pt.y;
wOut = rct.right;
hOut = rct.bottom;
}
void setWindowFrame(float x, float y, float w, float h)
{
MoveWindow(m_hwnd, x, y, w, h, true);
@ -511,17 +519,17 @@ public:
{
MoveWindow(m_hwnd, x, y, w, h, true);
}
float getVirtualPixelFactor() const
{
return 1.0;
}
bool isFullscreen() const
{
return m_gfxCtx->m_3dCtx.isFullscreen(this);
}
void setFullscreen(bool fs)
{
m_gfxCtx->m_3dCtx.setFullscreen(this, fs);
@ -570,13 +578,26 @@ public:
m_callback->mouseUp(coord, button, EModifierKey(modifierMask));
}
}
void _trackMouse()
{
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_NONCLIENT | TME_HOVER | TME_LEAVE;
tme.dwHoverTime = 500;
tme.hwndTrack = m_hwnd;
}
bool mouseTracking = false;
bool moving = false;
bool resizing = false;
void _incomingEvent(void* ev)
{
HWNDEvent& e = *static_cast<HWNDEvent*>(ev);
switch (e.uMsg)
{
case WM_SIZE:
case WM_SIZING:
{
SWindowRect rect;
getWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]);
@ -587,6 +608,17 @@ public:
m_callback->resized(rect);
return;
}
case WM_MOVING:
{
SWindowRect rect;
getWindowFrame(rect.location[0], rect.location[1], rect.size[0], rect.size[1]);
if (!rect.size[0] || !rect.size[1])
return;
if (m_callback)
m_callback->windowMoved(rect);
return;
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
@ -681,7 +713,50 @@ public:
{(unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam)},
{float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h)}
};
m_callback->mouseMove(coord);
if (!mouseTracking)
{
_trackMouse();
mouseTracking = true;
m_callback->mouseEnter(coord);
}
else
m_callback->mouseMove(coord);
}
return;
}
case WM_MOUSELEAVE:
case WM_NCMOUSELEAVE:
{
if (m_callback)
{
int x, y, w, h;
getWindowFrame(x, y, w, h);
SWindowCoord coord =
{
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h) }
};
m_callback->mouseLeave(coord);
mouseTracking = false;
}
return;
}
case WM_NCMOUSEHOVER:
case WM_MOUSEHOVER:
{
if (m_callback)
{
int x, y, w, h;
getWindowFrame(x, y, w, h);
SWindowCoord coord =
{
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ (unsigned)GET_X_LPARAM(e.lParam), (unsigned)GET_Y_LPARAM(e.lParam) },
{ float(GET_X_LPARAM(e.lParam)) / float(w), float(GET_Y_LPARAM(e.lParam)) / float(h) }
};
m_callback->mouseEnter(coord);
}
return;
}
@ -743,7 +818,7 @@ public:
{
return m_gfxCtx->getLoadContextDataFactory();
}
};
IWindow* _WindowWin32New(const SystemString& title, Boo3DAppContext& d3dCtx)