From fe0f60f77530f6b410ddcfe4c3764b42c27080f1 Mon Sep 17 00:00:00 2001 From: Harrand Date: Mon, 28 Oct 2024 09:23:58 +0000 Subject: [PATCH] [os.input] expanded input API --- cmake/compiler.cmake | 5 ++--- include/tz/os/input.hpp | 22 +++++++++++++++++++ src/tz/os/impl_win32.cpp | 46 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 3 deletions(-) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 94df0befde..2041bc4120 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -13,9 +13,9 @@ function(configure_msvc) # TODO target_compile_definitions(topaz PRIVATE -D_CRT_SECURE_NO_WARNINGS) if(${CMAKE_BUILD_TYPE} MATCHES "debug") - target_link_options(topaz PUBLIC /MTd) + target_link_options(topaz PRIVATE "/MTd") else() - target_link_options(topaz PUBLIC /MT) + target_link_options(topaz PRIVATE "/MT") endif() endfunction() @@ -31,7 +31,6 @@ function(configure_clang) configure_gnu_like() if(CMAKE_CXX_SIMULATE_ID MATCHES "MSVC") # clang-cl (or clang against MSVC). Just pretend we're msvc. - configure_msvc() return() endif() # Code below runs if we're clang proper. diff --git a/include/tz/os/input.hpp b/include/tz/os/input.hpp index 7579ea2eee..d8f700d617 100644 --- a/include/tz/os/input.hpp +++ b/include/tz/os/input.hpp @@ -1,6 +1,7 @@ #ifndef TOPAZ_OS_INPUT_HPP #define TOPAZ_OS_INPUT_HPP #include "tz/core/error.hpp" +#include namespace tz::os { @@ -91,6 +92,27 @@ namespace tz::os * @return True if the given key is currently pressed, otherwise false. */ bool is_key_pressed(key k); + constexpr std::pair invalid_mouse_position{-1u, -1u}; + /** + * @ingroup tz_os_input + * @brief Retrieve the mouse cursor's current position, in pixels, relative to the top-left of the window. + * + * If for whatever reason the cursor pos cannot be retrieved, {-1, -1} is returned. Some reasons could include: + * - You haven't opened a window via @ref open_window. + * - The mouse currently lies outside of the window. + */ + std::pair get_mouse_position(); + + enum class mouse_button + { + left, + right, + middle, + _count + }; + + bool is_mouse_clicked(mouse_button b); + std::pair get_mouse_click_position(mouse_button b); } #endif // TOPAZ_OS_INPUT_HPP \ No newline at end of file diff --git a/src/tz/os/impl_win32.cpp b/src/tz/os/impl_win32.cpp index bf3f684e8e..c66406c611 100644 --- a/src/tz/os/impl_win32.cpp +++ b/src/tz/os/impl_win32.cpp @@ -402,6 +402,43 @@ namespace tz::os return GetAsyncKeyState(key_mappings[static_cast(k)]) & 0x8000; } + std::pair get_mouse_position() + { + POINT p; + if(wnd != nullptr && GetCursorPos(&p)) + { + if(ScreenToClient(wnd, &p)) + { + if(std::cmp_greater(p.x, window_get_width()) || std::cmp_greater(p.y, window_get_height())) + { + return invalid_mouse_position; + } + p.x = std::clamp(static_cast(p.x), 0, static_cast(window_get_width())); + p.y = std::clamp(static_cast(p.y), 0, static_cast(window_get_height())); + return {p.x, p.y}; + } + } + return invalid_mouse_position; + } + + bool is_mouse_clicked(mouse_button b) + { + std::array(mouse_button::_count)> button_mappings + { + VK_LBUTTON, + VK_RBUTTON, + VK_MBUTTON + }; + return GetAsyncKeyState(button_mappings[static_cast(b)]) & 0x8000; + } + + std::pair last_mouse_click[static_cast(mouse_button::_count)]; + + std::pair get_mouse_click_position(mouse_button b) + { + return last_mouse_click[static_cast(b)]; + } + std::expected read_file(std::filesystem::path path) { HANDLE file = CreateFileA(path.string().c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); @@ -473,6 +510,15 @@ namespace tz::os kb_callback(wparam); } break; + case WM_RBUTTONDOWN: + last_mouse_click[static_cast(mouse_button::right)] = get_mouse_position(); + break; + case WM_LBUTTONDOWN: + last_mouse_click[static_cast(mouse_button::left)] = get_mouse_position(); + break; + case WM_MBUTTONDOWN: + last_mouse_click[static_cast(mouse_button::middle)] = get_mouse_position(); + break; } return DefWindowProcA(hwnd, msg, wparam, lparam); }