diff --git a/source/game.cpp b/source/game.cpp index b735d18..59d4a26 100644 --- a/source/game.cpp +++ b/source/game.cpp @@ -1451,7 +1451,7 @@ void Game::checkEvents() case SDLK_3: // Activa el modo para pasar el juego automaticamente { auto_pop_balloons_ = !auto_pop_balloons_; - Notifier::get()->showText("auto_pop_balloons_ " + boolToString(auto_pop_balloons_)); + Notifier::get()->showText({"auto_pop_balloons_ " + boolToString(auto_pop_balloons_)}); break; } case SDLK_4: // Suelta un item diff --git a/source/global_inputs.cpp b/source/global_inputs.cpp index a85913b..bbe035a 100644 --- a/source/global_inputs.cpp +++ b/source/global_inputs.cpp @@ -40,9 +40,9 @@ namespace globalInputs { #ifdef ARCADE const int index = code == section::Options::QUIT_WITH_CONTROLLER ? 116 : 94; - Notifier::get()->showText(lang::getText(index), std::string(), -1, exit_code); + Notifier::get()->showText({lang::getText(index), std::string()}, -1, exit_code); #else - Notifier::get()->showText(lang::getText(94), std::string(), -1, exit_code); + Notifier::get()->showText({lang::getText(94), std::string()}, -1, exit_code); #endif } } @@ -51,7 +51,7 @@ namespace globalInputs void reset() { section::name = section::Name::INIT; - Notifier::get()->showText("Reset"); + Notifier::get()->showText({"Reset"}); } // Activa o desactiva el audio @@ -68,7 +68,7 @@ namespace globalInputs JA_SetMusicVolume(0); JA_SetSoundVolume(0); } - Notifier::get()->showText("Audio " + boolToOnOff(options.audio.enabled)); + Notifier::get()->showText({"Audio " + boolToOnOff(options.audio.enabled)}); } // Comprueba los inputs que se pueden introducir en cualquier sección del juego @@ -82,7 +82,7 @@ namespace globalInputs { Screen::get()->toggleVideoMode(); const std::string mode = options.video.mode == ScreenVideoMode::WINDOW ? "Window" : "Fullscreen"; - Notifier::get()->showText(mode + " mode"); + Notifier::get()->showText({mode + " mode"}); return; } @@ -91,7 +91,7 @@ namespace globalInputs { Screen::get()->decWindowSize(); const std::string size = std::to_string(options.video.window.size); - Notifier::get()->showText("Window size x" + size); + Notifier::get()->showText({"Window size x" + size}); return; } @@ -100,7 +100,7 @@ namespace globalInputs { Screen::get()->incWindowSize(); const std::string size = std::to_string(options.video.window.size); - Notifier::get()->showText("Window size x" + size); + Notifier::get()->showText({"Window size x" + size}); return; } #endif diff --git a/source/notifier.cpp b/source/notifier.cpp index 4199bdf..1f86289 100644 --- a/source/notifier.cpp +++ b/source/notifier.cpp @@ -2,12 +2,14 @@ #include // Para SDL_BLENDMODE_BLEND #include // Para SDL_PIXELFORMAT_RGBA8888 #include // Para string -#include "jail_audio.h" // Para JA_DeleteSound, JA_LoadSound, JA_Pla... -#include "param.h" // Para Param, param, ParamNotification, Par... -#include "screen.h" // Para Screen -#include "sprite.h" // Para Sprite -#include "text.h" // Para Text -#include "texture.h" // Para Texture +#include +#include +#include "jail_audio.h" // Para JA_DeleteSound, JA_LoadSound, JA_Pla... +#include "param.h" // Para Param, param, ParamNotification, Par... +#include "screen.h" // Para Screen +#include "sprite.h" // Para Sprite +#include "text.h" // Para Text +#include "texture.h" // Para Texture // [SINGLETON] Hay que definir las variables estáticas, desde el .h sólo la hemos declarado Notifier *Notifier::notifier_ = nullptr; @@ -51,7 +53,9 @@ Notifier::~Notifier() void Notifier::render() { for (int i = (int)notifications_.size() - 1; i >= 0; --i) + { notifications_[i].sprite->render(); + } } // Actualiza el estado de las notificaiones @@ -154,39 +158,41 @@ void Notifier::clearFinishedNotifications() } } -void Notifier::showText(std::string text1, std::string text2, int icon, const std::string &code) +void Notifier::showText(std::vector texts, int icon, const std::string &code) { - // Cuenta el número de textos a mostrar - const int num_texts = !text1.empty() + !text2.empty(); - // Si no hay texto, acaba - if (num_texts == 0) + if (texts.empty()) { return; } - // Si solo hay un texto, lo coloca en la primera variable - if (num_texts == 1) - { - text1 += text2; - text2.clear(); - } - // Si las notificaciones no se apilan, elimina las anteriores if (!stack_) { clearNotifications(); } + // Elimina las cadenas vacías + texts.erase(std::remove_if(texts.begin(), texts.end(), [](const std::string &s) + { return s.empty(); }), + texts.end()); + + // Encuentra la cadena más larga + std::string longest; + for (const auto &text : texts) + { + if (text.length() > longest.length()) + longest = text; + } + // Inicializa variables - constexpr auto icon_size = 16; - constexpr auto padding_out = 1; + constexpr int icon_size = 16; + constexpr int padding_out = 1; const auto padding_in_h = text_->getCharacterSize(); const auto padding_in_v = text_->getCharacterSize() / 2; - const auto icon_space = icon >= 0 ? icon_size + padding_in_h : 0; - const std::string txt = text1.length() > text2.length() ? text1 : text2; - const auto width = text_->lenght(txt) + (padding_in_h * 2) + icon_space; - const auto height = (text_->getCharacterSize() * num_texts) + (padding_in_v * 2); + const int icon_space = icon >= 0 ? icon_size + padding_in_h : 0; + const int width = text_->lenght(longest) + (padding_in_h * 2) + icon_space; + const int height = (text_->getCharacterSize() * texts.size()) + (padding_in_v * 2); const auto shape = NotificationShape::SQUARED; // Posición horizontal @@ -212,11 +218,11 @@ void Notifier::showText(std::string text1, std::string text2, int icon, const st auto offset = 0; if (param.notification.pos_v == NotifyPosition::TOP) { - offset = (int)notifications_.size() > 0 ? notifications_.back().y + travel_dist : desp_v; + offset = !notifications_.empty() ? notifications_.back().y + travel_dist : desp_v; } else { - offset = (int)notifications_.size() > 0 ? notifications_.back().y - travel_dist : desp_v; + offset = !notifications_.empty() ? notifications_.back().y - travel_dist : desp_v; } // Crea la notificacion @@ -226,8 +232,7 @@ void Notifier::showText(std::string text1, std::string text2, int icon, const st n.code = code; n.y = offset; n.travel_dist = travel_dist; - n.text1 = text1; - n.text2 = text2; + n.texts = texts; n.shape = shape; auto y_pos = offset + (param.notification.pos_v == NotifyPosition::TOP ? -travel_dist : travel_dist); n.rect = {desp_h, y_pos, width, height}; @@ -264,7 +269,7 @@ void Notifier::showText(std::string text1, std::string text2, int icon, const st } // Dibuja el icono de la notificación - if (has_icons_ && icon >= 0 && num_texts == 2) + if (has_icons_ && icon >= 0 && texts.size() >= 2) { auto sp = std::make_unique(icon_texture_, (SDL_Rect){0, 0, icon_size, icon_size}); sp->setPosition({padding_in_h, padding_in_v, icon_size, icon_size}); @@ -273,15 +278,12 @@ void Notifier::showText(std::string text1, std::string text2, int icon, const st } // Escribe el texto de la notificación - Color color{255, 255, 255}; - if (num_texts == 2) - { // Dos lineas de texto - text_->writeColored(padding_in_h + icon_space, padding_in_v, text1, color); - text_->writeColored(padding_in_h + icon_space, padding_in_v + text_->getCharacterSize() + 1, text2, color); - } - else - { // Una linea de texto - text_->writeColored(padding_in_h + icon_space, padding_in_v, text1, color); + const Color color{255, 255, 255}; + int iterator = 0; + for (const auto &text : texts) + { + text_->writeColored(padding_in_h + icon_space, padding_in_v + iterator * (text_->getCharacterSize() + 1), text, color); + ++iterator; } // Deja de dibujar en la textura @@ -294,26 +296,18 @@ void Notifier::showText(std::string text1, std::string text2, int icon, const st n.texture->setAlpha(0); // Añade la notificación a la lista - notifications_.push_back(n); + notifications_.emplace_back(n); } // Indica si hay notificaciones activas -bool Notifier::isActive() -{ - if ((int)notifications_.size() > 0) - { - return true; - } - - return false; -} +bool Notifier::isActive() { return !notifications_.empty(); } // Finaliza y elimnina todas las notificaciones activas void Notifier::clearNotifications() { - for (int i = 0; i < (int)notifications_.size(); ++i) + for (auto ¬ification : notifications_) { - notifications_[i].status = NotificationStatus::FINISHED; + notification.status = NotificationStatus::FINISHED; } clearFinishedNotifications(); @@ -323,9 +317,9 @@ void Notifier::clearNotifications() std::vector Notifier::getCodes() { std::vector codes; - for (int i = 0; i < (int)notifications_.size(); ++i) + for (const auto ¬ification : notifications_) { - codes.push_back(notifications_[i].code); + codes.emplace_back(notification.code); } return codes; } \ No newline at end of file diff --git a/source/notifier.h b/source/notifier.h index 68d768e..6c4ea66 100644 --- a/source/notifier.h +++ b/source/notifier.h @@ -35,8 +35,7 @@ private: { std::shared_ptr texture; std::shared_ptr sprite; - std::string text1; - std::string text2; + std::vector texts; int counter; NotificationStatus status; NotificationShape shape; @@ -47,7 +46,7 @@ private: // Constructor explicit Notification() - : texture(nullptr), sprite(nullptr), text1(""), text2(""), counter(0), status(NotificationStatus::RISING), + : texture(nullptr), sprite(nullptr), texts(), counter(0), status(NotificationStatus::RISING), shape(NotificationShape::SQUARED), rect{0, 0, 0, 0}, y(0), travel_dist(0), code("") {} }; @@ -95,15 +94,8 @@ public: // Actualiza el estado de las notificaiones void update(); - /** - * @brief Muestra una notificación de texto por pantalla. - * - * @param text1 Primer texto opcional para mostrar (valor predeterminado: cadena vacía). - * @param text2 Segundo texto opcional para mostrar (valor predeterminado: cadena vacía). - * @param icon Icono opcional para mostrar (valor predeterminado: -1). - * @param code Permite asignar un código a la notificación (valor predeterminado: cadena vacía). - */ - void showText(std::string text1 = std::string(), std::string text2 = std::string(), int icon = -1, const std::string &code = std::string()); + // Muestra una notificación de texto por pantalla + void showText(std::vector texts, int icon = -1, const std::string &code = std::string()); // Indica si hay notificaciones activas bool isActive(); diff --git a/source/screen.cpp b/source/screen.cpp index aab0fde..3c0e7ec 100644 --- a/source/screen.cpp +++ b/source/screen.cpp @@ -342,7 +342,7 @@ void Screen::toggleShaders() options.video.shaders = !options.video.shaders; setVideoMode(options.video.mode); const std::string value = options.video.shaders ? "on" : "off"; - Notifier::get()->showText("Shaders " + value); + Notifier::get()->showText({"Shaders " + value}); } // Activa / desactiva la información de debug diff --git a/source/title.cpp b/source/title.cpp index 8fe8147..b8183c5 100644 --- a/source/title.cpp +++ b/source/title.cpp @@ -315,7 +315,7 @@ void Title::swapKeyboard() { swapOptionsKeyboard(); std::string text = lang::getText(100) + std::to_string(getPlayerWhoUsesKeyboard()) + ": " + lang::getText(69); - Notifier::get()->showText(text); + Notifier::get()->showText({text}); } // Muestra información sobre los controles y los jugadores @@ -343,5 +343,5 @@ void Title::showControllers() } } - Notifier::get()->showText(text.at(0), text.at(1)); + Notifier::get()->showText({text.at(0), text.at(1)}); }