#ifndef _UI_VALUE_HPP #define _UI_VALUE_HPP #include #include #include #include #include #include "ui-element.hpp" template class UIValue : public UIElement { public: UIValue(int x, int y, string label, T& value, TTF_Font* font, uint32_t textColor, SDL_Renderer& renderer); ~UIValue() override; void render(int x, int y) override; private: string label; T* value; T oldValue; TTF_Font* font; SDL_Color textColor; SDL_Texture* texture; void createTexture(); }; template UIValue::UIValue(int x, int y, string label, T& value, TTF_Font* font, uint32_t textColor, SDL_Renderer& renderer) : UIElement(x, y, 0, 0, renderer, nullptr, nullptr, nullptr), label(label), value(&value), oldValue(value), font(font), texture(nullptr) { this->textColor = { static_cast((textColor >> 24) & 0xFF), static_cast((textColor >> 16) & 0xFF), static_cast((textColor >> 8) & 0xFF), static_cast(textColor & 0xFF) }; this->createTexture(); } template UIValue::~UIValue() { if (this->texture != nullptr) { SDL_DestroyTexture(this->texture); this->texture = nullptr; } } template void UIValue::createTexture() { // destroy the old texture before re-creating it if (this->texture != nullptr) { SDL_DestroyTexture(this->texture); this->texture = nullptr; } ostringstream oss; oss << label << *this->value; string text = oss.str(); SDL_Surface* surface = TTF_RenderText_Blended(this->font, text.c_str(), this->textColor); if (surface == nullptr) { cout << "Unable to render text surface! SDL_ttf Error: " << TTF_GetError() << endl; } this->texture = SDL_CreateTextureFromSurface(&this->renderer, surface); if (this->texture == nullptr) { cout << "Unable to create texture from rendered text! SDL Error: " << SDL_GetError() << endl; // SDL_FreeSurface(surface); } SDL_FreeSurface(surface); TTF_SizeText(this->font, text.c_str(), &this->width, &this->height); } template void UIValue::render(int x, int y) { if (this->oldValue != *this->value) { this->createTexture(); this->oldValue = *this->value; } SDL_Rect rect = { this->x + x, this->y + y, this->width, this->height }; SDL_RenderCopy(&this->renderer, this->texture, nullptr, &rect); } #endif // _UI_VALUE_HPP