Display an indicator next to each playlist item showing its position in the queue
This commit is contained in:
parent
41183107d2
commit
f750ac1351
|
@ -161,6 +161,9 @@ QVariant Playlist::data(const QModelIndex& index, int role) const {
|
|||
case Role_StopAfter:
|
||||
return stop_after_.isValid() && stop_after_.row() == index.row();
|
||||
|
||||
case Role_QueuePosition:
|
||||
return queue_->PositionOf(index);
|
||||
|
||||
case Qt::EditRole:
|
||||
case Qt::ToolTipRole:
|
||||
case Qt::DisplayRole: {
|
||||
|
|
|
@ -83,6 +83,7 @@ class Playlist : public QAbstractListModel {
|
|||
Role_IsCurrent = Qt::UserRole + 1,
|
||||
Role_IsPaused,
|
||||
Role_StopAfter,
|
||||
Role_QueuePosition,
|
||||
};
|
||||
|
||||
static const char* kRowsMimetype;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "playlistdelegates.h"
|
||||
#include "queue.h"
|
||||
#include "core/utilities.h"
|
||||
#include "library/librarybackend.h"
|
||||
#include "widgets/trackslider.h"
|
||||
|
@ -27,11 +28,72 @@
|
|||
#include <QHelpEvent>
|
||||
#include <QHeaderView>
|
||||
#include <QScrollBar>
|
||||
#include <QLinearGradient>
|
||||
|
||||
const int PlaylistDelegateBase::kMinHeight = 19;
|
||||
|
||||
QueuedItemDelegate::QueuedItemDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void QueuedItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
||||
QStyledItemDelegate::paint(painter, option, index);
|
||||
|
||||
if (index.column() == Playlist::Column_Title ||
|
||||
index.column() == Queue::Column_CombinedArtistTitle) {
|
||||
const int queue_pos = index.data(Playlist::Role_QueuePosition).toInt();
|
||||
if (queue_pos != -1) {
|
||||
QFont smaller = option.font;
|
||||
smaller.setPointSize(smaller.pointSize() - 2);
|
||||
smaller.setBold(true);
|
||||
|
||||
const int kQueueBoxBorder = 1;
|
||||
const int kQueueBoxCornerRadius = 3;
|
||||
const int kQueueBoxLength = QFontMetrics(smaller).width('7') * 4;
|
||||
const QRgb kQueueBoxGradientColor1 = qRgb(102, 150, 227);
|
||||
const QRgb kQueueBoxGradientColor2 = qRgb(77, 121, 200);
|
||||
const int kQueueOpacitySteps = 10;
|
||||
const float kQueueOpacityLowerBound = 0.4;
|
||||
|
||||
QRect rect(option.rect);
|
||||
rect.setLeft(rect.right() - kQueueBoxLength - kQueueBoxBorder);
|
||||
rect.setWidth(kQueueBoxLength);
|
||||
rect.setTop(rect.top() + kQueueBoxBorder);
|
||||
rect.setBottom(rect.bottom() - kQueueBoxBorder - 1);
|
||||
|
||||
QRect text_rect(rect);
|
||||
text_rect.setBottom(text_rect.bottom() + 1);
|
||||
|
||||
QLinearGradient gradient(rect.topLeft(), rect.bottomLeft());
|
||||
gradient.setColorAt(0.0, kQueueBoxGradientColor1);
|
||||
gradient.setColorAt(1.0, kQueueBoxGradientColor2);
|
||||
|
||||
// Turn on antialisaing
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
float opacity = kQueueOpacitySteps - qMin(kQueueOpacitySteps, queue_pos);
|
||||
opacity /= kQueueOpacitySteps;
|
||||
opacity *= 1.0 - kQueueOpacityLowerBound;
|
||||
opacity += kQueueOpacityLowerBound;
|
||||
painter->setOpacity(opacity);
|
||||
|
||||
// Draw the box
|
||||
painter->setPen(QPen(Qt::white, 1));
|
||||
painter->setBrush(gradient);
|
||||
painter->drawRoundedRect(rect, kQueueBoxCornerRadius, kQueueBoxCornerRadius);
|
||||
|
||||
// Draw the text
|
||||
painter->setFont(smaller);
|
||||
painter->drawText(rect, Qt::AlignCenter, QString::number(queue_pos+1));
|
||||
|
||||
painter->setOpacity(1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlaylistDelegateBase::PlaylistDelegateBase(QTreeView* view, const QString& suffix)
|
||||
: QStyledItemDelegate(view),
|
||||
: QueuedItemDelegate(view),
|
||||
view_(view),
|
||||
suffix_(suffix)
|
||||
{
|
||||
|
@ -67,18 +129,19 @@ QString PlaylistDelegateBase::displayText(const QVariant& value, const QLocale&)
|
|||
}
|
||||
|
||||
QSize PlaylistDelegateBase::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const {
|
||||
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
||||
QSize size = QueuedItemDelegate::sizeHint(option, index);
|
||||
if (size.height() < kMinHeight)
|
||||
size.setHeight(kMinHeight);
|
||||
return size;
|
||||
}
|
||||
|
||||
void PlaylistDelegateBase::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
|
||||
QStyledItemDelegate::paint(painter, Adjusted(option, index), index);
|
||||
QueuedItemDelegate::paint(painter, Adjusted(option, index), index);
|
||||
|
||||
QPoint top_left(-view_->horizontalScrollBar()->value(),
|
||||
-view_->verticalScrollBar()->value());
|
||||
|
||||
// Stop after indicator
|
||||
if (view_->header()->logicalIndexAt(top_left) == index.column()) {
|
||||
if (index.data(Playlist::Role_StopAfter).toBool()) {
|
||||
QColor color(Qt::white);
|
||||
|
|
|
@ -25,7 +25,13 @@
|
|||
#include <QStringListModel>
|
||||
#include <QCompleter>
|
||||
|
||||
class PlaylistDelegateBase : public QStyledItemDelegate {
|
||||
class QueuedItemDelegate : public QStyledItemDelegate {
|
||||
public:
|
||||
QueuedItemDelegate(QObject* parent);
|
||||
void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
|
||||
};
|
||||
|
||||
class PlaylistDelegateBase : public QueuedItemDelegate {
|
||||
Q_OBJECT
|
||||
public:
|
||||
PlaylistDelegateBase(QTreeView* view, const QString& suffix = QString());
|
||||
|
|
|
@ -101,20 +101,28 @@ int Queue::columnCount(const QModelIndex &parent) const {
|
|||
}
|
||||
|
||||
QVariant Queue::data(const QModelIndex& proxy_index, int role) const {
|
||||
if (role != Qt::DisplayRole)
|
||||
return QVariant();
|
||||
switch (role) {
|
||||
case Playlist::Role_QueuePosition:
|
||||
return proxy_index.row();
|
||||
|
||||
QModelIndex source_index = source_indexes_[proxy_index.row()];
|
||||
case Qt::DisplayRole: {
|
||||
QModelIndex source_index = source_indexes_[proxy_index.row()];
|
||||
|
||||
if (proxy_index.column() == Column_CombinedArtistTitle) {
|
||||
const QString artist = source_index.sibling(source_index.row(), Playlist::Column_Artist).data().toString();
|
||||
const QString title = source_index.sibling(source_index.row(), Playlist::Column_Title).data().toString();
|
||||
if (proxy_index.column() == Column_CombinedArtistTitle) {
|
||||
const QString artist = source_index.sibling(source_index.row(), Playlist::Column_Artist).data().toString();
|
||||
const QString title = source_index.sibling(source_index.row(), Playlist::Column_Title).data().toString();
|
||||
|
||||
if (artist.isEmpty())
|
||||
return title;
|
||||
return artist + " - " + title;
|
||||
if (artist.isEmpty())
|
||||
return title;
|
||||
return artist + " - " + title;
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
QModelIndex source_index = source_indexes_[proxy_index.row()];
|
||||
return source_index.data(role);
|
||||
}
|
||||
}
|
||||
return source_index.data(role);
|
||||
}
|
||||
|
||||
void Queue::ToggleTracks(const QModelIndexList &source_indexes) {
|
||||
|
@ -135,3 +143,7 @@ void Queue::ToggleTracks(const QModelIndexList &source_indexes) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
int Queue::PositionOf(const QModelIndex& source_index) const {
|
||||
return mapFromSource(source_index).row();
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
};
|
||||
|
||||
bool is_empty() const;
|
||||
int PositionOf(const QModelIndex& source_index) const;
|
||||
|
||||
QModelIndex TakeNext();
|
||||
void ToggleTracks(const QModelIndexList& source_indexes);
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlistdelegates.h"
|
||||
#include "playlistmanager.h"
|
||||
#include "queue.h"
|
||||
#include "queuemanager.h"
|
||||
|
@ -27,6 +28,8 @@ QueueManager::QueueManager(QWidget *parent)
|
|||
current_playlist_(NULL)
|
||||
{
|
||||
ui_->setupUi(this);
|
||||
|
||||
ui_->list->setItemDelegate(new QueuedItemDelegate(this));
|
||||
}
|
||||
|
||||
QueueManager::~QueueManager() {
|
||||
|
|
|
@ -21,7 +21,17 @@
|
|||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QListView" name="list"/>
|
||||
<widget class="QListView" name="list">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="uniformItemSizes">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
|
|
Loading…
Reference in New Issue