mirror of
https://github.com/libretro/RetroArch
synced 2025-04-03 10:21:31 +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 */
|
/* http://www.informit.com/articles/article.aspx?p=1613548 */
|
||||||
|
|
||||||
ThumbnailDelegate::ThumbnailDelegate(QObject* parent) :
|
ThumbnailDelegate::ThumbnailDelegate(const GridItem &gridItem, QObject* parent) :
|
||||||
QStyledItemDelegate(parent)
|
QStyledItemDelegate(parent), m_style(gridItem)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThumbnailDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex& index) const
|
void ThumbnailDelegate::paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
QStyleOptionViewItem opt = option;
|
QStyleOptionViewItem opt = option;
|
||||||
const QWidget *widget = opt.widget;
|
const QWidget *widget = opt.widget;
|
||||||
QStyle *style = widget->style();
|
QStyle *style = widget->style();
|
||||||
int margin = 11;
|
int padding = m_style.padding;
|
||||||
int textMargin = 4;
|
int textTopMargin = 4; /* Qt seemingly reports -4 the actual line height. */
|
||||||
int textHeight = painter->fontMetrics().height() + margin + margin;
|
int textHeight = painter->fontMetrics().height() + padding + padding;
|
||||||
QRect rect = opt.rect;
|
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>();
|
QPixmap pixmap = index.data(PlaylistModel::THUMBNAIL).value<QPixmap>();
|
||||||
|
|
||||||
painter->save();
|
painter->save();
|
||||||
@ -34,14 +33,14 @@ void ThumbnailDelegate::paint(QPainter* painter, const QStyleOptionViewItem &opt
|
|||||||
if (!pixmap.isNull())
|
if (!pixmap.isNull())
|
||||||
{
|
{
|
||||||
QPixmap pixmapScaled = pixmap.scaled(adjusted.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
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 */
|
/* draw the text */
|
||||||
if (!opt.text.isEmpty())
|
if (!opt.text.isEmpty())
|
||||||
{
|
{
|
||||||
QPalette::ColorGroup cg = opt.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
|
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);
|
QString elidedText = painter->fontMetrics().elidedText(opt.text, opt.textElideMode, textRect.width(), Qt::TextShowMnemonic);
|
||||||
|
|
||||||
if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
|
if (cg == QPalette::Normal && !(opt.state & QStyle::State_Active))
|
||||||
@ -95,7 +94,8 @@ void GridView::calculateRectsIfNecessary() const
|
|||||||
|
|
||||||
const int maxWidth = viewport()->width();
|
const int maxWidth = viewport()->width();
|
||||||
|
|
||||||
switch (m_viewMode) {
|
switch (m_viewMode)
|
||||||
|
{
|
||||||
case Anchored:
|
case Anchored:
|
||||||
{
|
{
|
||||||
int columns = (maxWidth - m_spacing) / (m_size + m_spacing);
|
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);
|
m_rectForRow[row] = QRectF(x, y, m_size, m_size);
|
||||||
x = nextX;
|
x = nextX;
|
||||||
}
|
}
|
||||||
m_idealHeight = y + m_size + m_spacing;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -137,7 +136,6 @@ void GridView::calculateRectsIfNecessary() const
|
|||||||
m_rectForRow[row] = QRectF(x, y, m_size, m_size);
|
m_rectForRow[row] = QRectF(x, y, m_size, m_size);
|
||||||
x = nextX;
|
x = nextX;
|
||||||
}
|
}
|
||||||
m_idealHeight = y + m_size + m_spacing;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -156,7 +154,7 @@ void GridView::calculateRectsIfNecessary() const
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
m_idealHeight = y + m_size + m_spacing;
|
||||||
m_hashIsDirty = false;
|
m_hashIsDirty = false;
|
||||||
viewport()->update();
|
viewport()->update();
|
||||||
}
|
}
|
||||||
@ -407,3 +405,77 @@ void GridView::updateGeometries()
|
|||||||
|
|
||||||
emit(visibleItemsChangedMaybe());
|
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 <QAbstractItemView>
|
||||||
#include <QStyledItemDelegate>
|
#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
|
class ThumbnailDelegate : public QStyledItemDelegate
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ThumbnailDelegate(QObject* parent = 0);
|
ThumbnailDelegate(const GridItem &gridItem, QObject* parent = 0);
|
||||||
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex& index) const;
|
void paint(QPainter* painter, const QStyleOptionViewItem &option, const QModelIndex& index) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const GridItem &m_style;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GridView : public QAbstractItemView
|
class GridView : public QAbstractItemView
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
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:
|
public:
|
||||||
enum ViewMode
|
enum ViewMode
|
||||||
{
|
{
|
||||||
@ -35,6 +48,10 @@ public:
|
|||||||
void scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint);
|
void scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint);
|
||||||
void setGridSize(const int newSize);
|
void setGridSize(const int newSize);
|
||||||
void setviewMode(ViewMode mode);
|
void setviewMode(ViewMode mode);
|
||||||
|
QString getLayout() const;
|
||||||
|
void setLayout(QString layout);
|
||||||
|
int getSpacing() const;
|
||||||
|
void setSpacing(const int spacing);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void visibleItemsChangedMaybe() const;
|
void visibleItemsChangedMaybe() const;
|
||||||
@ -63,7 +80,7 @@ private:
|
|||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
int m_size = 255;
|
int m_size = 255;
|
||||||
int m_spacing = 7;
|
int m_spacing = DEFAULT_GRID_SPACING;
|
||||||
QVector<QModelIndex> m_visibleIndexes;
|
QVector<QModelIndex> m_visibleIndexes;
|
||||||
ViewMode m_viewMode = Centered;
|
ViewMode m_viewMode = Centered;
|
||||||
mutable int m_idealHeight;
|
mutable int m_idealHeight;
|
||||||
|
@ -431,5 +431,9 @@ static const QString qt_theme_dark_stylesheet = QStringLiteral(R"(
|
|||||||
GridView {
|
GridView {
|
||||||
background-color:rgb(25,25,25);
|
background-color:rgb(25,25,25);
|
||||||
selection-color: white;
|
selection-color: white;
|
||||||
|
qproperty-layout: "fixed";
|
||||||
|
}
|
||||||
|
GridItem {
|
||||||
|
qproperty-thumbnailvalign: "center";
|
||||||
}
|
}
|
||||||
)");
|
)");
|
||||||
|
@ -322,6 +322,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
,m_playlistThumbnailDownloadWasCanceled(false)
|
,m_playlistThumbnailDownloadWasCanceled(false)
|
||||||
,m_pendingDirScrollPath()
|
,m_pendingDirScrollPath()
|
||||||
,m_thumbnailTimer(new QTimer(this))
|
,m_thumbnailTimer(new QTimer(this))
|
||||||
|
,m_gridItem(this)
|
||||||
{
|
{
|
||||||
settings_t *settings = config_get_ptr();
|
settings_t *settings = config_get_ptr();
|
||||||
QDir playlistDir(settings->paths.directory_playlist);
|
QDir playlistDir(settings->paths.directory_playlist);
|
||||||
@ -417,7 +418,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
m_tableView->setSortingEnabled(true);
|
m_tableView->setSortingEnabled(true);
|
||||||
m_tableView->verticalHeader()->setVisible(false);
|
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_gridView->setModel(m_proxyModel);
|
||||||
|
|
||||||
m_logWidget->setObjectName("logWidget");
|
m_logWidget->setObjectName("logWidget");
|
||||||
@ -566,6 +567,7 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||||||
connect(m_thumbnailTimer, SIGNAL(timeout()), this, SLOT(updateVisibleItems()));
|
connect(m_thumbnailTimer, SIGNAL(timeout()), this, SLOT(updateVisibleItems()));
|
||||||
connect(this, SIGNAL(updateThumbnails()), 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(visibleItemsChangedMaybe()), this, SLOT(startTimer()));
|
||||||
|
|
||||||
connect(m_gridView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(currentItemChanged(const QModelIndex&)));
|
connect(m_gridView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(currentItemChanged(const QModelIndex&)));
|
||||||
@ -1134,6 +1136,8 @@ void MainWindow::setTheme(Theme theme)
|
|||||||
{
|
{
|
||||||
m_currentTheme = theme;
|
m_currentTheme = theme;
|
||||||
|
|
||||||
|
setDefaultCustomProperties();
|
||||||
|
|
||||||
switch(theme)
|
switch(theme)
|
||||||
{
|
{
|
||||||
case THEME_SYSTEM_DEFAULT:
|
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)
|
void MainWindow::changeThumbnailType(ThumbnailType type)
|
||||||
{
|
{
|
||||||
m_playlistModel->setThumbnailType(type);
|
m_playlistModel->setThumbnailType(type);
|
||||||
|
@ -271,6 +271,26 @@ public slots:
|
|||||||
void appendMessage(const QString& text);
|
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
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -347,6 +367,7 @@ public:
|
|||||||
QString getSpecialPlaylistPath(SpecialPlaylist playlist);
|
QString getSpecialPlaylistPath(SpecialPlaylist playlist);
|
||||||
QVector<QPair<QString, QString> > getPlaylists();
|
QVector<QPair<QString, QString> > getPlaylists();
|
||||||
QString getScrubbedString(QString str);
|
QString getScrubbedString(QString str);
|
||||||
|
void setDefaultCustomProperties();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void thumbnailChanged(const QPixmap &pixmap);
|
void thumbnailChanged(const QPixmap &pixmap);
|
||||||
@ -574,6 +595,7 @@ private:
|
|||||||
QString m_pendingDirScrollPath;
|
QString m_pendingDirScrollPath;
|
||||||
|
|
||||||
QTimer *m_thumbnailTimer;
|
QTimer *m_thumbnailTimer;
|
||||||
|
GridItem m_gridItem;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event);
|
void closeEvent(QCloseEvent *event);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user