osb/source/frontend/StarSongbookInterface.cpp

112 lines
3.5 KiB
C++
Raw Normal View History

2023-06-20 04:33:09 +00:00
#include "StarSongbookInterface.hpp"
#include "StarGuiReader.hpp"
#include "StarRoot.hpp"
#include "StarListWidget.hpp"
#include "StarLabelWidget.hpp"
#include "StarTextBoxWidget.hpp"
#include "StarPlayer.hpp"
#include "StarAssets.hpp"
namespace Star {
2024-05-24 02:10:48 +00:00
String const SongPathPrefix = "/songs/";
2023-06-20 04:33:09 +00:00
SongbookInterface::SongbookInterface(PlayerPtr player) {
m_player = std::move(player);
2023-06-20 04:33:09 +00:00
auto assets = Root::singleton().assets();
GuiReader reader;
reader.registerCallback("close", [=](Widget*) { dismiss(); });
reader.registerCallback("btnPlay",
[=](Widget*) {
if (play())
dismiss();
});
reader.registerCallback("group", [=](Widget*) {});
2024-03-08 16:39:39 +00:00
reader.registerCallback("search", [=](Widget*) {});
2023-06-20 04:33:09 +00:00
reader.construct(assets->json("/interface/windowconfig/songbook.config:paneLayout"), this);
2024-03-15 10:29:14 +00:00
Root::singleton().registerReloadListener(
m_reloadListener = make_shared<CallbackListener>([this]() {
refresh(true);
})
);
2023-06-20 04:33:09 +00:00
2024-03-15 10:29:14 +00:00
refresh(true);
2024-03-08 16:39:39 +00:00
}
void SongbookInterface::update(float dt) {
Pane::update(dt);
2024-03-15 10:29:14 +00:00
refresh();
2023-06-20 04:33:09 +00:00
}
bool SongbookInterface::play() {
auto songList = fetchChild<ListWidget>("songs.list");
auto songWidget = songList->selectedWidget();
2024-03-15 10:29:14 +00:00
if (!songWidget) return false;
auto& songName = m_files.at(songWidget->data().toUInt());
2023-06-20 04:33:09 +00:00
auto group = fetchChild<TextBoxWidget>("group")->getText();
JsonObject song;
song["resource"] = songName;
auto buffer = Root::singleton().assets()->bytes(songName);
song["abc"] = String(buffer->ptr(), buffer->size());
m_player->songbook()->play(song, group);
return true;
}
2024-03-15 10:29:14 +00:00
void SongbookInterface::refresh(bool reloadFiles) {
if (reloadFiles) {
m_files = Root::singleton().assets()->scanExtension(".abc").values();
2024-05-24 02:10:48 +00:00
eraseWhere(m_files, [](String& song) {
if (!song.beginsWith(SongPathPrefix, String::CaseInsensitive)) {
Logger::warn("Song '{}' isn't in {}, ignoring", SongPathPrefix.size(), song);
return true;
}
return false;
});
2024-03-15 10:29:14 +00:00
sort(m_files, [](String const& a, String const& b) -> bool { return b.compare(a, String::CaseInsensitive) > 0; });
}
auto& search = fetchChild<TextBoxWidget>("search")->getText();
2024-03-15 10:29:14 +00:00
if (m_lastSearch != search || reloadFiles) {
m_lastSearch = search;
auto songList = fetchChild<ListWidget>("songs.list");
songList->clear();
if (search.empty()) {
for (size_t i = 0; i != m_files.size(); ++i) {
auto widget = songList->addItem();
widget->setData(i);
auto songName = widget->fetchChild<LabelWidget>("songName");
2024-05-24 02:10:48 +00:00
String const& song = m_files[i];
songName->setText(song.substr(SongPathPrefix.size(), song.size() - (SongPathPrefix.size() + 4)));
2024-03-15 10:29:14 +00:00
widget->show();
}
} else {
for (size_t i = 0; i != m_files.size(); ++i) {
StringView song = m_files[i];
2024-05-24 02:10:48 +00:00
song = song.substr(SongPathPrefix.size(), song.size() - (SongPathPrefix.size() + 4));
2024-03-15 10:29:14 +00:00
auto find = song.find(search, 0, String::CaseInsensitive);
if (find != NPos) {
auto widget = songList->addItem();
widget->setData(i);
String text = "";
size_t last = 0;
do {
text += strf("^#bbb;{}^#7f7;{}", song.substr(last, find - last), song.substr(find, search.size()));
last = find + search.size();
find = song.find(search, last, String::CaseInsensitive);
} while (find != NPos);
auto songName = widget->fetchChild<LabelWidget>("songName");
songName->setText(text + strf("^#bbb;{}", song.substr(last)));
widget->show();
}
}
}
}
}
2024-03-08 16:39:39 +00:00
}