• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

libkdegames

  • sources
  • kde-4.14
  • kdegames
  • libkdegames
kgthemeselector.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright 2009-2012 Stefan Majewsky <majewsky@gmx.net> *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU Library General Public License *
6  * version 2 as published by the Free Software Foundation *
7  * *
8  * This program is distributed in the hope that it will be useful, *
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
11  * GNU Library General Public License for more details. *
12  * *
13  * You should have received a copy of the GNU Library General Public *
14  * License along with this program; if not, write to the *
15  * Free Software Foundation, Inc., *
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
17  ***************************************************************************/
18 
19 #include "kgthemeselector.h"
20 #include "kgthemeselector_p.h"
21 
22 #include <QtGui/QAbstractItemView>
23 #include <QtGui/QApplication>
24 #include <QtGui/QCloseEvent>
25 #include <QtGui/QFont>
26 #include <QtGui/QFontMetrics>
27 #include <QtGui/QListWidget>
28 #include <QtGui/QPainter>
29 #include <QtGui/QPushButton>
30 #include <QtGui/QScrollBar>
31 #include <QtGui/QVBoxLayout>
32 #include <KDE/KIcon>
33 #include <KDE/KLocalizedString>
34 #include <KNS3/DownloadDialog>
35 
36 namespace Metrics
37 {
38  const int Padding = 6;
39  const QSize ThumbnailBaseSize(64, 64);
40 }
41 
42 //BEGIN KgThemeSelector
43 
44 class KgThemeSelector::Private
45 {
46  public:
47  KgThemeSelector* q;
48  KgThemeProvider* m_provider;
49  Options m_options;
50  QListWidget* m_list;
51  QPushButton* m_knsButton;
52 
53  void fillList();
54 
55  Private(KgThemeProvider* provider, Options options, KgThemeSelector* q) : q(q), m_provider(provider), m_options(options), m_knsButton(0) {}
56 
57  void _k_updateListSelection(const KgTheme* theme);
58  void _k_updateProviderSelection();
59  void _k_showNewStuffDialog();
60 };
61 
62 KgThemeSelector::KgThemeSelector(KgThemeProvider* provider, Options options, QWidget* parent)
63  : QWidget(parent)
64  , d(new Private(provider, options, this))
65 {
66  d->m_list = new QListWidget(this);
67  d->m_list->setSelectionMode(QAbstractItemView::SingleSelection);
68  d->m_list->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
69  //load themes from provider
70  d->fillList();
71  //setup appearance of the theme list (min. size = 4 items)
72  KgThemeDelegate* delegate = new KgThemeDelegate(d->m_list);
73  const QSize itemSizeHint = delegate->sizeHint(QStyleOptionViewItem(), QModelIndex());
74  const QSize scrollBarSizeHint = d->m_list->verticalScrollBar()->sizeHint();
75  d->m_list->setMinimumSize(itemSizeHint.width() + 2 * scrollBarSizeHint.width(), 4.1 * itemSizeHint.height());
76  //monitor change selection in both directions
77  connect(d->m_provider, SIGNAL(currentThemeChanged(const KgTheme*)),
78  SLOT(_k_updateListSelection(const KgTheme*)));
79  connect(d->m_list, SIGNAL(itemSelectionChanged()),
80  SLOT(_k_updateProviderSelection()));
81  //setup main layout
82  QVBoxLayout* layout = new QVBoxLayout(this);
83  layout->setMargin(0);
84  layout->addWidget(d->m_list);
85  //setup KNS button
86  if (options & EnableNewStuffDownload)
87  {
88  d->m_knsButton = new QPushButton(KIcon("get-hot-new-stuff"),
89  i18n("Get New Themes..."), this);
90  layout->addWidget(d->m_knsButton);
91  connect(d->m_knsButton, SIGNAL(clicked()), SLOT(_k_showNewStuffDialog()));
92  }
93 }
94 
95 KgThemeSelector::~KgThemeSelector()
96 {
97  delete d;
98 }
99 
100 void KgThemeSelector::Private::fillList()
101 {
102  m_list->clear();
103  foreach (const KgTheme* theme, m_provider->themes())
104  {
105  QListWidgetItem* item = new QListWidgetItem(theme->name(), m_list);
106  item->setData(Qt::DecorationRole,
107  m_provider->generatePreview(theme, Metrics::ThumbnailBaseSize));
108  item->setData(KgThemeDelegate::DescriptionRole, theme->description());
109  item->setData(KgThemeDelegate::AuthorRole, theme->author());
110  item->setData(KgThemeDelegate::AuthorEmailRole, theme->authorEmail());
111  item->setData(KgThemeDelegate::IdRole, theme->identifier());
112  }
113  _k_updateListSelection(m_provider->currentTheme());
114 }
115 
116 void KgThemeSelector::Private::_k_updateListSelection(const KgTheme* theme)
117 {
118  for (int idx = 0; idx < m_list->count(); ++idx)
119  {
120  QListWidgetItem* item = m_list->item(idx);
121  const QByteArray thisId = item->data(KgThemeDelegate::IdRole).toByteArray();
122  if (thisId == theme->identifier())
123  {
124  m_list->setCurrentItem(item, QItemSelectionModel::ClearAndSelect);
125  return;
126  }
127  }
128  //make sure that something is selected
129  if (m_list->count() > 0)
130  {
131  m_list->setCurrentRow(0, QItemSelectionModel::ClearAndSelect);
132  }
133 }
134 
135 void KgThemeSelector::Private::_k_updateProviderSelection()
136 {
137  const QListWidgetItem* selItem = m_list->selectedItems().value(0);
138  if (!selItem)
139  {
140  return;
141  }
142  const QByteArray selId = selItem->data(KgThemeDelegate::IdRole).toByteArray();
143  //select the theme with this identifier
144  foreach (const KgTheme* theme, m_provider->themes())
145  {
146  if (theme->identifier() == selId)
147  {
148  m_provider->setCurrentTheme(theme);
149  }
150  }
151 }
152 
153 void KgThemeSelector::Private::_k_showNewStuffDialog()
154 {
155  KNS3::DownloadDialog dialog(q);
156  dialog.exec();
157  if (!dialog.changedEntries().isEmpty())
158  {
159  m_provider->rediscoverThemes();
160  fillList();
161  }
162  //restore previous selection
163  _k_updateListSelection(m_provider->currentTheme());
164 }
165 
166 class KgThemeSelector::Dialog : public KDialog
167 {
168  public:
169  Dialog(KgThemeSelector* sel, const QString& caption)
170  {
171  setMainWidget(sel);
172  //replace
173  QPushButton* btn = sel->d->m_knsButton;
174  if (btn)
175  {
176  btn->hide();
177  setButtons(Close | User1);
178  setButtonText(User1, btn->text());
179  //cannot use btn->icon() because setButtonIcon() wants KIcon
180  setButtonIcon(User1, KIcon("get-hot-new-stuff"));
181  connect(this, SIGNAL(user1Clicked()), btn, SIGNAL(clicked()));
182  }
183  else
184  {
185  setButtons(Close);
186  }
187  //window caption
188  if (caption.isEmpty())
189  {
190  setCaption(i18nc("@title:window config dialog", "Select theme"));
191  }
192  else
193  {
194  setCaption(caption);
195  }
196  show();
197  }
198  protected:
199  virtual void closeEvent(QCloseEvent* event)
200  {
201  event->accept();
202  KgThemeSelector* sel = qobject_cast<KgThemeSelector*>(mainWidget());
203  //delete myself, but *not* the KgThemeSelector
204  sel->setParent(0);
205  deleteLater();
206  //restore the KNS button
207  if (sel->d->m_knsButton)
208  {
209  sel->d->m_knsButton->show();
210  }
211  }
212 };
213 
214 void KgThemeSelector::showAsDialog(const QString& caption)
215 {
216  if (!isVisible())
217  {
218  new KgThemeSelector::Dialog(this, caption);
219  }
220 }
221 
222 //END KgThemeSelector
223 //BEGIN KgThemeDelegate
224 
225 KgThemeDelegate::KgThemeDelegate(QObject* parent)
226  : QStyledItemDelegate(parent)
227 {
228  QAbstractItemView* view = qobject_cast<QAbstractItemView*>(parent);
229  if (view)
230  view->setItemDelegate(this);
231 }
232 
233 QRect KgThemeDelegate::thumbnailRect(const QRect& baseRect) const
234 {
235  QRect thumbnailBaseRect(QPoint(Metrics::Padding + baseRect.left(), 0), Metrics::ThumbnailBaseSize);
236  thumbnailBaseRect.moveCenter(QPoint(thumbnailBaseRect.center().x(), baseRect.center().y()));
237  if (QApplication::isRightToLeft())
238  thumbnailBaseRect.moveRight(baseRect.right() - Metrics::Padding);
239  return thumbnailBaseRect;
240 }
241 
242 void KgThemeDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
243 {
244  const bool rtl = option.direction == Qt::RightToLeft;
245  QRect baseRect = option.rect;
246  //draw background
247  QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, 0);
248  //draw thumbnail
249  QRect thumbnailBaseRect = this->thumbnailRect(baseRect);
250  const QPixmap thumbnail = index.data(Qt::DecorationRole).value<QPixmap>().scaled(Metrics::ThumbnailBaseSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
251  QRect thumbnailRect(thumbnailBaseRect.topLeft(), thumbnail.size());
252  thumbnailRect.translate( //center inside thumbnailBaseRect
253  (thumbnailBaseRect.width() - thumbnailRect.width()) / 2,
254  (thumbnailBaseRect.height() - thumbnailRect.height()) / 2
255  );
256  painter->drawPixmap(thumbnailRect.topLeft(), thumbnail);
257  //find metrics: text
258  QStringList texts; QList<QFont> fonts;
259  {
260  QString name = index.data(Qt::DisplayRole).toString();
261  if (name.isEmpty())
262  name = i18n("[No name]");
263  texts << name;
264  QFont theFont(painter->font()); theFont.setBold(true); fonts << theFont;
265  }{
266  QString comment = index.data(DescriptionRole).toString();
267  if (!comment.isEmpty())
268  {
269  texts << comment;
270  fonts << painter->font();
271  }
272  }{
273  QString author = index.data(AuthorRole).toString();
274  if (!author.isEmpty())
275  {
276  const QString authorString = ki18nc("Author attribution, e.g. \"by Jack\"", "by %1").subs(author).toString();
277  texts << authorString;
278  QFont theFont(painter->font()); theFont.setItalic(true); fonts << theFont;
279  }
280  }
281  //TODO: display AuthorEmailRole
282  QList<QRect> textRects; int totalTextHeight = 0;
283  for (int i = 0; i < texts.count(); ++i)
284  {
285  QFontMetrics fm(fonts[i]);
286  textRects << fm.boundingRect(texts[i]);
287  textRects[i].setHeight(qMax(textRects[i].height(), fm.lineSpacing()));
288  totalTextHeight += textRects[i].height();
289  }
290  QRect textBaseRect(baseRect);
291  if (rtl)
292  {
293  textBaseRect.setRight(thumbnailBaseRect.left() - Metrics::Padding);
294  textBaseRect.adjust(Metrics::Padding, Metrics::Padding, 0, -Metrics::Padding);
295  }
296  else
297  {
298  textBaseRect.setLeft(thumbnailBaseRect.right() + Metrics::Padding);
299  textBaseRect.adjust(0, Metrics::Padding, -Metrics::Padding, -Metrics::Padding);
300  }
301  textBaseRect.setHeight(totalTextHeight);
302  textBaseRect.moveTop(baseRect.top() + (baseRect.height() - textBaseRect.height()) / 2);
303  //draw texts
304  QRect currentTextRect(textBaseRect);
305  painter->save();
306  for (int i = 0; i < texts.count(); ++i)
307  {
308  painter->setFont(fonts[i]);
309  const QRect& textRect = textRects[i];
310  currentTextRect.setHeight(textRect.height());
311  const QFontMetrics fm(fonts[i]);
312  const QString text = fm.elidedText(texts[i], Qt::ElideRight, currentTextRect.width());
313  painter->drawText(currentTextRect, Qt::AlignLeft | Qt::AlignVCenter, text);
314  currentTextRect.moveTop(currentTextRect.bottom());
315  }
316  painter->restore();
317 }
318 
319 QSize KgThemeDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
320 {
321  Q_UNUSED(option) Q_UNUSED(index)
322  //TODO: take text size into account
323  return QSize(400, Metrics::ThumbnailBaseSize.height() + 2 * Metrics::Padding);
324 }
325 
326 //END KgThemeDelegate
327 
328 #include "kgthemeselector.moc"
QWidget::layout
QLayout * layout() const
KgTheme::description
QString description
Definition: kgtheme.h:76
QModelIndex
QVariant::toByteArray
QByteArray toByteArray() const
Metrics::ThumbnailBaseSize
const QSize ThumbnailBaseSize(64, 64)
QPixmap::size
QSize size() const
QWidget
QApplication::isRightToLeft
bool isRightToLeft()
KgTheme::name
QString name
Definition: kgtheme.h:75
QSize::width
int width() const
KgThemeSelector::EnableNewStuffDownload
Enable downloading of additional themes with KNewStuff3.
Definition: kgthemeselector.h:52
KgThemeDelegate::KgThemeDelegate
KgThemeDelegate(QObject *parent=0)
Definition: kgthemeselector.cpp:225
QAbstractItemView
KgTheme::authorEmail
QString authorEmail
Definition: kgtheme.h:78
KgThemeDelegate::thumbnailRect
QRect thumbnailRect(const QRect &baseRect) const
Definition: kgthemeselector.cpp:233
QRect::right
int right() const
QByteArray
Metrics::Padding
const int Padding
Definition: kgthemeselector.cpp:38
kgthemeselector_p.h
QPainter::font
const QFont & font() const
KgThemeProvider
A theme provider manages KgTheme instances, and maintains a selection of the currentTheme().
Definition: kgthemeprovider.h:39
QFont
QListWidgetItem
QRect::translate
void translate(int dx, int dy)
QWidget::isVisible
bool isVisible() const
QPainter::save
void save()
QVariant::value
T value() const
QRect::height
int height() const
QPoint
QFontMetrics
QListWidget
kgthemeselector.h
QWidget::setParent
void setParent(QWidget *parent)
QPoint::x
int x() const
QPoint::y
int y() const
QFont::setBold
void setBold(bool enable)
QCloseEvent
QObject::name
const char * name() const
QRect
QFontMetrics::boundingRect
QRect boundingRect(QChar ch) const
QPainter::setFont
void setFont(const QFont &font)
QBoxLayout::addWidget
void addWidget(QWidget *widget, int stretch, QFlags< Qt::AlignmentFlag > alignment)
QList::count
int count(const T &value) const
KgThemeDelegate
Definition: kgthemeselector_p.h:26
KgThemeSelector
Theme selection widget.
Definition: kgthemeselector.h:42
KgThemeDelegate::AuthorRole
Definition: kgthemeselector_p.h:32
QRect::top
int top() const
QStyleOptionViewItem
QObject
QRect::left
int left() const
QPainter::drawPixmap
void drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
QPainter
QString::isEmpty
bool isEmpty() const
QAbstractItemView::setItemDelegate
void setItemDelegate(QAbstractItemDelegate *delegate)
QFontMetrics::elidedText
QString elidedText(const QString &text, Qt::TextElideMode mode, int width, int flags) const
QListWidgetItem::data
virtual QVariant data(int role) const
QVBoxLayout
QPainter::drawText
void drawText(const QPointF &position, const QString &text)
QRect::center
QPoint center() const
QObject::deleteLater
void deleteLater()
QString
QList
QWidget::hide
void hide()
QRect::moveTop
void moveTop(int y)
KgThemeSelector::KgThemeSelector
KgThemeSelector(KgThemeProvider *provider, Options options=DefaultBehavior, QWidget *parent=0)
Definition: kgthemeselector.cpp:62
QLayout::setMargin
void setMargin(int margin)
QStringList
QPixmap
KgThemeDelegate::sizeHint
virtual QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: kgthemeselector.cpp:319
KgThemeSelector::~KgThemeSelector
virtual ~KgThemeSelector()
Definition: kgthemeselector.cpp:95
QSize
QListWidgetItem::setData
virtual void setData(int role, const QVariant &value)
QFont::setItalic
void setItalic(bool enable)
KgThemeDelegate::AuthorEmailRole
Definition: kgthemeselector_p.h:33
QPainter::restore
void restore()
QRect::setRight
void setRight(int x)
KgThemeDelegate::paint
virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
Definition: kgthemeselector.cpp:242
KgThemeDelegate::DescriptionRole
Definition: kgthemeselector_p.h:31
QRect::width
int width() const
QModelIndex::data
QVariant data(int role) const
QApplication::style
QStyle * style()
KgTheme::author
QString author
Definition: kgtheme.h:77
QRect::setHeight
void setHeight(int height)
QWidget::setCaption
void setCaption(const QString &c)
QSize::height
int height() const
QRect::adjust
void adjust(int dx1, int dy1, int dx2, int dy2)
QRect::bottom
int bottom() const
QRect::topLeft
QPoint topLeft() const
QStyle::drawPrimitive
virtual void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const =0
QAbstractButton::text
text
QPushButton
KgTheme::identifier
QByteArray identifier
Definition: kgtheme.h:71
KgThemeDelegate::IdRole
Definition: kgthemeselector_p.h:34
QWidget::show
void show()
KgTheme
A theme describes the visual appearance of a game.
Definition: kgtheme.h:68
QWidget::closeEvent
virtual void closeEvent(QCloseEvent *event)
QRect::moveRight
void moveRight(int x)
QRect::moveCenter
void moveCenter(const QPoint &position)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
QVariant::toString
QString toString() const
QWidget::event
virtual bool event(QEvent *event)
QRect::setLeft
void setLeft(int x)
QFontMetrics::lineSpacing
int lineSpacing() const
QWidget::caption
QString caption() const
QStyledItemDelegate
KgThemeSelector::showAsDialog
void showAsDialog(const QString &caption=QString())
Create and show a non-modal dialog which displays this selector.
Definition: kgthemeselector.cpp:214
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:42 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkdegames

Skip menu "libkdegames"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal