diff --git a/src/ui/audio/PlayQueue.cpp b/src/ui/audio/PlayQueue.cpp index 3e17d9ef..9c4beb4b 100644 --- a/src/ui/audio/PlayQueue.cpp +++ b/src/ui/audio/PlayQueue.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include "resource/CoverResource.hpp" @@ -34,6 +35,7 @@ #include "PlayQueue.hpp" static const int CoverRole = Wt::UserRole + 1; +static const int NameRole = Wt::UserRole + 2; namespace { @@ -47,17 +49,20 @@ namespace { Wt::WModelIndex index1 = model->index(row1, i); Wt::WModelIndex index2 = model->index(row2, i); + // swap data associated with standard roles { auto tmp = model->itemData(index1); // 1 -> tmp model->setItemData(index1, model->itemData(index2)); // 2 -> 1 model->setItemData(index2, tmp); // tmp-> 2 } - // Workaround, do the same thing for the CoverRole + // swap data associated with our custom roles + const std::vector(roles) = {CoverRole, NameRole}; + BOOST_FOREACH(int role, roles) { - auto tmp = model->data(index1, CoverRole); - model->setData(index1, model->data(index2, CoverRole), CoverRole); - model->setData(index2, tmp, CoverRole); + auto tmp = model->data(index1, role); + model->setData(index1, model->data(index2, role), role); + model->setData(index2, tmp, role); } } } @@ -68,10 +73,8 @@ namespace UserInterface { enum ColumnId { COLUMN_ID_TRACK_ID = 0, - COLUMN_ID_POS = 1, - COLUMN_ID_COVER = 2, - COLUMN_ID_NAME = 3, - COLUMN_ID_DURATION = 4 + COLUMN_ID_COVER = 1, + COLUMN_ID_NAME = 2, }; static const int trackPosInvalid = -1; @@ -227,6 +230,12 @@ TrackSelector::setSize(std::size_t size) refreshPositions(); } +struct Name +{ + Wt::WString track; + Wt::WString artist; +}; + class PlayQueueItemDelegate : public Wt::WItemDelegate { public: @@ -249,8 +258,43 @@ class PlayQueueItemDelegate : public Wt::WItemDelegate image->setImageLink(Wt::WLink(resource)); + // Apply style if any + Wt::WString styleClass = Wt::asString(index.data(Wt::StyleClassRole)); + + // Apply selection style if any + if (flags & Wt::RenderSelected) + styleClass += " " + Wt::WApplication::instance()->theme()->activeClass(); + + image->setStyleClass(styleClass); + res = image; res->setObjectName("z"); + + } + else if (!index.data(NameRole).empty()) + { + Name name = boost::any_cast(index.data(NameRole)); + + Wt::WContainerWidget *container = new Wt::WContainerWidget(); + Wt::WText* track = new Wt::WText(name.track, Wt::PlainText, container); + Wt::WText* artist = new Wt::WText(name.artist, Wt::PlainText, container); + + artist->setInline(false); + track->setInline(false); + + artist->setStyleClass("playqueue-artist"); + track->setStyleClass("playqueue-track"); + + // Apply style if any + Wt::WString styleClass = Wt::asString(index.data(Wt::StyleClassRole)); + + // Apply selection style if any + if (flags & Wt::RenderSelected) + styleClass += " " + Wt::WApplication::instance()->theme()->activeClass(); + + container->setStyleClass(styleClass); + + res = container; } else res = Wt::WItemDelegate::update(widget, index, flags); @@ -269,14 +313,12 @@ _db(db), _curPlayedTrackPos(trackPosInvalid), _trackSelector(new TrackSelector()) { - _model = new Wt::WStandardItemModel(0, 5, this); + _model = new Wt::WStandardItemModel(0, 3, this); // 0 Column is hidden (track id) _model->setHeaderData(COLUMN_ID_TRACK_ID, Wt::WString("#")); - _model->setHeaderData(COLUMN_ID_POS, Wt::WString("#")); _model->setHeaderData(COLUMN_ID_COVER, Wt::WString("Cover")); _model->setHeaderData(COLUMN_ID_NAME, Wt::WString("Track")); - _model->setHeaderData(COLUMN_ID_DURATION, Wt::WString("Duration")); this->setModel(_model); this->setSelectionMode(Wt::ExtendedSelection); @@ -284,8 +326,9 @@ _trackSelector(new TrackSelector()) this->setAlternatingRowColors(true); this->setRowHeight(64); this->setColumnWidth(COLUMN_ID_COVER, 64); - this->setColumnWidth(COLUMN_ID_POS, 50); - this->setColumnWidth(COLUMN_ID_DURATION, 75); + this->setColumnWidth(COLUMN_ID_NAME, 240); + + this->setLayoutSizeAware(true); this->setColumnHidden(COLUMN_ID_TRACK_ID, true); @@ -310,6 +353,14 @@ _trackSelector(new TrackSelector()) } +void +PlayQueue::layoutSizeChanged (int width, int height) +{ + std::size_t coverColumnSize = this->columnWidth(COLUMN_ID_COVER).toPixels(); + // Set the remaining size for the name column + this->setColumnWidth(COLUMN_ID_NAME, width - coverColumnSize - (7 * 2) - 2); +} + void PlayQueue::setShuffle(bool enable) { @@ -358,10 +409,12 @@ PlayQueue::addTracks(const std::vector& trackIds) _model->insertRows(dataRow, 1); _model->setData(dataRow, COLUMN_ID_TRACK_ID, track.id(), Wt::UserRole); - _model->setData(dataRow, COLUMN_ID_POS, dataRow + 1); _model->setData(dataRow, COLUMN_ID_COVER, track->hasCover() ? track->getPath() : "none", CoverRole); - _model->setData(dataRow, COLUMN_ID_NAME, track->getArtistName() + " - " + track->getName()); - _model->setData(dataRow, COLUMN_ID_DURATION, track->getDuration()); + + Name name; + name.track = Wt::WString::fromUTF8(track->getName()); + name.artist = Wt::WString::fromUTF8(track->getArtistName()); + _model->setData(dataRow, COLUMN_ID_NAME, name, NameRole); } } @@ -453,16 +506,12 @@ PlayQueue::setPlayingTrackPos(int newRowPos) // calling the update method of our custom item delegate gives bad results if (oldRowPos >= 0) { - _model->setData(oldRowPos, COLUMN_ID_POS, boost::any(), Wt::StyleClassRole); _model->setData(oldRowPos, COLUMN_ID_NAME, boost::any(), Wt::StyleClassRole); - _model->setData(oldRowPos, COLUMN_ID_DURATION, boost::any(), Wt::StyleClassRole); } if (newRowPos >= 0) { - _model->setData(newRowPos, COLUMN_ID_POS, "playqueue-playing", Wt::StyleClassRole); _model->setData(newRowPos, COLUMN_ID_NAME, "playqueue-playing", Wt::StyleClassRole); - _model->setData(newRowPos, COLUMN_ID_DURATION, "playqueue-playing", Wt::StyleClassRole); } } diff --git a/src/ui/audio/PlayQueue.hpp b/src/ui/audio/PlayQueue.hpp index 18b1d918..b82280b6 100644 --- a/src/ui/audio/PlayQueue.hpp +++ b/src/ui/audio/PlayQueue.hpp @@ -64,6 +64,8 @@ class PlayQueue : public Wt::WTableView private: + void layoutSizeChanged (int width, int height); + bool readTrack(int rowId); void setPlayingTrackPos(int newRowPos); void renumber(int firstId, int lastId); diff --git a/src/ui/docroot/css/lms.css b/src/ui/docroot/css/lms.css index 1b5ed3f8..fb82490b 100644 --- a/src/ui/docroot/css/lms.css +++ b/src/ui/docroot/css/lms.css @@ -15,9 +15,28 @@ div.contents { } .playqueue-playing { + background-color: rgba(202, 167, 66, 1); +} + +.Wt-tableview .playqueue-playing { + color: #FFF; +} + +.Wt-tableview .Wt-tv-contents.Wt-striped div.playqueue-playing:nth-child(odd) { + background-color: rgba(202, 167, 66, 1); +} + +.playqueue-track { + margin-top: 12px; + line-height: normal; font-weight: bold; } +.playqueue-artist { + line-height: normal; + font-style: italic; +} + .mediaplayer { background-color: #ccc; border-radius: 10px;