From d6e7ec89a86f13726a7651ab95a6a4f099260c77 Mon Sep 17 00:00:00 2001 From: Stepland <16676308+Stepland@users.noreply.github.com> Date: Sun, 9 Feb 2020 17:19:19 +0100 Subject: [PATCH] Variable panel size and spacing --- src/Screens/MusicSelect/MusicSelect.cpp | 8 +-- src/Screens/MusicSelect/MusicSelect.hpp | 3 +- src/Screens/MusicSelect/Panel.cpp | 54 ++++++++-------- src/Screens/MusicSelect/Panel.hpp | 29 +++++---- src/Screens/MusicSelect/Ribbon.cpp | 82 +++++++++++++------------ src/Screens/MusicSelect/Ribbon.hpp | 4 +- 6 files changed, 94 insertions(+), 86 deletions(-) diff --git a/src/Screens/MusicSelect/MusicSelect.cpp b/src/Screens/MusicSelect/MusicSelect.cpp index 7c8a479..c7d8600 100644 --- a/src/Screens/MusicSelect/MusicSelect.cpp +++ b/src/Screens/MusicSelect/MusicSelect.cpp @@ -10,9 +10,9 @@ MusicSelect::Screen::Screen(const Data::SongList& t_song_list) : song_list(t_song_list), resources(), - ribbon(resources), + ribbon(resources, m_panel_size, m_panel_spacing), selected_panel(), - button_highlight(panel_size), + button_highlight(m_panel_size), key_mapping() { /* @@ -31,7 +31,7 @@ MusicSelect::Screen::Screen(const Data::SongList& t_song_list) : } void MusicSelect::Screen::select_chart(sf::RenderWindow& window) { - window.create(sf::VideoMode(panel_size*4, panel_size*4), "jujube", sf::Style::Titlebar); + window.create(sf::VideoMode(m_panel_size*4, m_panel_size*4), "jujube", sf::Style::Titlebar); window.setFramerateLimit(60); ImGui::SFML::Init(window); bool chart_selected = false; @@ -78,7 +78,7 @@ void MusicSelect::Screen::handle_key_press(const sf::Event::KeyEvent& key_event) void MusicSelect::Screen::handle_mouse_click(const sf::Event::MouseButtonEvent& mouse_button_event) { if (mouse_button_event.button == sf::Mouse::Left) { - int clicked_panel_index = (mouse_button_event.x / panel_size) + 4 * (mouse_button_event.y / panel_size); + int clicked_panel_index = (mouse_button_event.x / m_panel_size) + 4 * (mouse_button_event.y / m_panel_size); auto button = fromIndex(clicked_panel_index); if (button) { press_button(*button); diff --git a/src/Screens/MusicSelect/MusicSelect.hpp b/src/Screens/MusicSelect/MusicSelect.hpp index 65c31c6..908d68e 100644 --- a/src/Screens/MusicSelect/MusicSelect.hpp +++ b/src/Screens/MusicSelect/MusicSelect.hpp @@ -24,7 +24,8 @@ namespace MusicSelect { private: // Data const Data::SongList& song_list; - std::size_t panel_size = 150; + std::size_t m_panel_size = 150; + std::size_t m_panel_spacing = 0; // Resources Resources resources; diff --git a/src/Screens/MusicSelect/Panel.cpp b/src/Screens/MusicSelect/Panel.cpp index 8d4f9c6..e7dc4cf 100644 --- a/src/Screens/MusicSelect/Panel.cpp +++ b/src/Screens/MusicSelect/Panel.cpp @@ -5,72 +5,73 @@ #include "MusicSelect.hpp" namespace MusicSelect { - void ColorPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) { - sf::RectangleShape panel{{area.width*0.9f, area.height*0.9f}}; - panel.setFillColor(this->color); - panel.setOrigin(panel.getSize().x / 2.f, panel.getSize().y / 2.f); - panel.setPosition(area.left+area.width/2.f, area.top+area.height/2.f); - target.draw(panel); + void ColorPanel::draw(sf::RenderTarget& target, sf::RenderStates states) const { + sf::RectangleShape panel{{m_size*0.9f, m_size*0.9f}}; + panel.setFillColor(m_color); + states.transform *= getTransform(); + target.draw(panel, states); } void CategoryPanel::click(Ribbon& ribbon, std::size_t from_button_index) { ribbon.move_to_next_category(from_button_index); } - void CategoryPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) { + void CategoryPanel::draw(sf::RenderTarget& target, sf::RenderStates states) const { + states.transform *= getTransform(); sf::RectangleShape red_rectangle; red_rectangle.setFillColor(sf::Color::Transparent); red_rectangle.setOutlineColor(sf::Color::Red); red_rectangle.setOutlineThickness(1.f); - sf::RectangleShape frame{{area.width*0.9f, area.height*0.9f}}; + sf::RectangleShape frame{{m_size*0.9f, m_size*0.9f}}; frame.setFillColor(sf::Color::Black); frame.setOutlineThickness(1.f); frame.setOutlineColor(sf::Color::White); frame.setOrigin(frame.getSize().x / 2.f, frame.getSize().y / 2.f); - frame.setPosition(area.left+area.width/2.f, area.top+area.height/2.f); - target.draw(frame); + frame.setPosition(m_size/2.f, m_size/2.f); + target.draw(frame, states); sf::Text top_text; - top_text.setFont(resources.noto_sans_medium); + top_text.setFont(m_resources.noto_sans_medium); top_text.setString("category"); top_text.setCharacterSize(50U); top_text.setFillColor(sf::Color::White); auto bounds = top_text.getLocalBounds(); - top_text.setScale(area.width*0.45f / bounds.width, area.width*0.45f / bounds.width); - top_text.setPosition(area.left + area.width*0.07f, area.top + area.height*0.07f); - target.draw(top_text); + top_text.setScale(m_size*0.45f / bounds.width, m_size*0.45f / bounds.width); + top_text.setPosition(m_size*0.07f, m_size*0.07f); + target.draw(top_text, states); set_to_global_bounds(red_rectangle, top_text); - target.draw(red_rectangle); + target.draw(red_rectangle, states); sf::Text label_text; - label_text.setFont(resources.noto_sans_medium); - label_text.setString(this->label); + label_text.setFont(m_resources.noto_sans_medium); + label_text.setString(m_label); label_text.setCharacterSize(100U); label_text.setFillColor(sf::Color::White); auto text_bounds = label_text.getLocalBounds(); label_text.setOrigin(text_bounds.width / 2.f, text_bounds.height / 2.f); if (text_bounds.height > text_bounds.width) { - label_text.setScale(area.height*0.8f / text_bounds.height, area.height*0.8f / text_bounds.height); + label_text.setScale(m_size*0.8f/text_bounds.height, m_size*0.8f/text_bounds.height); } else { - label_text.setScale(area.width*0.8f / text_bounds.width, area.width*0.8f / text_bounds.width); + label_text.setScale(m_size*0.8f/text_bounds.width, m_size*0.8f/text_bounds.width); } - label_text.setPosition(area.left + area.width / 2.f, area.top + area.height / 2.f); - target.draw(label_text); + label_text.setPosition(m_size / 2.f, m_size / 2.f); + target.draw(label_text, states); set_to_global_bounds(red_rectangle, label_text); - target.draw(red_rectangle); + target.draw(red_rectangle, states); } void SongPanel::click(Ribbon& ribbon, std::size_t from_button_index) { } - void SongPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) { + void SongPanel::draw(sf::RenderTarget& target, sf::RenderStates states) const { if (m_song.cover) { - auto loaded_texture = resources.covers.async_get(m_song.folder/m_song.cover.value()); + auto loaded_texture = m_resources.covers.async_get(m_song.folder/m_song.cover.value()); if (loaded_texture) { + states.transform *= getTransform(); sf::Sprite cover{*(loaded_texture->texture)}; auto alpha = static_cast( m_seconds_to_alpha.clampedTransform( @@ -79,9 +80,8 @@ namespace MusicSelect { ); cover.setColor(sf::Color(255, 255, 255, alpha)); auto bounds = cover.getGlobalBounds(); - cover.setPosition(area.left, area.top); - cover.setScale(area.width / bounds.width, area.width / bounds.width); - target.draw(cover); + cover.setScale(m_size / bounds.width, m_size / bounds.height); + target.draw(cover, states); } } } diff --git a/src/Screens/MusicSelect/Panel.hpp b/src/Screens/MusicSelect/Panel.hpp index 3693c8b..2bcd10e 100644 --- a/src/Screens/MusicSelect/Panel.hpp +++ b/src/Screens/MusicSelect/Panel.hpp @@ -13,46 +13,49 @@ namespace MusicSelect { // A Panel holds anything that can go under a button on the moving part // of the music select screen, be it nothing, a category indicator, or a song - class Panel { + class Panel : public sf::Drawable, public sf::Transformable { public: + Panel(const std::size_t& size, Resources& resources) : m_size(size), m_resources(resources) {}; // What happens when you click on the panel virtual void click(Ribbon& ribbon, std::size_t from_button_index) = 0; - // How the panel should be displayed - virtual void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) = 0; virtual ~Panel() = default; + protected: + const std::size_t& m_size; + Resources& m_resources; }; class EmptyPanel final : public Panel { public: + using Panel::Panel; void click(Ribbon& ribbon, std::size_t from_button_index) override {return;}; - void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override {return;}; + private: + void draw(sf::RenderTarget& target, sf::RenderStates states) const override {return;}; }; class ColorPanel final : public Panel { public: - explicit ColorPanel(const sf::Color& t_color) : color(t_color) {}; + ColorPanel(const std::size_t& size, Resources& resources, const sf::Color& t_color) : Panel(size, resources), m_color(t_color) {}; void click(Ribbon& ribbon, std::size_t from_button_index) override {return;}; - void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override; private: - const sf::Color color; + void draw(sf::RenderTarget& target, sf::RenderStates states) const override; + const sf::Color m_color; }; class CategoryPanel final : public Panel { public: - explicit CategoryPanel(const std::string& t_label) : label(t_label) {}; + explicit CategoryPanel(const std::size_t& size, Resources& resources, const std::string& t_label) : Panel(size, resources), m_label(t_label) {}; void click(Ribbon& ribbon, std::size_t from_button_index) override; - void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override; - private: - std::string label; + void draw(sf::RenderTarget& target, sf::RenderStates states) const override; + std::string m_label; }; class SongPanel final : public Panel { public: - explicit SongPanel(const Data::Song& t_song) : m_song(t_song) {}; + explicit SongPanel(const std::size_t& size, Resources& resources, const Data::Song& t_song) : Panel(size, resources), m_song(t_song) {}; void click(Ribbon& ribbon, std::size_t from_button_index) override; - void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override; private: + void draw(sf::RenderTarget& target, sf::RenderStates states) const override; const Data::Song& m_song; const Toolkit::AffineTransform m_seconds_to_alpha{0.0f, 0.15f, 0.f, 255.f}; }; diff --git a/src/Screens/MusicSelect/Ribbon.cpp b/src/Screens/MusicSelect/Ribbon.cpp index 734170f..7e8e9dc 100644 --- a/src/Screens/MusicSelect/Ribbon.cpp +++ b/src/Screens/MusicSelect/Ribbon.cpp @@ -62,10 +62,12 @@ bool MusicSelect::MoveAnimation::ended() { return clock.getElapsedTime() / m_time_factor > sf::milliseconds(300); } -MusicSelect::Ribbon::Ribbon(Resources& t_resources) : +MusicSelect::Ribbon::Ribbon(Resources& t_resources, unsigned int panel_size, unsigned int panel_spacing) : m_resources(t_resources), m_layout(), - empty_song() + empty_song(), + m_panel_size(panel_size), + m_panel_spacing(panel_spacing) { std::cout << "Loaded MusicSelect::Ribbon" << std::endl; } @@ -84,19 +86,19 @@ void MusicSelect::Ribbon::title_sort(const Data::SongList &song_list) { categories [std::string(1, letter)] .push_back( - std::make_shared(song) + std::make_shared(m_panel_size, m_resources, song) ); } else if ('a' <= letter and letter <= 'z') { categories [std::string(1, 'A' + (letter - 'a'))] .push_back( - std::make_shared(song) + std::make_shared(m_panel_size, m_resources, song) ); } else { - categories["?"].push_back(std::make_shared(song)); + categories["?"].push_back(std::make_shared(m_panel_size, m_resources, song)); } } else { - categories["?"].push_back(std::make_shared(song)); + categories["?"].push_back(std::make_shared(m_panel_size, m_resources, song)); } } layout_from_category_map(categories); @@ -105,15 +107,15 @@ void MusicSelect::Ribbon::title_sort(const Data::SongList &song_list) { void MusicSelect::Ribbon::test_sort() { m_layout.clear(); m_layout.push_back({ - std::make_shared(), - std::make_shared("A"), - std::make_shared("truc") + std::make_shared(m_panel_size, m_resources), + std::make_shared(m_panel_size, m_resources, "A"), + std::make_shared(m_panel_size, m_resources, "truc") }); for (size_t i = 0; i < 3; i++) { m_layout.push_back({ - std::make_shared(), - std::make_shared(), - std::make_shared() + std::make_shared(m_panel_size, m_resources), + std::make_shared(m_panel_size, m_resources), + std::make_shared(m_panel_size, m_resources) }); } } @@ -128,6 +130,7 @@ void MusicSelect::Ribbon::test2_sort() { for (int i = 0; i < category_size; i++) { categories[std::string(1, letter)].push_back( std::make_shared( + m_panel_size, m_resources, sf::Color( panel_hue_generator.generate(), panel_hue_generator.generate(), @@ -148,7 +151,7 @@ void MusicSelect::Ribbon::test_song_cover_sort() { auto category_size = category_size_generator.generate(); for (int i = 0; i < category_size; i++) { categories[std::string(1, letter)].push_back( - std::make_shared(this->empty_song) + std::make_shared(m_panel_size, m_resources, this->empty_song) ); } } @@ -177,7 +180,7 @@ void MusicSelect::Ribbon::layout_from_category_map(const std::map> current_column; - current_column.push_back(std::make_shared(category)); + current_column.push_back(std::make_shared(m_panel_size, m_resources, category)); for (auto &&panel : panels) { if (current_column.size() == 3) { m_layout.push_back({current_column[0], current_column[1], current_column[2]}); @@ -188,7 +191,7 @@ void MusicSelect::Ribbon::layout_from_category_map(const std::map()); + current_column.push_back(std::make_shared(m_panel_size, m_resources)); } m_layout.push_back({current_column[0], current_column[1], current_column[2]}); } @@ -270,19 +273,12 @@ void MusicSelect::Ribbon::draw_with_animation(sf::RenderTarget &target, sf::Rend for (int column_offset = -1; column_offset <= 4; column_offset++) { std::size_t actual_column = (column_zero + column_offset + m_layout.size()) % m_layout.size(); for (int row = 0; row < 3; row++) { - m_layout - .at(actual_column) - .at(row) - ->draw( - m_resources, - target, - sf::FloatRect( - (static_cast(relative_column_zero + column_offset) - float_position) * 150.f, - row * 150.f, - 150.f, - 150.f - ) + auto panel = m_layout.at(actual_column).at(row); + panel->setPosition( + (static_cast(relative_column_zero + column_offset) - float_position) * (m_panel_size+m_panel_spacing), + row * (m_panel_size+m_panel_spacing) ); + target.draw(*panel); } } } @@ -291,19 +287,9 @@ void MusicSelect::Ribbon::draw_without_animation(sf::RenderTarget &target, sf::R for (int column = -1; column <= 4; column++) { int actual_column_index = (column + m_position + m_layout.size()) % m_layout.size(); for (int row = 0; row < 3; row++) { - m_layout - .at(actual_column_index) - .at(row) - ->draw( - m_resources, - target, - sf::FloatRect( - column * 150.f, - row * 150.f, - 150.f, - 150.f - ) - ); + auto panel = m_layout.at(actual_column_index).at(row); + panel->setPosition(column * (m_panel_size+m_panel_spacing), row * (m_panel_size+m_panel_spacing)); + target.draw(*panel); } } } @@ -312,6 +298,22 @@ void MusicSelect::Ribbon::draw_debug() { if (debug) { ImGui::Begin("Ribbon Debug", &debug); { ImGui::SliderFloat("Time Slowdown Factor", &m_time_factor, 1.f, 10.f); + if (ImGui::CollapsingHeader("Panels")) { + auto panel_size = static_cast(m_panel_size); + if(ImGui::InputInt("Size", &panel_size)) { + if (panel_size < 0) { + panel_size = 0; + } + m_panel_size = static_cast(panel_size); + } + auto panel_spacing = static_cast(m_panel_spacing); + if(ImGui::InputInt("Spacing", &panel_spacing)) { + if (panel_spacing < 0) { + panel_spacing = 0; + } + m_panel_spacing = static_cast(panel_spacing); + } + } } ImGui::End(); } diff --git a/src/Screens/MusicSelect/Ribbon.hpp b/src/Screens/MusicSelect/Ribbon.hpp index 2d6cab0..5ba053c 100644 --- a/src/Screens/MusicSelect/Ribbon.hpp +++ b/src/Screens/MusicSelect/Ribbon.hpp @@ -32,7 +32,7 @@ namespace MusicSelect { // It can be sorted in a number of ways class Ribbon final : public sf::Drawable, public Toolkit::Debuggable { public: - Ribbon(Resources& t_resources); + Ribbon(Resources& t_resources, unsigned int panel_size, unsigned int panel_spacing); void title_sort(const Data::SongList& song_list); void test_sort(); void test2_sort(); @@ -55,5 +55,7 @@ namespace MusicSelect { Resources& m_resources; float m_time_factor = 1.f; Data::Song empty_song; + std::size_t m_panel_size; + std::size_t m_panel_spacing; }; } \ No newline at end of file