aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLoek Le Blansch <loek@pipeframe.xyz>2024-12-19 09:13:43 +0100
committerLoek Le Blansch <loek@pipeframe.xyz>2024-12-19 09:13:43 +0100
commitd8f1e161b0c98baa7dde287c484529a8b1291626 (patch)
tree2f0eb1c7175375eac6efbf6d1e847d51bcd257cd /src
parenta6ba1eb5b6b6a1782182008e0044bf1ac04733dc (diff)
parent7c76d1743d5b0c3cf6eb05076fae88e948f3e22f (diff)
Merge branch 'wouter/button-improvement' of github.com:lonkaars/crepe
Diffstat (limited to 'src')
-rw-r--r--src/crepe/api/Button.cpp6
-rw-r--r--src/crepe/api/Button.h49
-rw-r--r--src/crepe/api/Event.h12
-rw-r--r--src/crepe/system/InputSystem.cpp32
-rw-r--r--src/crepe/system/InputSystem.h33
-rw-r--r--src/test/InputTest.cpp54
6 files changed, 103 insertions, 83 deletions
diff --git a/src/crepe/api/Button.cpp b/src/crepe/api/Button.cpp
index 305922c..40153c9 100644
--- a/src/crepe/api/Button.cpp
+++ b/src/crepe/api/Button.cpp
@@ -2,9 +2,7 @@
namespace crepe {
-Button::Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset,
- const std::function<void()> & on_click)
- : UIObject(id, dimensions, offset),
- on_click(on_click) {}
+Button::Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset)
+ : UIObject(id, dimensions, offset) {}
} // namespace crepe
diff --git a/src/crepe/api/Button.h b/src/crepe/api/Button.h
index 08f5dec..d42527e 100644
--- a/src/crepe/api/Button.h
+++ b/src/crepe/api/Button.h
@@ -2,11 +2,23 @@
#include <functional>
+#include "Event.h"
#include "UIObject.h"
namespace crepe {
-//! Represents a clickable UI button, derived from the UiObject class.
+/**
+ * \brief Button component.
+ *
+ * This component creates a clickable surface at the transform location with the specified width and height.
+ *
+ * The Button can be used in scripts by subscribing a EventHandler to the following events:
+ * - ButtonPressEvent
+ * - ButtonEnterEvent
+ * - ButtonExitEvent
+ * \see EventManager
+ *
+ */
class Button : public UIObject {
public:
/**
@@ -15,43 +27,22 @@ public:
* \param id The unique ID of the game object associated with this button.
* \param dimensions The width and height of the UIObject
* \param offset The offset relative this GameObjects Transform
- * \param on_click callback function that will be invoked when the button is clicked.
*/
- Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset,
- const std::function<void()> & on_click);
-
- // TODO: create separate toggle button class
- /**
- * \brief The callback function to be executed when the button is clicked.
- *
- * This function is invoked whenever the button is clicked. It can be set to any
- * function that matches the signature `void()`.
- */
- std::function<void()> on_click = nullptr;
-
+ Button(game_object_id_t id, const vec2 & dimensions, const vec2 & offset);
/**
- * \brief Callback function to be executed when the mouse enters the button's boundaries.
+ * \brief Get the maximum number of instances for this component
*
- * This function is triggered when the mouse cursor moves over the button, allowing
- * custom actions like visual effects, highlighting, or sound effects.
+ * Since the button Event transfers the GameObject Metadata it will be the same for each button so only one button is allowed per GameObject
+ *
+ * \return 1
*/
- std::function<void()> on_mouse_enter = nullptr;
-
- /**
- * \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_mouse_exit = nullptr;
+ virtual int get_instances_max() const { return 1; }
private:
- //! friend relation for is_pressed and hover variables
+ //! friend relation hover variable
friend class InputSystem;
//! Indicates whether the mouse is currently hovering over the button
bool hover = false;
-
-public:
};
} // namespace crepe
diff --git a/src/crepe/api/Event.h b/src/crepe/api/Event.h
index 73bf461..8e38280 100644
--- a/src/crepe/api/Event.h
+++ b/src/crepe/api/Event.h
@@ -3,9 +3,10 @@
#include <string>
-#include "api/KeyCodes.h"
#include "types.h"
+#include "KeyCodes.h"
+
namespace crepe {
/**
@@ -95,15 +96,6 @@ public:
};
/**
- * \brief Event triggered when text is submitted, e.g., from a text input.
- */
-class TextSubmitEvent : public Event {
-public:
- //! The submitted text.
- std::string text = "";
-};
-
-/**
* \brief Event triggered to indicate the application is shutting down.
*/
class ShutDownEvent : public Event {};
diff --git a/src/crepe/system/InputSystem.cpp b/src/crepe/system/InputSystem.cpp
index fca540f..60daa55 100644
--- a/src/crepe/system/InputSystem.cpp
+++ b/src/crepe/system/InputSystem.cpp
@@ -10,10 +10,8 @@ using namespace crepe;
void InputSystem::update() {
ComponentManager & mgr = this->mediator.component_manager;
-
SDLContext & context = this->mediator.sdl_context;
std::vector<EventData> event_list = context.get_events();
- RefVector<Button> buttons = mgr.get_components_by_type<Button>();
RefVector<Camera> cameras = mgr.get_components_by_type<Camera>();
OptionalRef<Camera> curr_cam_ref;
@@ -155,28 +153,25 @@ void InputSystem::handle_non_mouse_event(const EventData & event) {
void InputSystem::handle_move(const EventData & event_data, const vec2 & mouse_pos) {
ComponentManager & mgr = this->mediator.component_manager;
-
+ EventManager & event_mgr = this->mediator.event_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());
-
+ Metadata & metadata
+ = mgr.get_components_by_id<Metadata>(button.game_object_id).front();
+ Transform & transform
+ = mgr.get_components_by_id<Transform>(button.game_object_id).front();
bool was_hovering = button.hover;
if (this->is_mouse_inside_button(mouse_pos, button, transform)) {
button.hover = true;
- if (!button.on_mouse_enter) continue;
if (!was_hovering) {
- button.on_mouse_enter();
+ event_mgr.trigger_event<ButtonEnterEvent>(metadata);
}
} else {
button.hover = false;
- // Trigger the on_exit callback if the hover state just changed to false
- if (!button.on_mouse_exit) continue;
if (was_hovering) {
- button.on_mouse_exit();
+ event_mgr.trigger_event<ButtonExitEvent>(metadata);
}
}
}
@@ -184,19 +179,18 @@ void InputSystem::handle_move(const EventData & event_data, const vec2 & mouse_p
void InputSystem::handle_click(const MouseButton & mouse_button, const vec2 & mouse_pos) {
ComponentManager & mgr = this->mediator.component_manager;
-
+ EventManager & event_mgr = this->mediator.event_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();
+ Metadata & metadata
+ = mgr.get_components_by_id<Metadata>(button.game_object_id).front();
+ Transform & transform
+ = mgr.get_components_by_id<Transform>(button.game_object_id).front();
if (this->is_mouse_inside_button(mouse_pos, button, transform)) {
-
- button.on_click();
+ event_mgr.trigger_event<ButtonPressEvent>(metadata);
}
}
}
diff --git a/src/crepe/system/InputSystem.h b/src/crepe/system/InputSystem.h
index eefd9fe..e580d8e 100644
--- a/src/crepe/system/InputSystem.h
+++ b/src/crepe/system/InputSystem.h
@@ -3,6 +3,8 @@
#include "../api/Config.h"
#include "../facade/EventData.h"
+#include "../api/Event.h"
+#include "../api/Metadata.h"
#include "../types.h"
#include "../util/OptionalRef.h"
@@ -13,6 +15,37 @@ namespace crepe {
class Camera;
class Button;
class Transform;
+//! Event triggered when a button is clicked
+class ButtonPressEvent : public Event {
+public:
+ //! Metadata of the button.
+ const Metadata & metadata;
+ /**
+ * \param metadata Metadata of the button pressed
+ */
+ ButtonPressEvent(const Metadata & metadata) : metadata(metadata){};
+};
+//! Event triggered when the mouse enters a button
+class ButtonEnterEvent : public Event {
+public:
+ //! Metadata of the button.
+ const Metadata & metadata;
+ /**
+ * \param metadata Metadata of the button pressed
+ */
+ ButtonEnterEvent(const Metadata & metadata) : metadata(metadata){};
+};
+//! Event triggered when the mouse leaves a button
+class ButtonExitEvent : public Event {
+public:
+ //! Metadata of the button.
+ const Metadata & metadata;
+ /**
+ * \param metadata Metadata of the button pressed
+ */
+ ButtonExitEvent(const Metadata & metadata) : metadata(metadata){};
+};
+
/**
* \brief Handles the processing of input events created by SDLContext
*
diff --git a/src/test/InputTest.cpp b/src/test/InputTest.cpp
index 2d844d4..ce8ea44 100644
--- a/src/test/InputTest.cpp
+++ b/src/test/InputTest.cpp
@@ -2,7 +2,6 @@
#include <crepe/manager/ResourceManager.h>
#include <crepe/system/RenderSystem.h>
-
#define protected public
#define private public
@@ -214,8 +213,12 @@ TEST_F(InputTest, MouseClick) {
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>(vec2{100, 100}, vec2{0, 0}, on_click);
+ event_manager.subscribe<ButtonPressEvent>([&](const ButtonPressEvent & event) {
+ button_clicked = true;
+ EXPECT_EQ(event.metadata.game_object_id, button_obj.id);
+ return false;
+ });
+ auto & button = button_obj.add_component<Button>(vec2{100, 100}, vec2{0, 0});
bool hover = false;
button.active = true;
@@ -232,25 +235,19 @@ TEST_F(InputTest, testButtonClick) {
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>(vec2{100, 100}, vec2{0, 0}, on_click);
+ bool button_hover = false;
+ event_manager.subscribe<ButtonEnterEvent>([&](const ButtonEnterEvent & event) {
+ button_hover = true;
+ EXPECT_EQ(event.metadata.game_object_id, button_obj.id);
+ return false;
+ });
+ event_manager.subscribe<ButtonExitEvent>([&](const ButtonExitEvent & event) {
+ button_hover = false;
+ EXPECT_EQ(event.metadata.game_object_id, button_obj.id);
+ return false;
+ });
+ auto & button = button_obj.add_component<Button>(vec2{100, 100}, vec2{0, 0});
button.active = true;
-
- // Mouse not on button
- SDL_Event event;
- SDL_zero(event);
- event.type = SDL_MOUSEMOTION;
- event.motion.x = 700;
- event.motion.y = 700;
- event.motion.xrel = 10;
- event.motion.yrel = 10;
- SDL_PushEvent(&event);
-
- input_system.update();
- event_manager.dispatch_events();
- EXPECT_FALSE(button.hover);
-
// Mouse on button
SDL_Event hover_event;
SDL_zero(hover_event);
@@ -264,4 +261,19 @@ TEST_F(InputTest, testButtonHover) {
input_system.update();
event_manager.dispatch_events();
EXPECT_TRUE(button.hover);
+ EXPECT_TRUE(button_hover);
+ // Mouse not on button
+ SDL_Event event;
+ SDL_zero(event);
+ event.type = SDL_MOUSEMOTION;
+ event.motion.x = 500;
+ event.motion.y = 500;
+ event.motion.xrel = 10;
+ event.motion.yrel = 10;
+ SDL_PushEvent(&event);
+
+ input_system.update();
+ event_manager.dispatch_events();
+ EXPECT_FALSE(button.hover);
+ EXPECT_FALSE(button_hover);
}