1
0
mirror of synced 2024-11-12 01:40:47 +01:00

Fallback cover loading

This commit is contained in:
Stepland 2020-02-05 22:05:10 +01:00
parent 30285d94c5
commit c532cc8a2d
11 changed files with 112 additions and 25 deletions

View File

@ -38,8 +38,10 @@ sources = [
'src/Screens/MusicSelect/Ribbon.hpp',
'src/Screens/MusicSelect/Ribbon.cpp',
# 'src/Screens/Result.hpp',
'src/Resources/CoverAtlas.hpp',
'src/Resources/CoverAtlas.cpp',
'src/Resources/Autoloader.hpp',
'src/Resources/Autoloader.cpp',
# 'src/Resources/CoverAtlas.hpp',
# 'src/Resources/CoverAtlas.cpp',
'src/Toolkit/AffineTransform.hpp',
'src/Toolkit/Debuggable.hpp',
'src/Toolkit/EasingFunctions.hpp',

View File

@ -8,8 +8,6 @@
#include <unordered_map>
#include <vector>
#include "../Resources/CoverAtlas.hpp"
namespace fs = std::filesystem;
namespace Data {

View File

@ -0,0 +1,19 @@
#include "Autoloader.hpp"
void Textures::Autoloader::load(const fs::path& t_path) {
if (m_mapping.find(t_path) != m_mapping.end()) {
return;
}
auto texture = std::make_shared<sf::Texture>();
if (!texture->loadFromFile(t_path)) {
throw std::invalid_argument("Unable to load cover image : "+t_path.string());
}
m_mapping[t_path] = texture;
}
std::shared_ptr<sf::Texture> Textures::Autoloader::get(const fs::path& t_path) {
if (m_mapping.find(t_path) == m_mapping.end()) {
this->load(t_path);
}
return m_mapping.at(t_path);
}

View File

@ -0,0 +1,33 @@
#pragma once
#include <filesystem>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <SFML/Graphics.hpp>
namespace fs = std::filesystem;
// Define the way we hash fs::path for use in unordered maps
namespace std {
template <>
struct hash<fs::path> {
std::size_t operator()(const fs::path& p) const {
return std::hash<std::string>()(p.string());
}
};
}
namespace Textures {
// Loads textures on demand and stores them in a map for easy path-based access
class Autoloader {
public:
Autoloader() = default;
std::shared_ptr<sf::Texture> get(const fs::path& t_path);
private:
void load(const fs::path& t_path);
mutable std::unordered_map<fs::path, std::shared_ptr<sf::Texture>> m_mapping;
};
}

View File

@ -15,13 +15,13 @@ MusicSelect::Screen::Screen(const Data::SongList& t_song_list) :
for (const auto& song : song_list.songs) {
if (song.cover) {
try {
resources.cover_previews.emplace_back(song.cover.value());
resources.covers.get(song.cover.value());
} catch(const std::exception& e) {
std::cerr << e.what() << '\n';
}
}
}
ribbon.test2_sort();
ribbon.test_song_cover_sort();
}
void MusicSelect::Screen::select_chart(sf::RenderWindow& window) {

View File

@ -4,7 +4,7 @@
#include "MusicSelect.hpp"
void MusicSelect::ColorPanel::draw(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
void MusicSelect::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);
@ -16,7 +16,7 @@ void MusicSelect::CategoryPanel::click(Ribbon& ribbon, std::size_t from_button_i
ribbon.move_to_next_category(from_button_index);
}
void MusicSelect::CategoryPanel::draw(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
void MusicSelect::CategoryPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
sf::RectangleShape red_rectangle;
red_rectangle.setFillColor(sf::Color::Transparent);
red_rectangle.setOutlineColor(sf::Color::Red);
@ -62,14 +62,21 @@ void MusicSelect::CategoryPanel::draw(const Resources& resources, sf::RenderTarg
target.draw(red_rectangle);
}
void MusicSelect::SongPanel::click(Ribbon& ribbon, std::size_t from_button_index) {
}
void MusicSelect::SongPanel::draw(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
void MusicSelect::SongPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
sf::Sprite cover;
sf::Texture& cover_texture = resources.fallback_cover;
if (false and m_song.cover) {
cover_texture = *resources.covers.get(m_song.cover.value());
}
cover.setTexture(cover_texture);
auto bounds = cover.getGlobalBounds();
cover.setPosition(area.left, area.top);
cover.setScale(area.width / bounds.width, area.width / bounds.width);
target.draw(cover);
}
void MusicSelect::set_to_global_bounds(sf::RectangleShape& rect, const sf::Text& text) {

View File

@ -17,21 +17,21 @@ namespace MusicSelect {
// 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(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) = 0;
virtual void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) = 0;
virtual ~Panel() = default;
};
class EmptyPanel final : public Panel {
public:
void click(Ribbon& ribbon, std::size_t from_button_index) override {return;};
void draw(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override {return;};
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override {return;};
};
class ColorPanel final : public Panel {
public:
explicit ColorPanel(const sf::Color& t_color) : color(t_color) {};
void click(Ribbon& ribbon, std::size_t from_button_index) override {return;};
void draw(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
private:
const sf::Color color;
};
@ -40,7 +40,7 @@ namespace MusicSelect {
public:
explicit CategoryPanel(const std::string& t_label) : label(t_label) {};
void click(Ribbon& ribbon, std::size_t from_button_index) override;
void draw(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
private:
std::string label;
@ -48,11 +48,11 @@ namespace MusicSelect {
class SongPanel final : public Panel {
public:
explicit SongPanel(const Data::Song& t_song) : song(t_song) {};
explicit SongPanel(const Data::Song& t_song) : m_song(t_song) {};
void click(Ribbon& ribbon, std::size_t from_button_index) override;
void draw(const Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
private:
const Data::Song& song;
const Data::Song& m_song;
};
void set_to_global_bounds(sf::RectangleShape& rect, const sf::Text& text);

View File

@ -1,8 +1,16 @@
#include "Resources.hpp"
#include <iostream>
MusicSelect::Resources::Resources() {
MusicSelect::Resources::Resources() :
covers(),
fallback_cover(),
noto_sans_medium()
{
if (not noto_sans_medium.loadFromFile("assets/fonts/NotoSans-Medium.ttf")) {
throw std::runtime_error("Unable to load assets/fonts/NotoSans-Medium.ttf");
}
}
if (not fallback_cover.loadFromFile("assets/textures/fallback_cover.png")) {
throw std::runtime_error("Unable to load assets/textures/fallback_cover.png");
}
}

View File

@ -2,12 +2,13 @@
#include <SFML/Graphics.hpp>
#include "../../Resources/CoverAtlas.hpp"
#include "../../Resources/Autoloader.hpp"
namespace MusicSelect {
struct Resources {
Resources();
Textures::CoverAltas cover_previews;
Textures::Autoloader covers;
sf::Texture fallback_cover;
sf::Font noto_sans_medium;
};
}

View File

@ -10,6 +10,7 @@
#include <vector>
#include "Panel.hpp"
#include "../../Data/SongList.hpp"
#include "../../Toolkit/QuickRNG.hpp"
MusicSelect::MoveAnimation::MoveAnimation(int previous_pos, int next_pos, size_t ribbon_size, Direction direction, float &t_time_factor) :
@ -131,6 +132,23 @@ void MusicSelect::Ribbon::test2_sort() {
layout_from_category_map(categories);
}
void MusicSelect::Ribbon::test_song_cover_sort() {
std::string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
std::map<std::string, std::vector<std::shared_ptr<Panel>>> categories;
Toolkit::UniformIntRNG category_size_generator{1, 10};
for (auto &&letter : alphabet) {
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<MusicSelect::SongPanel>(
Data::Song{}
)
);
}
}
layout_from_category_map(categories);
}
std::size_t MusicSelect::Ribbon::get_layout_column(const std::size_t& button_index) const {
return (m_position + (button_index % 4)) % m_layout.size();

View File

@ -32,10 +32,11 @@ namespace MusicSelect {
// It can be sorted in a number of ways
class Ribbon final : public sf::Drawable, public Toolkit::Debuggable {
public:
Ribbon(const Resources& t_resources) : m_resources(t_resources) {};
Ribbon(Resources& t_resources) : m_resources(t_resources) {};
void title_sort(const Data::SongList& song_list);
void test_sort();
void test2_sort();
void test_song_cover_sort();
const std::shared_ptr<MusicSelect::Panel>& get_panel_under_button(std::size_t button_index) const;
void click_on(std::size_t button_index);
void move_right();
@ -51,7 +52,7 @@ namespace MusicSelect {
std::vector<std::array<std::shared_ptr<Panel>,3>> m_layout;
std::size_t m_position = 0;
mutable std::optional<MoveAnimation> m_move_animation;
const Resources& m_resources;
Resources& m_resources;
float m_time_factor = 1.f;
};
}