From 6d36291f5123ef62b28ea8c3a70279f0a5657303 Mon Sep 17 00:00:00 2001 From: Sergio Valor Date: Wed, 6 Aug 2025 14:12:29 +0200 Subject: [PATCH] claude: treballant en el nou define_buttons --- source/define_buttons.cpp | 178 +++++++++++++++++++++---------- source/define_buttons.h | 75 ++++++------- source/sections/title.cpp | 88 +++------------ source/sections/title.h | 4 - source/ui/action_list_option.cpp | 95 +++++++++++++++++ source/ui/action_list_option.h | 42 ++++++++ source/ui/menu_option.h | 5 +- source/ui/menu_renderer.cpp | 36 ++++--- source/ui/service_menu.cpp | 54 ++++++++-- source/ui/service_menu.h | 7 +- source/ui/window_message.cpp | 172 +++++++++++++++++++++++++++++ source/ui/window_message.h | 84 +++++++++++++++ 12 files changed, 650 insertions(+), 190 deletions(-) create mode 100644 source/ui/action_list_option.cpp create mode 100644 source/ui/action_list_option.h create mode 100644 source/ui/window_message.cpp create mode 100644 source/ui/window_message.h diff --git a/source/define_buttons.cpp b/source/define_buttons.cpp index 8cda907..24b9547 100644 --- a/source/define_buttons.cpp +++ b/source/define_buttons.cpp @@ -1,69 +1,55 @@ #include "define_buttons.h" -#include // Para __all_of_fn, all_of -#include // Para identity -#include // Para allocator, shared_ptr, __shared_ptr_access, operator== +#include +#include +#include -#include "input.h" // Para Input -#include "input_types.h" // Para InputAction -#include "lang.h" // Para getText -#include "options.h" // Para Gamepad -#include "param.h" // Para Param, param, ParamGame, ParamTitle -#include "resource.h" // Para Resource -#include "text.h" // Para Text +#include "input.h" +#include "input_types.h" +#include "lang.h" +#include "options.h" +#include "param.h" +#include "resource.h" +#include "text.h" +#include "ui/window_message.h" -// Constructor DefineButtons::DefineButtons() - : input_(Input::get()), - - x_(param.game.width / 2), - y_(param.title.press_start_position) { + : input_(Input::get()) { + clearButtons(); auto gamepads = input_->getGamepads(); for (auto gamepad : gamepads) { controller_names_.emplace_back(Input::getControllerName(gamepad)); } + + // Crear la ventana de mensaje + auto text_renderer = Resource::get()->getText("04b_25_flat"); + window_message_ = std::make_unique( + text_renderer, + Lang::getText("[DEFINE_BUTTONS] TITLE"), + Color{20, 30, 50, 200}, // Fondo azul oscuro semi-transparente + Color{100, 150, 200, 255}, // Borde azul claro + Color{255, 255, 255, 255}, // Título blanco + Color{220, 220, 220, 255} // Texto gris claro + ); + + window_message_->setPadding(20.0f); + window_message_->setLineSpacing(8.0f); } -// Dibuja el objeto en pantalla void DefineButtons::render() { - static auto text_ = Resource::get()->getText("8bithud"); - if (enabled_) { - text_->writeCentered(x_, y_ - 10, Lang::getText("[DEFINE_BUTTONS] PLAYER") + std::to_string(static_cast(options_gamepad_->player_id))); - text_->writeCentered(x_, y_, options_gamepad_->name); - text_->writeCentered(x_, y_ + 10, buttons_.at(index_button_).label); + if (enabled_ && window_message_) { + window_message_->render(); } } -// Comprueba el botón que se ha pulsado -void DefineButtons::doControllerButtonDown(const SDL_GamepadButtonEvent &event) { - auto gamepad = input_->getGamepad(event.which); - - // Asegúrate de que el gamepad sea válido y sea el que corresponde - if (!gamepad || gamepad != options_gamepad_->instance) { - return; - } - - const auto BUTTON = static_cast(event.button); - if (checkButtonNotInUse(BUTTON)) { - buttons_.at(index_button_).button = BUTTON; - incIndexButton(); +void DefineButtons::update() { + if (enabled_ && window_message_) { + window_message_->update(); } } -// Asigna los botones definidos al input_ -void DefineButtons::bindButtons(Options::Gamepad *options_gamepad) { - for (const auto &button : buttons_) { - Input::bindGameControllerButton(options_gamepad->instance, button.action, button.button); - } - - // Remapea los inputs a inputs - Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_SELECT, Input::Action::FIRE_LEFT); - Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_BACK, Input::Action::FIRE_CENTER); -} - -// Comprueba los eventos void DefineButtons::checkEvents(const SDL_Event &event) { if (enabled_) { switch (event.type) { @@ -79,7 +65,6 @@ void DefineButtons::checkEvents(const SDL_Event &event) { } } -// Habilita el objeto auto DefineButtons::enable(Options::Gamepad *options_gamepad) -> bool { if (options_gamepad != nullptr) { options_gamepad_ = options_gamepad; @@ -87,12 +72,52 @@ auto DefineButtons::enable(Options::Gamepad *options_gamepad) -> bool { finished_ = false; index_button_ = 0; clearButtons(); + updateWindowMessage(); + + if (window_message_) { + window_message_->autoSize(); + window_message_->centerOnScreen(); + window_message_->show(); + } + return true; } return false; } -// Incrementa el indice de los botones +void DefineButtons::disable() { + enabled_ = false; + finished_ = false; + + if (window_message_) { + window_message_->hide(); + } +} + +void DefineButtons::doControllerButtonDown(const SDL_GamepadButtonEvent &event) { + auto gamepad = input_->getGamepad(event.which); + + if (!gamepad || gamepad != options_gamepad_->instance) { + return; + } + + const auto BUTTON = static_cast(event.button); + if (checkButtonNotInUse(BUTTON)) { + buttons_.at(index_button_).button = BUTTON; + incIndexButton(); + updateWindowMessage(); + } +} + +void DefineButtons::bindButtons(Options::Gamepad *options_gamepad) { + for (const auto &button : buttons_) { + Input::bindGameControllerButton(options_gamepad->instance, button.action, button.button); + } + + Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_SELECT, Input::Action::FIRE_LEFT); + Input::bindGameControllerButton(options_gamepad->instance, Input::Action::SM_BACK, Input::Action::FIRE_CENTER); +} + void DefineButtons::incIndexButton() { if (index_button_ < buttons_.size() - 1) { ++index_button_; @@ -101,14 +126,12 @@ void DefineButtons::incIndexButton() { } } -// Comprueba que un botón no esté ya asignado auto DefineButtons::checkButtonNotInUse(SDL_GamepadButton button) -> bool { return std::ranges::all_of(buttons_, [button](const auto &b) { return b.button != button; }); } -// Limpia la asignación de botones void DefineButtons::clearButtons() { buttons_.clear(); buttons_.emplace_back(Lang::getText("[DEFINE_BUTTONS] FIRE_LEFT"), Input::Action::FIRE_LEFT, SDL_GAMEPAD_BUTTON_INVALID); @@ -118,12 +141,57 @@ void DefineButtons::clearButtons() { buttons_.emplace_back(Lang::getText("[DEFINE_BUTTONS] SERVICE_MENU"), Input::Action::SERVICE, SDL_GAMEPAD_BUTTON_INVALID); } -// Comprueba si ha finalizado void DefineButtons::checkEnd() { if (finished_) { - bindButtons(options_gamepad_); // Asigna los botones definidos al input_ - input_->saveGamepadConfigFromGamepad(options_gamepad_->instance); // Guarda los cambios - input_->resetInputStates(); // Reinicia los estados de las pulsaciones de los botones - enabled_ = false; // Deshabilita + bindButtons(options_gamepad_); + input_->saveGamepadConfigFromGamepad(options_gamepad_->instance); + input_->resetInputStates(); + + // Mostrar mensaje de finalización brevemente + if (window_message_) { + window_message_->clearTexts(); + window_message_->addText(Lang::getText("[DEFINE_BUTTONS] CONFIGURATION_COMPLETE")); + window_message_->autoSize(); + window_message_->centerOnScreen(); + } + + // Se deshabilitará desde el ServiceMenu después de un breve delay + } +} + +void DefineButtons::updateWindowMessage() { + if (!window_message_ || !options_gamepad_) { + return; + } + + // Configurar título + std::string title = Lang::getText("[DEFINE_BUTTONS] CONFIGURING") + ": " + options_gamepad_->name; + window_message_->setTitle(title); + + // Limpiar textos anteriores + window_message_->clearTexts(); + + if (index_button_ < buttons_.size()) { + // Mostrar progreso + std::string progress = "(" + std::to_string(index_button_ + 1) + "/" + + std::to_string(buttons_.size()) + ")"; + window_message_->addText(progress); + window_message_->addText(""); + + // Instrucción actual + std::string instruction = Lang::getText("[DEFINE_BUTTONS] PRESS_BUTTON_FOR") + ":"; + window_message_->addText(instruction); + window_message_->addText(buttons_.at(index_button_).label); + + // Botones ya configurados + if (index_button_ > 0) { + window_message_->addText(""); + window_message_->addText(Lang::getText("[DEFINE_BUTTONS] CONFIGURED") + ":"); + + for (size_t i = 0; i < index_button_; ++i) { + std::string configured = "✓ " + buttons_[i].label; + window_message_->addText(configured); + } + } } } \ No newline at end of file diff --git a/source/define_buttons.h b/source/define_buttons.h index a860509..b962274 100644 --- a/source/define_buttons.h +++ b/source/define_buttons.h @@ -1,58 +1,59 @@ #pragma once -#include // Para SDL_GamepadButton, SDL_Event, SDL_GamepadButtonEvent +#include -#include // Para size_t -#include // Para string -#include // Para move -#include // Para vector +#include +#include +#include +#include +#include -#include "input.h" // Para Input +#include "input.h" + +class WindowMessage; namespace Options { struct Gamepad; -} // namespace Options +} -// Clase DefineButtons class DefineButtons { public: - // Estructura para definir botones struct Button { - std::string label; // Texto en pantalla - Input::Action action; // Acción asociada - SDL_GamepadButton button; // Botón del mando + std::string label; + Input::Action action; + SDL_GamepadButton button; - Button(std::string label, Input::Action action, SDL_GamepadButton button) - : label(std::move(label)), action(action), button(button) {} + Button(std::string label, Input::Action action, SDL_GamepadButton button) + : label(std::move(label)), action(action), button(button) {} }; DefineButtons(); ~DefineButtons() = default; - void render(); // Dibuja el objeto en pantalla - void checkEvents(const SDL_Event &event); // Procesa los eventos - auto enable(Options::Gamepad *options_gamepad) -> bool; // Habilita la redefinición de botones - [[nodiscard]] auto isEnabled() const -> bool { return enabled_; }; // Comprueba si está habilitado + void render(); + void update(); + void checkEvents(const SDL_Event &event); + auto enable(Options::Gamepad *options_gamepad) -> bool; + void disable(); + [[nodiscard]] auto isEnabled() const -> bool { return enabled_; } + [[nodiscard]] auto isFinished() const -> bool { return finished_; } private: - // Objetos - Input *input_ = nullptr; // Gestión de entrada + Input *input_ = nullptr; + std::unique_ptr window_message_; - // Variables - bool enabled_ = false; // Indica si está activo - bool finished_ = false; // Indica si ha terminado - int x_ = 0; // Coordenadas de texto - int y_ = 0; // Coordenadas de texto - std::vector