diff options
-rw-r--r-- | src/crepe/api/Button.cpp | 6 | ||||
-rw-r--r-- | src/crepe/api/Button.h | 42 | ||||
-rw-r--r-- | src/crepe/api/Event.h | 4 | ||||
-rw-r--r-- | src/crepe/facade/SDLContext.h | 2 | ||||
-rw-r--r-- | src/crepe/system/InputSystem.cpp | 64 | ||||
-rw-r--r-- | src/crepe/system/InputSystem.h | 10 | ||||
-rw-r--r-- | src/test/InputTest.cpp | 12 |
7 files changed, 75 insertions, 65 deletions
diff --git a/src/crepe/api/Button.cpp b/src/crepe/api/Button.cpp index c0ff5a8..a27ff53 100644 --- a/src/crepe/api/Button.cpp +++ b/src/crepe/api/Button.cpp @@ -2,12 +2,10 @@ namespace crepe { -Button::Button(game_object_id_t id, int width, int height, bool is_toggle, - std::function<void()> on_click) +Button::Button(game_object_id_t id, int width, int height, std::function<void()> on_click, bool is_toggle + ) : UiObject(id, width, height), is_toggle(is_toggle), - is_pressed(false), - hover(false), on_click(on_click) {} } // namespace crepe diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h index 2fa94ae..1410529 100644 --- a/src/crepe/api/Button.h +++ b/src/crepe/api/Button.h @@ -24,8 +24,7 @@ public: * \param is_toggle Optional flag to indicate if the button is a toggle button. Defaults to false. * \param on_click callback function that will be invoked when the button is clicked. */ - Button(game_object_id_t id, int width, int height, bool is_toggle = false, - std::function<void()> on_click = nullptr); + Button(game_object_id_t id, int width, int height, std::function<void()> on_click, bool is_toggle = false); /** * \brief Indicates if the button is a toggle button (can be pressed and released). @@ -33,29 +32,46 @@ public: * A toggle button allows for a pressed/released state, whereas a regular button * typically only has an on-click state. */ - bool is_toggle; + bool is_toggle = false; /** - * \brief Indicates whether the button is currently pressed. + * \brief The callback function to be executed when the button is clicked. * - * This state is true when the button is actively pressed and false otherwise. + * This function is invoked whenever the button is clicked. It can be set to any + * function that matches the signature `void()`. */ - bool is_pressed; + std::function<void()> on_click; + + /** + * \brief Callback function to be executed when the mouse enters the button's boundaries. + * + * This function is triggered when the mouse cursor moves over the button, allowing + * custom actions like visual effects, highlighting, or sound effects. + */ + std::function<void()> on_enter; /** - * \brief Indicates whether the mouse is currently hovering over the button. + * \brief Callback function to be executed when the mouse exits the button's boundaries. + * + * This function is triggered when the mouse cursor moves out of the button's area, + * allowing custom actions like resetting visual effects or playing exit-related effects. + */ + std::function<void()> on_exit; + private: + friend class InputSystem; + /** + * \brief Indicates whether the button is currently pressed. * - * This is set to true when the mouse is over the button and false otherwise. + * This state is true when the button is actively pressed and false otherwise. */ - bool hover; + bool is_pressed = false; /** - * \brief The callback function to be executed when the button is clicked. + * \brief Indicates whether the mouse is currently hovering over the button. * - * This function is invoked whenever the button is clicked. It can be set to any - * function that matches the signature `void()`. Defaults to nullptr. + * This is set to true when the mouse is over the button and false otherwise. */ - std::function<void()> on_click; + bool hover = false; public: /** diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index a7d5511..91a30b5 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -89,10 +89,10 @@ public: //! Y-coordinate of the mouse position at the time of the event. int mouse_y = 0; - // Relative movement in x + // Movement since last event in x int rel_x = 0; - // Relative movement in y + // Movement since last event in y int rel_y = 0; }; diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 886dda8..546e3fe 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -86,7 +86,7 @@ private: * This method maps an SDL key code to the corresponding `Keycode` enum value, * which is used internally by the system to identify the keys. * - * @param sdlKey The SDL key code to convert. + * @param sdl_key The SDL key code to convert. * @return The corresponding `Keycode` value. */ Keycode sdl_to_keycode(SDL_Keycode sdl_key); diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index 070f804..4695620 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -80,50 +80,54 @@ void InputSystem::update() { } void InputSystem::handle_move(const SDLContext::EventData & event_data) { - ComponentManager & mgr = this->component_manager; - - RefVector<Button> buttons = mgr.get_components_by_type<Button>(); - RefVector<Transform> transforms = mgr.get_components_by_type<Transform>(); - - for (Button & button : buttons) { - OptionalRef<Transform> transform = find_transform_for_button(button, transforms); - if (!transform) continue; - - if (button.active && is_mouse_inside_button(event_data, button, transform)) { - button.hover = true; - } else { - button.hover = false; - } - } + ComponentManager & mgr = this->component_manager; + + RefVector<Button> buttons = mgr.get_components_by_type<Button>(); + + + for (Button & button : buttons) { + RefVector<Transform> transform_vec = mgr.get_components_by_id<Transform>(button.game_object_id); + OptionalRef<Transform> transform(transform_vec.front().get()); + if (!transform) continue; + + bool was_hovering = button.hover; // Store previous hover state + + // Check if the mouse is inside the button + if (button.active && is_mouse_inside_button(event_data, button, transform)) { + button.hover = true; + + // Trigger the on_enter callback if the hover state just changed to true + if (!was_hovering && button.on_enter) { + button.on_enter(); + } + } else { + button.hover = false; + + // Trigger the on_exit callback if the hover state just changed to false + if (was_hovering && button.on_exit) { + button.on_exit(); + } + } + } } + void InputSystem::handle_click(const SDLContext::EventData & event_data) { ComponentManager & mgr = this->component_manager; RefVector<Button> buttons = mgr.get_components_by_type<Button>(); - RefVector<Transform> transforms = mgr.get_components_by_type<Transform>(); + for (Button & button : buttons) { - OptionalRef<Transform> transform_ref = find_transform_for_button(button, transforms); + RefVector<Transform> transform_vec = mgr.get_components_by_id<Transform>(button.game_object_id); + OptionalRef<Transform> transform(transform_vec.front().get()); - if (button.active && is_mouse_inside_button(event_data, button, transform_ref)) { + if (button.active && is_mouse_inside_button(event_data, button, transform)) { handle_button_press(button); } } } -OptionalRef<Transform> -InputSystem::find_transform_for_button(Button & button, RefVector<Transform> & transforms) { - - for (auto & transform : transforms) { - if (button.game_object_id == transform.get().game_object_id) { - return OptionalRef<Transform>(transform); - } - } - - return OptionalRef<Transform>(); -} - bool InputSystem::is_mouse_inside_button(const SDLContext::EventData & event_data, const Button & button, const Transform & transform) { return event_data.mouse_position.first >= transform.position.x diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h index b648144..c6ca114 100644 --- a/src/crepe/system/InputSystem.h +++ b/src/crepe/system/InputSystem.h @@ -54,16 +54,6 @@ private: * This method processes the mouse movement event and updates the button hover state. */ void handle_move(const SDLContext::EventData & eventData); - - /** - * \brief Finds the transform component associated with a button. - * \param button The button to find the associated transform for. - * \param transforms A list of transforms to search through. - * \return A pointer to the transform of the button, or nullptr if not found. - */ - OptionalRef<Transform> find_transform_for_button(Button & button, - RefVector<Transform> & transforms); - /** * \brief Checks if the mouse position is inside the bounds of the button. * \param eventData The event data containing the mouse position. diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp index d6ebb6f..2467839 100644 --- a/src/test/InputTest.cpp +++ b/src/test/InputTest.cpp @@ -1,5 +1,6 @@ #include <gtest/gtest.h> #define protected public +#define private public #include "api/EventManager.h" #include "api/KeyCodes.h" #include "system/InputSystem.h" @@ -188,13 +189,13 @@ TEST_F(InputTest, MouseClick) { TEST_F(InputTest, testButtonClick) { GameObject obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1); - - auto & button = obj.add_component<Button>(100, 100); bool button_clicked = false; + std::function<void()> on_click = [&]() { button_clicked = true; }; + auto & button = obj.add_component<Button>(100, 100,on_click,false); + bool hover = false; button.active = true; - std::function<void()> on_click = [&]() { button_clicked = true; }; - button.on_click = on_click; + button.is_pressed = false; button.is_toggle = false; this->simulate_mouse_click(101, 101, SDL_BUTTON_LEFT); @@ -210,8 +211,9 @@ TEST_F(InputTest, testButtonClick) { TEST_F(InputTest, testButtonHover) { GameObject obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1); - auto & button = obj.add_component<Button>(100, 100); bool button_clicked = false; + std::function<void()> on_click = [&]() { button_clicked = true; }; + auto & button = obj.add_component<Button>(100, 100,on_click,false); button.active = true; button.width = 100; button.height = 100; |