diff --git a/src/graphics/input/focus.cpp b/src/graphics/input/focus.cpp index 334ab2a..4b58b12 100644 --- a/src/graphics/input/focus.cpp +++ b/src/graphics/input/focus.cpp @@ -2,6 +2,7 @@ #include "focus.hpp" #include "../camera.hpp" #include "../../util/math.hpp" +#include "mouse.hpp" #include @@ -11,13 +12,23 @@ using namespace sim::graphics; static std::unique_ptr state = nullptr; +static bool mouse_visible = false; +static bool mouse_locked = false; static bool triggered = false; void focus::on_keypress(int key, int sc, int action, int mods) { if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) { - state = nullptr; + if(is_mouse_locked()) + { + clear_mouse_locked(); + } + + else + { + mouse_locked = true; + } } if(state) @@ -59,6 +70,23 @@ void focus::update() { triggered = false; + bool locked = is_mouse_locked(); + + if(locked != mouse_visible) + { + if(locked) + { + mouse::show_cursor(); + } + + else + { + mouse::hide_cursor(); + } + + mouse_visible = locked; + } + if(state) { state->update(); @@ -70,11 +98,22 @@ bool focus::is_focused() return (state != nullptr); } -void focus::clear() +void focus::clear_focus() { state = nullptr; } +bool focus::is_mouse_locked() +{ + return is_focused() || mouse_locked; +} + +void focus::clear_mouse_locked() +{ + mouse_locked = false; + state = nullptr; +} + void focus::set(std::unique_ptr f) { state = std::move(f); diff --git a/src/graphics/input/focus.hpp b/src/graphics/input/focus.hpp index f5ce407..b641f30 100644 --- a/src/graphics/input/focus.hpp +++ b/src/graphics/input/focus.hpp @@ -16,9 +16,11 @@ struct focus_t virtual void update() { } }; -void clear(); bool is_focused(); +void clear_focus(); bool is_triggered(); +bool is_mouse_locked(); +void clear_mouse_locked(); void set(std::unique_ptr f); void on_keypress(int key, int sc, int action, int mods); void on_mouse_button(int button, int action, int mods); diff --git a/src/graphics/input/mouse.cpp b/src/graphics/input/mouse.cpp index 2c7059b..5059b6a 100644 --- a/src/graphics/input/mouse.cpp +++ b/src/graphics/input/mouse.cpp @@ -13,7 +13,7 @@ static double xpos = 0, ypos = 0; static void cb_cursor_pos(GLFWwindow* win, double x, double y) { - if(focus::is_focused()) + if(focus::is_mouse_locked()) { focus::on_cursor_pos(x - xpos, y - ypos); } @@ -38,6 +38,24 @@ void mouse::get(double& x, double& y) y = ypos; } +void mouse::show_cursor() +{ + double x, y; + GLFWwindow* win = window::get_window(); + glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_NORMAL); + glfwGetCursorPos(win, &x, &y); + cb_cursor_pos(win, x, y); +} + +void mouse::hide_cursor() +{ + double x, y; + GLFWwindow* win = window::get_window(); + glfwSetInputMode(win, GLFW_CURSOR, GLFW_CURSOR_DISABLED); + glfwGetCursorPos(win, &x, &y); + cb_cursor_pos(win, x, y); +} + void mouse::init() { GLFWwindow* win = window::get_window(); diff --git a/src/graphics/input/mouse.hpp b/src/graphics/input/mouse.hpp index 20125d9..0534ead 100644 --- a/src/graphics/input/mouse.hpp +++ b/src/graphics/input/mouse.hpp @@ -6,6 +6,8 @@ namespace sim::graphics::mouse void init(); void get(double& x, double& y); +void show_cursor(); +void hide_cursor(); };