Fallback cover loading
This commit is contained in:
parent
30285d94c5
commit
c532cc8a2d
@ -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',
|
||||
|
@ -8,8 +8,6 @@
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "../Resources/CoverAtlas.hpp"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace Data {
|
||||
|
19
src/Resources/Autoloader.cpp
Normal file
19
src/Resources/Autoloader.cpp
Normal 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);
|
||||
}
|
33
src/Resources/Autoloader.hpp
Normal file
33
src/Resources/Autoloader.hpp
Normal 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;
|
||||
};
|
||||
}
|
@ -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) {
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user