mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 04:20:27 +00:00
Qt: make grid view customizable by stylesheet
This commit is contained in:
parent
7bb23d15bd
commit
ca9952ceef
@ -6,21 +6,20 @@
|
||||
|
||||
/* http://www.informit.com/articles/article.aspx?p=1613548 */
|
||||
|
||||
ThumbnailDelegate::ThumbnailDelegate(QObject* parent) :
|
||||
QStyledItemDelegate(parent)
|
||||
ThumbnailDelegate::ThumbnailDelegate(const GridItem &gridItem, QObject* parent) :
|
||||
QStyledItemDelegate(parent), m_style(gridItem)
|
||||
{
|
||||
}
|
||||
|
||||
void ThumbnailDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex& index) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
const QWidget *widget = opt.widget;
|
||||
QStyle *style = widget->style();
|
||||
int margin = 11;
|
||||
int textMargin = 4;
|
||||
int textHeight = painter->fontMetrics().height() + margin + margin;
|
||||
int padding = m_style.padding;
|
||||
int textTopMargin = 4; /* Qt seemingly reports -4 the actual line height. */
|
||||
int textHeight = painter->fontMetrics().height() + padding + padding;
|
||||
QRect rect = opt.rect;
|
||||
QRect adjusted = rect.adjusted(margin, margin, -margin, -textHeight + textMargin);
|
||||
QRect adjusted = rect.adjusted(padding, padding, -padding, -textHeight + textTopMargin);
|
||||
QPixmap pixmap = index.data(PlaylistModel::THUMBNAIL).value<QPixmap>();
|
||||
|
||||
painter->save();
|
||||
@ -34,14 +33,14 @@ void ThumbnailDelegate::paint(QPainter* painter, const QStyleOptionViewItem &opt
|
||||
if (!pixmap.isNull())
|
||||
{
|
||||
QPixmap pixmapScaled = pixmap.scaled(adjusted.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
style->drawItemPixmap(painter, adjusted, Qt::AlignHCenter | Qt::AlignBottom, pixmapScaled);
|
||||
style->drawItemPixmap(painter, adjusted, Qt::AlignHCenter | m_style.thumbnailVerticalAlignmentFlag, pixmapScaled);
|
||||
}
|
||||
|
||||
/* draw the text */
|
||||
if (!opt.text.isEmpty())
|
||||
{
|
||||
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
||||
QRect textRect = QRect(rect.x() + margin, rect.y() + adjusted.height() - textMargin + margin, rect.width() - 2 * margin, textHeight);
|
||||
QRect textRect = QRect(rect.x() + padding, rect.y() + adjusted.height() - textTopMargin + padding, rect.width() - 2 * padding, textHeight);
|
||||
QString elidedText = painter->fontMetrics().elidedText(opt.text, opt.textElideMode, textRect.width(), Qt::TextShowMnemonic);
|
||||
|
||||
if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
|
||||
@ -95,7 +94,8 @@ void GridView::calculateRectsIfNecessary() const
|
||||
|
||||
const int maxWidth = viewport()->width();
|
||||
|
||||
switch (m_viewMode) {
|
||||
switch (m_viewMode)
|
||||
{
|
||||
case Anchored:
|
||||
{
|
||||
int columns = (maxWidth - m_spacing) / (m_size + m_spacing);
|
||||
@ -114,7 +114,6 @@ void GridView::calculateRectsIfNecessary() const
|
||||
m_rectForRow[row] = QRectF(x, y, m_size, m_size);
|
||||
x = nextX;
|
||||
}
|
||||
m_idealHeight = y + m_size + m_spacing;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -137,7 +136,6 @@ void GridView::calculateRectsIfNecessary() const
|
||||
m_rectForRow[row] = QRectF(x, y, m_size, m_size);
|
||||
x = nextX;
|
||||
}
|
||||
m_idealHeight = y + m_size + m_spacing;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -156,7 +154,7 @@ void GridView::calculateRectsIfNecessary() const
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_idealHeight = y + m_size + m_spacing;
|
||||
m_hashIsDirty = false;
|
||||
viewport()->update();
|
||||
}
|
||||
@ -407,3 +405,77 @@ void GridView::updateGeometries()
|
||||
|
||||
emit(visibleItemsChangedMaybe());
|
||||
}
|
||||
|
||||
QString GridView::getLayout() const
|
||||
{
|
||||
switch (m_viewMode)
|
||||
{
|
||||
case Simple:
|
||||
return "simple";
|
||||
case Anchored:
|
||||
return "anchored";
|
||||
case Centered:
|
||||
default:
|
||||
return "centered";
|
||||
}
|
||||
}
|
||||
|
||||
void GridView::setLayout(QString layout)
|
||||
{
|
||||
if (layout == "anchored")
|
||||
m_viewMode = Anchored;
|
||||
else if (layout == "centered")
|
||||
m_viewMode = Centered;
|
||||
else if (layout == "fixed")
|
||||
m_viewMode = Simple;
|
||||
}
|
||||
|
||||
int GridView::getSpacing() const
|
||||
{
|
||||
return m_spacing;
|
||||
}
|
||||
|
||||
void GridView::setSpacing(const int spacing)
|
||||
{
|
||||
m_spacing = spacing;
|
||||
}
|
||||
|
||||
GridItem::GridItem(QWidget* parent) : QWidget(parent)
|
||||
, thumbnailVerticalAlignmentFlag(Qt::AlignBottom)
|
||||
, padding(11)
|
||||
{
|
||||
}
|
||||
|
||||
int GridItem::getPadding() const
|
||||
{
|
||||
return padding;
|
||||
}
|
||||
|
||||
void GridItem::setPadding(const int value)
|
||||
{
|
||||
padding = value;
|
||||
}
|
||||
|
||||
QString GridItem::getThumbnailVerticalAlign() const
|
||||
{
|
||||
switch (thumbnailVerticalAlignmentFlag)
|
||||
{
|
||||
case Qt::AlignTop:
|
||||
return "top";
|
||||
case Qt::AlignVCenter:
|
||||
return "center";
|
||||
case Qt::AlignBottom:
|
||||
default:
|
||||
return "bottom";
|
||||
}
|
||||
}
|
||||
|
||||
void GridItem::setThumbnailVerticalAlign(const QString valign)
|
||||
{
|
||||
if (valign == "top")
|
||||
thumbnailVerticalAlignmentFlag = Qt::AlignTop;
|
||||
else if (valign == "center")
|
||||
thumbnailVerticalAlignmentFlag = Qt::AlignVCenter;
|
||||
else if (valign == "bottom")
|
||||
thumbnailVerticalAlignmentFlag = Qt::AlignBottom;
|
||||
}
|
||||
|
@ -4,19 +4,32 @@
|
||||
#include <QAbstractItemView>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
#define DEFAULT_GRID_ITEM_MARGIN 11
|
||||
#define DEFAULT_GRID_ITEM_THUMBNAIL_ALIGNMENT "bottom"
|
||||
#define DEFAULT_GRID_SPACING 7
|
||||
#define DEFAULT_GRID_LAYOUT "centered"
|
||||
|
||||
class GridItem;
|
||||
|
||||
class ThumbnailDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ThumbnailDelegate(QObject* parent = 0);
|
||||
ThumbnailDelegate(const GridItem &gridItem, QObject* parent = 0);
|
||||
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex& index) const;
|
||||
|
||||
private:
|
||||
const GridItem &m_style;
|
||||
};
|
||||
|
||||
class GridView : public QAbstractItemView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString layout READ getLayout WRITE setLayout DESIGNABLE true SCRIPTABLE true)
|
||||
Q_PROPERTY(int spacing READ getSpacing WRITE setSpacing DESIGNABLE true SCRIPTABLE true)
|
||||
|
||||
public:
|
||||
enum ViewMode
|
||||
{
|
||||
@ -35,6 +48,10 @@ public:
|
||||
void scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint);
|
||||
void setGridSize(const int newSize);
|
||||
void setviewMode(ViewMode mode);
|
||||
QString getLayout() const;
|
||||
void setLayout(QString layout);
|
||||
int getSpacing() const;
|
||||
void setSpacing(const int spacing);
|
||||
|
||||
signals:
|
||||
void visibleItemsChangedMaybe() const;
|
||||
@ -63,7 +80,7 @@ private:
|
||||
void refresh();
|
||||
|
||||
int m_size = 255;
|
||||
int m_spacing = 7;
|
||||
int m_spacing = DEFAULT_GRID_SPACING;
|
||||
QVector<QModelIndex> m_visibleIndexes;
|
||||
ViewMode m_viewMode = Centered;
|
||||
mutable int m_idealHeight;
|
||||
|
@ -431,5 +431,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"(
|
||||
GridView {
|
||||
background-color:rgb(25,25,25);
|
||||
selection-color: white;
|
||||
qproperty-layout: "fixed";
|
||||
}
|
||||
GridItem {
|
||||
qproperty-thumbnailvalign: "center";
|
||||
}
|
||||
)");
|
||||
|
@ -322,6 +322,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
,m_playlistThumbnailDownloadWasCanceled(false)
|
||||
,m_pendingDirScrollPath()
|
||||
,m_thumbnailTimer(new QTimer(this))
|
||||
,m_gridItem(this)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
QDir playlistDir(settings->paths.directory_playlist);
|
||||
@ -417,7 +418,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
m_tableView->setSortingEnabled(true);
|
||||
m_tableView->verticalHeader()->setVisible(false);
|
||||
|
||||
m_gridView->setItemDelegate(new ThumbnailDelegate(this));
|
||||
m_gridView->setItemDelegate(new ThumbnailDelegate(m_gridItem, this));
|
||||
m_gridView->setModel(m_proxyModel);
|
||||
|
||||
m_logWidget->setObjectName("logWidget");
|
||||
@ -566,6 +567,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
connect(m_thumbnailTimer, SIGNAL(timeout()), this, SLOT(updateVisibleItems()));
|
||||
connect(this, SIGNAL(updateThumbnails()), this, SLOT(updateVisibleItems()));
|
||||
|
||||
/* TODO: Handle scroll and resize differently. */
|
||||
connect(m_gridView, SIGNAL(visibleItemsChangedMaybe()), this, SLOT(startTimer()));
|
||||
|
||||
connect(m_gridView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(currentItemChanged(const QModelIndex&)));
|
||||
@ -1134,6 +1136,8 @@ void MainWindow::setTheme(Theme theme)
|
||||
{
|
||||
m_currentTheme = theme;
|
||||
|
||||
setDefaultCustomProperties();
|
||||
|
||||
switch(theme)
|
||||
{
|
||||
case THEME_SYSTEM_DEFAULT:
|
||||
@ -1159,6 +1163,14 @@ void MainWindow::setTheme(Theme theme)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setDefaultCustomProperties()
|
||||
{
|
||||
m_gridView->setLayout(QString(DEFAULT_GRID_LAYOUT));
|
||||
m_gridView->setSpacing(DEFAULT_GRID_SPACING);
|
||||
m_gridItem.setThumbnailVerticalAlign(QString(DEFAULT_GRID_ITEM_THUMBNAIL_ALIGNMENT));
|
||||
m_gridItem.setPadding(DEFAULT_GRID_ITEM_MARGIN);
|
||||
}
|
||||
|
||||
void MainWindow::changeThumbnailType(ThumbnailType type)
|
||||
{
|
||||
m_playlistModel->setThumbnailType(type);
|
||||
|
@ -271,6 +271,26 @@ public slots:
|
||||
void appendMessage(const QString& text);
|
||||
};
|
||||
|
||||
/* Used to store styling since delegates don't inherit QWidget. */
|
||||
class GridItem : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString thumbnailvalign READ getThumbnailVerticalAlign WRITE setThumbnailVerticalAlign)
|
||||
Q_PROPERTY(int padding READ getPadding WRITE setPadding)
|
||||
|
||||
public:
|
||||
GridItem(QWidget* parent);
|
||||
|
||||
Qt::AlignmentFlag thumbnailVerticalAlignmentFlag;
|
||||
int padding;
|
||||
|
||||
int getPadding() const;
|
||||
void setPadding(const int value);
|
||||
QString getThumbnailVerticalAlign() const;
|
||||
void setThumbnailVerticalAlign(const QString valign);
|
||||
};
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -347,6 +367,7 @@ public:
|
||||
QString getSpecialPlaylistPath(SpecialPlaylist playlist);
|
||||
QVector<QPair<QString, QString> > getPlaylists();
|
||||
QString getScrubbedString(QString str);
|
||||
void setDefaultCustomProperties();
|
||||
|
||||
signals:
|
||||
void thumbnailChanged(const QPixmap &pixmap);
|
||||
@ -574,6 +595,7 @@ private:
|
||||
QString m_pendingDirScrollPath;
|
||||
|
||||
QTimer *m_thumbnailTimer;
|
||||
GridItem m_gridItem;
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
Loading…
x
Reference in New Issue
Block a user