diff --git a/src/engine/core/Application.cpp b/src/engine/core/Application.cpp index da4f728..3e8a26b 100644 --- a/src/engine/core/Application.cpp +++ b/src/engine/core/Application.cpp @@ -5,6 +5,7 @@ #include "Application.h" #include "../layer/Layer.h" +#include "../platform/glfw/InputManager.h" Application* Application::instance = nullptr; @@ -38,6 +39,7 @@ void Application::run() { layer->onUpdate(); } window->OnUpdate(); + InputManager::update(); } } diff --git a/src/engine/core/gui/uiComponent/UiButton.cpp b/src/engine/core/gui/uiComponent/UiButton.cpp index 7e387da..f165e82 100644 --- a/src/engine/core/gui/uiComponent/UiButton.cpp +++ b/src/engine/core/gui/uiComponent/UiButton.cpp @@ -11,17 +11,38 @@ UiButton::UiButton(const GLuint textureID, std::string label, Font &font, const LayoutStyle &style): textureID(textureID), text(std::move(label)), font(font), UiComponent(style) { } +void UiButton::onClick() { + if (clickListener) { + clickListener(); + } +} + void UiButton::onCollectRenderData(UiRenderBundle &uiRenderBundle) { glm::vec2 position = glm::vec2(uiPositioner.screenSpace.x, uiPositioner.screenSpace.y); glm::vec2 size = glm::vec2(uiPositioner.screenSpace.width, uiPositioner.screenSpace.height); - if (isHovered()) { - float brightness = 1.15f; - float tintStrength = 0.f; - uiRenderBundle.addGUITexture(std::make_shared(textureID, position, size, brightness, glm::vec3(0.3, 0.6, 1.0), tintStrength)); - } else { - uiRenderBundle.addGUITexture(std::make_shared(textureID, position, size)); - } + VisualStyle visualStyle = getVisualStyle(); + uiRenderBundle.addGUITexture( + std::make_shared( + textureID, + position, + size, + visualStyle.brightness, + visualStyle.tintColor, + visualStyle.tintStrength + ) + ); uiRenderBundle.addGUIText(std::make_shared(font, text, uiPositioner.screenSpace)); } + +VisualStyle UiButton::getVisualStyle() const { + switch (state) { + case UiState::PRESSED: + return {1.0f, glm::vec3(0.3, 0.6, 1.0), 0.15f}; + case UiState::HOVERED: + return {1.15f, glm::vec3(0.0f), 0.0f}; + default: + return {}; + } +} diff --git a/src/engine/core/gui/uiComponent/UiButton.h b/src/engine/core/gui/uiComponent/UiButton.h index 23648b1..47fe2bd 100644 --- a/src/engine/core/gui/uiComponent/UiButton.h +++ b/src/engine/core/gui/uiComponent/UiButton.h @@ -6,13 +6,23 @@ #define DICEWARS_SIEDLER_UIBUTTON_H #include "UiComponent.h" +struct VisualStyle { + float brightness = 1.0f; + glm::vec3 tintColor = glm::vec3(0.0f); + float tintStrength = 0.0f; +}; class Font; class UiButton : public UiComponent{ public: UiButton(GLuint textureID, std::string label, Font& font, const LayoutStyle& style); + void setOnClick(std::function callback) { + printf("Clicklister added!\n"); + clickListener = std::move(callback); + } + void onClick() override; protected: void onCollectRenderData(UiRenderBundle &uiRenderBundle) override; @@ -20,6 +30,10 @@ private: std::string text; Font& font; GLuint textureID; + + VisualStyle getVisualStyle() const; + + std::function clickListener; }; diff --git a/src/engine/core/gui/uiComponent/UiComponent.cpp b/src/engine/core/gui/uiComponent/UiComponent.cpp index 9a31be5..ac4ec25 100644 --- a/src/engine/core/gui/uiComponent/UiComponent.cpp +++ b/src/engine/core/gui/uiComponent/UiComponent.cpp @@ -4,7 +4,9 @@ #include "UiComponent.h" +#include "../../Application.h" #include "../../../platform/glfw/InputManager.h" +#include "GLFW/glfw3.h" void UiComponent::addChild(std::unique_ptr child) { child->parent = this; @@ -46,6 +48,21 @@ bool UiComponent::isMouseOver(float mouseX, float mouseY) { void UiComponent::onUpdate(float) { glm::vec2 mousePos = InputManager::getMousePositionNormalized(); - hovered = isMouseOver(mousePos.x, mousePos.y); + bool hoveredNow = isMouseOver(mousePos.x, mousePos.y); + + bool pressedThisFrame = hoveredNow && InputManager::isMouseButtonPressed(GLFW_MOUSE_BUTTON_LEFT); + bool releasedFrame = InputManager::isMouseButtonReleased(GLFW_MOUSE_BUTTON_LEFT); + + if (pressedThisFrame) { + state = UiState::PRESSED; + } else if (releasedFrame) { + if (state == UiState::PRESSED && hoveredNow) { + onClick(); + } + state = hoveredNow ? UiState::HOVERED : UiState::NORMAL; + } else { + if (state != UiState::PRESSED) + state = hoveredNow ? UiState::HOVERED : UiState::NORMAL; + } } diff --git a/src/engine/core/gui/uiComponent/UiComponent.h b/src/engine/core/gui/uiComponent/UiComponent.h index d43f873..b47bc22 100644 --- a/src/engine/core/gui/uiComponent/UiComponent.h +++ b/src/engine/core/gui/uiComponent/UiComponent.h @@ -11,6 +11,10 @@ #include "UiRenderBundle.h" #include "../../../renderer/model/GUITexture.h" +enum class UiState { + NORMAL, HOVERED, PRESSED +}; + class UiComponent { public: @@ -34,10 +38,11 @@ public: uiPositioner.setLayout(style); } - [[nodiscard]] bool isHovered() const { return hovered; } + [[nodiscard]] bool isHovered() const { return state == UiState::HOVERED; } + virtual void onClick() {}; protected: bool visible = true; - bool hovered = false; + UiState state = UiState::NORMAL; virtual void onUpdate(float ); virtual void onCollectRenderData(UiRenderBundle& uiRenderBundle) {} diff --git a/src/engine/platform/glfw/InputManager.cpp b/src/engine/platform/glfw/InputManager.cpp index d239862..72f979c 100644 --- a/src/engine/platform/glfw/InputManager.cpp +++ b/src/engine/platform/glfw/InputManager.cpp @@ -5,7 +5,9 @@ #include "InputManager.h" #include "../../core/Application.h" -#include "GLFW/glfw3.h" + +bool InputManager::current[GLFW_MOUSE_BUTTON_LAST] = { false }; +bool InputManager::previous[GLFW_MOUSE_BUTTON_LAST] = { false }; bool InputManager::isKeyPressed(int keycode) { auto window = static_cast(Application::getInstance().getWindow().GetNativeWindow()); @@ -13,8 +15,18 @@ bool InputManager::isKeyPressed(int keycode) { } bool InputManager::isMouseButtonPressed(int button) { - auto window = static_cast(Application::getInstance().getWindow().GetNativeWindow()); - return glfwGetMouseButton(window, button) == GLFW_PRESS; + return current[button] && !previous[button]; +} + +bool InputManager::isMouseButtonReleased(int button) { + return !current[button] && previous[button]; +} + +void InputManager::update() { + for (int i=0; i < GLFW_MOUSE_BUTTON_LAST; ++i) { + previous[i] = current[i]; + current[i] = glfwGetMouseButton(static_cast(Application::getInstance().getWindow().GetNativeWindow()), i) == GLFW_PRESS; + } } glm::vec2 InputManager::getMousePosition() { @@ -41,3 +53,7 @@ glm::vec2 InputManager::getMouseDelta() { return delta; } +bool InputManager::isMouseButtonDown(int button) { + return current[button]; +} + diff --git a/src/engine/platform/glfw/InputManager.h b/src/engine/platform/glfw/InputManager.h index 464ff20..2155d0d 100644 --- a/src/engine/platform/glfw/InputManager.h +++ b/src/engine/platform/glfw/InputManager.h @@ -4,18 +4,29 @@ #ifndef INPUTMANAGER_H #define INPUTMANAGER_H +#define GLFW_INCLUDE_NONE +#include "GLFW/glfw3.h" #include "glm/vec2.hpp" class InputManager { public: static bool isKeyPressed(int keycode); - static bool isMouseButtonPressed(int button); static glm::vec2 getMousePosition(); static glm::vec2 getMousePositionNormalized(); glm::vec2 getMouseDelta(); + static bool isMouseButtonDown(int button); + static bool isMouseButtonPressed(int button); + static bool isMouseButtonReleased(int button); + + static void update(); + +private: + static bool current[GLFW_MOUSE_BUTTON_LAST]; + static bool previous[GLFW_MOUSE_BUTTON_LAST]; + }; diff --git a/src/game/UILayer.cpp b/src/game/UILayer.cpp index 63f5681..d0b4f77 100644 --- a/src/game/UILayer.cpp +++ b/src/game/UILayer.cpp @@ -4,6 +4,9 @@ #include "UILayer.h" +#include +#include + #include "../engine/core/gui/text/Font.h" #include "../engine/core/gui/uiComponent/UiButton.h" #include "../engine/core/gui/uiComponent/UiImage.h" @@ -52,6 +55,11 @@ void UILayer::onAttach() { //auto text = std::make_unique(*font, "Hello World!", glm::vec2(0.5f, 0.5f), glm::vec3(1,1,1)); auto button = std::make_unique(Loader::instance().loadTextureFromFile("assets/textures/texture.png").getTextureID(), "Button", *font, imageStyle); + + button->setOnClick([]() { + std::cout << "Button Clicked!" << std::endl; + }); + rootContainer->addChild(std::move(button)); } diff --git a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp index 7157f46..08f600c 100644 --- a/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp +++ b/src/game/hexWorld/ecs/systems/BuildingPlacementSystem.cpp @@ -5,6 +5,7 @@ #include "BuildingPlacementSystem.h" #include "../../RessourceType.h" +#include "../../../../engine/core/Application.h" #include "../../../../engine/core/ECS/ModelComponent.h" #include "../../../../engine/core/ECS/TileRenderComponent.h" #include "../../../../engine/core/ECS/TransformComponent.h"