diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/crepe/api/Button.cpp | 4 | ||||
| -rw-r--r-- | src/crepe/api/Button.h | 27 | ||||
| -rw-r--r-- | src/crepe/api/Event.h | 14 | ||||
| -rw-r--r-- | src/crepe/api/UiObject.cpp | 5 | ||||
| -rw-r--r-- | src/crepe/api/UiObject.h | 21 | ||||
| -rw-r--r-- | src/crepe/facade/SDLContext.cpp | 3 | ||||
| -rw-r--r-- | src/crepe/facade/SDLContext.h | 19 | ||||
| -rw-r--r-- | src/crepe/system/InputSystem.cpp | 70 | ||||
| -rw-r--r-- | src/crepe/system/InputSystem.h | 19 | ||||
| -rw-r--r-- | src/example/button.cpp | 7 | ||||
| -rw-r--r-- | src/test/InputTest.cpp | 10 | 
11 files changed, 101 insertions, 98 deletions
| diff --git a/src/crepe/api/Button.cpp b/src/crepe/api/Button.cpp index d325014..f179f60 100644 --- a/src/crepe/api/Button.cpp +++ b/src/crepe/api/Button.cpp @@ -2,9 +2,9 @@  namespace crepe { -Button::Button(game_object_id_t id, int width, int height, std::function<void()> on_click, +Button::Button(game_object_id_t id, vec2 dimensions,vec2 offset, std::function<void()> on_click,  			   bool is_toggle) -	: UiObject(id, width, height), +	: UIObject(id, dimensions,offset),  	  is_toggle(is_toggle),  	  on_click(on_click) {} diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h index 06d64d6..043cc78 100644 --- a/src/crepe/api/Button.h +++ b/src/crepe/api/Button.h @@ -7,25 +7,21 @@  namespace crepe {  /** - * \class Button   * \brief Represents a clickable UI button, derived from the UiObject class.   *  - * This class provides functionality for a button in the UI, including toggle state, - * click handling, and mouse hover detection. A callback function can be provided to - * handle button clicks.   */ -class Button : public UiObject { +class Button : public UIObject {  public:  	/**       * \brief Constructs a Button with the specified game object ID and dimensions.       *        * \param id The unique ID of the game object associated with this button. -     * \param width The width of the button. -     * \param height The height of the button. +     * \param Dimensions The width and height of the UIObject +     * \param offset The offset relative this GameObjects Transform       * \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, std::function<void()> on_click, +	Button(game_object_id_t id, vec2 dimensions,vec2 offset, std::function<void()> on_click,  		   bool is_toggle = false);  	/** @@ -50,7 +46,7 @@ public:  	 * 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 = nullptr; +	std::function<void()> on_mouse_enter = nullptr;  	/**  	 * \brief Callback function to be executed when the mouse exits the button's boundaries. @@ -58,14 +54,15 @@ public:  	 * 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 = nullptr; +	std::function<void()> on_mouse_exit = nullptr;  private: +	//! friend relation for is_pressed and hover variables  	friend class InputSystem;  	/** -     * \brief Indicates whether the button is currently pressed. +     * \brief Indicates whether the toggle button is pressed       *  -     * This state is true when the button is actively pressed and false otherwise. +     *  This state indicates if the toggle button is pressed or not       */  	bool is_pressed = false; @@ -77,12 +74,6 @@ private:  	bool hover = false;  public: -	/** -     * \brief Retrieves the maximum number of instances allowed for this button type. -     *  -     * \return Always returns 1, as only a single instance of this type is allowed. -     */ -	virtual int get_instances_max() const override { return 1; }  };  } // namespace crepe diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h index 91a30b5..8083d7c 100644 --- a/src/crepe/api/Event.h +++ b/src/crepe/api/Event.h @@ -90,10 +90,12 @@ public:  	int mouse_y = 0;  	// Movement since last event in x -	int rel_x = 0; +	int delta_x = 0;  	// Movement since last event in y -	int rel_y = 0; +	int delta_y = 0; + +	  };  /** @@ -102,13 +104,15 @@ public:  class MouseScrollEvent : public Event {  public:  	//! X-coordinate of the mouse position at the time of the event. -	int scroll_x = 0; +	int mouse_x = 0;  	//! Y-coordinate of the mouse position at the time of the event. -	int scroll_y = 0; +	int mouse_y = 0;  	//! scroll direction (-1 = down, 1 = up) -	int direction = 0; +	int scroll_direction = 0; +	//! scroll amount in y axis (from and away from the person). +	float scroll_delta = 0;  };  /**   * \brief Event triggered during a collision between objects. diff --git a/src/crepe/api/UiObject.cpp b/src/crepe/api/UiObject.cpp index 7859a90..0262d31 100644 --- a/src/crepe/api/UiObject.cpp +++ b/src/crepe/api/UiObject.cpp @@ -2,7 +2,6 @@  using namespace crepe; -UiObject::UiObject(game_object_id_t id, int width, int height) +UIObject::UIObject(game_object_id_t id, vec2 dimensions,vec2 offset)  	: Component(id), -	  width(width), -	  height(height){}; +	  dimensions(dimensions),offset(offset){} diff --git a/src/crepe/api/UiObject.h b/src/crepe/api/UiObject.h index c056877..1130f99 100644 --- a/src/crepe/api/UiObject.h +++ b/src/crepe/api/UiObject.h @@ -8,26 +8,19 @@ namespace crepe {   * @class UiObject   * \brief Represents a UI object in the game, derived from the Component class.   */ -class UiObject : public Component { +class UIObject : public Component {  public:  	/**       * \brief Constructs a UiObject with the specified game object ID.       * \param id The unique ID of the game object associated with this UI object. +	 * \param dimensions width and height of the UIObject +	 * \param offset Offset relative to the GameObject Transform       */ -	UiObject(game_object_id_t id, int width, int height); +	UIObject(game_object_id_t id, vec2 dimensions,vec2 offset); +	//! Width and height of the UIObject +	vec2 dimensions; +	vec2 offset; -	//! The width of the UI object. -	int width = 0; - -	//! The height of the UI object. -	int height = 0; - -public: -	/** -     * \brief Retrieves the maximum number of instances allowed for this UI object type. -     * /return Always returns 1, as only a single instance is allowed. -     */ -	virtual int get_instances_max() const override { return 1; }  };  } // namespace crepe diff --git a/src/crepe/facade/SDLContext.cpp b/src/crepe/facade/SDLContext.cpp index a657373..aba7ce7 100644 --- a/src/crepe/facade/SDLContext.cpp +++ b/src/crepe/facade/SDLContext.cpp @@ -393,7 +393,8 @@ std::vector<SDLContext::EventData> SDLContext::get_events() {  				event_list.push_back(EventData{  					.event_type = SDLContext::EventType::MOUSEWHEEL,  					.mouse_position = {event.motion.x, event.motion.y}, -					.wheel_delta = event.wheel.y, +					.scroll_direction = event.wheel.direction, +					.scroll_delta = event.wheel.preciseY,  				});  			} break;  		} diff --git a/src/crepe/facade/SDLContext.h b/src/crepe/facade/SDLContext.h index 2228950..bd0427a 100644 --- a/src/crepe/facade/SDLContext.h +++ b/src/crepe/facade/SDLContext.h @@ -62,7 +62,8 @@ public:  		bool key_repeat = false;  		MouseButton mouse_button = MouseButton::NONE;  		std::pair<int, int> mouse_position = {-1, -1}; -		int wheel_delta = -1; +		int scroll_direction = -1; +		float scroll_delta = INFINITY;  		std::pair<int, int> rel_mouse_move = {-1, -1};  	};  	/** @@ -80,35 +81,35 @@ private:  	//! will only use get_events  	friend class InputSystem;  	/** -	 * @brief Retrieves a list of all events from the SDL context. +	 * \brief Retrieves a list of all events from the SDL context.  	 *   	 * This method retrieves all the events from the SDL context that are currently  	 * available. It is primarily used by the InputSystem to process various  	 * input events such as mouse clicks, mouse movements, and keyboard presses.  	 *  -	 * @return A vector of `SDLContext::EventData` containing the events. +	 * \return Events that occurred since last call to `get_events()`  	 */  	std::vector<SDLContext::EventData> get_events();  	/** -	 * @brief Converts an SDL key code to the custom Keycode type. +	 * \brief Converts an SDL key code to the custom Keycode type.  	 *   	 * 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 sdl_key The SDL key code to convert. -	 * @return The corresponding `Keycode` value. +	 * \param sdl_key The SDL key code to convert. +	 * \return The corresponding `Keycode` value or `Keycode::NONE` if the key is unrecognized.  	 */  	Keycode sdl_to_keycode(SDL_Keycode sdl_key);  	/** -	 * @brief Converts an SDL mouse button code to the custom MouseButton type. +	 * \brief Converts an SDL mouse button code to the custom MouseButton type.  	 *   	 * This method maps an SDL mouse button code to the corresponding `MouseButton`   	 * enum value, which is used internally by the system to identify mouse buttons.  	 *  -	 * @param sdl_button The SDL mouse button code to convert. -	 * @return The corresponding `MouseButton` value. +	 * \param sdl_button The SDL mouse button code to convert. +	 * \return The corresponding `MouseButton` value or `MouseButton::NONE` if the key is unrecognized  	 */  	MouseButton sdl_to_mousebutton(Uint8 sdl_button); diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp index 11749e1..bbf2547 100644 --- a/src/crepe/system/InputSystem.cpp +++ b/src/crepe/system/InputSystem.cpp @@ -37,7 +37,7 @@ void InputSystem::update() {  				|| 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{ @@ -59,8 +59,8 @@ void InputSystem::update() {  					.mouse_y = world_mouse_y,  					.button = event.mouse_button,  				}); -				last_mouse_down_position = {world_mouse_x, world_mouse_y}; -				last_mouse_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) { @@ -72,10 +72,10 @@ void InputSystem::update() {  					.button = event.mouse_button,  				});  				//check if its a click by checking the last button down -				int delta_x = world_mouse_x - last_mouse_down_position.first; -				int delta_y = world_mouse_y - last_mouse_down_position.second; +				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 (last_mouse_button == event.mouse_button +				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{ @@ -84,7 +84,7 @@ void InputSystem::update() {  						.button = event.mouse_button,  					}); -					handle_click(event.mouse_button, world_mouse_x, world_mouse_y); +					this->handle_click(event.mouse_button, world_mouse_x, world_mouse_y);  				}  			} break;  			case SDLContext::EventType::MOUSEMOVE: @@ -94,16 +94,17 @@ void InputSystem::update() {  				event_mgr.queue_event<MouseMoveEvent>(MouseMoveEvent{  					.mouse_x = world_mouse_x,  					.mouse_y = world_mouse_y, -					.rel_x = event.rel_mouse_move.first, -					.rel_y = event.rel_mouse_move.second, +					.delta_x = event.rel_mouse_move.first, +					.delta_y = event.rel_mouse_move.second,  				});  				handle_move(event, world_mouse_x, world_mouse_y);  				break;  			case SDLContext::EventType::MOUSEWHEEL:  				event_mgr.queue_event<MouseScrollEvent>(MouseScrollEvent{ -					.scroll_x = event.wheel_delta, -					.scroll_y = 0, -					.direction = event.wheel_delta, +					.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: @@ -115,7 +116,7 @@ void InputSystem::update() {  	}  }  void InputSystem::handle_move(const SDLContext::EventData & event_data, -							  const int & world_mouse_x, const int & world_mouse_y) { +							  const int world_mouse_x, const int world_mouse_y) {  	ComponentManager & mgr = this->component_manager;  	RefVector<Button> buttons = mgr.get_components_by_type<Button>(); @@ -127,23 +128,23 @@ void InputSystem::handle_move(const SDLContext::EventData & event_data,  		bool was_hovering = button.hover;  		if (button.active -			&& is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { +			&& this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) {  			button.hover = true; -			if (!was_hovering && button.on_enter) { -				button.on_enter(); +			if (!was_hovering && button.on_mouse_enter) { +				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_exit) { -				button.on_exit(); +			if (was_hovering && button.on_mouse_exit) { +				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 int world_mouse_x, +							   const int world_mouse_y) {  	ComponentManager & mgr = this->component_manager;  	RefVector<Button> buttons = mgr.get_components_by_type<Button>(); @@ -154,30 +155,39 @@ void InputSystem::handle_click(const MouseButton & mouse_button, const int & wor  		Transform& transform(transform_vec.front().get());  		if (button.active -			&& is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { -			handle_button_press(button); +			&& this->is_mouse_inside_button(world_mouse_x, world_mouse_y, button, transform)) { +			this->handle_button_press(button);  		}  	}  } -bool InputSystem::is_mouse_inside_button(const int & mouse_x, const int & mouse_y, -										 const Button & button, const Transform & transform) { -	int half_width = button.width / 2; -	int half_height = button.height / 2; +bool InputSystem::is_mouse_inside_button(const int mouse_x, const int mouse_y, +                                         const Button &button, const Transform &transform) { +    int actual_x = transform.position.x + button.offset.x; +    int actual_y = transform.position.y + button.offset.y; -	return mouse_x >= transform.position.x - half_width -		   && mouse_x <= transform.position.x + half_width -		   && mouse_y >= transform.position.y - half_height -		   && mouse_y <= transform.position.y + half_height; +    int half_width = button.dimensions.x / 2; +    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;  } +  void InputSystem::handle_button_press(Button & button) { +	//checks if the button is a toggle button  	if (button.is_toggle) { +		//if the toggle button is not in a pressed state and it has a on_click call the on_click  		if (!button.is_pressed && button.on_click) {  			button.on_click();  		} +		//toggle the pressed state  		button.is_pressed = !button.is_pressed;  	} else if (button.on_click) { +		// if the button is not a toggle button and has a on_click call the on_click  		button.on_click();  	}  } diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h index e65ad30..557ba47 100644 --- a/src/crepe/system/InputSystem.h +++ b/src/crepe/system/InputSystem.h @@ -13,7 +13,7 @@ class Button;  class Transform;  /** - * \brief Handles the processing of input events like mouse and keyboard interactions. + * \brief Handles the processing of input events created by SDLContext   *   * This system processes events such as mouse clicks, mouse movement, and keyboard   * actions. It is responsible for detecting interactions with UI buttons and @@ -31,14 +31,15 @@ public:  private:  	//! Stores the last position of the mouse when the button was pressed. -	std::pair<int, int> last_mouse_down_position{INFINITY, INFINITY}; +	ivec2 last_mouse_down_position{std::numeric_limits<int>::max(), std::numeric_limits<int>::max()};  	//! Stores the last mouse button pressed.  	MouseButton last_mouse_button = MouseButton::NONE; -	// -	//! The tolerance in game units for detecting a mouse click. +	 +	//! The maximum allowable distance between mouse down and mouse up to register as a click.  	const int click_tolerance = 5; +  	/**  	* \brief Handles the mouse click event.  	* \param mouse_button The mouse button involved in the click. @@ -47,8 +48,8 @@ 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 int world_mouse_x, +					  const int world_mouse_y);  	/**  	* \brief Handles the mouse movement event. @@ -58,8 +59,8 @@ 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 int world_mouse_x, +					 const int world_mouse_y);  	/**  	* \brief Checks if the mouse position is inside the bounds of the button. @@ -69,7 +70,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 int world_mouse_x, const int world_mouse_y,  								const Button & button, const Transform & transform);  	/** diff --git a/src/example/button.cpp b/src/example/button.cpp index 52fa199..7efd889 100644 --- a/src/example/button.cpp +++ b/src/example/button.cpp @@ -34,7 +34,12 @@ int main(int argc, char * argv[]) {  	auto & sprite2 = button_obj.add_component<Sprite>(  		s2, Color::GREEN, Sprite::FlipSettings{false, false}, 2, 1, 100);  	std::function<void()> on_click = [&]() { std::cout << "button clicked" << std::endl; }; -	auto & button = button_obj.add_component<Button>(100, 100, on_click, false); +	std::function<void()> on_enter = [&]() { std::cout << "enter" << std::endl; }; +	std::function<void()> on_exit = [&]() { std::cout << "exit" << std::endl; }; +	auto & button = button_obj.add_component<Button>(vec2{100,100},vec2{0,0}, on_click, false); +	button.on_mouse_enter = on_enter; +	button.on_mouse_exit = on_exit; +	button.is_toggle = true;  	button.active = true;  	auto start = std::chrono::steady_clock::now();  	while (true) { diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp index 32111c0..f7d1059 100644 --- a/src/test/InputTest.cpp +++ b/src/test/InputTest.cpp @@ -119,8 +119,8 @@ TEST_F(InputTest, MouseMove) {  		function_triggered = true;  		EXPECT_EQ(e.mouse_x, 0);  		EXPECT_EQ(e.mouse_y, 0); -		EXPECT_EQ(e.rel_x, 10); -		EXPECT_EQ(e.rel_y, 10); +		EXPECT_EQ(e.delta_x , 10); +		EXPECT_EQ(e.delta_y , 10);  		return false;  	};  	event_manager.subscribe<MouseMoveEvent>(on_mouse_move); @@ -223,7 +223,7 @@ TEST_F(InputTest, testButtonClick) {  	GameObject button_obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);  	bool button_clicked = false;  	std::function<void()> on_click = [&]() { button_clicked = true; }; -	auto & button = button_obj.add_component<Button>(100, 100, on_click, false); +	auto & button = button_obj.add_component<Button>(vec2{100,100},vec2{0,0}, on_click, false);  	bool hover = false;  	button.active = true; @@ -249,10 +249,8 @@ TEST_F(InputTest, testButtonHover) {  	GameObject button_obj = mgr.new_object("body", "person", vec2{0, 0}, 0, 1);  	bool button_clicked = false;  	std::function<void()> on_click = [&]() { button_clicked = true; }; -	auto & button = button_obj.add_component<Button>(100, 100, on_click, false); +	auto & button = button_obj.add_component<Button>(vec2{100,100},vec2{0,0}, on_click, false);  	button.active = true; -	button.width = 100; -	button.height = 100;  	button.is_pressed = false;  	button.is_toggle = false; |