IT BUILDS
This commit is contained in:
parent
97d5f1493a
commit
73a02bf924
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#ifndef MEMON_HPP_
|
||||||
|
#define MEMON_HPP_
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -168,6 +169,7 @@ namespace stepland {
|
|||||||
} else {
|
} else {
|
||||||
m.load_from_memon_fallback(j);
|
m.load_from_memon_fallback(j);
|
||||||
}
|
}
|
||||||
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -176,9 +178,9 @@ namespace stepland {
|
|||||||
* this way the difficulty names are guaranteed to be unique
|
* this way the difficulty names are guaranteed to be unique
|
||||||
* - "jacket path" is now "album cover path" because engrish much ?
|
* - "jacket path" is now "album cover path" because engrish much ?
|
||||||
*/
|
*/
|
||||||
void load_from_memon_v0_1_0(nlohmann::json memon) {
|
void load_from_memon_v0_1_0(nlohmann::json memon_json) {
|
||||||
|
|
||||||
auto metadata = memon.at("metadata");
|
auto metadata = memon_json.at("metadata");
|
||||||
if (not metadata.is_object()) {
|
if (not metadata.is_object()) {
|
||||||
throw std::invalid_argument("metadata fields is not an object");
|
throw std::invalid_argument("metadata fields is not an object");
|
||||||
}
|
}
|
||||||
@ -190,11 +192,11 @@ namespace stepland {
|
|||||||
this->BPM = metadata.value("BPM",120.0f);
|
this->BPM = metadata.value("BPM",120.0f);
|
||||||
this->offset = metadata.value("offset",0.0f);
|
this->offset = metadata.value("offset",0.0f);
|
||||||
|
|
||||||
if (not memon.at("data").is_object()) {
|
if (not memon_json.at("data").is_object()) {
|
||||||
throw std::invalid_argument("data field is not an object");
|
throw std::invalid_argument("data field is not an object");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& [dif_name, chart_json] : memon.at("data").items()) {
|
for (auto& [dif_name, chart_json] : memon_json.at("data").items()) {
|
||||||
|
|
||||||
chart new_chart;
|
chart new_chart;
|
||||||
new_chart.level = chart_json.value("level", 0);
|
new_chart.level = chart_json.value("level", 0);
|
||||||
@ -234,9 +236,9 @@ namespace stepland {
|
|||||||
* - "data" is an array of charts, each with a difficulty name
|
* - "data" is an array of charts, each with a difficulty name
|
||||||
* - the album cover path field is named "jacket path"
|
* - the album cover path field is named "jacket path"
|
||||||
*/
|
*/
|
||||||
void load_from_memon_fallback(nlohmann::json memon) {
|
void load_from_memon_fallback(nlohmann::json memon_json) {
|
||||||
|
|
||||||
auto metadata = memon.at("metadata");
|
auto metadata = memon_json.at("metadata");
|
||||||
if (not metadata.is_object()) {
|
if (not metadata.is_object()) {
|
||||||
throw std::invalid_argument("metadata fields is not an object");
|
throw std::invalid_argument("metadata fields is not an object");
|
||||||
}
|
}
|
||||||
@ -248,11 +250,11 @@ namespace stepland {
|
|||||||
this->BPM = metadata.value("BPM",120.f);
|
this->BPM = metadata.value("BPM",120.f);
|
||||||
this->offset = metadata.value("offset",0.f);
|
this->offset = metadata.value("offset",0.f);
|
||||||
|
|
||||||
if (not memon.at("data").is_array()) {
|
if (not memon_json.at("data").is_array()) {
|
||||||
throw std::invalid_argument("data field is not an array");
|
throw std::invalid_argument("data field is not an array");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& chart_json : memon.at("data")) {
|
for (auto& chart_json : memon_json.at("data")) {
|
||||||
chart new_chart;
|
chart new_chart;
|
||||||
new_chart.level = chart_json.value("level", 0);
|
new_chart.level = chart_json.value("level", 0);
|
||||||
new_chart.resolution = chart_json.at("resolution").get<int>();
|
new_chart.resolution = chart_json.at("resolution").get<int>();
|
||||||
@ -289,4 +291,6 @@ namespace stepland {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* MEMON_HPP_ */
|
||||||
|
@ -41,5 +41,12 @@ executable(
|
|||||||
'jujube',
|
'jujube',
|
||||||
sources,
|
sources,
|
||||||
dependencies: [sfml, filesystem],
|
dependencies: [sfml, filesystem],
|
||||||
include_directories : include_directories('include')
|
include_directories : include_directories('include'),
|
||||||
|
cpp_args : [
|
||||||
|
'-Wall',
|
||||||
|
'-Wextra',
|
||||||
|
'-Wshadow',
|
||||||
|
'-Wnon-virtual-dtor',
|
||||||
|
'-pedantic'
|
||||||
|
]
|
||||||
)
|
)
|
@ -1,73 +1,83 @@
|
|||||||
#include "Note.hpp"
|
#include "Note.hpp"
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
|
||||||
|
Note::Note(
|
||||||
|
unsigned int t_position,
|
||||||
|
sf::Time t_timing,
|
||||||
|
sf::Time t_length,
|
||||||
|
unsigned int t_tail_position
|
||||||
|
) :
|
||||||
|
position(t_position),
|
||||||
|
timing(t_timing),
|
||||||
|
length(t_length),
|
||||||
|
tail_position(t_tail_position)
|
||||||
|
{
|
||||||
|
if (t_position > 15) {
|
||||||
|
throw std::out_of_range(
|
||||||
|
"Tried creating a note with invalid position : "
|
||||||
|
+std::to_string(t_position)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Data::Note::Note(
|
if (t_length.asMicroseconds() < 0) {
|
||||||
unsigned int t_position,
|
throw std::out_of_range(
|
||||||
sf::Time t_timing,
|
"Tried creating a long note with negative length : "
|
||||||
sf::Time t_length,
|
+std::to_string(t_length.asSeconds())+"s"
|
||||||
unsigned int t_tail_position
|
);
|
||||||
) :
|
}
|
||||||
position(t_position),
|
if (t_length.asMicroseconds() > 0) {
|
||||||
timing(t_timing),
|
if (t_tail_position > 5) {
|
||||||
length(t_length),
|
throw std::out_of_range(
|
||||||
tail_position(t_tail_position)
|
"Tried creating a long note with invalid tail position : "
|
||||||
{
|
+std::to_string(t_tail_position)
|
||||||
if (t_position > 15) {
|
);
|
||||||
throw std::out_of_range("Tried creating a note with invalid position : "+std::to_string(t_position));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (t_length.asMicroseconds() < 0) {
|
|
||||||
throw std::out_of_range("Tried creating a long note with negative length : "+std::to_string(t_length.asSeconds)+ "s");
|
|
||||||
|
|
||||||
}
|
|
||||||
if (t_length.asMicroseconds() > 0) {
|
|
||||||
if (t_tail_position > 5) {
|
|
||||||
throw std::out_of_range("Tried creating a long note with invalid tail position : "+std::to_string(t_tail_position));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
bool Data::Note::operator==(const Data::Note &rhs) const {
|
bool Note::operator==(const Note &rhs) const {
|
||||||
return timing == rhs.timing && position == rhs.position;
|
return timing == rhs.timing && position == rhs.position;
|
||||||
}
|
|
||||||
|
|
||||||
bool Data::Note::operator!=(const Data::Note &rhs) const {
|
|
||||||
return !(rhs == *this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Data::Note::operator<(const Data::Note &rhs) const {
|
|
||||||
if (timing < rhs.timing) {
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
if (rhs.timing < timing) {
|
|
||||||
return false;
|
bool Note::operator!=(const Note &rhs) const {
|
||||||
|
return !(rhs == *this);
|
||||||
}
|
}
|
||||||
return position < rhs.position;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Data::Note::operator>(const Data::Note &rhs) const {
|
bool Note::operator<(const Note &rhs) const {
|
||||||
return rhs < *this;
|
if (timing < rhs.timing) {
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
if (rhs.timing < timing) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return position < rhs.position;
|
||||||
|
}
|
||||||
|
|
||||||
bool Data::Note::operator<=(const Data::Note &rhs) const {
|
bool Note::operator>(const Note &rhs) const {
|
||||||
return !(rhs < *this);
|
return rhs < *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Data::Note::operator>=(const Data::Note &rhs) const {
|
bool Note::operator<=(const Note &rhs) const {
|
||||||
return !(*this < rhs);
|
return !(rhs < *this);
|
||||||
}
|
}
|
||||||
const unsigned int Data::Note::getPosition() const {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sf::Time& Data::Note::getTiming() const {
|
bool Note::operator>=(const Note &rhs) const {
|
||||||
return timing;
|
return !(*this < rhs);
|
||||||
}
|
}
|
||||||
|
unsigned int Note::getPosition() const {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
const sf::Time& Data::Note::getLength() const {
|
const sf::Time& Note::getTiming() const {
|
||||||
return length;
|
return timing;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned int Data::Note::getTailPosition() const {
|
const sf::Time& Note::getLength() const {
|
||||||
return tail_position;
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Note::getTailPosition() const {
|
||||||
|
return tail_position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,10 @@ namespace Data {
|
|||||||
bool operator<=(const Note &rhs) const;
|
bool operator<=(const Note &rhs) const;
|
||||||
bool operator>=(const Note &rhs) const;
|
bool operator>=(const Note &rhs) const;
|
||||||
|
|
||||||
const unsigned int getPosition() const;
|
unsigned int getPosition() const;
|
||||||
const sf::Time& getTiming() const;
|
const sf::Time& getTiming() const;
|
||||||
const sf::Time& getLength() const;
|
const sf::Time& getLength() const;
|
||||||
const unsigned int getTailPosition() const;
|
unsigned int getTailPosition() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -27,4 +27,4 @@ namespace Data {
|
|||||||
const unsigned int tail_position = 0;
|
const unsigned int tail_position = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
};
|
}
|
@ -49,7 +49,7 @@ namespace Data {
|
|||||||
fs::begin(folder),
|
fs::begin(folder),
|
||||||
fs::end(folder),
|
fs::end(folder),
|
||||||
[](const fs::directory_entry& de) {
|
[](const fs::directory_entry& de) {
|
||||||
de.path().extension() == ".memo" or
|
return de.path().extension() == ".memo" or
|
||||||
de.path().extension() == ".memon";
|
de.path().extension() == ".memon";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -93,14 +93,14 @@ namespace Data {
|
|||||||
// .memo ?
|
// .memo ?
|
||||||
auto memo_files = getMemoFiles(song_folder);
|
auto memo_files = getMemoFiles(song_folder);
|
||||||
if (not memo_files.empty()) {
|
if (not memo_files.empty()) {
|
||||||
throw std::exception("jujube does not support .memo files for now ...");
|
throw std::invalid_argument("jujube does not support .memo files for now ...");
|
||||||
} else {
|
} else {
|
||||||
throw std::invalid_argument("No valid file found in song folder");
|
throw std::invalid_argument("No valid file found in song folder");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<fs::path>& getMemoFiles(fs::path song_folder) {
|
const std::vector<fs::path> getMemoFiles(fs::path song_folder) {
|
||||||
std::vector<fs::path> res;
|
std::vector<fs::path> res;
|
||||||
for (const auto& p : fs::directory_iterator(song_folder)) {
|
for (const auto& p : fs::directory_iterator(song_folder)) {
|
||||||
if (p.path().extension() == ".memo") {
|
if (p.path().extension() == ".memo") {
|
||||||
@ -110,7 +110,7 @@ namespace Data {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<fs::path>& getMemonFiles(fs::path song_folder) {
|
const std::vector<fs::path> getMemonFiles(fs::path song_folder) {
|
||||||
std::vector<fs::path> res;
|
std::vector<fs::path> res;
|
||||||
for (const auto& p : fs::directory_iterator(song_folder)) {
|
for (const auto& p : fs::directory_iterator(song_folder)) {
|
||||||
if (p.path().extension() == ".memon") {
|
if (p.path().extension() == ".memon") {
|
||||||
|
@ -46,6 +46,6 @@ namespace Data {
|
|||||||
// .memon files also accepted
|
// .memon files also accepted
|
||||||
const std::vector<fs::path> getSongFolders();
|
const std::vector<fs::path> getSongFolders();
|
||||||
std::list<fs::path> recursiveSongSearch(fs::path song_or_pack);
|
std::list<fs::path> recursiveSongSearch(fs::path song_or_pack);
|
||||||
const std::vector<fs::path>& getMemoFiles(fs::path song_folder);
|
const std::vector<fs::path> getMemoFiles(fs::path song_folder);
|
||||||
const std::vector<fs::path>& getMemonFiles(fs::path song_folder);
|
const std::vector<fs::path> getMemonFiles(fs::path song_folder);
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ sf::Sprite Textures::CoverAltas::at(const fs::path& path) const {
|
|||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto location = get_detailed_location(path_to_index.at(path));
|
auto location = get_detailed_location(index);
|
||||||
sf::IntRect rect(location.column*256, location.row*256, 256, 256);
|
sf::IntRect rect(location.column*256, location.row*256, 256, 256);
|
||||||
sf::Sprite cover;
|
sf::Sprite cover;
|
||||||
cover.setTexture(textures.at(location.texture_index)->getTexture());
|
cover.setTexture(textures.at(location.texture_index)->getTexture());
|
||||||
|
@ -18,7 +18,7 @@ namespace std {
|
|||||||
return std::hash<std::string>()(p.string());
|
return std::hash<std::string>()(p.string());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
namespace Textures {
|
namespace Textures {
|
||||||
|
|
||||||
@ -50,4 +50,4 @@ namespace Textures {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DetailedLocation get_detailed_location(unsigned int location);
|
DetailedLocation get_detailed_location(unsigned int location);
|
||||||
};
|
}
|
||||||
|
@ -37,9 +37,14 @@ void MusicSelect::Screen::select_chart(sf::RenderWindow& window) {
|
|||||||
// drawing the ribbon
|
// drawing the ribbon
|
||||||
for (size_t panel = 0; panel < 12; panel++) {
|
for (size_t panel = 0; panel < 12; panel++) {
|
||||||
ribbon.at(panel)->draw(
|
ribbon.at(panel)->draw(
|
||||||
*this,
|
resources,
|
||||||
window,
|
window,
|
||||||
sf::FloatRect((panel%4)*150.f, (panel/4)*150.f, 150.f, 150.f)
|
sf::FloatRect(
|
||||||
|
(panel%4)*150.f,
|
||||||
|
(panel/4)*150.f,
|
||||||
|
150.f,
|
||||||
|
150.f
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
window.display();
|
window.display();
|
||||||
@ -47,10 +52,4 @@ void MusicSelect::Screen::select_chart(sf::RenderWindow& window) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MusicSelect::Screen::handle_key(const sf::Event::KeyEvent& key_event) {
|
void MusicSelect::Screen::handle_key(const sf::Event::KeyEvent& key_event) {
|
||||||
auto panel = key_mapping.key_to_button(key_event.code);
|
|
||||||
if (panel) {
|
|
||||||
if (Button::B2 <= *panel and *panel <= Button::B12) {
|
|
||||||
ribbon.at()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -33,4 +33,4 @@ namespace MusicSelect {
|
|||||||
KeyMapping key_mapping;
|
KeyMapping key_mapping;
|
||||||
void handle_key(const sf::Event::KeyEvent& key_event);
|
void handle_key(const sf::Event::KeyEvent& key_event);
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
#include "MusicSelect.hpp"
|
#include "MusicSelect.hpp"
|
||||||
|
|
||||||
|
void MusicSelect::CategoryPanel::click(Screen& screen) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void MusicSelect::CategoryPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
|
void MusicSelect::CategoryPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
|
||||||
sf::RectangleShape frame{{area.width*0.9f, area.height*0.9f}};
|
sf::RectangleShape frame{{area.width*0.9f, area.height*0.9f}};
|
||||||
frame.setFillColor(sf::Color::Black);
|
frame.setFillColor(sf::Color::Black);
|
||||||
@ -27,12 +31,22 @@ void MusicSelect::CategoryPanel::draw(Resources& resources, sf::RenderTarget& ta
|
|||||||
label_text.setString(this->label);
|
label_text.setString(this->label);
|
||||||
label_text.setCharacterSize(24U);
|
label_text.setCharacterSize(24U);
|
||||||
label_text.setFillColor(sf::Color::White);
|
label_text.setFillColor(sf::Color::White);
|
||||||
auto bounds = label_text.getLocalBounds();
|
auto text_bounds = label_text.getLocalBounds();
|
||||||
label_text.setOrigin(bounds.width / 2.f, bounds.height / 2.f);
|
label_text.setOrigin(text_bounds.width / 2.f, text_bounds.height / 2.f);
|
||||||
if (bounds.height > bounds.width) {
|
if (text_bounds.height > text_bounds.width) {
|
||||||
label_text.setScale(area.height*0.8f / bounds.height, area.height*0.8f / bounds.height);
|
label_text.setScale(area.height*0.8f / text_bounds.height, area.height*0.8f / text_bounds.height);
|
||||||
} else {
|
} else {
|
||||||
label_text.setScale(area.width*0.8f / bounds.width, area.width*0.8f / bounds.width);
|
label_text.setScale(area.width*0.8f / text_bounds.width, area.width*0.8f / text_bounds.width);
|
||||||
}
|
}
|
||||||
label_text.setPosition(area.left + area.width / 2.f, area.top + area.height / 2.f);
|
label_text.setPosition(area.left + area.width / 2.f, area.top + area.height / 2.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void MusicSelect::SongPanel::click(Screen& screen) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicSelect::SongPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
#include <SFML/Window.hpp>
|
#include <SFML/Window.hpp>
|
||||||
|
|
||||||
|
#include "../../Data/SongList.hpp"
|
||||||
#include "Resources.hpp"
|
#include "Resources.hpp"
|
||||||
|
|
||||||
namespace MusicSelect {
|
namespace MusicSelect {
|
||||||
@ -28,7 +29,7 @@ namespace MusicSelect {
|
|||||||
|
|
||||||
class CategoryPanel final : public Panel {
|
class CategoryPanel final : public Panel {
|
||||||
public:
|
public:
|
||||||
CategoryPanel(const std::string& t_label) : label(t_label) {};
|
explicit CategoryPanel(const std::string& t_label) : label(t_label) {};
|
||||||
void click(Screen& screen) override;
|
void click(Screen& screen) override;
|
||||||
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
|
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
|
||||||
private:
|
private:
|
||||||
@ -37,7 +38,7 @@ namespace MusicSelect {
|
|||||||
|
|
||||||
class SongPanel final : public Panel {
|
class SongPanel final : public Panel {
|
||||||
public:
|
public:
|
||||||
SongPanel(const Data::Song& t_song) : song(t_song) {};
|
explicit SongPanel(const Data::Song& t_song) : song(t_song) {};
|
||||||
void click(Screen& screen) override;
|
void click(Screen& screen) override;
|
||||||
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
|
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
|
||||||
private:
|
private:
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
MusicSelect::Ribbon MusicSelect::Ribbon::title_sort(const Data::SongList& song_list) {
|
MusicSelect::Ribbon MusicSelect::Ribbon::title_sort(const Data::SongList& song_list) {
|
||||||
std::map<char,std::vector<Data::Song>> categories;
|
std::map<char,std::vector<Data::Song>> categories;
|
||||||
for (const auto& song : song_list.songs) {
|
for (const auto& song : song_list.songs) {
|
||||||
if (song.title.size > 0) {
|
if (song.title.size() > 0) {
|
||||||
char letter = song.title[0];
|
char letter = song.title[0];
|
||||||
if ('A' <= letter and letter <= 'Z') {
|
if ('A' <= letter and letter <= 'Z') {
|
||||||
categories[letter].push_back(song);
|
categories[letter].push_back(song);
|
||||||
@ -22,22 +22,25 @@ MusicSelect::Ribbon MusicSelect::Ribbon::title_sort(const Data::SongList& song_l
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ribbon ribbon;
|
Ribbon ribbon;
|
||||||
for (const auto& [letter, songs] : categories) {
|
for (auto& [letter, songs] : categories) {
|
||||||
std::vector<std::unique_ptr<Panel>> panels = {std::make_unique<CategoryPanel>(letter)};
|
std::vector<std::unique_ptr<Panel>> panels;
|
||||||
|
panels.emplace_back(
|
||||||
|
std::make_unique<CategoryPanel>(
|
||||||
|
std::string(1, letter)
|
||||||
|
)
|
||||||
|
);
|
||||||
std::sort(songs.begin(), songs.end(), Data::Song::sort_by_title);
|
std::sort(songs.begin(), songs.end(), Data::Song::sort_by_title);
|
||||||
for (const auto& song : songs) {
|
for (const auto& song : songs) {
|
||||||
panels.push_back(std::make_unique<SongPanel>(song));
|
panels.push_back(std::make_unique<SongPanel>(song));
|
||||||
}
|
}
|
||||||
while (panels.size % 3 != 0) {
|
while (panels.size() % 3 != 0) {
|
||||||
panels.push_back(std::make_unique<EmptyPanel>());
|
panels.push_back(std::make_unique<EmptyPanel>());
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < panels.size; i += 3) {
|
for (size_t i = 0; i < panels.size(); i += 3) {
|
||||||
std::array<std::unique_ptr<Panel>,3> column = {
|
ribbon.layout.emplace_back();
|
||||||
std::move(panels[i]),
|
for (size_t j = 0; j < 3; j++) {
|
||||||
std::move(panels[i+1]),
|
ribbon.layout.back()[j] = std::move(panels[i+j]);
|
||||||
std::move(panels[i+2])
|
}
|
||||||
};
|
|
||||||
ribbon.layout.push_back(column);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ribbon;
|
return ribbon;
|
||||||
|
@ -8,7 +8,7 @@ namespace MusicSelect {
|
|||||||
// It can be sorted in a number of ways
|
// It can be sorted in a number of ways
|
||||||
class Ribbon {
|
class Ribbon {
|
||||||
public:
|
public:
|
||||||
Ribbon();
|
Ribbon() = default;
|
||||||
static Ribbon title_sort(const Data::SongList& song_list);
|
static Ribbon title_sort(const Data::SongList& song_list);
|
||||||
static Ribbon test_sort();
|
static Ribbon test_sort();
|
||||||
const auto& get_layout() {return layout;};
|
const auto& get_layout() {return layout;};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user