92 lines
2.3 KiB
C++

#pragma once
#if !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GUI_WIDGET_HPP_INCLUDED)
#define SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GUI_WIDGET_HPP_INCLUDED 1
#include <memory>
#include <vector>
#include <unordered_set>
#include "./ui_renderer.hpp"
#include "../sdlpp/event.hpp"
namespace sdl_gpu_test
{
enum class EventResponse
{
UNHANDLED,
HANDLED
};
class Widget
{
protected:
class WidgetTree* mTree = nullptr;
class ParentWidget* mParent = nullptr;
public:
virtual ~Widget() noexcept = default;
virtual void handleEnteredTree() {}
virtual void handleMouseMotion(const sdlpp::MouseMotionEvent& /* event */) {}
virtual EventResponse handleMouseButton(const sdlpp::MouseButtonEvent& /* event */) { return EventResponse::UNHANDLED; }
virtual void revalidate() {}
void invalidate();
private:
void enterTree(class WidgetTree* tree, class ParentWidget* parent);
friend class ParentWidget;
friend class WidgetTree;
};
using widget_ptr_t = std::unique_ptr<Widget>;
class ParentWidget : public Widget
{
private:
std::vector<widget_ptr_t> mChildren;
public:
void handleEnteredTree() override;
void handleMouseMotion(const sdlpp::MouseMotionEvent& event) override;
EventResponse handleMouseButton(const sdlpp::MouseButtonEvent& event) override;
Widget* addChild(widget_ptr_t&& child);
template<typename TChild>
TChild* emplaceChild(typename TChild::create_args_t args)
{
return static_cast<TChild*>(addChild(std::make_unique<TChild>(args)));
}
};
struct WidgetTreeInitArgs
{
UIRenderer* renderer = nullptr;
};
class WidgetTree
{
private:
UIRenderer* mRenderer = nullptr;
ParentWidget mRootWidget;
std::unordered_set<Widget*> mInvalidWidgets;
public:
void init(const WidgetTreeInitArgs& args);
void revalidateWidgets();
[[nodiscard]]
UIRenderer& getRenderer() const noexcept { return *mRenderer; }
[[nodiscard]]
ParentWidget& getRootWidget() noexcept { return mRootWidget; }
void notifyMouseMoved(const sdlpp::MouseMotionEvent& event);
EventResponse notifyMouseButton(const sdlpp::MouseButtonEvent& event);
void invalidateWidget(Widget* widget) noexcept;
};
} // namespace sdl_gpu_test
#endif // !defined(SDL_GPU_TEST_PRIVATE_SDL_GPU_TEST_GUI_WIDGET_HPP_INCLUDED)