Implement Event::WindowMoved for Win32

This commit is contained in:
Mark Jansen 2025-01-04 22:27:50 +01:00
parent 796592edae
commit 9b1226f23a
No known key found for this signature in database
GPG Key ID: B39240EE84BEAE8B
4 changed files with 70 additions and 3 deletions

View File

@ -63,6 +63,15 @@ public:
Vector2u size; //!< New size, in pixels Vector2u size; //!< New size, in pixels
}; };
////////////////////////////////////////////////////////////
/// \brief WindowMoved event subtype
///
////////////////////////////////////////////////////////////
struct WindowMoved
{
Vector2i position; //!< New position, in pixels
};
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Lost focus event subtype /// \brief Lost focus event subtype
/// ///
@ -355,6 +364,7 @@ private:
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
std::variant<Closed, std::variant<Closed,
Resized, Resized,
WindowMoved,
FocusLost, FocusLost,
FocusGained, FocusGained,
TextEntered, TextEntered,

View File

@ -186,6 +186,8 @@ m_cursorGrabbed(m_fullscreen)
auto [width, height] = Vector2i(mode.size); auto [width, height] = Vector2i(mode.size);
ReleaseDC(nullptr, screenDC); ReleaseDC(nullptr, screenDC);
m_lastPosition = {left, top};
// Choose the window style according to the Style parameter // Choose the window style according to the Style parameter
DWORD win32Style = WS_VISIBLE; DWORD win32Style = WS_VISIBLE;
if (style == Style::None) if (style == Style::None)
@ -771,7 +773,24 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
break; break;
} }
// Start resizing case WM_MOVE:
{
// Push a move event
if (!m_resizing && m_lastPosition != getPosition())
{
// Update the last handled position
m_lastPosition = getPosition();
// Push a move event
pushEvent(Event::WindowMoved{m_lastPosition});
// Restore/update cursor grabbing
grabCursor(m_cursorGrabbed);
}
break;
}
// Start resizing / moving
case WM_ENTERSIZEMOVE: case WM_ENTERSIZEMOVE:
{ {
m_resizing = true; m_resizing = true;
@ -779,7 +798,7 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
break; break;
} }
// Stop resizing // Stop resizing / moving
case WM_EXITSIZEMOVE: case WM_EXITSIZEMOVE:
{ {
m_resizing = false; m_resizing = false;
@ -793,6 +812,14 @@ void WindowImplWin32::processEvent(UINT message, WPARAM wParam, LPARAM lParam)
// Push a resize event // Push a resize event
pushEvent(Event::Resized{m_lastSize}); pushEvent(Event::Resized{m_lastSize});
} }
if (m_lastPosition != getPosition())
{
// Update the last handled position
m_lastPosition = getPosition();
// Push a move event
pushEvent(Event::WindowMoved{m_lastPosition});
}
// Restore/update cursor grabbing // Restore/update cursor grabbing
grabCursor(m_cursorGrabbed); grabCursor(m_cursorGrabbed);

View File

@ -302,6 +302,7 @@ private:
LoadCursor(nullptr, IDC_ARROW)}; //!< Last cursor used -- this data is not owned by the window and is required to be always valid LoadCursor(nullptr, IDC_ARROW)}; //!< Last cursor used -- this data is not owned by the window and is required to be always valid
HICON m_icon{}; //!< Custom icon assigned to the window HICON m_icon{}; //!< Custom icon assigned to the window
bool m_keyRepeatEnabled{true}; //!< Automatic key-repeat state for keydown events bool m_keyRepeatEnabled{true}; //!< Automatic key-repeat state for keydown events
Vector2i m_lastPosition; //!< The last handled position of the window
Vector2u m_lastSize; //!< The last handled size of the window Vector2u m_lastSize; //!< The last handled size of the window
bool m_resizing{}; //!< Is the window being resized? bool m_resizing{}; //!< Is the window being resized?
char16_t m_surrogate{}; //!< First half of the surrogate pair, in case we're receiving a Unicode character in two events char16_t m_surrogate{}; //!< First half of the surrogate pair, in case we're receiving a Unicode character in two events

View File

@ -19,6 +19,11 @@ struct
return "Resized"; return "Resized";
} }
std::string_view operator()(const sf::Event::WindowMoved&) const
{
return "WindowMoved";
}
std::string_view operator()(const sf::Event::KeyPressed&) const std::string_view operator()(const sf::Event::KeyPressed&) const
{ {
return "KeyPressed"; return "KeyPressed";
@ -45,7 +50,7 @@ TEST_CASE("[Window] sf::Event")
SECTION("Construction") SECTION("Construction")
{ {
SECTION("Template constructor") SECTION("Template constructor resize")
{ {
const sf::Event event = sf::Event::Resized{{1, 2}}; const sf::Event event = sf::Event::Resized{{1, 2}};
CHECK(event.is<sf::Event::Resized>()); CHECK(event.is<sf::Event::Resized>());
@ -53,6 +58,14 @@ TEST_CASE("[Window] sf::Event")
const auto& resized = *event.getIf<sf::Event::Resized>(); const auto& resized = *event.getIf<sf::Event::Resized>();
CHECK(resized.size == sf::Vector2u(1, 2)); CHECK(resized.size == sf::Vector2u(1, 2));
} }
SECTION("Template constructor window move")
{
const sf::Event event = sf::Event::WindowMoved{{1, 2}};
CHECK(event.is<sf::Event::WindowMoved>());
CHECK(event.getIf<sf::Event::WindowMoved>());
const auto& windowMoved = *event.getIf<sf::Event::WindowMoved>();
CHECK(windowMoved.position == sf::Vector2i(1, 2));
}
} }
SECTION("Assign all possible values") SECTION("Assign all possible values")
@ -67,6 +80,12 @@ TEST_CASE("[Window] sf::Event")
const auto& resized = *event.getIf<sf::Event::Resized>(); const auto& resized = *event.getIf<sf::Event::Resized>();
CHECK(resized.size == sf::Vector2u(1, 2)); CHECK(resized.size == sf::Vector2u(1, 2));
event = sf::Event::WindowMoved{{3, 4}};
CHECK(event.is<sf::Event::WindowMoved>());
CHECK(event.getIf<sf::Event::WindowMoved>());
const auto& windowMoved = *event.getIf<sf::Event::WindowMoved>();
CHECK(windowMoved.position == sf::Vector2i(3, 4));
event = sf::Event::FocusLost{}; event = sf::Event::FocusLost{};
CHECK(event.is<sf::Event::FocusLost>()); CHECK(event.is<sf::Event::FocusLost>());
CHECK(event.getIf<sf::Event::FocusLost>()); CHECK(event.getIf<sf::Event::FocusLost>());
@ -221,6 +240,9 @@ TEST_CASE("[Window] sf::Event")
const sf::Event::Resized resized; const sf::Event::Resized resized;
CHECK(resized.size == sf::Vector2u()); CHECK(resized.size == sf::Vector2u());
const sf::Event::WindowMoved windowMoved;
CHECK(windowMoved.position == sf::Vector2i());
const sf::Event::TextEntered textEntered; const sf::Event::TextEntered textEntered;
CHECK(textEntered.unicode == 0); CHECK(textEntered.unicode == 0);
@ -302,12 +324,19 @@ TEST_CASE("[Window] sf::Event")
REQUIRE(mouseMoved); REQUIRE(mouseMoved);
mouseMoved->position = sf::Vector2i(6, 9); mouseMoved->position = sf::Vector2i(6, 9);
CHECK(mouseMoved->position == sf::Vector2i(6, 9)); CHECK(mouseMoved->position == sf::Vector2i(6, 9));
event = sf::Event::WindowMoved{{1, 2}};
auto* windowMoved = event.getIf<sf::Event::WindowMoved>();
REQUIRE(windowMoved);
windowMoved->position = sf::Vector2i(3, 4);
CHECK(windowMoved->position == sf::Vector2i(3, 4));
} }
SECTION("visit()") SECTION("visit()")
{ {
CHECK(sf::Event(sf::Event::Closed{}).visit(visitor) == "Closed"); CHECK(sf::Event(sf::Event::Closed{}).visit(visitor) == "Closed");
CHECK(sf::Event(sf::Event::Resized{}).visit(visitor) == "Resized"); CHECK(sf::Event(sf::Event::Resized{}).visit(visitor) == "Resized");
CHECK(sf::Event(sf::Event::WindowMoved{}).visit(visitor) == "WindowMoved");
CHECK(sf::Event(sf::Event::FocusLost{}).visit(visitor) == "Other"); CHECK(sf::Event(sf::Event::FocusLost{}).visit(visitor) == "Other");
CHECK(sf::Event(sf::Event::FocusGained{}).visit(visitor) == "Other"); CHECK(sf::Event(sf::Event::FocusGained{}).visit(visitor) == "Other");
CHECK(sf::Event(sf::Event::KeyPressed{}).visit(visitor) == "KeyPressed"); CHECK(sf::Event(sf::Event::KeyPressed{}).visit(visitor) == "KeyPressed");