diff options
Diffstat (limited to 'src/crepe/system')
-rw-r--r-- | src/crepe/system/InputSystem.cpp | 235 | ||||
-rw-r--r-- | src/crepe/system/InputSystem.h | 13 |
2 files changed, 136 insertions, 112 deletions
diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index a710ae2..459feb3 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -1,3 +1,4 @@ + #include "../api/Button.h" #include "../manager/ComponentManager.h" #include "../manager/EventManager.h" @@ -16,6 +17,7 @@ void InputSystem::update() { RefVector<Button> buttons = mgr.get_components_by_type<Button>(); RefVector<Camera> cameras = mgr.get_components_by_type<Camera>(); OptionalRef<Camera> curr_cam_ref; + // Find the active camera for (Camera & cam : cameras) { if (!cam.active) continue; @@ -23,149 +25,182 @@ void InputSystem::update() { break; } if (!curr_cam_ref) return; + Camera & current_cam = curr_cam_ref; RefVector<Transform> transform_vec = mgr.get_components_by_id<Transform>(current_cam.game_object_id); Transform & cam_transform = transform_vec.front().get(); - int camera_origin_x = cam_transform.position.x + current_cam.data.postion_offset.x - - (current_cam.viewport_size.x / 2); - int camera_origin_y = cam_transform.position.y + current_cam.data.postion_offset.y - - (current_cam.viewport_size.y / 2); + + ivec2 camera_origin; + camera_origin.y = cam_transform.position.y + current_cam.data.postion_offset.y + - (current_cam.viewport_size.y / 2); + camera_origin.x = cam_transform.position.x + current_cam.data.postion_offset.x + - (current_cam.viewport_size.x / 2); for (const SDLContext::EventData & event : event_list) { - int world_mouse_x = event.mouse_position.x + camera_origin_x; - int world_mouse_y = event.mouse_position.y + camera_origin_y; - // check if the mouse is within the viewport - bool mouse_in_viewport - = !(world_mouse_x < camera_origin_x - || world_mouse_x > camera_origin_x + current_cam.viewport_size.x - || world_mouse_y < camera_origin_y - || world_mouse_y > camera_origin_y + current_cam.viewport_size.y); - - switch (event.event_type) { - case SDLContext::EventType::KEYDOWN: - event_mgr.queue_event<KeyPressEvent>(KeyPressEvent{ - .repeat = event.key_repeat, - .key = event.key, - }); - break; - case SDLContext::EventType::KEYUP: - event_mgr.queue_event<KeyReleaseEvent>(KeyReleaseEvent{ - .key = event.key, - }); - break; - case SDLContext::EventType::MOUSEDOWN: - if (!mouse_in_viewport) { + // Only calculate mouse coordinates for relevant events + if (event.event_type == SDLContext::EventType::MOUSEDOWN + || event.event_type == SDLContext::EventType::MOUSEUP + || event.event_type == SDLContext::EventType::MOUSEMOVE + || event.event_type == SDLContext::EventType::MOUSEWHEEL) { + + ivec2 adjusted_mouse; + adjusted_mouse.x = event.mouse_data.mouse_position.x + camera_origin.x; + adjusted_mouse.y = event.mouse_data.mouse_position.y + camera_origin.y; + // Check if the mouse is within the viewport + bool mouse_in_viewport + = !(adjusted_mouse.x < camera_origin.x + || adjusted_mouse.x > camera_origin.x + current_cam.viewport_size.x + || adjusted_mouse.y < camera_origin.y + || adjusted_mouse.y > camera_origin.y + current_cam.viewport_size.y); + + if (!mouse_in_viewport) continue; + + // Handle mouse-specific events + switch (event.event_type) { + case SDLContext::EventType::MOUSEDOWN: + event_mgr.queue_event<MousePressEvent>({ + .mouse_pos = {adjusted_mouse.x, adjusted_mouse.y}, + .button = event.mouse_data.mouse_button, + }); + this->last_mouse_down_position = {adjusted_mouse.x, adjusted_mouse.y}; + this->last_mouse_button = event.mouse_data.mouse_button; break; - } - event_mgr.queue_event<MousePressEvent>(MousePressEvent{ - .mouse_x = world_mouse_x, - .mouse_y = world_mouse_y, - .button = event.mouse_button, - }); - this->last_mouse_down_position = {world_mouse_x, world_mouse_y}; - this->last_mouse_button = event.mouse_button; - break; - case SDLContext::EventType::MOUSEUP: { - if (!mouse_in_viewport) { + + case SDLContext::EventType::MOUSEUP: { + event_mgr.queue_event<MouseReleaseEvent>({ + .mouse_pos = {adjusted_mouse.x, adjusted_mouse.y}, + .button = event.mouse_data.mouse_button, + }); + int delta_x = adjusted_mouse.x - this->last_mouse_down_position.x; + int delta_y = adjusted_mouse.y - this->last_mouse_down_position.y; + + if (this->last_mouse_button == event.mouse_data.mouse_button + && std::abs(delta_x) <= click_tolerance + && std::abs(delta_y) <= click_tolerance) { + event_mgr.queue_event<MouseClickEvent>({ + .mouse_pos = {adjusted_mouse.x, adjusted_mouse.y}, + .button = event.mouse_data.mouse_button, + }); + this->handle_click(event.mouse_data.mouse_button, adjusted_mouse); + } break; } - event_mgr.queue_event<MouseReleaseEvent>(MouseReleaseEvent{ - .mouse_x = world_mouse_x, - .mouse_y = world_mouse_y, - .button = event.mouse_button, - }); - //check if its a click by checking the last button down - int delta_x = world_mouse_x - this->last_mouse_down_position.x; - int delta_y = world_mouse_y - this->last_mouse_down_position.y; - - if (this->last_mouse_button == event.mouse_button - && std::abs(delta_x) <= click_tolerance - && std::abs(delta_y) <= click_tolerance) { - event_mgr.queue_event<MouseClickEvent>(MouseClickEvent{ - .mouse_x = world_mouse_x, - .mouse_y = world_mouse_y, - .button = event.mouse_button, + + case SDLContext::EventType::MOUSEMOVE: + event_mgr.queue_event<MouseMoveEvent>({ + .mouse_pos = {adjusted_mouse.x, adjusted_mouse.y}, + .mouse_delta = event.mouse_data.rel_mouse_move, }); + this->handle_move(event, adjusted_mouse); + break; - this->handle_click(event.mouse_button, world_mouse_x, world_mouse_y); - } - } break; - case SDLContext::EventType::MOUSEMOVE: - if (!mouse_in_viewport) { + case SDLContext::EventType::MOUSEWHEEL: + event_mgr.queue_event<MouseScrollEvent>({ + .mouse_pos = {adjusted_mouse.x, adjusted_mouse.y}, + .scroll_direction = event.mouse_data.scroll_direction, + .scroll_delta = event.mouse_data.scroll_delta, + }); break; - } - event_mgr.queue_event<MouseMoveEvent>(MouseMoveEvent{ - .mouse_x = world_mouse_x, - .mouse_y = world_mouse_y, - .delta_x = event.rel_mouse_move.x, - .delta_y = event.rel_mouse_move.y, - }); - this->handle_move(event, world_mouse_x, world_mouse_y); - break; - case SDLContext::EventType::MOUSEWHEEL: - event_mgr.queue_event<MouseScrollEvent>(MouseScrollEvent{ - .mouse_x = world_mouse_x, - .mouse_y = world_mouse_y, - .scroll_direction = event.scroll_direction, - .scroll_delta = event.scroll_delta, - }); - break; - case SDLContext::EventType::SHUTDOWN: - event_mgr.queue_event<ShutDownEvent>(ShutDownEvent{}); - break; - default: - break; + + default: + break; + } + } else { + // Handle non-mouse events + switch (event.event_type) { + case SDLContext::EventType::KEYDOWN: + event_mgr.queue_event<KeyPressEvent>( + {.repeat = event.key_data.key_repeat, .key = event.key_data.key}); + break; + case SDLContext::EventType::KEYUP: + event_mgr.queue_event<KeyReleaseEvent>({.key = event.key_data.key}); + break; + case SDLContext::EventType::SHUTDOWN: + event_mgr.queue_event<ShutDownEvent>({}); + break; + case SDLContext::EventType::WINDOW_EXPOSE: + event_mgr.queue_event<WindowExposeEvent>({}); + break; + case SDLContext::EventType::WINDOW_RESIZE: + event_mgr.queue_event<WindowResizeEvent>( + WindowResizeEvent{.dimensions = event.window_data.resize_dimension}); + break; + case SDLContext::EventType::WINDOW_MOVE: + event_mgr.queue_event<WindowMoveEvent>( + {.delta_move = event.window_data.move_delta}); + break; + case SDLContext::EventType::WINDOW_MINIMIZE: + event_mgr.queue_event<WindowMinimizeEvent>({}); + break; + case SDLContext::EventType::WINDOW_MAXIMIZE: + event_mgr.queue_event<WindowMaximizeEvent>({}); + break; + case SDLContext::EventType::WINDOW_FOCUS_GAIN: + event_mgr.queue_event<WindowFocusGainEvent>({}); + break; + case SDLContext::EventType::WINDOW_FOCUS_LOST: + event_mgr.queue_event<WindowFocusLostEvent>({}); + break; + default: + break; + } } } } + void InputSystem::handle_move(const SDLContext::EventData & event_data, - const int world_mouse_x, const int world_mouse_y) { + const ivec2& mouse_pos) { ComponentManager & mgr = this->mediator.component_manager; RefVector<Button> buttons = mgr.get_components_by_type<Button>(); for (Button & button : buttons) { + if(!button.active) continue; RefVector<Transform> transform_vec = mgr.get_components_by_id<Transform>(button.game_object_id); Transform & transform(transform_vec.front().get()); bool was_hovering = button.hover; - if (button.active - && this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { + if (this->is_mouse_inside_button(mouse_pos, button, + transform)) { button.hover = true; - if (!was_hovering && button.on_mouse_enter) { + if(!button.on_mouse_enter) continue; + if (!was_hovering) { button.on_mouse_enter(); } } else { button.hover = false; // Trigger the on_exit callback if the hover state just changed to false - if (was_hovering && button.on_mouse_exit) { + if(!button.on_mouse_exit) continue; + if (was_hovering) { button.on_mouse_exit(); } } } } -void InputSystem::handle_click(const MouseButton & mouse_button, const int world_mouse_x, - const int world_mouse_y) { +void InputSystem::handle_click(const MouseButton & mouse_button, const ivec2& mouse_pos) { ComponentManager & mgr = this->mediator.component_manager; RefVector<Button> buttons = mgr.get_components_by_type<Button>(); for (Button & button : buttons) { + if(!button.active) continue; + if (!button.on_click) continue; RefVector<Transform> transform_vec = mgr.get_components_by_id<Transform>(button.game_object_id); Transform & transform = transform_vec.front().get(); - - if (button.active - && this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { - this->handle_button_press(button); + + if (this->is_mouse_inside_button(mouse_pos, button, + transform)) { + + button.on_click(); } } } -bool InputSystem::is_mouse_inside_button(const int mouse_x, const int mouse_y, +bool InputSystem::is_mouse_inside_button(const ivec2& mouse_pos, const Button & button, const Transform & transform) { int actual_x = transform.position.x + button.offset.x; int actual_y = transform.position.y + button.offset.y; @@ -174,17 +209,7 @@ bool InputSystem::is_mouse_inside_button(const int mouse_x, const int mouse_y, int half_height = button.dimensions.y / 2; // Check if the mouse is within the button's boundaries - return mouse_x >= actual_x - half_width && mouse_x <= actual_x + half_width - && mouse_y >= actual_y - half_height && mouse_y <= actual_y + half_height; + return mouse_pos.x >= actual_x - half_width && mouse_pos.x <= actual_x + half_width + && mouse_pos.y >= actual_y - half_height && mouse_pos.y <= actual_y + half_height; } -void InputSystem::handle_button_press(Button & button) { - if (button.is_toggle) { - if (!button.is_pressed && button.on_click) { - button.on_click(); - } - button.is_pressed = !button.is_pressed; - } else if (button.on_click) { - button.on_click(); - } -} diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h index 87e86f8..3703635 100644 --- a/src/crepe/system/InputSystem.h +++ b/src/crepe/system/InputSystem.h @@ -1,5 +1,6 @@ #pragma once +#include "../api/Config.h" #include "../facade/SDLContext.h" #include "../types.h" #include "../util/OptionalRef.h" @@ -37,8 +38,8 @@ private: //! Stores the last mouse button pressed. MouseButton last_mouse_button = MouseButton::NONE; - //! The maximum allowable distance between mouse down and mouse up to register as a click. - const int click_tolerance = 5; + //! The maximum allowable distance between mouse down and mouse up to register as a click. This can be changed using the Config. + int click_tolerance = Config::get_instance().input.click_tolerance; /** * \brief Handles the mouse click event. @@ -48,8 +49,7 @@ private: * * This method processes the mouse click event and triggers the corresponding button action. */ - void handle_click(const MouseButton & mouse_button, const int world_mouse_x, - const int world_mouse_y); + void handle_click(const MouseButton & mouse_button,const ivec2& mouse_pos); /** * \brief Handles the mouse movement event. @@ -59,8 +59,7 @@ private: * * This method processes the mouse movement event and updates the button hover state. */ - void handle_move(const SDLContext::EventData & event_data, const int world_mouse_x, - const int world_mouse_y); + void handle_move(const SDLContext::EventData & event_data, const ivec2& mouse_pos); /** * \brief Checks if the mouse position is inside the bounds of the button. @@ -70,7 +69,7 @@ private: * \param transform The transform component of the button. * \return True if the mouse is inside the button, false otherwise. */ - bool is_mouse_inside_button(const int world_mouse_x, const int world_mouse_y, + bool is_mouse_inside_button(const ivec2& mouse_pos, const Button & button, const Transform & transform); /** |