#pragma once #include #include #include #include #include #include #include namespace Game::Object { struct UITextboxConfig { SDL_Color bgColor = {20, 20, 20, 210}; SDL_Color borderColor = {110, 110, 110, 255}; SDL_Color focusedBorderColor = {200, 175, 70, 255}; SDL_Color textColor = {255, 255, 255, 255}; SDL_Color focusedTextColor = {255, 240, 180, 255}; SDL_Color placeholderColor = {120, 120, 120, 200}; float borderThickness = 2.f; float paddingX = 8.f; float paddingY = 4.f; float minWidth = 160.f; float minHeight = 32.f; int maxLength = 0; // 0 = unlimited std::string placeholder = ""; float cursorBlinkRate = 0.53f; // seconds per blink phase }; class UITextBox : public Entity { public: UITextBox(const std::string& name, std::shared_ptr font, const Transform& transform, float x = 0.f, float y = 0.f, UITextboxConfig config = {}); ~UITextBox() override = default; void start() override; void update(float deltaTime) override; void render(Game::Renderer::Renderer* renderer, Game::Renderer::RendererConfig config) override; void setText(const std::string& text); std::string getText() const; std::string getValue() const; bool isFocused() const; void setPosition(float x, float y) { mX = x; mY = y; } std::pair getPosition() const { return {mX, mY}; } private: bool isMouseInsideBox() const; void refreshVisualText(); float mX, mY; std::string mText; bool mIsFocused = false; float mBoxWidth = 0.f; float mBoxHeight = 0.f; bool mNeedsTextRefresh = true; UITextboxConfig mConfig; float mCursorTimer = 0.f; bool mCursorVisible = true; }; }