diff --git a/approot/search.xml b/approot/search.xml index 4f248d70..cb417139 100644 --- a/approot/search.xml +++ b/approot/search.xml @@ -3,29 +3,29 @@ - -
-
${releases}
-
-
-
- ${link-type class="form-select"} -
-
- ${artists} -
-
${tracks}
+
+
+ ${results} + + + +
+
+ ${link-type class="form-select"} +
+
+ ${artists}
diff --git a/src/lms/ui/explore/SearchView.cpp b/src/lms/ui/explore/SearchView.cpp index 471f431d..1f05006c 100644 --- a/src/lms/ui/explore/SearchView.cpp +++ b/src/lms/ui/explore/SearchView.cpp @@ -19,6 +19,8 @@ #include "SearchView.hpp" +#include + #include "services/database/Artist.hpp" #include "services/database/Release.hpp" #include "services/database/Session.hpp" @@ -35,142 +37,162 @@ using namespace Database; namespace UserInterface { - SearchView::SearchView(Filters& filters, PlayQueueController& playQueueController) - : Wt::WTemplate {Wt::WString::tr("Lms.Explore.Search.template")} - , _playQueueController {playQueueController} - , _filters {filters} - , _artistCollector {filters, ArtistCollector::Mode::Search, getMaxCount(Mode::Artist)} - , _releaseCollector {filters, ReleaseCollector::Mode::Search, getMaxCount(Mode::Release)} - , _trackCollector {filters, TrackCollector::Mode::Search, getMaxCount(Mode::Track)} - { - addFunction("tr", &Wt::WTemplate::Functions::tr); + SearchView::SearchView(Filters& filters, PlayQueueController& playQueueController) + : Wt::WTemplate{ Wt::WString::tr("Lms.Explore.Search.template") } + , _playQueueController{ playQueueController } + , _filters{ filters } + , _artistCollector{ filters, ArtistCollector::Mode::Search, getMaxCount(Mode::Artist) } + , _releaseCollector{ filters, ReleaseCollector::Mode::Search, getMaxCount(Mode::Release) } + , _trackCollector{ filters, TrackCollector::Mode::Search, getMaxCount(Mode::Track) } + { + addFunction("tr", &Wt::WTemplate::Functions::tr); - _artists = bindNew("artists", Wt::WString::tr("Lms.Explore.Artists.template.container")); - _artists->onRequestElements.connect([this] { addSomeArtists(); }); + _stack = bindNew("results"); - _artistLinkType = bindNew("link-type"); - _artistLinkType->setModel(ArtistListHelpers::createArtistLinkTypesModel()); - _artistLinkType->changed().connect([this] - { - const std::optional linkType {static_cast(_artistLinkType->model().get())->getValue(_artistLinkType->currentIndex())}; - refreshView(linkType); - }); + // releases + _releases = _stack->addNew(Wt::WString::tr("Lms.Explore.Releases.template.container")); + _releases->onRequestElements.connect([this] { addSomeReleases(); }); - _releases = bindNew("releases", Wt::WString::tr("Lms.Explore.Releases.template.container")); - _releases->onRequestElements.connect([this] { addSomeReleases(); }); + // artists + { + Wt::WTemplate* artistResults{ _stack->addNew(Wt::WString::tr("Lms.Explore.Search.template.artists")) }; - _tracks = bindNew("tracks"); - _tracks->onRequestElements.connect([this] { addSomeTracks(); }); + _artistLinkType = artistResults->bindNew("link-type"); + _artistLinkType->setModel(ArtistListHelpers::createArtistLinkTypesModel()); + _artistLinkType->changed().connect([this] + { + const std::optional linkType{ static_cast(_artistLinkType->model().get())->getValue(_artistLinkType->currentIndex()) }; + refreshView(linkType); + }); - filters.updated().connect([=] - { - refreshView(); - }); + _artists = artistResults->bindNew("artists", Wt::WString::tr("Lms.Explore.Artists.template.container")); + _artists->onRequestElements.connect([this] { addSomeArtists(); }); + } - LmsApp->getScannerEvents().scanComplete.connect(this, [this](const Scanner::ScanStats& stats) - { - if (stats.nbChanges()) - _artistLinkType->setModel(ArtistListHelpers::createArtistLinkTypesModel()); - }); - } + // Tracks + _tracks = _stack->addNew(); + _tracks->onRequestElements.connect([this] { addSomeTracks(); }); - std::size_t - SearchView::getBatchSize(Mode mode) const - { - auto it {_batchSizes.find(mode)}; - assert(it != _batchSizes.cend()); - return it->second; - } + // Menu + auto bindMenuItem{ [this](std::size_t index, const std::string& var, const Wt::WString& title) + { + Wt::WPushButton* menuItem {bindNew(var, title)}; + menuItem->clicked().connect([=] + { + _stack->setCurrentIndex(index); + _currentActiveItem->removeStyleClass("active"); + menuItem->addStyleClass("active"); + _currentActiveItem = menuItem; + }); - std::size_t - SearchView::getMaxCount(Mode mode) const - { - auto it {_maxCounts.find(mode)}; - assert(it != _maxCounts.cend()); - return it->second; - } + if (index == 0) + { + _currentActiveItem = menuItem; + _currentActiveItem->addStyleClass("active"); + } + } }; - void - SearchView::refreshView(std::optional linkType) - { - _artistCollector.setArtistLinkType(linkType); - refreshView(); - } + bindMenuItem(0, "releases", Wt::WString::tr("Lms.Explore.releases")); + bindMenuItem(1, "artists", Wt::WString::tr("Lms.Explore.artists")); + bindMenuItem(2, "tracks", Wt::WString::tr("Lms.Explore.tracks")); - void - SearchView::refreshView(const Wt::WString& searchText) - { - _releaseCollector.setSearch(searchText.toUTF8()); - _artistCollector.setSearch(searchText.toUTF8()); - _trackCollector.setSearch(searchText.toUTF8()); - refreshView(); - } + filters.updated().connect([=] + { + refreshView(); + }); - void - SearchView::refreshView() - { - _artists->reset(); - _releases->reset(); - _tracks->reset(); + LmsApp->getScannerEvents().scanComplete.connect(this, [this](const Scanner::ScanStats& stats) + { + if (stats.nbChanges()) + _artistLinkType->setModel(ArtistListHelpers::createArtistLinkTypesModel()); + }); + } - addSomeArtists(); - addSomeReleases(); - addSomeTracks(); - } + std::size_t SearchView::getBatchSize(Mode mode) const + { + auto it{ _batchSizes.find(mode) }; + assert(it != _batchSizes.cend()); + return it->second; + } - void - SearchView::addSomeArtists() - { - using namespace Database; + std::size_t SearchView::getMaxCount(Mode mode) const + { + auto it{ _maxCounts.find(mode) }; + assert(it != _maxCounts.cend()); + return it->second; + } - const Range range {_artists->getCount(), getBatchSize(Mode::Artist)}; - const RangeResults artistIds {_artistCollector.get(range)}; - { - auto transaction {LmsApp->getDbSession().createSharedTransaction()}; + void SearchView::refreshView(std::optional linkType) + { + _artistCollector.setArtistLinkType(linkType); + refreshView(); + } - for (const ArtistId artistId : artistIds.results) - { - const Artist::pointer artist {Artist::find(LmsApp->getDbSession(), artistId)}; - _artists->add(ArtistListHelpers::createEntry(artist)); - } - } - } + void SearchView::refreshView(const Wt::WString& searchText) + { + _releaseCollector.setSearch(searchText.toUTF8()); + _artistCollector.setSearch(searchText.toUTF8()); + _trackCollector.setSearch(searchText.toUTF8()); + refreshView(); + } - void - SearchView::addSomeReleases() - { - using namespace Database; + void SearchView::refreshView() + { + _artists->reset(); + _releases->reset(); + _tracks->reset(); + } - const Range range {_releases->getCount(), getBatchSize(Mode::Release)}; - const RangeResults releaseIds {_releaseCollector.get(range)}; - { - auto transaction {LmsApp->getDbSession().createSharedTransaction()}; + void SearchView::addSomeArtists() + { + using namespace Database; - for (const ReleaseId releaseId : releaseIds.results) - { - const Release::pointer release {Release::find(LmsApp->getDbSession(), releaseId)}; - _releases->add(ReleaseListHelpers::createEntry(release)); - } - } - } + const Range range{ _artists->getCount(), getBatchSize(Mode::Artist) }; + const RangeResults artistIds{ _artistCollector.get(range) }; + { + auto transaction{ LmsApp->getDbSession().createSharedTransaction() }; - void - SearchView::addSomeTracks() - { - using namespace Database; + for (const ArtistId artistId : artistIds.results) + { + const Artist::pointer artist{ Artist::find(LmsApp->getDbSession(), artistId) }; + _artists->add(ArtistListHelpers::createEntry(artist)); + } + } + } - const Range range {_tracks->getCount(), getBatchSize(Mode::Track)}; - const RangeResults trackIds {_trackCollector.get(range)}; + void SearchView::addSomeReleases() + { + using namespace Database; - { - auto transaction {LmsApp->getDbSession().createSharedTransaction()}; + const Range range{ _releases->getCount(), getBatchSize(Mode::Release) }; + const RangeResults releaseIds{ _releaseCollector.get(range) }; + { + auto transaction{ LmsApp->getDbSession().createSharedTransaction() }; - for (const TrackId trackId : trackIds.results) - { - const Track::pointer track {Track::find(LmsApp->getDbSession(), trackId)}; - _tracks->add(TrackListHelpers::createEntry(track, _playQueueController, _filters)); - } - } - } + for (const ReleaseId releaseId : releaseIds.results) + { + const Release::pointer release{ Release::find(LmsApp->getDbSession(), releaseId) }; + _releases->add(ReleaseListHelpers::createEntry(release)); + } + } + } + + void SearchView::addSomeTracks() + { + using namespace Database; + + const Range range{ _tracks->getCount(), getBatchSize(Mode::Track) }; + const RangeResults trackIds{ _trackCollector.get(range) }; + + { + auto transaction{ LmsApp->getDbSession().createSharedTransaction() }; + + for (const TrackId trackId : trackIds.results) + { + const Track::pointer track{ Track::find(LmsApp->getDbSession(), trackId) }; + _tracks->add(TrackListHelpers::createEntry(track, _playQueueController, _filters)); + } + } + } } // namespace UserInterface diff --git a/src/lms/ui/explore/SearchView.hpp b/src/lms/ui/explore/SearchView.hpp index 71581760..5b7f4989 100644 --- a/src/lms/ui/explore/SearchView.hpp +++ b/src/lms/ui/explore/SearchView.hpp @@ -33,62 +33,61 @@ namespace UserInterface { - class InfiniteScrollingContainer; - class Filters; - class PlayQueueController; + class InfiniteScrollingContainer; + class Filters; + class PlayQueueController; - class SearchView : public Wt::WTemplate - { - public: - SearchView(Filters& filters, PlayQueueController& playQueueController); + class SearchView : public Wt::WTemplate + { + public: + SearchView(Filters& filters, PlayQueueController& playQueueController); - void refreshView(const Wt::WString& searchText); + void refreshView(const Wt::WString& searchText); - private: - // same order as in the menu - enum class Mode - { - Artist, - Release, - Track, - }; + private: + // same order as in the menu + enum class Mode + { + Artist, + Release, + Track, + }; - static constexpr Mode _defaultMode {Mode::Release}; - static inline std::unordered_map _batchSizes - { - {Mode::Artist, 6}, - {Mode::Release, 6}, - {Mode::Track, 6}, - }; - static inline std::unordered_map _maxCounts - { - {Mode::Artist, 1000}, - {Mode::Release, 504}, - {Mode::Track, 500}, - }; - std::size_t getBatchSize(Mode mode) const; - std::size_t getMaxCount(Mode mode) const; + static constexpr Mode _defaultMode{ Mode::Release }; + static inline std::unordered_map _batchSizes + { + {Mode::Artist, 6}, + {Mode::Release, 6}, + {Mode::Track, 6}, + }; + static inline std::unordered_map _maxCounts + { + {Mode::Artist, 1000}, + {Mode::Release, 504}, + {Mode::Track, 500}, + }; + std::size_t getBatchSize(Mode mode) const; + std::size_t getMaxCount(Mode mode) const; - void refreshView(); - void refreshView(std::optional linkType); - void addSomeArtists(); - void addSomeReleases(); - void addSomeTracks(); + void refreshView(); + void refreshView(std::optional linkType); + void addSomeArtists(); + void addSomeReleases(); + void addSomeTracks(); - PlayQueueController& _playQueueController; - Filters& _filters; - ArtistCollector _artistCollector; - ReleaseCollector _releaseCollector; - TrackCollector _trackCollector; + PlayQueueController& _playQueueController; + Filters& _filters; + ArtistCollector _artistCollector; + ReleaseCollector _releaseCollector; + TrackCollector _trackCollector; + Wt::WStackedWidget* _stack{}; + Wt::WWidget* _currentActiveItem {}; + InfiniteScrollingContainer* _artists{}; + InfiniteScrollingContainer* _releases{}; + InfiniteScrollingContainer* _tracks{}; - InfiniteScrollingContainer* _artists {}; - InfiniteScrollingContainer* _releases {}; - InfiniteScrollingContainer* _tracks {}; - - Wt::WComboBox* _artistLinkType {}; - - std::vector _results; - }; + Wt::WComboBox* _artistLinkType{}; + }; } // namespace UserInterface