From 13f91aa1959ef18410ea5b8afdede13ba128bbdd Mon Sep 17 00:00:00 2001 From: Kae <80987908+Novaenia@users.noreply.github.com> Date: Fri, 15 Mar 2024 21:29:14 +1100 Subject: [PATCH] Songbook search improvements --- .../windowconfig/songbook.config.patch | 39 ++++---- source/frontend/StarSongbookInterface.cpp | 91 ++++++++++--------- source/frontend/StarSongbookInterface.hpp | 5 +- 3 files changed, 73 insertions(+), 62 deletions(-) diff --git a/assets/opensb/interface/windowconfig/songbook.config.patch b/assets/opensb/interface/windowconfig/songbook.config.patch index 36991a5..0ef4c54 100644 --- a/assets/opensb/interface/windowconfig/songbook.config.patch +++ b/assets/opensb/interface/windowconfig/songbook.config.patch @@ -1,23 +1,22 @@ { - "paneLayout" : { - "group" : { - "position" : [8, 71] - }, - "search" : { - "type" : "textbox", - "position" : [86, 71], - "hint" : "Search", - "maxWidth" : 50 - }, - - "lblBandInput" : { - "position" : [3, 68] - }, - "lblSearchInput" : { - "type" : "image", - "file" : "/interface/songbook/band.png", - "position" : [81, 68], - "zlevel" : -3 - } + "paneLayout" : { + "group" : { + "position" : [8, 71] + }, + "search" : { + "type" : "textbox", + "position" : [86, 71], + "hint" : "Search", + "maxWidth" : 50 + }, + "lblBandInput" : { + "position" : [3, 68] + }, + "lblSearchInput" : { + "type" : "image", + "file" : "/interface/songbook/band.png", + "position" : [81, 68], + "zlevel" : -3 } + } } \ No newline at end of file diff --git a/source/frontend/StarSongbookInterface.cpp b/source/frontend/StarSongbookInterface.cpp index cc6a17d..28145b6 100644 --- a/source/frontend/StarSongbookInterface.cpp +++ b/source/frontend/StarSongbookInterface.cpp @@ -27,57 +27,25 @@ SongbookInterface::SongbookInterface(PlayerPtr player) { reader.construct(assets->json("/interface/windowconfig/songbook.config:paneLayout"), this); - auto songList = fetchChild("songs.list"); - auto search = fetchChild("search")->getText(); + Root::singleton().registerReloadListener( + m_reloadListener = make_shared([this]() { + refresh(true); + }) + ); - if (m_searchValue != search) - m_searchValue = search; - - m_files = assets->scan(".abc"); - sort(m_files, [](String const& a, String const& b) -> bool { return b.compare(a, String::CaseInsensitive) > 0; }); - for (auto s : m_files) { - auto song = s.substr(7, s.length() - (7 + 4)); - if (song.contains(m_searchValue, String::CaseInsensitive)) { - auto widget = songList->addItem(); - widget->setData(s); - auto songName = widget->fetchChild("songName"); - songName->setText(song); - - widget->show(); - } - } + refresh(true); } void SongbookInterface::update(float dt) { Pane::update(dt); - - auto search = fetchChild("search")->getText(); - if (m_searchValue != search) { - m_searchValue = search; - - auto songList = fetchChild("songs.list"); - songList->clear(); - - for (auto s : m_files) { - auto song = s.substr(7, s.length() - (7 + 4)); - if (song.contains(m_searchValue, String::CaseInsensitive)) { - auto widget = songList->addItem(); - widget->setData(s); - auto songName = widget->fetchChild("songName"); - songName->setText(song); - - widget->show(); - } - } - } + refresh(); } bool SongbookInterface::play() { auto songList = fetchChild("songs.list"); auto songWidget = songList->selectedWidget(); - if (!songWidget) - return false; - auto songName = songWidget->data().toString(); + if (!songWidget) return false; + auto& songName = m_files.at(songWidget->data().toUInt()); auto group = fetchChild("group")->getText(); JsonObject song; @@ -89,4 +57,45 @@ bool SongbookInterface::play() { return true; } +void SongbookInterface::refresh(bool reloadFiles) { + if (reloadFiles) { + m_files = Root::singleton().assets()->scanExtension(".abc").values(); + sort(m_files, [](String const& a, String const& b) -> bool { return b.compare(a, String::CaseInsensitive) > 0; }); + } + auto search = fetchChild("search")->getText(); + if (m_lastSearch != search || reloadFiles) { + m_lastSearch = search; + auto songList = fetchChild("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("songName"); + songName->setText(m_files[i]); + widget->show(); + } + } else { + for (size_t i = 0; i != m_files.size(); ++i) { + StringView song = m_files[i]; + 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("songName"); + songName->setText(text + strf("^#bbb;{}", song.substr(last))); + widget->show(); + } + } + } + } +} + } \ No newline at end of file diff --git a/source/frontend/StarSongbookInterface.hpp b/source/frontend/StarSongbookInterface.hpp index f8a6cb2..a32ef59 100644 --- a/source/frontend/StarSongbookInterface.hpp +++ b/source/frontend/StarSongbookInterface.hpp @@ -2,6 +2,7 @@ #include "StarSongbook.hpp" #include "StarPane.hpp" +#include "StarListener.hpp" namespace Star { @@ -18,8 +19,10 @@ public: private: PlayerPtr m_player; StringList m_files; - String m_searchValue; + String m_lastSearch; + CallbackListenerPtr m_reloadListener; bool play(); + void refresh(bool reloadFiles = false); }; }