not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / plasma / shells / common / kcategorizeditemsviewdelegate.cpp
blobb2aaf8de8fef8e1e11e20391662f36c63ec349d7
1 /*
2 * Copyright (C) 2007 Ivan Cukic <ivan.cukic+kde@gmail.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library/Lesser General Public License
6 * version 2, or (at your option) any later version, as published by the
7 * Free Software Foundation
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library/Lesser General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "kcategorizeditemsviewdelegate_p.h"
22 #include <cmath>
24 #include <QtCore/QtCore>
26 #include <KIconLoader>
28 #include "kcategorizeditemsview_p.h"
30 #define FAV_ICON_SIZE 24
31 #define EMBLEM_ICON_SIZE 16
32 #define UNIVERSAL_PADDING 6
33 #define FADE_LENGTH 32
34 #define MAIN_ICON_SIZE 48
35 #define DROPDOWN_PADDING 2
36 #define DROPDOWN_SEPARATOR_HEIGHT 32
38 KCategorizedItemsViewDelegate::KCategorizedItemsViewDelegate(QObject * parent)
39 : QItemDelegate(parent), m_favoriteIcon("bookmarks"),
40 m_favoriteAddIcon("list-add"), m_removeIcon("list-remove"),
41 m_infoIcon("dialog-information"),
42 m_onFavoriteIconItem(NULL)
44 m_parent = (KCategorizedItemsView *) parent;
47 void KCategorizedItemsViewDelegate::paint(QPainter *painter,
48 const QStyleOptionViewItem &option, const QModelIndex &index) const
50 KCategorizedItemsViewModels::AbstractItem * item = getItemByProxyIndex(index);
51 if (!item) {
52 return;
55 QStyleOptionViewItemV4 opt(option);
56 QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
57 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
59 switch (index.column()) {
60 case 0:
61 paintColMain(painter, option, item);
62 break;
63 case 1:
64 paintColFav(painter, option, item);
65 break;
66 case 2:
67 paintColRemove(painter, option, item);
68 break;
69 case 3:
70 paintColInfo(painter, option, item);
71 break;
72 default:
73 kDebug() << "unexpected column";
77 int KCategorizedItemsViewDelegate::calcItemHeight(const QStyleOptionViewItem &option) const
79 // Painting main column
80 QFont titleFont = option.font;
81 titleFont.setBold(true);
82 titleFont.setPointSize(titleFont.pointSize() + 2);
84 int textHeight = QFontInfo(titleFont).pixelSize() + QFontInfo(option.font).pixelSize();
85 //kDebug() << textHeight << qMax(textHeight, MAIN_ICON_SIZE) + 2 * UNIVERSAL_PADDING;
86 return qMax(textHeight, MAIN_ICON_SIZE) + 2 * UNIVERSAL_PADDING;
89 void KCategorizedItemsViewDelegate::paintColMain(
90 QPainter *painter, const QStyleOptionViewItem &option,
91 const KCategorizedItemsViewModels::AbstractItem *item) const
93 const int left = option.rect.left();
94 const int top = option.rect.top();
95 const int width = option.rect.width();
96 const int height = calcItemHeight(option);
98 bool leftToRight = (painter->layoutDirection() == Qt::LeftToRight);
99 QIcon::Mode iconMode = QIcon::Normal;
101 QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
102 option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
104 // Painting main column
105 QFont titleFont = option.font;
106 titleFont.setBold(true);
107 titleFont.setPointSize(titleFont.pointSize() + 2);
109 QPixmap pixmap(width, height);
110 pixmap.fill(Qt::transparent);
111 QPainter p(&pixmap);
112 p.translate(-option.rect.topLeft());
114 QLinearGradient gradient;
116 QString title = item->name();
117 QString description = item->description();
119 // Painting
121 // Text
122 int textInner = 2 * UNIVERSAL_PADDING + MAIN_ICON_SIZE;
124 p.setPen(foregroundColor);
125 p.setFont(titleFont);
126 p.drawText(left + (leftToRight ? textInner : 0),
127 top, width - textInner, height / 2,
128 Qt::AlignBottom | Qt::AlignLeft, title);
129 p.setFont(option.font);
130 p.drawText(left + (leftToRight ? textInner : 0),
131 top + height / 2,
132 width - textInner, height / 2,
133 Qt::AlignTop | Qt::AlignLeft, description);
135 // Main icon
136 item->icon().paint(
138 leftToRight ? left + UNIVERSAL_PADDING : left + width - UNIVERSAL_PADDING - MAIN_ICON_SIZE,
139 top + UNIVERSAL_PADDING,
140 MAIN_ICON_SIZE,
141 MAIN_ICON_SIZE,
142 Qt::AlignCenter, iconMode);
144 // Counting the number of emblems for this item
145 int emblemCount = 0;
146 QPair < Filter, QIcon > emblem;
147 foreach (emblem, m_parent->m_emblems) {
148 if (item->passesFiltering(emblem.first)) {
149 ++emblemCount;
153 // Gradient part of the background - fading of the text at the end
154 if (leftToRight) {
155 gradient = QLinearGradient(left + width - UNIVERSAL_PADDING - FADE_LENGTH, 0,
156 left + width - UNIVERSAL_PADDING, 0);
157 gradient.setColorAt(0, Qt::white);
158 gradient.setColorAt(1, Qt::transparent);
159 } else {
160 gradient = QLinearGradient(left + UNIVERSAL_PADDING, 0,
161 left + UNIVERSAL_PADDING + FADE_LENGTH, 0);
162 gradient.setColorAt(0, Qt::transparent);
163 gradient.setColorAt(1, Qt::white);
166 QRect paintRect = option.rect;
167 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
168 p.fillRect(paintRect, gradient);
170 if (leftToRight) {
171 gradient.setStart(
172 left + width - emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) - FADE_LENGTH, 0);
173 gradient.setFinalStop(
174 left + width - emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
175 } else {
176 gradient.setStart(
177 left + UNIVERSAL_PADDING + emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
178 gradient.setFinalStop(
179 left + UNIVERSAL_PADDING + emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) + FADE_LENGTH, 0);
181 paintRect.setHeight(UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2);
182 p.fillRect(paintRect, gradient);
184 // Emblems icons
185 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
186 int emblemLeft = leftToRight ? (left + width - EMBLEM_ICON_SIZE) : left; // - FAV_ICON_SIZE - 2 * UNIVERSAL_PADDING
187 foreach (emblem, m_parent->m_emblems) {
188 if (item->passesFiltering(emblem.first)) {
189 emblem.second.paint(&p,
190 emblemLeft, top + UNIVERSAL_PADDING + (FAV_ICON_SIZE - EMBLEM_ICON_SIZE)/2,
191 EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
192 if (leftToRight) {
193 emblemLeft -= UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
194 } else {
195 emblemLeft += UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
199 p.end();
201 painter->drawPixmap(option.rect.topLeft(), pixmap);
204 void KCategorizedItemsViewDelegate::paintColFav(
205 QPainter *painter, const QStyleOptionViewItem &option,
206 const KCategorizedItemsViewModels::AbstractItem *item) const
208 int left = option.rect.left();
209 int top = option.rect.top();
210 int width = option.rect.width();
212 // Painting favorite icon column
214 if (! (option.state & QStyle::State_MouseOver) && m_onFavoriteIconItem == item) {
215 m_onFavoriteIconItem = NULL;
218 QIcon::Mode iconMode = QIcon::Normal;
219 if (!item->isFavorite()) {
220 iconMode = QIcon::Disabled;
221 } else if (option.state & QStyle::State_MouseOver) {
222 iconMode = QIcon::Active;
225 m_favoriteIcon.paint(
226 painter,
227 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING,
228 top + UNIVERSAL_PADDING,
229 FAV_ICON_SIZE,
230 FAV_ICON_SIZE,
231 Qt::AlignCenter,
232 iconMode);
234 const KIcon &icon = (item->isFavorite())? m_removeIcon : m_favoriteAddIcon;
236 if ((option.state & QStyle::State_MouseOver) && (m_onFavoriteIconItem != item)) {
237 icon.paint(
238 painter,
239 left + width - EMBLEM_ICON_SIZE - UNIVERSAL_PADDING,
240 top + UNIVERSAL_PADDING,
241 EMBLEM_ICON_SIZE,
242 EMBLEM_ICON_SIZE,
243 Qt::AlignCenter,
244 iconMode);
248 void KCategorizedItemsViewDelegate::paintColInfo(
249 QPainter *painter, const QStyleOptionViewItem &option,
250 const KCategorizedItemsViewModels::AbstractItem *item) const
252 QIcon::Mode infoMode = QIcon::Normal;
253 if (!(option.state & QStyle::State_MouseOver)) {
254 return;
257 int left = option.rect.left();
258 int top = option.rect.top();
259 int width = option.rect.width();
261 // Painting info icon column
263 m_infoIcon.paint(
264 painter,
265 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING,
266 top + UNIVERSAL_PADDING,
267 FAV_ICON_SIZE,
268 FAV_ICON_SIZE,
269 Qt::AlignCenter,
270 infoMode);
273 void KCategorizedItemsViewDelegate::paintColRemove(
274 QPainter *painter, const QStyleOptionViewItem &option,
275 const KCategorizedItemsViewModels::AbstractItem *item) const
277 // Painting remove icon column
278 int running = item->running();
279 if (!running) {
280 return;
283 int left = option.rect.left();
284 int top = option.rect.top();
285 int width = option.rect.width();
287 QIcon::Mode iconMode = QIcon::Normal;
288 if (option.state & QStyle::State_MouseOver) {
289 iconMode = QIcon::Active;
292 m_removeIcon.paint(painter,
293 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
294 FAV_ICON_SIZE, FAV_ICON_SIZE, Qt::AlignCenter, iconMode);
296 if (running == 1) {
297 return;
299 //paint number
300 QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
301 option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
302 painter->setPen(foregroundColor);
303 painter->setFont(option.font);
304 painter->drawText(
305 left + UNIVERSAL_PADDING, //FIXME might be wrong
306 top + UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2,
307 width - 2 * UNIVERSAL_PADDING, MAIN_ICON_SIZE / 2,
308 Qt::AlignCenter, QString::number(running));
311 bool KCategorizedItemsViewDelegate::editorEvent(
312 QEvent *event, QAbstractItemModel *model,
313 const QStyleOptionViewItem &option, const QModelIndex &index)
315 if (event->type() == QEvent::MouseButtonPress) {
316 KCategorizedItemsViewModels::AbstractItem *item = getItemByProxyIndex(index);
317 if (index.column() == 1) {
318 m_onFavoriteIconItem = item;
319 item->setFavorite(!item->isFavorite());
320 return true;
321 } else if (index.column() == 2 && item->running()) {
322 item->setRunning(0);
323 emit destroyApplets(item->name());
324 return true;
325 } else if (index.column() == 3) {
326 emit infoAboutApplet(item->name());
327 return true;
331 return QItemDelegate::editorEvent(event, model, option, index);
334 QSize KCategorizedItemsViewDelegate::sizeHint(const QStyleOptionViewItem &option,
335 const QModelIndex &index) const
337 int width = (index.column() == 0) ? 0 : FAV_ICON_SIZE;
338 return QSize(width, calcItemHeight(option));
341 int KCategorizedItemsViewDelegate::columnWidth (int column, int viewWidth) const {
342 if (column != 0) {
343 return FAV_ICON_SIZE + 3 * UNIVERSAL_PADDING;
344 } else {
345 return viewWidth - 3 * columnWidth(1, viewWidth);
349 KCategorizedItemsViewModels::AbstractItem *KCategorizedItemsViewDelegate::getItemByProxyIndex(
350 const QModelIndex &index) const
352 return (AbstractItem *)m_parent->m_modelItems->itemFromIndex(m_parent->m_modelFilterItems->mapToSource(index));
355 // KCategorizedItemsViewFilterDelegate
357 KCategorizedItemsViewFilterDelegate::KCategorizedItemsViewFilterDelegate(QObject *parent)
358 : QItemDelegate(parent)
360 kDebug() << "KCategorizedItemsViewFilterDelegate(QObject *parent)\n";
364 void KCategorizedItemsViewFilterDelegate::paint(QPainter *painter,
365 const QStyleOptionViewItem &option, const QModelIndex &index) const
367 if (index.flags() & Qt::ItemIsEnabled) {
368 QItemDelegate::paint(painter, option, index);
369 } else {
370 QStyleOptionViewItem separatorOption(option);
371 int height = QItemDelegate::sizeHint(option, index).height() + 2 * DROPDOWN_PADDING;
373 separatorOption.state &= ~(QStyle::State_Selected |
374 QStyle::State_MouseOver |
375 QStyle::State_HasFocus);
376 separatorOption.rect.setTop(
377 separatorOption.rect.top() + separatorOption.rect.height() - height);
378 separatorOption.rect.setHeight(height);
379 QItemDelegate::paint(painter, separatorOption, index);
380 /*painter->drawLine(
381 option.rect.left(),
382 option.rect.top() + 1,
383 option.rect.left() + option.rect.width(),
384 option.rect.top() + 1);*/
388 QSize KCategorizedItemsViewFilterDelegate::sizeHint(const QStyleOptionViewItem &option,
389 const QModelIndex &index) const
391 QSize size = QItemDelegate::sizeHint(option, index);
392 if (index.flags() & Qt::ItemIsEnabled) {
393 size.setHeight(size.height() + 2 * DROPDOWN_PADDING);
394 } else {
395 size.setHeight(DROPDOWN_SEPARATOR_HEIGHT);
397 return size;
400 #include "kcategorizeditemsviewdelegate_p.moc"