Added ability to grab the cursor (w/ Windows impl.)
* When grabbed, the mouse cursor may not be moved outside a window's client frame. * Fullscreen windows always grab the mouse cursor. * The effect is only active while the SFML window is the active foreground window. * Right now this is only implemented for Windows. Signed-off-by: Marco Antognini <antognini.marco@gmail.com>
This commit is contained in:
parent
ba9383f25e
commit
f7dcc10a70
@ -348,6 +348,21 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
void setMouseCursorVisible(bool visible);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Grab or release the mouse cursor
|
||||
///
|
||||
/// If set, grabs the mouse cursor inside this window's client
|
||||
/// area so it may no longer be moved outside its bounds.
|
||||
/// Note that grabbing is only active while the window has
|
||||
/// focus and calling this function for fullscreen windows
|
||||
/// won't have any effect (fullscreen windows always grab the
|
||||
/// cursor).
|
||||
///
|
||||
/// \param grabbed True to enable, false to disable
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void setMouseCursorGrabbed(bool grabbed);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable automatic key-repeat
|
||||
///
|
||||
|
@ -313,6 +313,14 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorVisible(bool visible);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Grab or release the mouse cursor
|
||||
///
|
||||
/// \param grabbed True to enable, false to disable
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorGrabbed(bool grabbed);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable automatic key-repeat
|
||||
///
|
||||
|
@ -486,6 +486,13 @@ void WindowImplCocoa::setMouseCursorVisible(bool visible)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setMouseCursorGrabbed(bool grabbed)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplCocoa::setKeyRepeatEnabled(bool enabled)
|
||||
{
|
||||
|
@ -96,6 +96,12 @@ namespace sf {
|
||||
////////////////////////////////////////////////////////////
|
||||
-(BOOL)isMouseInside;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Grab or release the mouse cursor
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
-(void)setCursorGrabbed:(bool)grabbed;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get window position
|
||||
///
|
||||
|
@ -366,7 +366,8 @@ m_hiddenCursor (0),
|
||||
m_keyRepeat (true),
|
||||
m_previousSize (-1, -1),
|
||||
m_useSizeHints (false),
|
||||
m_fullscreen (false)
|
||||
m_fullscreen (false),
|
||||
m_cursorGrabbed (false)
|
||||
{
|
||||
// Open a connection with the X server
|
||||
m_display = OpenDisplay();
|
||||
@ -420,7 +421,8 @@ m_hiddenCursor (0),
|
||||
m_keyRepeat (true),
|
||||
m_previousSize (-1, -1),
|
||||
m_useSizeHints (false),
|
||||
m_fullscreen ((style & Style::Fullscreen) != 0)
|
||||
m_fullscreen ((style & Style::Fullscreen) != 0),
|
||||
m_cursorGrabbed (m_fullscreen)
|
||||
{
|
||||
// Open a connection with the X server
|
||||
m_display = OpenDisplay();
|
||||
@ -952,6 +954,26 @@ void WindowImplX11::setMouseCursorVisible(bool visible)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplX11::setMouseCursorGrabbed(bool grabbed)
|
||||
{
|
||||
// This has no effect in fullscreen mode
|
||||
if (m_fullscreen || (m_cursorGrabbed == grabbed))
|
||||
return;
|
||||
|
||||
if (grabbed)
|
||||
{
|
||||
// TODO XGrabPointer(m_display, m_window, true, 0, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
|
||||
m_cursorGrabbed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO XUngrabPointer(m_display, CurrentTime);
|
||||
m_cursorGrabbed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplX11::setKeyRepeatEnabled(bool enabled)
|
||||
{
|
||||
@ -1661,6 +1683,10 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
||||
if (m_inputContext)
|
||||
XSetICFocus(m_inputContext);
|
||||
|
||||
// Grab cursor
|
||||
if (m_cursorGrabbed)
|
||||
;// TODO XGrabPointer(m_display, m_window, true, 0, GrabModeAsync, GrabModeAsync, m_window, None, CurrentTime);
|
||||
|
||||
Event event;
|
||||
event.type = Event::GainedFocus;
|
||||
pushEvent(event);
|
||||
@ -1703,6 +1729,10 @@ bool WindowImplX11::processEvent(XEvent& windowEvent)
|
||||
if (m_inputContext)
|
||||
XUnsetICFocus(m_inputContext);
|
||||
|
||||
// Release cursor
|
||||
if (m_cursorGrabbed)
|
||||
;// TODO XUngrabPointer(m_display, CurrentTime);
|
||||
|
||||
Event event;
|
||||
event.type = Event::LostFocus;
|
||||
pushEvent(event);
|
||||
|
@ -147,6 +147,14 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorVisible(bool visible);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Grab or release the mouse cursor
|
||||
///
|
||||
/// \param grabbed True to enable, false to disable
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorGrabbed(bool grabbed);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable automatic key-repeat
|
||||
///
|
||||
@ -318,7 +326,8 @@ private:
|
||||
bool m_keyRepeat; ///< Is the KeyRepeat feature enabled?
|
||||
Vector2i m_previousSize; ///< Previous size of the window, to find if a ConfigureNotify event is a resize event (could be a move event only)
|
||||
bool m_useSizeHints; ///< Is the size of the window fixed with size hints?
|
||||
bool m_fullscreen; ///< Is window in fullscreen?
|
||||
bool m_fullscreen; ///< Is the window in fullscreen?
|
||||
bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -132,7 +132,9 @@ m_keyRepeatEnabled(true),
|
||||
m_lastSize (0, 0),
|
||||
m_resizing (false),
|
||||
m_surrogate (0),
|
||||
m_mouseInside (false)
|
||||
m_mouseInside (false),
|
||||
m_fullscreen (false),
|
||||
m_cursorGrabbed (false)
|
||||
{
|
||||
// Set that this process is DPI aware and can handle DPI scaling
|
||||
setProcessDpiAware();
|
||||
@ -156,7 +158,9 @@ m_keyRepeatEnabled(true),
|
||||
m_lastSize (mode.width, mode.height),
|
||||
m_resizing (false),
|
||||
m_surrogate (0),
|
||||
m_mouseInside (false)
|
||||
m_mouseInside (false),
|
||||
m_fullscreen (style & Style::Fullscreen),
|
||||
m_cursorGrabbed (m_fullscreen)
|
||||
{
|
||||
// Set that this process is DPI aware and can handle DPI scaling
|
||||
setProcessDpiAware();
|
||||
@ -187,8 +191,7 @@ m_mouseInside (false)
|
||||
}
|
||||
|
||||
// In windowed mode, adjust width and height so that window will have the requested client area
|
||||
bool fullscreen = (style & Style::Fullscreen) != 0;
|
||||
if (!fullscreen)
|
||||
if (!m_fullscreen)
|
||||
{
|
||||
RECT rectangle = {0, 0, width, height};
|
||||
AdjustWindowRect(&rectangle, win32Style, false);
|
||||
@ -204,7 +207,7 @@ m_mouseInside (false)
|
||||
setSize(Vector2u(mode.width, mode.height));
|
||||
|
||||
// Switch to fullscreen if requested
|
||||
if (fullscreen)
|
||||
if (m_fullscreen)
|
||||
switchToFullscreen(mode);
|
||||
|
||||
// Increment window count
|
||||
@ -277,6 +280,9 @@ Vector2i WindowImplWin32::getPosition() const
|
||||
void WindowImplWin32::setPosition(const Vector2i& position)
|
||||
{
|
||||
SetWindowPos(m_handle, NULL, position.x, position.y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
|
||||
|
||||
if(m_cursorGrabbed)
|
||||
grabCursor(true);
|
||||
}
|
||||
|
||||
|
||||
@ -363,6 +369,14 @@ void WindowImplWin32::setMouseCursorVisible(bool visible)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::setMouseCursorGrabbed(bool grabbed)
|
||||
{
|
||||
m_cursorGrabbed = grabbed;
|
||||
grabCursor(m_cursorGrabbed);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::setKeyRepeatEnabled(bool enabled)
|
||||
{
|
||||
@ -485,6 +499,23 @@ void WindowImplWin32::setTracking(bool track)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::grabCursor(bool grabbed)
|
||||
{
|
||||
if (grabbed)
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(m_handle, &rect);
|
||||
MapWindowPoints(m_handle, NULL, reinterpret_cast<LPPOINT>(&rect), 2);
|
||||
ClipCursor(&rect);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClipCursor(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@ -536,6 +567,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
event.size.width = m_lastSize.x;
|
||||
event.size.height = m_lastSize.y;
|
||||
pushEvent(event);
|
||||
|
||||
// Restore/update cursor grabbing
|
||||
grabCursor(m_cursorGrabbed);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -544,6 +578,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
case WM_ENTERSIZEMOVE:
|
||||
{
|
||||
m_resizing = true;
|
||||
grabCursor(false);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -565,6 +600,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
event.size.height = m_lastSize.y;
|
||||
pushEvent(event);
|
||||
}
|
||||
|
||||
// Restore/update cursor grabbing
|
||||
grabCursor(m_cursorGrabbed);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -582,6 +620,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
// Gain focus event
|
||||
case WM_SETFOCUS:
|
||||
{
|
||||
// Restore cursor grabbing
|
||||
grabCursor(m_cursorGrabbed);
|
||||
|
||||
Event event;
|
||||
event.type = Event::GainedFocus;
|
||||
pushEvent(event);
|
||||
@ -591,6 +632,9 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
|
||||
// Lost focus event
|
||||
case WM_KILLFOCUS:
|
||||
{
|
||||
// Ungrab the cursor
|
||||
grabCursor(false);
|
||||
|
||||
Event event;
|
||||
event.type = Event::LostFocus;
|
||||
pushEvent(event);
|
||||
|
@ -145,6 +145,14 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorVisible(bool visible);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Grab or release the mouse cursor
|
||||
///
|
||||
/// \param grabbed True to enable, false to disable
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorGrabbed(bool grabbed);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable automatic key-repeat
|
||||
///
|
||||
@ -216,6 +224,19 @@ private:
|
||||
////////////////////////////////////////////////////////////
|
||||
void setTracking(bool track);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Grab or release the mouse cursor
|
||||
///
|
||||
/// This is not to be confused with setMouseCursorGrabbed.
|
||||
/// Here m_cursorGrabbed is not modified; it is used,
|
||||
/// for example, to release the cursor when switching to
|
||||
/// another application.
|
||||
///
|
||||
/// \param grabbed True to enable, false to disable
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void grabCursor(bool grabbed);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Convert a Win32 virtual key code to a SFML key code
|
||||
///
|
||||
@ -252,6 +273,8 @@ private:
|
||||
bool m_resizing; ///< Is the window being resized?
|
||||
Uint16 m_surrogate; ///< First half of the surrogate pair, in case we're receiving a Unicode character in two events
|
||||
bool m_mouseInside; ///< Mouse is inside the window?
|
||||
bool m_fullscreen; ///< Is the window fullscreen?
|
||||
bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -288,6 +288,14 @@ void Window::setMouseCursorVisible(bool visible)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Window::setMouseCursorGrabbed(bool grabbed)
|
||||
{
|
||||
if (m_impl)
|
||||
m_impl->setMouseCursorGrabbed(grabbed);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void Window::setKeyRepeatEnabled(bool enabled)
|
||||
{
|
||||
|
@ -186,6 +186,14 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorVisible(bool visible) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Grab or release the mouse cursor and keeps it from leaving
|
||||
///
|
||||
/// \param grabbed True to enable, false to disable
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setMouseCursorGrabbed(bool grabbed) = 0;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Enable or disable automatic key-repeat
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user