diff --git a/include/blt/gfx/input.h b/include/blt/gfx/input.h index 93f3a02..1b48280 100644 --- a/include/blt/gfx/input.h +++ b/include/blt/gfx/input.h @@ -26,6 +26,11 @@ namespace blt::gfx class input_manager { + public: + double mouseX = 0, mouseY = 0; + double mouseLastX = 0, mouseLastY = 0; + double deltaX = 0, deltaY = 0; + double scroll = 0; private: KEY_STATE* key_state; MOUSE_STATE* mouse_state; @@ -70,7 +75,8 @@ namespace blt::gfx return key_state[key]; } - bool isKeyPressed(std::size_t key){ + bool isKeyPressed(std::size_t key) + { if (key >= key_size) expand_keys(key); return key_state[key] != KEY_STATE::RELEASE; @@ -83,12 +89,28 @@ namespace blt::gfx return mouse_state[mouse]; } - bool isMousePressed(std::size_t mouse){ + bool isMousePressed(std::size_t mouse) + { if (mouse >= mouse_size) expand_mouse(mouse); return mouse_state[mouse] != MOUSE_STATE::RELEASE; } + void updateMousePos(double x, double y) + { + mouseLastX = mouseX; + mouseLastY = mouseY; + mouseX = x; + mouseY = y; + deltaX = mouseX - mouseLastX; + deltaY = mouseY - mouseLastY; + } + + void updateScroll(double s) + { + scroll = s; + } + ~input_manager() { delete[] key_state; diff --git a/include/blt/gfx/window.h b/include/blt/gfx/window.h index 9b2be84..054e474 100644 --- a/include/blt/gfx/window.h +++ b/include/blt/gfx/window.h @@ -56,6 +56,30 @@ namespace blt::gfx void init(const window_data& data); + double getMouseX(); + + double getMouseY(); + + double getMouseDX(); + + double getMouseDY(); + + void lockCursor(); + + void unlockCursor(); + + bool isCursorLocked(); + + bool isCursorInWindow(); + + void setRawInput(bool state); + + bool isRawInput(); + + void setClipboard(const std::string& str); + + std::string getClipboard(); + void cleanup(); } diff --git a/src/blt/gfx/window.cpp b/src/blt/gfx/window.cpp index 4b2aa81..ea025a4 100644 --- a/src/blt/gfx/window.cpp +++ b/src/blt/gfx/window.cpp @@ -7,6 +7,7 @@ #include #include #include +#include void error_callback(int error, const char* description) { @@ -19,15 +20,70 @@ namespace blt::gfx // because we aren't meant to have multiple GLFW windows (especially with GLAD) we will keep the window as global state.1 struct { + /* GLFW Window Object */ GLFWwindow* window = nullptr; + /* BLT internal input state manager, handles keyboard/mouse allocations + states */ input_manager inputManager; + /* stores any drag and dropped paths for processing */ + std::queue pendingPaths; + /* current width and height of the window */ std::int32_t width = 0; std::int32_t height = 0; } window_state; void create_callbacks() { - + /* Setup keyboard callback */ + glfwSetKeyCallback(window_state.window, [](GLFWwindow* window, int key, int scancode, int action, int mods) { + if (key < 0 || key == GLFW_KEY_UNKNOWN) + return; + KEY_STATE state; + switch (action) + { + case GLFW_PRESS: + state = KEY_STATE::PRESS; + break; + case GLFW_REPEAT: + state = KEY_STATE::REPEAT; + break; + default: + state = KEY_STATE::RELEASE; + } + window_state.inputManager.key(key) = state; + }); + + /* Setup mouse button callback */ + glfwSetMouseButtonCallback(window_state.window, [](GLFWwindow* window, int button, int action, int mods) { + if (button < 0) + return; + MOUSE_STATE state; + switch (action) + { + case GLFW_PRESS: + state = MOUSE_STATE::PRESS; + break; + default: + state = MOUSE_STATE::RELEASE; + break; + } + window_state.inputManager.mouse(button) = state; + }); + + /* Setup mouse cursor callback */ + glfwSetCursorPosCallback(window_state.window, [](GLFWwindow* window, double x, double y) { + window_state.inputManager.updateMousePos(x, y); + }); + + /* Setup mouse scroll callback */ + glfwSetScrollCallback(window_state.window, [](GLFWwindow* window, double x, double s) { + window_state.inputManager.updateScroll(s); + }); + + /* Setup drop input callback */ + glfwSetDropCallback(window_state.window, [](GLFWwindow* window, int count, const char** paths) { + for (int i = 0; i < count; i++) + window_state.pendingPaths.emplace(paths[i]); + }); } void init(const window_data& data) @@ -77,4 +133,65 @@ namespace blt::gfx glfwDestroyWindow(window_state.window); glfwTerminate(); } + + double getMouseX() + { + return window_state.inputManager.mouseX; + } + + double getMouseY() + { + return window_state.inputManager.mouseY; + } + + double getMouseDX() + { + return window_state.inputManager.deltaX; + } + + double getMouseDY() + { + return window_state.inputManager.deltaY; + } + + void lockCursor() + { + glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + } + + void unlockCursor() + { + glfwSetInputMode(window_state.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + } + + bool isCursorLocked() + { + return glfwGetInputMode(window_state.window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED; + } + + bool isCursorInWindow() + { + return glfwGetWindowAttrib(window_state.window, GLFW_HOVERED); + } + + void setRawInput(bool state) + { + if (glfwRawMouseMotionSupported()) + glfwSetInputMode(window_state.window, GLFW_RAW_MOUSE_MOTION, state ? GLFW_TRUE : GLFW_FALSE); + } + + bool isRawInput() + { + return glfwGetInputMode(window_state.window, GLFW_RAW_MOUSE_MOTION); + } + + void setClipboard(const std::string& str) + { + glfwSetClipboardString(window_state.window, str.c_str()); + } + + std::string getClipboard() + { + return glfwGetClipboardString(window_state.window); + } }