Show song cover on HUD
This commit is contained in:
parent
3dd50d463b
commit
c61b470f55
@ -41,8 +41,10 @@ sources = [
|
||||
'src/Screens/MusicSelect/MusicSelect.cpp',
|
||||
'src/Screens/MusicSelect/Panel.hpp',
|
||||
'src/Screens/MusicSelect/Panel.cpp',
|
||||
'src/Screens/MusicSelect/Resources.hpp',
|
||||
'src/Screens/MusicSelect/Resources.cpp',
|
||||
'src/Screens/MusicSelect/SharedResources.hpp',
|
||||
'src/Screens/MusicSelect/SharedResources.cpp',
|
||||
'src/Screens/MusicSelect/SongInfo.hpp',
|
||||
'src/Screens/MusicSelect/SongInfo.cpp',
|
||||
'src/Screens/MusicSelect/Ribbon.hpp',
|
||||
'src/Screens/MusicSelect/Ribbon.cpp',
|
||||
# 'src/Screens/Result.hpp',
|
||||
|
@ -8,7 +8,8 @@
|
||||
#include <SFML/System.hpp>
|
||||
|
||||
namespace Data {
|
||||
// By convention all axis-independant lengths are expressed as a ratio of the screen WIDTH (see panel_size and spacing)
|
||||
// By convention all axis-independant lengths are expressed as a ratio of the screen WIDTH
|
||||
// see panel_size and panel_spacing for example
|
||||
struct Screen {
|
||||
std::size_t width = 768;
|
||||
std::size_t height = 1360;
|
||||
@ -47,35 +48,43 @@ namespace Data {
|
||||
Layout layout;
|
||||
|
||||
Preferences() : screen(), layout() {
|
||||
load();
|
||||
}
|
||||
|
||||
~Preferences() {
|
||||
save();
|
||||
}
|
||||
|
||||
void load() {
|
||||
auto path = std::filesystem::path("data/preferences.json");
|
||||
if (std::filesystem::exists(path)) {
|
||||
std::ifstream prefs_file;
|
||||
prefs_file.open(path);
|
||||
try {
|
||||
cereal::JSONInputArchive archive{prefs_file};
|
||||
this->serialize(archive);
|
||||
serialize(archive);
|
||||
} catch(const std::exception& e) {
|
||||
std::cerr << "Error while loading data/preferences.json : " << e.what() << std::endl;
|
||||
std::cerr << "Using fallback preferences instead" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~Preferences() {
|
||||
};
|
||||
|
||||
void save() {
|
||||
auto data_folder = std::filesystem::path("data");
|
||||
if (not std::filesystem::exists(data_folder)) {
|
||||
std::filesystem::create_directory(data_folder);
|
||||
}
|
||||
if (not std::filesystem::is_directory(data_folder)) {
|
||||
std::cerr << "Could not save preferences : can't create data folder, a file named 'data' exists" << std::endl;
|
||||
std::cerr << "Can't create data folder to save preferences, a file named 'data' exists" << std::endl;
|
||||
}
|
||||
std::ofstream preferences_file;
|
||||
preferences_file.open(data_folder / "preferences.json", std::ofstream::trunc | std::ofstream::out);
|
||||
{
|
||||
cereal::JSONOutputArchive archive{preferences_file};
|
||||
serialize(archive);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<class Archive>
|
||||
void serialize(Archive & archive) {
|
||||
|
@ -11,6 +11,22 @@ namespace fs = std::filesystem;
|
||||
|
||||
namespace Data {
|
||||
|
||||
bool cmp_dif_name::operator()(const std::string &a, const std::string &b) const {
|
||||
if (dif_names.find(a) != dif_names.end()) {
|
||||
if (dif_names.find(b) != dif_names.end()) {
|
||||
return dif_names.find(a)->second < dif_names.find(b)->second;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (dif_names.find(b) != dif_names.end()) {
|
||||
return false;
|
||||
} else {
|
||||
return a < b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<fs::path> Song::full_cover_path() const {
|
||||
if (cover) {
|
||||
return folder/cover.value();
|
||||
|
@ -3,15 +3,23 @@
|
||||
#include <filesystem>
|
||||
#include <iterator>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace Data {
|
||||
|
||||
/*
|
||||
* Difficulty name ordering : BSC > ADV > EXT > anything else in lexicographical order
|
||||
*/
|
||||
struct cmp_dif_name {
|
||||
std::map<std::string,int> dif_names = {{"BSC",1},{"ADV",2},{"EXT",3}};
|
||||
bool operator()(const std::string& a, const std::string& b) const;
|
||||
};
|
||||
|
||||
// Basic metadata about a song
|
||||
struct Song {
|
||||
Song() = default;
|
||||
@ -26,7 +34,7 @@ namespace Data {
|
||||
// Mapping from chart difficulty (BSC, ADV, EXT ...) to the numeric level,
|
||||
// the level is stored multiplied by 10 and displayed divided by 10
|
||||
// to allow for decimal levels (introduced in jubeat ... festo ?)
|
||||
std::unordered_map<std::string, unsigned int> chart_levels;
|
||||
std::map<std::string, unsigned int, cmp_dif_name> chart_levels;
|
||||
|
||||
std::optional<fs::path> full_cover_path() const;
|
||||
|
||||
|
@ -28,9 +28,9 @@ namespace Textures {
|
||||
|
||||
// Hold time elapsed since loaded
|
||||
struct AutoloadedTexture {
|
||||
AutoloadedTexture(std::shared_ptr<sf::Texture> t_texture) : texture(t_texture), clock() {};
|
||||
AutoloadedTexture(std::shared_ptr<sf::Texture> t_texture) : texture(t_texture), loaded_since() {};
|
||||
std::shared_ptr<sf::Texture> texture;
|
||||
sf::Clock clock;
|
||||
sf::Clock loaded_since;
|
||||
};
|
||||
|
||||
// Loads textures asynchronously (in the background) on demand and stores them in a map for easy path-based access
|
||||
|
@ -11,6 +11,7 @@ MusicSelect::Screen::Screen(const Data::SongList& t_song_list) :
|
||||
song_list(t_song_list),
|
||||
resources(),
|
||||
ribbon(resources, m_panel_size, m_panel_spacing),
|
||||
song_info(resources, m_upper_part_width, m_upper_part_height),
|
||||
selected_panel(),
|
||||
button_highlight(m_panel_size, m_panel_spacing),
|
||||
key_mapping()
|
||||
@ -47,17 +48,20 @@ void MusicSelect::Screen::select_chart(sf::RenderWindow& window) {
|
||||
break;
|
||||
case sf::Event::MouseButtonPressed:
|
||||
handle_mouse_click(event.mouseButton);
|
||||
break;
|
||||
case sf::Event::Closed:
|
||||
window.close();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
ImGui::SFML::Update(window, imguiClock.restart());
|
||||
window.clear(sf::Color(252, 201, 0, 255));
|
||||
window.clear(sf::Color::Black);
|
||||
ribbon.draw_debug();
|
||||
window.draw(ribbon);
|
||||
window.draw(button_highlight);
|
||||
window.draw(song_info);
|
||||
ImGui::SFML::Render(window);
|
||||
window.display();
|
||||
}
|
||||
|
@ -9,7 +9,8 @@
|
||||
#include "../../Data/KeyMapping.hpp"
|
||||
#include "../../Toolkit/AffineTransform.hpp"
|
||||
#include "Ribbon.hpp"
|
||||
#include "Resources.hpp"
|
||||
#include "SongInfo.hpp"
|
||||
#include "SharedResources.hpp"
|
||||
#include "ButtonHighlight.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
@ -23,15 +24,18 @@ namespace MusicSelect {
|
||||
|
||||
private:
|
||||
// Data
|
||||
const Data::SongList& song_list;
|
||||
const Data::SongList song_list;
|
||||
float m_panel_size = 160.0f;
|
||||
float m_panel_spacing = 112.0f / 3.0f;
|
||||
float m_upper_part_width = 768.0f;
|
||||
float m_upper_part_height = 464.0f;
|
||||
|
||||
// Resources
|
||||
Resources resources;
|
||||
SharedResources resources;
|
||||
|
||||
// State
|
||||
Ribbon ribbon;
|
||||
SongInfo song_info;
|
||||
std::optional<std::reference_wrapper<SongPanel>> selected_panel;
|
||||
ButtonHighlight button_highlight;
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
#include "Panel.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include "MusicSelect.hpp"
|
||||
#include "SharedResources.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
void ColorPanel::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||
@ -64,7 +67,41 @@ namespace MusicSelect {
|
||||
}
|
||||
|
||||
void SongPanel::click(Ribbon& ribbon, std::size_t from_button_index) {
|
||||
|
||||
if (selected_chart.has_value()) {
|
||||
// The song was already selected : look for the next chart in order
|
||||
auto it = m_song.chart_levels.upper_bound(*selected_chart);
|
||||
if (it != m_song.chart_levels.cend()) {
|
||||
selected_chart = it->first;
|
||||
} else {
|
||||
selected_chart = m_song.chart_levels.cbegin()->first;
|
||||
}
|
||||
} else {
|
||||
// The song was not selected before : unselect the last one
|
||||
if (m_resources.selected_panel.has_value()) {
|
||||
m_resources.selected_panel->panel.unselect();
|
||||
}
|
||||
// Look for the first chart with dif greater or equal to the last select one
|
||||
// or else select the first chart
|
||||
auto it = m_song.chart_levels.lower_bound(ribbon.m_global_chart_dif);
|
||||
if (it != m_song.chart_levels.cend()) {
|
||||
selected_chart = it->first;
|
||||
} else {
|
||||
selected_chart = m_song.chart_levels.cbegin()->first;
|
||||
}
|
||||
}
|
||||
m_resources.selected_panel.emplace(TimedSelectedPanel{*this});
|
||||
}
|
||||
|
||||
void SongPanel::unselect() {
|
||||
selected_chart.reset();
|
||||
}
|
||||
|
||||
std::optional<ChartSelection> SongPanel::get_selected_chart() const {
|
||||
if (selected_chart) {
|
||||
return ChartSelection{m_song, *selected_chart};
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
void SongPanel::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||
@ -75,7 +112,7 @@ namespace MusicSelect {
|
||||
sf::Sprite cover{*(loaded_texture->texture)};
|
||||
auto alpha = static_cast<std::uint8_t>(
|
||||
m_seconds_to_alpha.clampedTransform(
|
||||
loaded_texture->clock.getElapsedTime().asSeconds()
|
||||
loaded_texture->loaded_since.getElapsedTime().asSeconds()
|
||||
)
|
||||
);
|
||||
cover.setColor(sf::Color(255, 255, 255, alpha));
|
||||
@ -89,7 +126,7 @@ namespace MusicSelect {
|
||||
song_title.setFont(m_resources.noto_sans_medium);
|
||||
song_title.setString(m_song.title);
|
||||
song_title.setCharacterSize(static_cast<unsigned int>(0.06875f*m_size));
|
||||
song_title.setFillColor(sf::Color::Black);
|
||||
song_title.setFillColor(sf::Color::White);
|
||||
auto song_title_bounds = song_title.getLocalBounds();
|
||||
// text is too long : scale it
|
||||
if (song_title_bounds.width > 0.88f * m_size) {
|
||||
@ -97,7 +134,6 @@ namespace MusicSelect {
|
||||
}
|
||||
song_title.setPosition(18.f/160.f,9.f/160.f);
|
||||
target.draw(song_title, states);
|
||||
|
||||
}
|
||||
|
||||
void set_to_global_bounds(sf::RectangleShape& rect, const sf::Text& text) {
|
||||
@ -130,4 +166,4 @@ namespace MusicSelect {
|
||||
message.setPosition(m_size*0.5f, m_size*0.5f);
|
||||
target.draw(message, states);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Window.hpp>
|
||||
|
||||
#include "../../Data/SongList.hpp"
|
||||
#include "../../Toolkit/AffineTransform.hpp"
|
||||
#include "Resources.hpp"
|
||||
#include "SharedResources.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
|
||||
class Ribbon;
|
||||
class SharedResources;
|
||||
|
||||
// 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 : public sf::Drawable, public sf::Transformable {
|
||||
public:
|
||||
Panel(const float& size, Resources& resources) : m_size(size), m_resources(resources) {};
|
||||
Panel(const float& size, SharedResources& 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;
|
||||
virtual ~Panel() = default;
|
||||
protected:
|
||||
const float& m_size;
|
||||
Resources& m_resources;
|
||||
SharedResources& m_resources;
|
||||
};
|
||||
|
||||
class EmptyPanel final : public Panel {
|
||||
@ -34,7 +38,7 @@ namespace MusicSelect {
|
||||
|
||||
class ColoredMessagePanel final : public Panel {
|
||||
public:
|
||||
ColoredMessagePanel(const float& size, Resources& resources, const sf::Color& color, const std::string& message) : Panel(size, resources), m_color(color), m_message(message) {};
|
||||
ColoredMessagePanel(const float& size, SharedResources& resources, const sf::Color& color, const std::string& message) : Panel(size, resources), m_color(color), m_message(message) {};
|
||||
void click(Ribbon& ribbon, std::size_t from_button_index) override {return;};
|
||||
private:
|
||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
@ -44,7 +48,7 @@ namespace MusicSelect {
|
||||
|
||||
class ColorPanel final : public Panel {
|
||||
public:
|
||||
ColorPanel(const float& size, Resources& resources, const sf::Color& t_color) : Panel(size, resources), m_color(t_color) {};
|
||||
ColorPanel(const float& size, SharedResources& 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;};
|
||||
private:
|
||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
@ -53,22 +57,37 @@ namespace MusicSelect {
|
||||
|
||||
class CategoryPanel final : public Panel {
|
||||
public:
|
||||
explicit CategoryPanel(const float& size, Resources& resources, const std::string& t_label) : Panel(size, resources), m_label(t_label) {};
|
||||
explicit CategoryPanel(const float& size, SharedResources& resources, const std::string& t_label) : Panel(size, resources), m_label(t_label) {};
|
||||
void click(Ribbon& ribbon, std::size_t from_button_index) override;
|
||||
private:
|
||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
std::string m_label;
|
||||
};
|
||||
|
||||
class SongPanel final : public Panel {
|
||||
struct ChartSelection {
|
||||
const Data::Song& song;
|
||||
const std::string& chart;
|
||||
};
|
||||
|
||||
class SelectablePanel : public Panel {
|
||||
public:
|
||||
explicit SongPanel(const float& size, Resources& resources, const Data::Song& t_song) : Panel(size, resources), m_song(t_song) {};
|
||||
using Panel::Panel;
|
||||
virtual ~SelectablePanel() = default;
|
||||
virtual void unselect() = 0;
|
||||
virtual std::optional<ChartSelection> get_selected_chart() const = 0;
|
||||
};
|
||||
|
||||
class SongPanel final : public SelectablePanel {
|
||||
public:
|
||||
explicit SongPanel(const float& size, SharedResources& resources, const Data::Song& t_song) : SelectablePanel(size, resources), m_song(t_song) {};
|
||||
void click(Ribbon& ribbon, std::size_t from_button_index) override;
|
||||
void unselect() override;
|
||||
std::optional<ChartSelection> get_selected_chart() const override;
|
||||
private:
|
||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
const Data::Song& m_song;
|
||||
const Toolkit::AffineTransform<float> m_seconds_to_alpha{0.0f, 0.15f, 0.f, 255.f};
|
||||
std::optional<std::reference_wrapper<std::string>> selected_chart;
|
||||
std::optional<std::string> selected_chart;
|
||||
};
|
||||
|
||||
void set_to_global_bounds(sf::RectangleShape& rect, const sf::Text& text);
|
||||
|
@ -1,14 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
#include "../../Resources/Autoloader.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
struct Resources {
|
||||
Resources();
|
||||
Textures::Autoloader covers;
|
||||
sf::Texture fallback_cover;
|
||||
sf::Font noto_sans_medium;
|
||||
};
|
||||
}
|
@ -64,7 +64,7 @@ namespace MusicSelect {
|
||||
return clock.getElapsedTime() / m_time_factor > sf::milliseconds(300);
|
||||
}
|
||||
|
||||
Ribbon::Ribbon(Resources& t_resources, float& panel_size, float& panel_spacing) :
|
||||
Ribbon::Ribbon(SharedResources& t_resources, float& panel_size, float& panel_spacing) :
|
||||
m_layout(),
|
||||
m_move_animation(),
|
||||
m_resources(t_resources),
|
||||
|
@ -3,11 +3,12 @@
|
||||
#include <SFML/Graphics/Drawable.hpp>
|
||||
#include <SFML/Graphics/Transformable.hpp>
|
||||
|
||||
#include "Panel.hpp"
|
||||
#include "../../Data/SongList.hpp"
|
||||
#include "../../Toolkit/AffineTransform.hpp"
|
||||
#include "../../Toolkit/Debuggable.hpp"
|
||||
#include "../../Toolkit/EasingFunctions.hpp"
|
||||
#include "Panel.hpp"
|
||||
#include "SharedResources.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
|
||||
@ -33,7 +34,7 @@ namespace MusicSelect {
|
||||
// It can be sorted in a number of ways
|
||||
class Ribbon final : public sf::Drawable, public sf::Transformable, public Toolkit::Debuggable {
|
||||
public:
|
||||
Ribbon(Resources& t_resources, float& panel_size, float& panel_spacing);
|
||||
Ribbon(SharedResources& t_resources, float& panel_size, float& panel_spacing);
|
||||
void title_sort(const Data::SongList& song_list);
|
||||
void test_sort();
|
||||
void test2_sort();
|
||||
@ -44,6 +45,7 @@ namespace MusicSelect {
|
||||
void move_left();
|
||||
void move_to_next_category(const std::size_t& from_button_index);
|
||||
void draw_debug() override;
|
||||
std::string m_global_chart_dif;
|
||||
private:
|
||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
void draw_with_animation(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||
@ -54,7 +56,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;
|
||||
Resources& m_resources;
|
||||
SharedResources& m_resources;
|
||||
float m_time_factor = 1.f;
|
||||
Data::Song empty_song;
|
||||
float& m_panel_size;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "Resources.hpp"
|
||||
#include "SharedResources.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
MusicSelect::Resources::Resources() :
|
||||
MusicSelect::SharedResources::SharedResources() :
|
||||
covers(),
|
||||
fallback_cover(),
|
||||
noto_sans_medium()
|
31
src/Screens/MusicSelect/SharedResources.hpp
Normal file
31
src/Screens/MusicSelect/SharedResources.hpp
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/System.hpp>
|
||||
|
||||
#include "../../Resources/Autoloader.hpp"
|
||||
#include "../../Data/SongList.hpp"
|
||||
|
||||
#include "Panel.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
|
||||
class SelectablePanel;
|
||||
|
||||
struct TimedSelectedPanel {
|
||||
TimedSelectedPanel(SelectablePanel& s) : panel(s), selected_since() {};
|
||||
SelectablePanel& panel;
|
||||
sf::Clock selected_since;
|
||||
};
|
||||
|
||||
struct SharedResources {
|
||||
SharedResources();
|
||||
Textures::Autoloader covers;
|
||||
sf::Texture fallback_cover;
|
||||
sf::Font noto_sans_medium;
|
||||
std::optional<TimedSelectedPanel> selected_panel;
|
||||
};
|
||||
}
|
54
src/Screens/MusicSelect/SongInfo.cpp
Normal file
54
src/Screens/MusicSelect/SongInfo.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include "SongInfo.hpp"
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
|
||||
namespace MusicSelect {
|
||||
|
||||
SongInfo::SongInfo(SharedResources& resources, const float& width, const float& height) :
|
||||
m_resources(resources),
|
||||
m_width(width),
|
||||
m_height(height),
|
||||
m_cover_fallback({height*0.8f, height*0.8f})
|
||||
{
|
||||
m_cover_fallback.setFillColor(sf::Color::Black);
|
||||
m_cover_fallback.setOutlineThickness(1.f);
|
||||
m_cover_fallback.setOutlineColor(sf::Color::White);
|
||||
m_cover_fallback.setPosition(height*0.1f, height*0.1f);
|
||||
}
|
||||
|
||||
void SongInfo::draw(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||
draw_cover(target, states);
|
||||
}
|
||||
}
|
||||
|
||||
void MusicSelect::SongInfo::draw_cover(sf::RenderTarget& target, sf::RenderStates states) const {
|
||||
states.transform *= getTransform();
|
||||
target.draw(m_cover_fallback, states);
|
||||
auto selected_panel = m_resources.selected_panel;
|
||||
if (not selected_panel.has_value()) {
|
||||
return;
|
||||
}
|
||||
auto selected_chart = selected_panel->panel.get_selected_chart();
|
||||
if (not selected_chart.has_value()) {
|
||||
return;
|
||||
}
|
||||
auto cover_path = selected_chart->song.full_cover_path();
|
||||
if (not cover_path.has_value()) {
|
||||
return;
|
||||
}
|
||||
auto cover_texture = m_resources.covers.async_get(*cover_path);
|
||||
if (not cover_texture.has_value()) {
|
||||
return;
|
||||
}
|
||||
sf::Sprite cover{*(cover_texture->texture)};
|
||||
auto bounds = cover.getGlobalBounds();
|
||||
cover.setScale(m_height*0.8f/bounds.width, m_height*0.8f/bounds.height);
|
||||
cover.setPosition(m_height*0.1f, m_height*0.1f);
|
||||
auto alpha = static_cast<std::uint8_t>(
|
||||
m_seconds_to_alpha.clampedTransform(
|
||||
selected_panel->selected_since.getElapsedTime().asSeconds()
|
||||
)
|
||||
);
|
||||
cover.setColor(sf::Color(255, 255, 255, alpha));
|
||||
target.draw(cover, states);
|
||||
}
|
24
src/Screens/MusicSelect/SongInfo.hpp
Normal file
24
src/Screens/MusicSelect/SongInfo.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/System.hpp>
|
||||
|
||||
#include "../../Toolkit/AffineTransform.hpp"
|
||||
|
||||
#include "SharedResources.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
// SongInfo displays the song info on the top part of the screen
|
||||
class SongInfo : public sf::Drawable, public sf::Transformable {
|
||||
public:
|
||||
SongInfo(SharedResources& resources, const float& width, const float& height);
|
||||
private:
|
||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
void draw_cover(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||
SharedResources& m_resources;
|
||||
const float& m_width;
|
||||
const float& m_height;
|
||||
sf::RectangleShape m_cover_fallback;
|
||||
const Toolkit::AffineTransform<float> m_seconds_to_alpha{0.0f, 0.3f, 0.f, 255.f};
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user