diff --git a/include/appstates/ConfirmState.hpp b/include/appstates/ConfirmState.hpp index 8b53636..e73eec5 100644 --- a/include/appstates/ConfirmState.hpp +++ b/include/appstates/ConfirmState.hpp @@ -256,7 +256,7 @@ class ConfirmState final : public BaseState OPTION_FONT_SIZE, sdl::text::NO_WRAP, colors::WHITE, - sm_yes); + sm_no); } private: @@ -429,7 +429,7 @@ class ConfirmState final : public BaseState else if (validCancel) { StateType::create_and_push(m_onCancel, m_taskData); } else { - FadeState::create_and_push(colors::DIM_BACKGROUND, colors::ALPHA_FADE_END, colors::ALPHA_FADE_END, nullptr); + FadeState::create_and_push(colors::DIM_BACKGROUND, colors::ALPHA_FADE_END, colors::ALPHA_FADE_BEGIN, nullptr); } // Deactivate this state. diff --git a/include/appstates/MessageState.hpp b/include/appstates/MessageState.hpp index 00bf08f..a051277 100644 --- a/include/appstates/MessageState.hpp +++ b/include/appstates/MessageState.hpp @@ -16,12 +16,21 @@ class MessageState final : public BaseState /// @param message Message to display. MessageState(std::string_view message); + /// @brief Same as above. Moves message instead of copying. + MessageState(std::string &message); + /// @brief Creates and returns a new MessageState. See constructor. static inline std::shared_ptr create(std::string_view message) { return std::make_shared(message); } + /// @brief Creates and returns a new MessageState. See constructor. + static inline std::shared_ptr create(std::string &message) + { + return std::make_shared(message); + } + /// @brief Same as above, only pushed to the StateManager before return. static inline std::shared_ptr create_and_push(std::string_view message) { @@ -30,6 +39,14 @@ class MessageState final : public BaseState return newState; } + /// @brief Same as above, only pushed to the StateManager before return. + static inline std::shared_ptr create_and_push(std::string &message) + { + auto newState = MessageState::create(message); + StateManager::push_state(newState); + return newState; + } + /// @brief Same as above, but creates and pushes a transition fade in between. static inline std::shared_ptr create_push_fade(std::string_view message) { @@ -39,6 +56,15 @@ class MessageState final : public BaseState return newState; } + /// @brief Same as above, but creates and pushes a transition fade in between. + static inline std::shared_ptr create_push_fade(std::string &message) + { + auto newState = MessageState::create(message); + auto fadeState = + FadeState::create_and_push(colors::DIM_BACKGROUND, colors::ALPHA_FADE_BEGIN, colors::ALPHA_FADE_END, newState); + return newState; + } + /// @brief Update override. void update() override; @@ -46,6 +72,14 @@ class MessageState final : public BaseState void render() override; private: + /// @brief States this state can be in. + enum class State + { + Opening, + Displaying, + Closing + }; + /// @brief Safe store of the message to display. std::string m_message{}; @@ -55,8 +89,8 @@ class MessageState final : public BaseState /// @brief Transition. ui::Transition m_transition{}; - /// @brief Bool to signal to close. - bool m_close{}; + /// @brief Stores the current state of the current state. + MessageState::State m_state{}; /// @brief This is the OK string. static inline const char *sm_okText{}; @@ -74,7 +108,10 @@ class MessageState final : public BaseState void initialize_static_members(); /// @brief Updates the dialog according to the transition. - void update_dialog(); + void update_dimensions() noexcept; + + /// @brief Updates and handles the input. + void update_handle_input() noexcept; /// @brief Closes and "hides" the dialog. void close_dialog(); diff --git a/source/appstates/MessageState.cpp b/source/appstates/MessageState.cpp index f9718e4..843da33 100644 --- a/source/appstates/MessageState.cpp +++ b/source/appstates/MessageState.cpp @@ -7,11 +7,47 @@ #include "input.hpp" #include "strings/strings.hpp" +namespace +{ + // Initial coordinates. + constexpr int INITIAL_WIDTH_HEIGHT = 32; + + // Target + constexpr int TARGET_WIDTH = 720; + constexpr int TARGET_HEIGHT = 256; +} + // ---- Construction ---- MessageState::MessageState(std::string_view message) : m_message(message) - , m_transition(0, 0, 32, 32, 0, 0, graphics::SCREEN_HEIGHT, 256, ui::Transition::DEFAULT_THRESHOLD) + , m_transition(0, + 0, + INITIAL_WIDTH_HEIGHT, + INITIAL_WIDTH_HEIGHT, + 0, + 0, + TARGET_WIDTH, + TARGET_HEIGHT, + ui::Transition::DEFAULT_THRESHOLD) + , m_state(State::Opening) +{ + MessageState::initialize_static_members(); + sm_dialogPop->play(); +} + +MessageState::MessageState(std::string &message) + : m_message(std::move(message)) + , m_transition(0, + 0, + INITIAL_WIDTH_HEIGHT, + INITIAL_WIDTH_HEIGHT, + 0, + 0, + TARGET_WIDTH, + TARGET_HEIGHT, + ui::Transition::DEFAULT_THRESHOLD) + , m_state(State::Opening) { MessageState::initialize_static_members(); sm_dialogPop->play(); @@ -21,17 +57,12 @@ MessageState::MessageState(std::string_view message) void MessageState::update() { - m_transition.update(); - sm_dialog->set_from_transition(m_transition, true); - if (!m_transition.in_place()) { return; } - - // To do: I only use this in one place right now. I'm not sure this guards correctly here? - const bool aPressed = input::button_pressed(HidNpadButton_A); - m_triggerGuard = m_triggerGuard || (aPressed && !m_triggerGuard); - const bool finished = m_triggerGuard && aPressed; - - if (finished) { MessageState::close_dialog(); } - else if (m_close && m_transition.in_place()) { MessageState::deactivate_state(); } + switch (m_state) + { + case State::Opening: MessageState::update_dimensions(); break; + case State::Displaying: MessageState::update_handle_input(); break; + case State::Closing: MessageState::update_dimensions(); break; + } } void MessageState::render() @@ -65,9 +96,35 @@ void MessageState::initialize_static_members() sm_dialog->set_from_transition(m_transition, true); } +void MessageState::update_dimensions() noexcept +{ + // Update the dialog. + m_transition.update(); + sm_dialog->set_from_transition(m_transition, true); + + // Conditions for state shifting. + const bool opened = m_state == State::Opening && m_transition.in_place(); + const bool closed = m_state == State::Closing && m_transition.in_place(); + if (opened) { m_state = State::Displaying; } + else if (closed) { MessageState::deactivate_state(); } +} + +void MessageState::update_handle_input() noexcept +{ + // Input bools. + const bool aPressed = input::button_pressed(HidNpadButton_A); + + // Handle the triggerguard. + m_triggerGuard = m_triggerGuard || (aPressed && !m_triggerGuard); + + // Conditions. + const bool finished = m_triggerGuard && aPressed; + if (finished) { MessageState::close_dialog(); } +} + void MessageState::close_dialog() { - m_close = true; + m_state = State::Closing; m_transition.set_target_width(32); m_transition.set_target_height(32); }