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; |