Files
coffee_crisis_arcade_edition/source/ui/window_message.cpp
Sergio Valor 100b7265d5 Text: revisada la classe
window_message: correcions
2025-08-07 12:40:24 +02:00

174 lines
4.6 KiB
C++

#include "window_message.h"
#include <algorithm>
#include <utility>
#include "param.h"
#include "screen.h"
#include "text.h"
WindowMessage::WindowMessage(
std::shared_ptr<Text> text_renderer,
const std::string& title,
const Color& bg_color,
const Color& border_color,
const Color& title_color,
const Color& text_color)
: text_renderer_(std::move(text_renderer)),
title_(title),
bg_color_(bg_color),
border_color_(border_color),
title_color_(title_color),
text_color_(text_color),
title_style_(Text::CENTER | Text::COLOR, title_color, title_color, 0, -2),
text_style_(Text::CENTER | Text::COLOR, text_color, text_color, 0, -2) {
}
void WindowMessage::render() {
if (!visible_) {
return;
}
SDL_Renderer* renderer = Screen::get()->getRenderer();
// Dibujar fondo con transparencia
SDL_SetRenderDrawColor(renderer, bg_color_.r, bg_color_.g, bg_color_.b, bg_color_.a);
SDL_RenderFillRect(renderer, &rect_);
// Dibujar borde
SDL_SetRenderDrawColor(renderer, border_color_.r, border_color_.g, border_color_.b, border_color_.a);
SDL_RenderRect(renderer, &rect_);
float current_y = rect_.y + padding_;
// Dibujar título si existe
if (!title_.empty()) {
text_renderer_->writeStyle(
rect_.x + rect_.w / 2.0f,
current_y,
title_,
title_style_);
current_y += text_renderer_->getCharacterSize() + line_spacing_ * 2;
// Línea separadora debajo del título
SDL_SetRenderDrawColor(renderer, border_color_.r, border_color_.g, border_color_.b, border_color_.a);
SDL_RenderLine(renderer,
rect_.x + padding_,
current_y - line_spacing_,
rect_.x + rect_.w - padding_,
current_y - line_spacing_);
}
// Dibujar textos
for (const auto& text : texts_) {
text_renderer_->writeStyle(
rect_.x + rect_.w / 2.0f,
current_y,
text,
text_style_);
current_y += text_renderer_->getCharacterSize() + line_spacing_;
}
}
void WindowMessage::update() {
// Por ahora no hay animaciones, pero se puede extender
}
void WindowMessage::show() {
visible_ = true;
}
void WindowMessage::hide() {
visible_ = false;
}
void WindowMessage::setTitle(const std::string& title) {
title_ = title;
}
void WindowMessage::setText(const std::string& text) {
texts_.clear();
texts_.push_back(text);
}
void WindowMessage::setTexts(const std::vector<std::string>& texts) {
texts_ = texts;
}
void WindowMessage::addText(const std::string& text) {
texts_.push_back(text);
}
void WindowMessage::clearTexts() {
texts_.clear();
}
void WindowMessage::setPosition(float x, float y) {
rect_.x = x;
rect_.y = y;
}
void WindowMessage::setSize(float width, float height) {
rect_.w = width;
rect_.h = height;
}
void WindowMessage::centerOnScreen() {
rect_.x = (param.game.width - rect_.w) / 2.0f;
rect_.y = (param.game.height - rect_.h) / 2.0f;
}
void WindowMessage::autoSize() {
calculateAutoSize();
}
void WindowMessage::calculateAutoSize() {
float content_width = calculateContentWidth();
float content_height = calculateContentHeight();
rect_.w = content_width + (padding_ * 2);
rect_.h = content_height + (padding_ * 2);
// Aplicar límites mínimos y máximos
rect_.w = std::max(rect_.w, 200.0f);
rect_.h = std::max(rect_.h, 100.0f);
// No exceder el 80% de la pantalla
rect_.w = std::min(rect_.w, param.game.width * 0.8f);
rect_.h = std::min(rect_.h, param.game.height * 0.8f);
}
auto WindowMessage::calculateContentHeight() const -> float {
float height = 0;
// Altura del título
if (!title_.empty()) {
height += text_renderer_->getCharacterSize() + line_spacing_ * 2; // Espacio extra para separador
}
// Altura de los textos
if (!texts_.empty()) {
height += (texts_.size() * text_renderer_->getCharacterSize());
height += ((texts_.size() - 1) * line_spacing_); // Espaciado entre líneas
}
return height;
}
auto WindowMessage::calculateContentWidth() const -> float {
float max_width = 200.0f; // Ancho mínimo
// Ancho del título
if (!title_.empty()) {
float title_width = text_renderer_->length(title_, -2);
max_width = std::max(max_width, title_width);
}
// Ancho de los textos
for (const auto& text : texts_) {
float text_width = text_renderer_->length(text, -2);
max_width = std::max(max_width, text_width);
}
return max_width;
}