From eae595ec4a125effe40a459f676c74f8a4b6faee Mon Sep 17 00:00:00 2001 From: Patrick Wuttke Date: Thu, 19 Sep 2024 16:35:56 +0200 Subject: [PATCH] Made the button type interactable. --- private/sdl_gpu_test/6_ui/app.cpp | 12 +++++++++ private/sdl_gpu_test/6_ui/app.hpp | 1 + private/sdl_gpu_test/gui/button.cpp | 41 ++++++++++++++++++++++++++--- private/sdl_gpu_test/gui/button.hpp | 18 ++++++++++--- private/sdl_gpu_test/gui/widget.cpp | 26 ++++++++++++++++++ private/sdl_gpu_test/gui/widget.hpp | 9 +++++++ 6 files changed, 101 insertions(+), 6 deletions(-) diff --git a/private/sdl_gpu_test/6_ui/app.cpp b/private/sdl_gpu_test/6_ui/app.cpp index a6802fe..308eb13 100644 --- a/private/sdl_gpu_test/6_ui/app.cpp +++ b/private/sdl_gpu_test/6_ui/app.cpp @@ -83,6 +83,10 @@ void UIApp::init(const AppInitArgs& args) .posX = 100, .posY = 500 }); + mButton->clicked.connect([&]() + { + mButton->setText("Thanks!"); + }); } void UIApp::update(const AppUpdateArgs& args) @@ -173,6 +177,8 @@ void UIApp::handleKeyboardEvent(const sdlpp::KeyboardEvent& event) void UIApp::handleMouseMotionEvent(const sdlpp::MouseMotionEvent& event) { + mWidgetTree.notifyMouseMoved(event); + if (event.state.left) { mRotation += 0.5f * event.xrel; @@ -180,6 +186,12 @@ void UIApp::handleMouseMotionEvent(const sdlpp::MouseMotionEvent& event) } } +void UIApp::handleMouseButtonEvent(const sdlpp::MouseButtonEvent& event) +{ + mWidgetTree.notifyMouseButton(event); +} + + void UIApp::createMeshPipeline() { // create shaders diff --git a/private/sdl_gpu_test/6_ui/app.hpp b/private/sdl_gpu_test/6_ui/app.hpp index 2b55100..671411b 100644 --- a/private/sdl_gpu_test/6_ui/app.hpp +++ b/private/sdl_gpu_test/6_ui/app.hpp @@ -39,6 +39,7 @@ public: void update(const AppUpdateArgs& args) override; void handleKeyboardEvent(const sdlpp::KeyboardEvent& event) override; void handleMouseMotionEvent(const sdlpp::MouseMotionEvent& event) override; + void handleMouseButtonEvent(const sdlpp::MouseButtonEvent&) override; private: void createMeshPipeline(); void processInput(const AppUpdateArgs& args); diff --git a/private/sdl_gpu_test/gui/button.cpp b/private/sdl_gpu_test/gui/button.cpp index 0d03c02..b3fcd4e 100644 --- a/private/sdl_gpu_test/gui/button.cpp +++ b/private/sdl_gpu_test/gui/button.cpp @@ -4,7 +4,8 @@ namespace sdl_gpu_test { Button::Button(ButtonCreateArgs args) : mText(std::move(args.text)), mTextColor(args.textColor), - mBackgroundColor(args.backgroundColor), mPosX(args.posX), mPosY(args.posY), mWidth(args.width), mHeight(args.height) + mBackgroundColor(args.backgroundColor), mHoveredColor(args.hoveredColor), mPosX(args.posX), mPosY(args.posY), + mWidth(args.width), mHeight(args.height) { } @@ -32,7 +33,22 @@ void Button::setBackgroundColor(const glm::vec4& color) if (color != mBackgroundColor) { mBackgroundColor = color; - invalidate(); + if (!mHovered) + { + invalidate(); + } + } +} + +void Button::setHoveredColor(const glm::vec4& color) +{ + if (color != mHoveredColor) + { + mHoveredColor = color; + if (mHovered) + { + invalidate(); + } } } @@ -59,6 +75,25 @@ void Button::handleEnteredTree() update(); } +void Button::handleMouseMotion(const sdlpp::MouseMotionEvent& event) +{ + const bool hovered = (event.x >= mPosX && event.x <= mPosX + mWidth) + && (event.y >= mPosY && event.y <= mPosY + mHeight); + if (hovered != mHovered) + { + mHovered = hovered; + invalidate(); + } +} + +void Button::handleMouseButton(const sdlpp::MouseButtonEvent&) +{ + if (mHovered) + { + clicked.emit(); + } +} + void Button::revalidate() { update(); @@ -81,7 +116,7 @@ void Button::update() .y = mPosY, .width = mWidth, .height = mHeight, - .color = mBackgroundColor + .color = mHovered ? mHoveredColor : mBackgroundColor }, &mPrimitiveID); mTree->getRenderer().drawTextCentered({ .x = mPosX + (mWidth / 2), diff --git a/private/sdl_gpu_test/gui/button.hpp b/private/sdl_gpu_test/gui/button.hpp index 69a5fa5..fefabea 100644 --- a/private/sdl_gpu_test/gui/button.hpp +++ b/private/sdl_gpu_test/gui/button.hpp @@ -5,6 +5,7 @@ #define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GUI_BUTTON_HPP_INCLUDED 1 #include +#include #include "./widget.hpp" @@ -15,6 +16,7 @@ struct ButtonCreateArgs std::string text; glm::vec4 textColor = {1.f, 1.f, 1.f, 1.f}; glm::vec4 backgroundColor = {1.f, 0.f, 0.f, 1.f}; + glm::vec4 hoveredColor = {1.f, 0.9f, 0.9f, 1.f}; int posX = 0; int posY = 0; int width = 256; @@ -27,12 +29,14 @@ public: using create_args_t = ButtonCreateArgs; private: std::string mText; - glm::vec4 mTextColor = {1.f, 1.f, 1.f, 1.f}; - glm::vec4 mBackgroundColor = {1.f, 1.f, 1.f, 1.f}; + glm::vec4 mTextColor; + glm::vec4 mBackgroundColor; + glm::vec4 mHoveredColor; int mPosX = 0; int mPosY = 0; int mWidth = 0; int mHeight = 0; + bool mHovered = false; UIRenderer::primitive_id_t mPrimitiveID = UIRenderer::UNSET_PRIMITIVE_ID; public: explicit Button(ButtonCreateArgs args); @@ -44,7 +48,10 @@ public: const glm::vec4& getTextColor() const noexcept { return mTextColor; } [[nodiscard]] - const glm::vec4& getBackgroundTextColor() const noexcept { return mBackgroundColor; } + const glm::vec4& getBackgroundColor() const noexcept { return mBackgroundColor; } + + [[nodiscard]] + const glm::vec4& getHoveredColor() const noexcept { return mHoveredColor; } [[nodiscard]] int getPosX() const noexcept { return mPosX; } @@ -55,13 +62,18 @@ public: void setText(std::string text); void setTextColor(const glm::vec4& color); void setBackgroundColor(const glm::vec4& color); + void setHoveredColor(const glm::vec4& color); void setPosX(int posX); void setPosY(int posY); void handleEnteredTree() override; + void handleMouseMotion(const sdlpp::MouseMotionEvent& event) override; + void handleMouseButton(const sdlpp::MouseButtonEvent&) override; void revalidate() override; private: void update(); +public: + mijin::Signal<> clicked; }; } // namespace sdl_gpu_test diff --git a/private/sdl_gpu_test/gui/widget.cpp b/private/sdl_gpu_test/gui/widget.cpp index 4bd26e1..a929777 100644 --- a/private/sdl_gpu_test/gui/widget.cpp +++ b/private/sdl_gpu_test/gui/widget.cpp @@ -31,6 +31,22 @@ void ParentWidget::handleEnteredTree() } } +void ParentWidget::handleMouseMotion(const sdlpp::MouseMotionEvent& event) +{ + for (widget_ptr_t& child : mChildren) + { + child->handleMouseMotion(event); + } +} + +void ParentWidget::handleMouseButton(const sdlpp::MouseButtonEvent& event) +{ + for (widget_ptr_t& child : mChildren) + { + child->handleMouseButton(event); + } +} + Widget* ParentWidget::addChild(widget_ptr_t&& child) { mChildren.push_back(std::move(child)); @@ -60,6 +76,16 @@ void WidgetTree::revalidateWidgets() mInvalidWidgets.clear(); } +void WidgetTree::notifyMouseMoved(const sdlpp::MouseMotionEvent& event) +{ + mRootWidget.handleMouseMotion(event); +} + +void WidgetTree::notifyMouseButton(const sdlpp::MouseButtonEvent& event) +{ + mRootWidget.handleMouseButton(event); +} + void WidgetTree::invalidateWidget(Widget* widget) noexcept { mInvalidWidgets.insert(widget); diff --git a/private/sdl_gpu_test/gui/widget.hpp b/private/sdl_gpu_test/gui/widget.hpp index 2d86a52..36eb989 100644 --- a/private/sdl_gpu_test/gui/widget.hpp +++ b/private/sdl_gpu_test/gui/widget.hpp @@ -9,6 +9,7 @@ #include #include "./ui_renderer.hpp" +#include "../sdlpp/event.hpp" namespace sdl_gpu_test { @@ -21,6 +22,9 @@ public: virtual ~Widget() noexcept = default; virtual void handleEnteredTree() {} + virtual void handleMouseMotion(const sdlpp::MouseMotionEvent& /* event */) {} + virtual void handleMouseButton(const sdlpp::MouseButtonEvent& /* event */) {} + virtual void revalidate() {} void invalidate(); @@ -38,6 +42,8 @@ private: std::vector mChildren; public: void handleEnteredTree() override; + void handleMouseMotion(const sdlpp::MouseMotionEvent& event) override; + void handleMouseButton(const sdlpp::MouseButtonEvent&) override; Widget* addChild(widget_ptr_t&& child); @@ -69,6 +75,9 @@ public: [[nodiscard]] ParentWidget& getRootWidget() noexcept { return mRootWidget; } + void notifyMouseMoved(const sdlpp::MouseMotionEvent& event); + void notifyMouseButton(const sdlpp::MouseButtonEvent& event); + void invalidateWidget(Widget* widget) noexcept; }; } // namespace sdl_gpu_test