File indexing completed on 2024-04-14 03:59:03

0001 /*
0002     SPDX-FileCopyrightText: 2012 Mathias Kraus <k.hias@gmx.de>
0003     SPDX-FileCopyrightText: 2009-2012 Stefan Majewsky <majewsky@gmx.net>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #include "playerselector.h"
0009 #include "playerselectoritem.h"
0010 #include "playersettings.h"
0011 
0012 #include <QPointer>
0013 #include <QAbstractItemView>
0014 #include <QApplication>
0015 #include <QFont>
0016 #include <QListWidget>
0017 #include <QPainter>
0018 #include <QPushButton>
0019 #include <QScrollBar>
0020 #include <QVBoxLayout>
0021 #include <QSvgRenderer>
0022 #include <QStandardPaths>
0023 #include <KConfig>
0024 #include <KLocalizedString>
0025 #include <QIcon>
0026 #include <KConfigGroup>
0027 //PlayerSelectorDelegate declaration
0028 #include <QStyledItemDelegate>
0029 class PlayerSelectorDelegate : public QStyledItemDelegate
0030 {
0031 public:
0032     explicit PlayerSelectorDelegate(QObject* parent = nullptr);
0033     void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override;
0034     ///@note The implementation is independent of @a option and @a index.
0035     QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override;
0036 };
0037 
0038 //BEGIN PlayerSelector
0039 
0040 struct PlayerSelector::Private
0041 {
0042     PlayerSelector* q;
0043     PlayerSettings* m_playerSettings;
0044     Options m_options;
0045     QListWidget* m_list;
0046     void fillList();
0047 
0048     Private(PlayerSettings* playerSettings, Options options, PlayerSelector* q) : q(q), m_playerSettings(playerSettings), m_options(options) {}
0049 };
0050 
0051 PlayerSelector::PlayerSelector(PlayerSettings* playerSettings, Options options, QWidget* parent)
0052     : QWidget(parent)
0053     , d(new Private(playerSettings, options, this))
0054 {
0055     d->m_list = new QListWidget(this);
0056     d->m_list->setSelectionMode(QAbstractItemView::NoSelection);
0057     d->m_list->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
0058     //load themes from provider
0059     d->fillList();
0060     //setup appearance of the theme list (min. size = 4 items)
0061     auto* delegate = new PlayerSelectorDelegate(d->m_list);
0062     const QSize itemSizeHint = delegate->sizeHint(QStyleOptionViewItem(), QModelIndex());
0063     const QSize scrollBarSizeHint = d->m_list->verticalScrollBar()->sizeHint();
0064     d->m_list->setMinimumSize(static_cast<int>(itemSizeHint.width() + 2 * scrollBarSizeHint.width()), static_cast<int>(3.3 * itemSizeHint.height()));
0065     //setup main layout
0066     auto* layout = new QVBoxLayout(this);
0067     layout->setContentsMargins(0, 0, 0, 0);
0068     layout->addWidget(d->m_list);
0069 }
0070 
0071 PlayerSelector::~PlayerSelector()
0072 {
0073     delete d;
0074 }
0075 
0076 void PlayerSelector::Private::fillList()
0077 {
0078     m_list->clear();
0079 
0080     QModelIndex modelIndex;
0081     PlayerSelectorItem* playerSelectorItem;
0082 
0083     QSvgRenderer renderer;
0084     const qreal dpr = qApp->devicePixelRatio();
0085     const int pixmapSize = 64 * dpr;
0086 
0087     QStringList playerIDs = m_playerSettings->playerIDs();
0088 
0089     for(int i = 0; i < playerIDs.count(); i++)
0090     {
0091         auto* item = new QListWidgetItem(playerIDs[i], m_list);
0092 
0093         item->setFlags(item->flags() & ~Qt::ItemIsSelectable);
0094 
0095         playerSelectorItem = new PlayerSelectorItem(playerIDs[i], m_playerSettings, m_list);
0096 
0097         renderer.load(QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("players/%1").arg(m_playerSettings->playerGraphicsFile(playerIDs[i]))));
0098         QPixmap pixmap(QSize(pixmapSize, pixmapSize));
0099         pixmap.fill(QColor(0, 0, 0, 0));
0100         QPainter pixPainter(&pixmap);
0101         renderer.render(&pixPainter, QStringLiteral("player_0"));
0102         pixmap.setDevicePixelRatio(dpr);
0103         playerSelectorItem->setPlayerPreviewPixmap(pixmap);
0104 
0105         KConfig desktopFile(QStandardPaths::locate(QStandardPaths::AppDataLocation, QStringLiteral("players/%1").arg(playerIDs[i])), KConfig::SimpleConfig);
0106         auto author = desktopFile.group(QStringLiteral("KGameTheme")).readEntry<QString>("Author", QStringLiteral(""));
0107         QString authorEmail = QStringLiteral("<a href=\"mailto:%1\">%1</a>").arg(desktopFile.group(QStringLiteral("KGameTheme")).readEntry<QString>("AuthorEmail", QStringLiteral("")));
0108         //TODO: QString description = desktopFile.group(QStringLiteral("KGameTheme")).readEntry<QString>("Description", "");
0109         playerSelectorItem->setPlayerAuthor(author, authorEmail);
0110 
0111         modelIndex = m_list->model()->index(i, 0, m_list->rootIndex());
0112         m_list->setIndexWidget(modelIndex, playerSelectorItem);
0113     }
0114 }
0115 
0116 //END PlayerSelector
0117 //BEGIN PlayerSelectorDelegate
0118 
0119 PlayerSelectorDelegate::PlayerSelectorDelegate(QObject* parent)
0120     : QStyledItemDelegate(parent)
0121 {
0122     auto* view = qobject_cast<QAbstractItemView*>(parent);
0123     if (view)
0124         view->setItemDelegate(this);
0125 }
0126 
0127 void PlayerSelectorDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& /*index*/) const
0128 {
0129     //draw background
0130     QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, nullptr);
0131 }
0132 
0133 QSize PlayerSelectorDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
0134 {
0135     Q_UNUSED(option) Q_UNUSED(index)
0136     //TODO: take text size into account
0137     return {600, 64 /*player preview height*/ + 2 * 6 /*padding*/ + 40 /* some space for the player name */};
0138 }
0139 
0140 //END PlayerSelectorDelegate
0141 
0142 #include "moc_playerselector.cpp"