diff --git a/include/Core/Engine.h b/include/Core/Engine.h index 7637cab..25776c3 100644 --- a/include/Core/Engine.h +++ b/include/Core/Engine.h @@ -53,7 +53,7 @@ #include "Physics/ESetImpulse.h" #include "GUI/Frame.h" -#include "GUI/TextureFrame.h" +#include "GUI/Button.h" namespace dd { @@ -74,11 +74,23 @@ public: m_FrameStack->Width = 1920; m_FrameStack->Height = 1080; { - auto button = new GUI::TextureFrame(m_FrameStack, "SuperButt"); - button->SetTexture("Textures/Test/TestBrick_Diffuse.png"); + auto button = new GUI::Button(m_FrameStack, "SuperButt"); + button->TextureReleased = "Textures/Test/TestBrick_Specular.png"; + button->TexturePressed = "Textures/Test/TestBrick_Normal.png"; + button->TextureHover = "Textures/Test/TestBrick_Diffuse.png"; + button->X = 50; + button->Y = 75; button->Width = 100; button->Height = 25; } + { + auto button = new GUI::TextureFrame(m_FrameStack, "BALLZ"); + button->SetTexture("Textures/Ball.png"); + button->X = 50; + button->Y = 75; + button->Width = 100; + button->Height = 100; + } m_InputManager = std::make_shared(m_Renderer->Window(), m_EventBroker); @@ -250,13 +262,16 @@ public: double dt = currentTime - m_LastTime; m_LastTime = currentTime; - ResourceManager::Update(); - // Update input m_InputManager->Update(dt); + // Swap event queues to get fresh input data in the read queue + m_EventBroker->Swap(); + + ResourceManager::Update(); m_World->Update(dt); - + m_EventBroker->Process(); + m_FrameStack->UpdateLayered(dt); // // if (glfwGetKey(m_Renderer->Window(), GLFW_KEY_R)) { diff --git a/include/GUI/Button.h b/include/GUI/Button.h new file mode 100644 index 0000000..27661eb --- /dev/null +++ b/include/GUI/Button.h @@ -0,0 +1,102 @@ +#ifndef GUI_BUTTON_H__ +#define GUI_BUTTON_H__ + +#include "GUI/TextureFrame.h" +#include "Core/EMouseMove.h" +#include "Core/EMousePress.h" +#include "Core/EMouseRelease.h" + +namespace dd +{ +namespace GUI +{ + +class Button : public TextureFrame +{ +public: + Button(Frame* parent, std::string name) + : TextureFrame(parent, name) + { + EVENT_SUBSCRIBE_MEMBER(m_EMouseMove, &Button::OnMouseMove); + EVENT_SUBSCRIBE_MEMBER(m_EMousePress, &Button::OnMousePress); + EVENT_SUBSCRIBE_MEMBER(m_EMouseRelease, &Button::OnMouseRelease); + } + + std::string TextureHover; + std::string TexturePressed; + std::string TextureReleased; + + void Draw(RenderQueueCollection& rq) override + { + if (m_Texture == nullptr && !TextureReleased.empty()) { + SetTexture(TextureReleased); + } + + TextureFrame::Draw(rq); + } + +protected: + bool m_MouseIsOver = false; + bool m_IsDown = false; + + virtual bool OnMouseMove(const Events::MouseMove& event) + { + bool isOver = Rectangle::Intersects(AbsoluteRectangle(), Rectangle(event.X, event.Y, 1, 1)); + if (isOver && !m_MouseIsOver) { // Enter + LOG_INFO("%s mouse enter", m_Name.c_str()); + if (!m_IsDown) { + SetTexture(TextureHover); + } + } else if (!isOver && m_MouseIsOver) { // Leave + LOG_INFO("%s mouse left", m_Name.c_str()); + if (!m_IsDown) { + SetTexture(TextureReleased); + } + } + m_MouseIsOver = isOver; + + return true; + } + virtual bool OnMousePress(const Events::MousePress& event) + { + if (!Rectangle::Intersects(AbsoluteRectangle(), Rectangle(event.X, event.Y, 1, 1))) { + return false; + } + + if (!TexturePressed.empty()) { + SetTexture(TexturePressed); + } + + LOG_INFO("%s mouse pressed", m_Name.c_str()); + + m_IsDown = true; + + return true; + } + virtual bool OnMouseRelease(const Events::MouseRelease& event) + { + bool isOver = Rectangle::Intersects(AbsoluteRectangle(), Rectangle(event.X, event.Y, 1, 1)); + if (!isOver && !m_IsDown) { + return false; + } + + if (!TextureReleased.empty()) { + SetTexture(TextureReleased); + } + + LOG_INFO("%s mouse released", m_Name.c_str()); + + m_IsDown = false; + + return true; + } + +private: + EventRelay m_EMouseMove; + EventRelay m_EMousePress; + EventRelay m_EMouseRelease; +}; + +} +} +#endif diff --git a/include/GUI/Frame.h b/include/GUI/Frame.h index 5015725..0c0d42e 100644 --- a/include/GUI/Frame.h +++ b/include/GUI/Frame.h @@ -36,15 +36,16 @@ public: // Set up a base frame with an event broker Frame(dd::EventBroker* eventBroker) : EventBroker(eventBroker) - , Rectangle() - { Initialize(); } + , Rectangle() { } // Create a frame as a child Frame(Frame* parent, std::string name) : m_Name(name) { SetParent(parent); - Initialize(); + EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Frame::OnKeyDown); + EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Frame::OnKeyUp); + EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Frame::OnCommand); } ~Frame() @@ -221,24 +222,13 @@ protected: std::map m_Children; // layer -> Children_t virtual bool OnKeyDown(const Events::KeyDown& event) { return false; } - virtual bool OnKeyUp(const Events::KeyUp& event) { return false; } - - //virtual bool OnMouseDown(const Events::KeyDown &event) { } - //virtual bool OnMouseUp(const Events::KeyDown &event) { } virtual bool OnCommand(const Events::InputCommand& event) { return false; } private: EventRelay m_EKeyDown; EventRelay m_EKeyUp; EventRelay m_EInputCommand; - - void Initialize() - { - EVENT_SUBSCRIBE_MEMBER(m_EKeyDown, &Frame::OnKeyDown); - EVENT_SUBSCRIBE_MEMBER(m_EKeyUp, &Frame::OnKeyUp); - EVENT_SUBSCRIBE_MEMBER(m_EInputCommand, &Frame::OnCommand); - } }; } diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt index 4361d50..badf9e0 100755 --- a/src/game/CMakeLists.txt +++ b/src/game/CMakeLists.txt @@ -85,7 +85,7 @@ source_group(Sound FILES ${SOURCE_FILES_Sound}) #) set(SOURCE_FILES_GUI "${INCLUDE_PATH}/GUI/Frame.h" -) + ../../include/GUI/Button.h) source_group(GUI FILES ${SOURCE_FILES_GUI}) set(SOURCE_FILES