diff --git a/include/graphics/colors.hpp b/include/graphics/colors.hpp index 0734167..8c9dee7 100644 --- a/include/graphics/colors.hpp +++ b/include/graphics/colors.hpp @@ -20,8 +20,8 @@ namespace colors inline constexpr sdl::Color TRANSPARENT = {0x00000000}; inline constexpr sdl::Color SLIDE_PANEL_CLEAR = {0x000000CC}; inline constexpr sdl::Color DIV_COLOR = {0x707070FF}; + inline constexpr sdl::Color GUIDE_COLOR = {0x0000007F}; inline constexpr uint8_t ALPHA_FADE_BEGIN = 0x00; inline constexpr uint8_t ALPHA_FADE_END = 0x88; - } // namespace colors diff --git a/include/ui/ControlGuide.hpp b/include/ui/ControlGuide.hpp index ff65223..54b4b0f 100644 --- a/include/ui/ControlGuide.hpp +++ b/include/ui/ControlGuide.hpp @@ -26,6 +26,9 @@ namespace ui /// @brief Renders the control guide. Both arguments are ignored in this case. void render(sdl::SharedTexture &target, bool hasFocus) override; + /// @brief This is a workaround for states where the guide can't really be hidden correctly. Ex: FileMode. + void reset() noexcept; + private: /// @brief Stores the pointer to the guide string. const char *m_guide{}; diff --git a/include/ui/SlideOutPanel.hpp b/include/ui/SlideOutPanel.hpp index 104143d..d2a6ab7 100644 --- a/include/ui/SlideOutPanel.hpp +++ b/include/ui/SlideOutPanel.hpp @@ -1,6 +1,7 @@ #pragma once #include "sdl.hpp" #include "ui/Element.hpp" +#include "ui/Transition.hpp" #include #include @@ -90,9 +91,6 @@ namespace ui /// @brief Whether or not to hide the panel. bool m_hidePanel{}; - /// @brief Current X coordinate to render to. Panels are always 720 pixels in height so no Y is required. - double m_x{}; - /// @brief Width of the panel in pixels. int m_width{}; @@ -102,6 +100,9 @@ namespace ui /// @brief Which side the panel is on. SlideOutPanel::Side m_side{}; + /// @brief Transition for the slide out effect. + ui::Transition m_transition{}; + /// @brief Render target if panel. sdl::SharedTexture m_renderTarget{}; @@ -111,16 +112,10 @@ namespace ui /// @brief Tracks the internal ID of render targets for panels. static inline int sm_targetID{}; - /// @brief Handles sliding out logic. - void slide_out() noexcept; + /// @brief Returns the target X to open the panel. + inline int get_target_open_x() { return m_side == Side::Left ? 0 : 1280 - m_width; } - /// @brief Slides the panel out from the left side. - void slide_out_left() noexcept; - - /// @brief Slides the panel out from the right side. - void slide_out_right() noexcept; - - /// @brief Contains the logic for hiding/closing the panel. - void close_hide_panel() noexcept; + /// @brief Returns the target X to close/hide the panel. + inline int get_target_close_x() { return m_side == Side::Left ? -m_width : 1280; } }; } // namespace ui diff --git a/romfs/Textures/GuideCap.png b/romfs/Textures/GuideCap.png index f005b8c..1e9e395 100644 Binary files a/romfs/Textures/GuideCap.png and b/romfs/Textures/GuideCap.png differ diff --git a/source/appstates/FileModeState.cpp b/source/appstates/FileModeState.cpp index 4d021c2..d2b6023 100644 --- a/source/appstates/FileModeState.cpp +++ b/source/appstates/FileModeState.cpp @@ -217,6 +217,7 @@ fslib::Directory &FileModeState::get_destination_directory() noexcept { return m void FileModeState::deactivate_state() noexcept { sm_frame->set_y(720); + sm_controlGuide->reset(); fslib::close_file_system(m_mountA); fslib::close_file_system(m_mountB); BaseState::deactivate(); diff --git a/source/ui/ControlGuide.cpp b/source/ui/ControlGuide.cpp index 8884968..447a587 100644 --- a/source/ui/ControlGuide.cpp +++ b/source/ui/ControlGuide.cpp @@ -36,7 +36,7 @@ void ui::ControlGuide::render(sdl::SharedTexture &target, bool hasFocus) const int guideY = m_transition.get_y(); sm_controlCap->render(sdl::Texture::Null, guideX, guideY); - sdl::render_rect_fill(sdl::Texture::Null, guideX + 16, guideY, m_guideWidth - 16, 48, colors::SLIDE_PANEL_CLEAR); + sdl::render_rect_fill(sdl::Texture::Null, guideX + 16, guideY, m_guideWidth - 16, 48, colors::GUIDE_COLOR); sdl::text::render(sdl::Texture::Null, guideX + 24, guideY + 10, 23, sdl::text::NO_WRAP, colors::WHITE, m_guide); } @@ -47,4 +47,10 @@ void ui::ControlGuide::initialize_static_members() if (sm_controlCap) { return; } sm_controlCap = sdl::TextureManager::load(NAME_CAP, "romfs:/Textures/GuideCap.png"); +} + +void ui::ControlGuide::reset() noexcept +{ + m_transition.set_target_x(1280); + m_transition.set_x(1280); } \ No newline at end of file diff --git a/source/ui/SlideOutPanel.cpp b/source/ui/SlideOutPanel.cpp index 092223c..b6b99a9 100644 --- a/source/ui/SlideOutPanel.cpp +++ b/source/ui/SlideOutPanel.cpp @@ -13,58 +13,71 @@ namespace } ui::SlideOutPanel::SlideOutPanel(int width, Side side) - : m_x(side == Side::Left ? static_cast(-width) : static_cast(SCREEN_WIDTH)) - , m_width(width) + : m_width(width) , m_targetX(side == Side::Left ? 0.0f : static_cast(SCREEN_WIDTH) - m_width) , m_side(side) + , m_transition(m_side == Side::Left ? -m_width : SCREEN_WIDTH, 0, m_targetX, 0, 4) , m_renderTarget( sdl::TextureManager::load("PANEL_" + std::to_string(sm_targetID++), m_width, 720, SDL_TEXTUREACCESS_TARGET)) {}; void ui::SlideOutPanel::update(bool hasFocus) { - if (hasFocus && SlideOutPanel::is_hidden()) { SlideOutPanel::unhide(); } + const int targetX = m_transition.get_target_x(); + if (hasFocus && targetX != m_targetX) { SlideOutPanel::unhide(); } - slide_out(); + m_transition.update(); - if (m_isOpen) + if (m_transition.in_place()) { for (auto ¤tElement : m_elements) { currentElement->update(hasFocus); } } } -void ui::SlideOutPanel::sub_update() { SlideOutPanel::close_hide_panel(); } +void ui::SlideOutPanel::sub_update() { m_transition.update(); } void ui::SlideOutPanel::render(sdl::SharedTexture &target, bool hasFocus) { for (auto ¤tElement : m_elements) { currentElement->render(m_renderTarget, hasFocus); } - m_renderTarget->render(target, m_x, 0); + const int x = m_transition.get_x(); + m_renderTarget->render(target, x, 0); } void ui::SlideOutPanel::clear_target() { m_renderTarget->clear(colors::SLIDE_PANEL_CLEAR); } void ui::SlideOutPanel::reset() noexcept { - m_x = m_side == Side::Left ? -(m_width) : SCREEN_WIDTH; + const int x = SlideOutPanel::get_target_close_x(); + m_transition.set_x(x); m_isOpen = false; m_closePanel = false; } -void ui::SlideOutPanel::close() noexcept { m_closePanel = true; } - -void ui::SlideOutPanel::hide() noexcept { m_hidePanel = true; } - -void ui::SlideOutPanel::unhide() noexcept { m_hidePanel = false; } - -bool ui::SlideOutPanel::is_open() const noexcept { return m_isOpen; } - -bool ui::SlideOutPanel::is_closed() noexcept +void ui::SlideOutPanel::close() noexcept { - close_hide_panel(); - const bool closed = m_side == Side::Left ? m_x <= -m_width : m_x >= SCREEN_WIDTH; - return m_closePanel && closed; + const int targetX = SlideOutPanel::get_target_close_x(); + m_transition.set_target_x(targetX); + m_closePanel = true; } +void ui::SlideOutPanel::hide() noexcept +{ + const int targetX = SlideOutPanel::get_target_close_x(); + m_transition.set_target_x(targetX); + m_hidePanel = true; +} + +void ui::SlideOutPanel::unhide() noexcept +{ + const int targetX = SlideOutPanel::get_target_open_x(); + m_transition.set_target_x(targetX); + m_hidePanel = false; +} + +bool ui::SlideOutPanel::is_open() const noexcept { return m_transition.in_place(); } + +bool ui::SlideOutPanel::is_closed() noexcept { return m_closePanel && m_transition.in_place(); } + bool ui::SlideOutPanel::is_hidden() const noexcept { return m_hidePanel; } void ui::SlideOutPanel::push_new_element(std::shared_ptr newElement) { m_elements.push_back(newElement); } @@ -72,59 +85,3 @@ void ui::SlideOutPanel::push_new_element(std::shared_ptr newElement void ui::SlideOutPanel::clear_elements() { m_elements.clear(); } sdl::SharedTexture &ui::SlideOutPanel::get_target() noexcept { return m_renderTarget; } - -void ui::SlideOutPanel::slide_out() noexcept -{ - const bool needsSlideOut = !m_isOpen && !m_closePanel && !m_hidePanel; - if (!needsSlideOut) { return; } - - const bool slideRight = m_side == SlideOutPanel::Side::Left && m_x < 0; - const bool slideLeft = m_side == SlideOutPanel::Side::Right && m_x > SCREEN_WIDTH - m_width; - - if (slideRight) { SlideOutPanel::slide_out_left(); } - else if (slideLeft) { SlideOutPanel::slide_out_right(); } -} - -void ui::SlideOutPanel::slide_out_left() noexcept -{ - const double scaling = config::get_animation_scaling(); - - m_x -= std::round(m_x / scaling); - - // This is a workaround for the floating points never lining up quite right. - const int distance = math::Util::absolute_distance(m_x, m_targetX); - if (distance <= 2) - { - m_x = m_targetX; - m_isOpen = true; - } -} - -void ui::SlideOutPanel::slide_out_right() noexcept -{ - const double scaling = config::get_animation_scaling(); - const double screenWidth = static_cast(SCREEN_WIDTH); - const double width = static_cast(m_width); - const double pixels = (screenWidth - width - m_x) / scaling; - m_x += std::round(pixels); - - const int distance = math::Util::absolute_distance(m_x, m_targetX); - if (distance <= 2) - { - m_x = m_targetX; - m_isOpen = true; - } -} - -void ui::SlideOutPanel::close_hide_panel() noexcept -{ - const double scaling = config::get_animation_scaling(); - const bool closeHide = m_closePanel || m_hidePanel; - const bool closeToLeft = closeHide && m_side == Side::Left && m_x > -m_width; - const bool closeToRight = closeHide && m_side == Side::Right && m_x < SCREEN_WIDTH; - if (closeToLeft) { m_x += -((m_width - m_x) / scaling); } - else if (closeToRight) { m_x += m_x / scaling; } - - const bool closedOrHidden = (m_x <= -m_width) || (m_x >= SCREEN_WIDTH); - if (closedOrHidden) { m_isOpen = false; } -}