File indexing completed on 2025-04-20 06:48:51
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"