From 606029664906c341e37d1fdfc6e7cfcd8f42a234 Mon Sep 17 00:00:00 2001 From: emeric Date: Mon, 19 Feb 2018 16:07:14 +0100 Subject: [PATCH] Added playlist skeleton --- Makefile.am | 1 + approot/playlist.xml | 40 ++++++++++++ approot/release.xml | 1 - src/Makefile.am | 1 + src/database/Playlist.cpp | 6 +- src/database/Playlist.hpp | 18 +++--- src/ui/ArtistView.cpp | 25 +++++++- src/ui/ArtistView.hpp | 11 +++- src/ui/ArtistsView.cpp | 1 + src/ui/ArtistsView.hpp | 8 ++- src/ui/Explore.cpp | 125 +++++++++++++++++++++++++++++++++++--- src/ui/Explore.hpp | 18 ++++++ src/ui/LmsApplication.cpp | 24 ++++++-- src/ui/PlaylistView.cpp | 67 ++++++++++++++++++++ src/ui/PlaylistView.hpp | 43 +++++++++++++ src/ui/ReleaseView.cpp | 19 ++++++ src/ui/ReleaseView.hpp | 9 ++- src/ui/ReleasesView.cpp | 17 +++++- src/ui/ReleasesView.hpp | 7 ++- src/ui/TracksView.cpp | 10 +++ src/ui/TracksView.hpp | 6 +- 21 files changed, 419 insertions(+), 38 deletions(-) create mode 100644 approot/playlist.xml create mode 100644 src/ui/PlaylistView.cpp create mode 100644 src/ui/PlaylistView.hpp diff --git a/Makefile.am b/Makefile.am index 0be57c11..7153c82b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -21,6 +21,7 @@ lms_approot_DATA = \ approot/artist.xml \ approot/mediaplayer.xml \ approot/messages.xml \ + approot/playlist.xml \ approot/releases.xml \ approot/release.xml \ approot/templates.xml \ diff --git a/approot/playlist.xml b/approot/playlist.xml new file mode 100644 index 00000000..077f9557 --- /dev/null +++ b/approot/playlist.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + ${entries} + + + +
+
+ ${cover class="media-object"} +
+
+

${name}

+
+
+ ${}${release-name}${} + ${}${artist-name}${} + + ${play-btn} ${remove-btn} +
+ +
diff --git a/approot/release.xml b/approot/release.xml index eff1d0a2..68def396 100644 --- a/approot/release.xml +++ b/approot/release.xml @@ -1,4 +1,3 @@ - diff --git a/src/Makefile.am b/src/Makefile.am index 58cd27d6..54f36b85 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -30,6 +30,7 @@ lms_SOURCES = \ $(srcdir)/ui/HomeView.cpp \ $(srcdir)/ui/LmsApplication.cpp \ $(srcdir)/ui/MediaPlayer.cpp \ + $(srcdir)/ui/PlaylistView.cpp \ $(srcdir)/ui/ReleasesView.cpp \ $(srcdir)/ui/ReleaseView.cpp \ $(srcdir)/ui/TracksView.cpp \ diff --git a/src/database/Playlist.cpp b/src/database/Playlist.cpp index 38aec290..c63e3777 100644 --- a/src/database/Playlist.cpp +++ b/src/database/Playlist.cpp @@ -54,7 +54,7 @@ Playlist::get(Wt::Dbo::Session& session, std::string name, Wt::Dbo::ptr us } std::vector -Playlist::get(Wt::Dbo::Session& session, Wt::Dbo::ptr user) +Playlist::getAll(Wt::Dbo::Session& session, Wt::Dbo::ptr user) { Wt::Dbo::collection res = session.find().where("user_id = ?").bind(user.id()).orderBy("name"); @@ -74,7 +74,7 @@ PlaylistEntry::create(Wt::Dbo::Session& session, Wt::Dbo::ptr track, Wt:: { return session.add( new PlaylistEntry( track, playlist, pos) ); } - +/* std::vector PlaylistEntry::getEntries(Wt::Dbo::Session& session, Playlist::pointer playlist) { @@ -87,6 +87,6 @@ PlaylistEntry::getEntries(Wt::Dbo::Session& session, Playlist::pointer playlist) res.push_back((*it)->getTrack().id()); return res; -} +}*/ } // namespace Database diff --git a/src/database/Playlist.hpp b/src/database/Playlist.hpp index a8e0ddf0..c2a02a36 100644 --- a/src/database/Playlist.hpp +++ b/src/database/Playlist.hpp @@ -40,15 +40,22 @@ class Playlist // Search utility static pointer get(Wt::Dbo::Session& session, std::string name, Wt::Dbo::ptr user); - - // ordered by name - static std::vector get(Wt::Dbo::Session& session, Wt::Dbo::ptr user); + static std::vector getAll(Wt::Dbo::Session& session, Wt::Dbo::ptr user); // Create utility static pointer create(Wt::Dbo::Session& session, std::string name, bool isPublic, Wt::Dbo::ptr user); // Accessors std::string getName() const { return _name; } + bool isPublic() const { return _isPublic; } + + // Modifiers + void addTrack(id_type trackId); + void addTracks(const std::vector& trackIds); + void clear(); + + // Get tracks, ordered by position + std::vector getEntries(Wt::Dbo::Session& session, int offset = -1, int size = -1); template void persist(Action& a) @@ -77,11 +84,6 @@ class PlaylistEntry PlaylistEntry(); PlaylistEntry(Wt::Dbo::ptr rack, Wt::Dbo::ptr playlist, int position); - // Search utility - - // Get the position ordered track id list - static std::vector getEntries(Wt::Dbo::Session& session,Wt::Dbo::ptr playlist); - // Create utility static pointer create(Wt::Dbo::Session& session, Wt::Dbo::ptr track, Wt::Dbo::ptr playlist, int position); diff --git a/src/ui/ArtistView.cpp b/src/ui/ArtistView.cpp index 47f1094e..fc529a4f 100644 --- a/src/ui/ArtistView.cpp +++ b/src/ui/ArtistView.cpp @@ -29,6 +29,7 @@ #include "utils/Utils.hpp" #include "LmsApplication.hpp" +#include "Filters.hpp" #include "ArtistView.hpp" namespace UserInterface { @@ -77,11 +78,21 @@ Artist::refresh() { auto playBtn = new Wt::WText(Wt::WString::tr("btn-artist-play-btn"), Wt::XHTMLText); t->bindWidget("play-btn", playBtn); + + playBtn->clicked().connect(std::bind([=] + { + artistPlay.emit(artistId); + })); } { auto addBtn = new Wt::WText(Wt::WString::tr("btn-artist-add-btn"), Wt::XHTMLText); t->bindWidget("add-btn", addBtn); + + addBtn->clicked().connect(std::bind([=] + { + artistAdd.emit(artistId); + })); } auto releasesContainer = new Wt::WContainerWidget(); @@ -90,11 +101,13 @@ Artist::refresh() auto releases = artist->getReleases(_filters->getClusterIds()); for (auto release : releases) { + auto releaseId = release.id(); + Wt::WTemplate* entry = new Wt::WTemplate(Wt::WString::tr("template-artist-entry"), releasesContainer); entry->addFunction("tr", Wt::WTemplate::Functions::tr); { - Wt::WAnchor* coverAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(release.id()))); + Wt::WAnchor* coverAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(releaseId))); Wt::WImage* cover = new Wt::WImage(coverAnchor); cover->setImageLink(SessionImageResource()->getReleaseUrl(release.id(), 128)); // Some images may not be square @@ -103,7 +116,7 @@ Artist::refresh() } { - Wt::WAnchor* releaseAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(release.id()))); + Wt::WAnchor* releaseAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(releaseId))); Wt::WText* releaseName = new Wt::WText(releaseAnchor); releaseName->setText(Wt::WString::fromUTF8(release->getName(), Wt::PlainText)); entry->bindWidget("name", releaseAnchor); @@ -128,9 +141,17 @@ Artist::refresh() auto playBtn = new Wt::WText(Wt::WString::tr("btn-artist-play-btn"), Wt::XHTMLText); entry->bindWidget("play-btn", playBtn); + playBtn->clicked().connect(std::bind([=] + { + releasePlay.emit(releaseId); + })); auto addBtn = new Wt::WText(Wt::WString::tr("btn-artist-add-btn"), Wt::XHTMLText); entry->bindWidget("add-btn", addBtn); + addBtn->clicked().connect(std::bind([=] + { + releaseAdd.emit(releaseId); + })); } } diff --git a/src/ui/ArtistView.hpp b/src/ui/ArtistView.hpp index eb7262d7..b6f7d78e 100644 --- a/src/ui/ArtistView.hpp +++ b/src/ui/ArtistView.hpp @@ -20,16 +20,23 @@ #pragma once #include - -#include "Filters.hpp" +#include namespace UserInterface { +class Filters; + class Artist : public Wt::WContainerWidget { public: Artist(Filters* filters, Wt::WContainerWidget* parent = 0); + Wt::Signal artistAdd; + Wt::Signal artistPlay; + + Wt::Signal releaseAdd; + Wt::Signal releasePlay; + private: void refresh(); diff --git a/src/ui/ArtistsView.cpp b/src/ui/ArtistsView.cpp index be50e252..c30ad77e 100644 --- a/src/ui/ArtistsView.cpp +++ b/src/ui/ArtistsView.cpp @@ -28,6 +28,7 @@ #include "utils/Utils.hpp" #include "LmsApplication.hpp" +#include "Filters.hpp" #include "ArtistsView.hpp" namespace UserInterface { diff --git a/src/ui/ArtistsView.hpp b/src/ui/ArtistsView.hpp index 2cc29bfc..74e07bab 100644 --- a/src/ui/ArtistsView.hpp +++ b/src/ui/ArtistsView.hpp @@ -20,16 +20,20 @@ #pragma once #include - -#include "Filters.hpp" +#include namespace UserInterface { +class Filters; + class Artists : public Wt::WContainerWidget { public: Artists(Filters* filters, Wt::WContainerWidget* parent = 0); + Wt::Signal artistAdd; + Wt::Signal artistPlay; + private: void refresh(std::vector searchKeywords = std::vector()); diff --git a/src/ui/Explore.cpp b/src/ui/Explore.cpp index 8686f0f2..20539133 100644 --- a/src/ui/Explore.cpp +++ b/src/ui/Explore.cpp @@ -25,6 +25,7 @@ #include "LmsApplication.hpp" +#include "Filters.hpp" #include "ArtistsView.hpp" #include "ArtistView.hpp" #include "ReleasesView.hpp" @@ -74,18 +75,47 @@ Explore::Explore(Wt::WContainerWidget* parent) { auto container = new Wt::WTemplate(Wt::WString::tr("template-explore"), this); - auto filters = new Filters(); - container->bindWidget("filters", filters); + _filters = new Filters(); + container->bindWidget("filters", _filters); // Contents Wt::WStackedWidget* stack = new Wt::WStackedWidget(); container->bindWidget("contents", stack); - stack->addWidget(new Artists(filters)); - stack->addWidget(new Artist(filters)); - stack->addWidget(new Releases(filters)); - stack->addWidget(new Release(filters)); - stack->addWidget(new Tracks(filters)); + auto artists = new Artists(_filters); + stack->addWidget(artists); + + artists->artistAdd.connect(this, &Explore::handleArtistAdd); + artists->artistPlay.connect(this, &Explore::handleArtistPlay); + + auto artist = new Artist(_filters); + stack->addWidget(artist); + + artist->artistAdd.connect(this, &Explore::handleArtistAdd); + artist->artistPlay.connect(this, &Explore::handleArtistPlay); + artist->releaseAdd.connect(this, &Explore::handleReleaseAdd); + artist->releasePlay.connect(this, &Explore::handleReleasePlay); + + auto releases = new Releases(_filters); + stack->addWidget(releases); + + releases->releaseAdd.connect(this, &Explore::handleReleaseAdd); + releases->releasePlay.connect(this, &Explore::handleReleasePlay); + + auto release = new Release(_filters); + stack->addWidget(release); + + release->releaseAdd.connect(this, &Explore::handleReleaseAdd); + release->releasePlay.connect(this, &Explore::handleReleasePlay); + release->trackAdd.connect(this, &Explore::handleTrackAdd); + release->trackPlay.connect(this, &Explore::handleTrackPlay); + + auto tracks = new Tracks(_filters); + stack->addWidget(tracks); + + tracks->trackAdd.connect(this, &Explore::handleTrackAdd); + tracks->trackPlay.connect(this, &Explore::handleTrackPlay); + wApp->internalPathChanged().connect(std::bind([=] { @@ -94,5 +124,86 @@ Explore::Explore(Wt::WContainerWidget* parent) handlePathChange(stack); } + +// TODO SQL this? +static std::vector getArtistTracks(Wt::Dbo::Session& session, Database::id_type artistId, std::set clusters) +{ + std::vector res; + + Wt::Dbo::Transaction transaction(session); + + auto artist = Database::Artist::getById(session, artistId); + if (!artist) + return res; + + auto releases = artist->getReleases(clusters); + for (auto release : releases) + { + auto tracks = release->getTracks(clusters); + + for (auto track : tracks) + { + res.push_back(track.id()); + } + } + + return res; +} + +static std::vector getReleaseTracks(Wt::Dbo::Session& session, Database::id_type releaseId, std::set clusters) +{ + std::vector res; + + Wt::Dbo::Transaction transaction(session); + + auto release = Database::Release::getById(session, releaseId); + if (!release) + return res; + + auto tracks = release->getTracks(clusters); + for (auto track : tracks) + { + res.push_back(track.id()); + } + + return res; +} + +void +Explore::handleArtistAdd(Database::id_type id) +{ + tracksAdd.emit(getArtistTracks(DboSession(), id, _filters->getClusterIds())); +} + +void +Explore::handleArtistPlay(Database::id_type id) +{ + tracksPlay.emit(getArtistTracks(DboSession(), id, _filters->getClusterIds())); +} + +void +Explore::handleReleaseAdd(Database::id_type id) +{ + tracksAdd.emit(getReleaseTracks(DboSession(), id, _filters->getClusterIds())); +} + +void +Explore::handleReleasePlay(Database::id_type id) +{ + tracksPlay.emit(getReleaseTracks(DboSession(), id, _filters->getClusterIds())); +} + +void +Explore::handleTrackAdd(Database::id_type id) +{ + tracksAdd.emit(std::vector(1, id)); +} + +void +Explore::handleTrackPlay(Database::id_type id) +{ + tracksPlay.emit(std::vector(1, id)); +} + } // namespace UserInterface diff --git a/src/ui/Explore.hpp b/src/ui/Explore.hpp index ac360a83..c7857811 100644 --- a/src/ui/Explore.hpp +++ b/src/ui/Explore.hpp @@ -21,12 +21,30 @@ #include +#include "database/Types.hpp" + namespace UserInterface { +class Filters; + class Explore : public Wt::WContainerWidget { public: Explore(Wt::WContainerWidget *parent = 0); + + Wt::Signal> tracksAdd; + Wt::Signal> tracksPlay; + + private: + + void handleArtistAdd(Database::id_type id); + void handleArtistPlay(Database::id_type id); + void handleReleaseAdd(Database::id_type id); + void handleReleasePlay(Database::id_type id); + void handleTrackAdd(Database::id_type id); + void handleTrackPlay(Database::id_type id); + + Filters* _filters; }; } // namespace UserInterface diff --git a/src/ui/LmsApplication.cpp b/src/ui/LmsApplication.cpp index b5582f34..51d0d665 100644 --- a/src/ui/LmsApplication.cpp +++ b/src/ui/LmsApplication.cpp @@ -32,6 +32,7 @@ #include "Explore.hpp" #include "HomeView.hpp" #include "MediaPlayer.hpp" +#include "PlaylistView.hpp" #include "LmsApplication.hpp" @@ -80,12 +81,13 @@ LmsApplication::LmsApplication(const Wt::WEnvironment& env, Wt::Dbo::SqlConnecti // Add a resource bundle messageResourceBundle().use(appRoot() + "artist"); messageResourceBundle().use(appRoot() + "artists"); - messageResourceBundle().use(appRoot() + "messages"); messageResourceBundle().use(appRoot() + "mediaplayer"); - messageResourceBundle().use(appRoot() + "templates"); + messageResourceBundle().use(appRoot() + "messages"); + messageResourceBundle().use(appRoot() + "playlist"); messageResourceBundle().use(appRoot() + "release"); messageResourceBundle().use(appRoot() + "releases"); messageResourceBundle().use(appRoot() + "tracks"); + messageResourceBundle().use(appRoot() + "templates"); setTitle("LMS"); @@ -266,10 +268,24 @@ LmsApplication::handleAuthEvent(void) main->bindWidget("contents", mainStack); mainStack->addWidget(new Home()); - mainStack->addWidget(new Explore()); - mainStack->addWidget(new Wt::WText("PLAYLIST")); + + auto explore = new Explore(); + mainStack->addWidget(explore); + + auto playlist = new Playlist(); + mainStack->addWidget(playlist); mainStack->addWidget(new Wt::WText("SETTINGS")); + explore->tracksAdd.connect(std::bind([=] (std::vector tracks) + { + playlist->addTracks(tracks); + }, std::placeholders::_1)); + + explore->tracksPlay.connect(std::bind([=] (std::vector tracks) + { + playlist->playTracks(tracks); + }, std::placeholders::_1)); + // MediaPlayer auto player = new MediaPlayer(); main->bindWidget("player", player); diff --git a/src/ui/PlaylistView.cpp b/src/ui/PlaylistView.cpp new file mode 100644 index 00000000..93f32f7a --- /dev/null +++ b/src/ui/PlaylistView.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2018 Emeric Poupon + * + * This file is part of LMS. + * + * LMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LMS. If not, see . + */ + +#include +#include + +#include "PlaylistView.hpp" + +namespace UserInterface { + +Playlist::Playlist(Wt::WContainerWidget* parent) +: Wt::WContainerWidget(parent) +{ + auto t = new Wt::WTemplate(Wt::WString::tr("template-playlist"), this); + t->addFunction("tr", &Wt::WTemplate::Functions::tr); + + auto saveBtn = new Wt::WText(Wt::WString::tr("btn-playlist-save-btn"), Wt::XHTMLText); + t->bindWidget("save-btn", saveBtn); + + auto loadBtn = new Wt::WText(Wt::WString::tr("btn-playlist-load-btn"), Wt::XHTMLText); + t->bindWidget("load-btn", loadBtn); + + auto clearBtn = new Wt::WText(Wt::WString::tr("btn-playlist-clear-btn"), Wt::XHTMLText); + t->bindWidget("clear-btn", clearBtn); + + _entriesContainer = new Wt::WContainerWidget(); + t->bindWidget("entries", _entriesContainer); +} + +void +Playlist::addTracks(const std::vector& trackIds) +{ + for (auto trackId : trackIds) + std::cerr << "Adding track " << trackId << std::endl; +} + +void +Playlist::playTracks(const std::vector& trackIds) +{ + for (auto trackId : trackIds) + std::cerr << "Playing track " << trackId << std::endl; +} + +void +Playlist::refresh() +{ + +} + +} // namespace UserInterface + diff --git a/src/ui/PlaylistView.hpp b/src/ui/PlaylistView.hpp new file mode 100644 index 00000000..fa1f6863 --- /dev/null +++ b/src/ui/PlaylistView.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 Emeric Poupon + * + * This file is part of LMS. + * + * LMS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * LMS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LMS. If not, see . + */ + +#pragma once + +#include + +#include "database/Types.hpp" + +namespace UserInterface { + +class Playlist : public Wt::WContainerWidget +{ + public: + Playlist(Wt::WContainerWidget* parent = 0); + + void addTracks(const std::vector& trackIds); + void playTracks(const std::vector& trackIds); + + private: + void refresh(); + + Wt::WContainerWidget* _entriesContainer; +}; + +} // namespace UserInterface + diff --git a/src/ui/ReleaseView.cpp b/src/ui/ReleaseView.cpp index db6d597b..bd224e47 100644 --- a/src/ui/ReleaseView.cpp +++ b/src/ui/ReleaseView.cpp @@ -29,6 +29,7 @@ #include "utils/Utils.hpp" #include "LmsApplication.hpp" +#include "Filters.hpp" #include "ReleaseView.hpp" namespace UserInterface { @@ -112,11 +113,19 @@ Release::refresh() { auto playBtn = new Wt::WText(Wt::WString::tr("btn-release-play-btn"), Wt::XHTMLText); t->bindWidget("play-btn", playBtn); + playBtn->clicked().connect(std::bind([=] + { + releasePlay.emit(releaseId); + })); } { auto addBtn = new Wt::WText(Wt::WString::tr("btn-release-add-btn"), Wt::XHTMLText); t->bindWidget("add-btn", addBtn); + addBtn->clicked().connect(std::bind([=] + { + releaseAdd.emit(releaseId); + })); } auto tracksContainer = new Wt::WContainerWidget(); @@ -129,6 +138,8 @@ Release::refresh() for (auto track : tracks) { + auto trackId = track.id(); + Wt::WTemplate* entry = new Wt::WTemplate(Wt::WString::tr("template-release-entry"), tracksContainer); entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::PlainText); @@ -159,9 +170,17 @@ Release::refresh() auto playBtn = new Wt::WText(Wt::WString::tr("btn-release-play-btn"), Wt::XHTMLText); entry->bindWidget("play-btn", playBtn); + playBtn->clicked().connect(std::bind([=] + { + trackPlay.emit(trackId); + })); auto addBtn = new Wt::WText(Wt::WString::tr("btn-release-add-btn"), Wt::XHTMLText); entry->bindWidget("add-btn", addBtn); + addBtn->clicked().connect(std::bind([=] + { + trackAdd.emit(trackId); + })); } } diff --git a/src/ui/ReleaseView.hpp b/src/ui/ReleaseView.hpp index b51568cd..a11be0c2 100644 --- a/src/ui/ReleaseView.hpp +++ b/src/ui/ReleaseView.hpp @@ -21,15 +21,20 @@ #include -#include "Filters.hpp" - namespace UserInterface { +class Filters; class Release : public Wt::WContainerWidget { public: Release(Filters* filters, Wt::WContainerWidget* parent = 0); + Wt::Signal releaseAdd; + Wt::Signal releasePlay; + + Wt::Signal trackAdd; + Wt::Signal trackPlay; + private: void refresh(); diff --git a/src/ui/ReleasesView.cpp b/src/ui/ReleasesView.cpp index 6b5d148f..9c1bfdf7 100644 --- a/src/ui/ReleasesView.cpp +++ b/src/ui/ReleasesView.cpp @@ -30,6 +30,7 @@ #include "utils/Utils.hpp" #include "LmsApplication.hpp" +#include "Filters.hpp" #include "ReleasesView.hpp" namespace UserInterface { @@ -77,18 +78,20 @@ Releases::refresh(std::vector searchKeywords) for (auto release : releases) { + auto releaseId = release.id(); + Wt::WTemplate* entry = new Wt::WTemplate(Wt::WString::tr("template-releases-entry"), _releasesContainer); entry->addFunction("tr", Wt::WTemplate::Functions::tr); - Wt::WAnchor* coverAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(release.id()))); + Wt::WAnchor* coverAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(releaseId))); Wt::WImage* cover = new Wt::WImage(coverAnchor); - cover->setImageLink(SessionImageResource()->getReleaseUrl(release.id(), 128)); + cover->setImageLink(SessionImageResource()->getReleaseUrl(releaseId, 128)); // Some images may not be square cover->setWidth(128); entry->bindWidget("cover", coverAnchor); { - Wt::WAnchor* releaseAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(release.id()))); + Wt::WAnchor* releaseAnchor = new Wt::WAnchor(Wt::WLink(Wt::WLink::InternalPath, "/release/" + std::to_string(releaseId))); Wt::WText* releaseName = new Wt::WText(releaseAnchor); releaseName->setText(Wt::WString::fromUTF8(release->getName(), Wt::PlainText)); entry->bindWidget("release-name", releaseAnchor); @@ -110,9 +113,17 @@ Releases::refresh(std::vector searchKeywords) auto playBtn = new Wt::WText(Wt::WString::tr("btn-releases-play-btn"), Wt::XHTMLText); entry->bindWidget("play-btn", playBtn); + playBtn->clicked().connect(std::bind([=] + { + releasePlay.emit(releaseId); + })); auto addBtn = new Wt::WText(Wt::WString::tr("btn-releases-add-btn"), Wt::XHTMLText); entry->bindWidget("add-btn", addBtn); + addBtn->clicked().connect(std::bind([=] + { + releaseAdd.emit(releaseId); + })); } } diff --git a/src/ui/ReleasesView.hpp b/src/ui/ReleasesView.hpp index bf741678..7cae344d 100644 --- a/src/ui/ReleasesView.hpp +++ b/src/ui/ReleasesView.hpp @@ -21,15 +21,18 @@ #include -#include "Filters.hpp" - namespace UserInterface { +class Filters; + class Releases : public Wt::WContainerWidget { public: Releases(Filters* filters, Wt::WContainerWidget* parent = 0); + Wt::Signal releaseAdd; + Wt::Signal releasePlay; + private: void refresh(std::vector searchKeywords = std::vector()); diff --git a/src/ui/TracksView.cpp b/src/ui/TracksView.cpp index d995a078..24e8fe54 100644 --- a/src/ui/TracksView.cpp +++ b/src/ui/TracksView.cpp @@ -29,6 +29,7 @@ #include "utils/Utils.hpp" #include "LmsApplication.hpp" +#include "Filters.hpp" #include "TracksView.hpp" namespace UserInterface { @@ -76,6 +77,7 @@ Tracks::refresh(std::vector searchKeywords) for (auto track : tracks) { + auto trackId = track.id(); Wt::WTemplate* entry = new Wt::WTemplate(Wt::WString::tr("template-tracks-entry"), _tracksContainer); entry->bindString("name", Wt::WString::fromUTF8(track->getName()), Wt::PlainText); @@ -109,9 +111,17 @@ Tracks::refresh(std::vector searchKeywords) auto playBtn = new Wt::WText(Wt::WString::tr("btn-tracks-play-btn"), Wt::XHTMLText); entry->bindWidget("play-btn", playBtn); + playBtn->clicked().connect(std::bind([=] + { + trackPlay.emit(trackId); + })); auto addBtn = new Wt::WText(Wt::WString::tr("btn-tracks-add-btn"), Wt::XHTMLText); entry->bindWidget("add-btn", addBtn); + addBtn->clicked().connect(std::bind([=] + { + trackAdd.emit(trackId); + })); } } diff --git a/src/ui/TracksView.hpp b/src/ui/TracksView.hpp index 3210e666..516e4f9b 100644 --- a/src/ui/TracksView.hpp +++ b/src/ui/TracksView.hpp @@ -21,15 +21,17 @@ #include -#include "Filters.hpp" - namespace UserInterface { +class Filters; class Tracks : public Wt::WContainerWidget { public: Tracks(Filters* filters, Wt::WContainerWidget* parent = 0); + Wt::Signal trackAdd; + Wt::Signal trackPlay; + private: void refresh(std::vector searchKeywords = std::vector());