00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kcategorizeditemsviewdelegate_p.h"
00021
00022 #include <cmath>
00023
00024 #include <QtCore/QtCore>
00025
00026 #include <KIconLoader>
00027
00028 #include "kcategorizeditemsview_p.h"
00029
00030 #define FAV_ICON_SIZE 24
00031 #define EMBLEM_ICON_SIZE 16
00032 #define UNIVERSAL_PADDING 6
00033 #define FADE_LENGTH 32
00034 #define MAIN_ICON_SIZE 48
00035 #define DROPDOWN_PADDING 2
00036 #define DROPDOWN_SEPARATOR_HEIGHT 32
00037
00038 KCategorizedItemsViewDelegate::KCategorizedItemsViewDelegate(QObject * parent)
00039 : QItemDelegate(parent), m_favoriteIcon("bookmarks"),
00040 m_favoriteAddIcon("list-add"), m_removeIcon("list-remove"),
00041 m_onFavoriteIconItem(NULL)
00042 {
00043 m_parent = (KCategorizedItemsView *) parent;
00044 }
00045
00046 void KCategorizedItemsViewDelegate::paint(QPainter *painter,
00047 const QStyleOptionViewItem &option, const QModelIndex &index) const
00048 {
00049 KCategorizedItemsViewModels::AbstractItem * item = getItemByProxyIndex(index);
00050 if (!item) {
00051 return;
00052 }
00053
00054 QStyleOptionViewItemV4 opt(option);
00055 QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
00056 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
00057
00058 switch (index.column()) {
00059 case 0:
00060 paintColMain(painter, option, item);
00061 break;
00062 case 1:
00063 paintColFav(painter, option, item);
00064 break;
00065 case 2:
00066 paintColRemove(painter, option, item);
00067 break;
00068 default:
00069 kDebug() << "unexpected column";
00070 }
00071 }
00072
00073 int KCategorizedItemsViewDelegate::calcItemHeight(const QStyleOptionViewItem &option) const
00074 {
00075
00076 QFont titleFont = option.font;
00077 titleFont.setBold(true);
00078 titleFont.setPointSize(titleFont.pointSize() + 2);
00079
00080 int textHeight = QFontInfo(titleFont).pixelSize() + QFontInfo(option.font).pixelSize();
00081
00082 return qMax(textHeight, MAIN_ICON_SIZE) + 2 * UNIVERSAL_PADDING;
00083 }
00084
00085 void KCategorizedItemsViewDelegate::paintColMain(QPainter *painter,
00086 const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const
00087 {
00088 const int left = option.rect.left();
00089 const int top = option.rect.top();
00090 const int width = option.rect.width();
00091 const int height = calcItemHeight(option);
00092
00093 bool leftToRight = (painter->layoutDirection() == Qt::LeftToRight);
00094 QIcon::Mode iconMode = QIcon::Normal;
00095
00096 QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
00097 option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
00098
00099
00100 QFont titleFont = option.font;
00101 titleFont.setBold(true);
00102 titleFont.setPointSize(titleFont.pointSize() + 2);
00103
00104 QPixmap pixmap(width, height);
00105 pixmap.fill(Qt::transparent);
00106 QPainter p(&pixmap);
00107 p.translate(-option.rect.topLeft());
00108
00109 QLinearGradient gradient;
00110
00111 QString title = item->name();
00112 QString description = item->description();
00113
00114
00115
00116
00117 int textInner = 2 * UNIVERSAL_PADDING + MAIN_ICON_SIZE;
00118
00119 p.setPen(foregroundColor);
00120 p.setFont(titleFont);
00121 p.drawText(left + (leftToRight ? textInner : 0),
00122 top, width - textInner, height / 2,
00123 Qt::AlignBottom | Qt::AlignLeft, title);
00124 p.setFont(option.font);
00125 p.drawText(left + (leftToRight ? textInner : 0),
00126 top + height / 2,
00127 width - textInner, height / 2,
00128 Qt::AlignTop | Qt::AlignLeft, description);
00129
00130
00131 item->icon().paint(&p,
00132 leftToRight ? left + UNIVERSAL_PADDING : left + width - UNIVERSAL_PADDING - MAIN_ICON_SIZE,
00133 top + UNIVERSAL_PADDING,
00134 MAIN_ICON_SIZE, MAIN_ICON_SIZE, Qt::AlignCenter, iconMode);
00135
00136
00137 int emblemCount = 0;
00138 QPair < Filter, QIcon * > emblem;
00139 foreach (emblem, m_parent->m_emblems) {
00140 if (item->passesFiltering(emblem.first)) ++emblemCount;
00141 }
00142
00143
00144 if (leftToRight) {
00145 gradient = QLinearGradient(left + width - UNIVERSAL_PADDING - FADE_LENGTH, 0,
00146 left + width - UNIVERSAL_PADDING, 0);
00147 gradient.setColorAt(0, Qt::white);
00148 gradient.setColorAt(1, Qt::transparent);
00149 } else {
00150 gradient = QLinearGradient(left + UNIVERSAL_PADDING, 0,
00151 left + UNIVERSAL_PADDING + FADE_LENGTH, 0);
00152 gradient.setColorAt(0, Qt::transparent);
00153 gradient.setColorAt(1, Qt::white);
00154 }
00155
00156 QRect paintRect = option.rect;
00157 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00158 p.fillRect(paintRect, gradient);
00159
00160 if (leftToRight) {
00161 gradient.setStart(left + width
00162 - emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) - FADE_LENGTH, 0);
00163 gradient.setFinalStop(left + width
00164 - emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
00165 } else {
00166 gradient.setStart(left + UNIVERSAL_PADDING
00167 + emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
00168 gradient.setFinalStop(left + UNIVERSAL_PADDING
00169 + emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) + FADE_LENGTH, 0);
00170 }
00171 paintRect.setHeight(UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2);
00172 p.fillRect(paintRect, gradient);
00173
00174
00175 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
00176 int emblemLeft = leftToRight ? (left + width - EMBLEM_ICON_SIZE) : left;
00177 foreach (emblem, m_parent->m_emblems) {
00178 if (item->passesFiltering(emblem.first)) {
00179 emblem.second->paint(&p,
00180 emblemLeft, top + UNIVERSAL_PADDING,
00181 EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
00182 if (leftToRight) {
00183 emblemLeft -= UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
00184 } else {
00185 emblemLeft += UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
00186 }
00187 }
00188 }
00189 p.end();
00190
00191 painter->drawPixmap(option.rect.topLeft(), pixmap);
00192 }
00193
00194 void KCategorizedItemsViewDelegate::paintColFav(QPainter *painter,
00195 const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const
00196 {
00197 int left = option.rect.left();
00198 int top = option.rect.top();
00199 int width = option.rect.width();
00200
00201
00202
00203 if (! (option.state & QStyle::State_MouseOver) && m_onFavoriteIconItem == item)
00204 m_onFavoriteIconItem = NULL;
00205
00206 QIcon::Mode iconMode = QIcon::Normal;
00207 if (!item->isFavorite()) {
00208 iconMode = QIcon::Disabled;
00209 } else if (option.state & QStyle::State_MouseOver) {
00210 iconMode = QIcon::Active;
00211 }
00212
00213 m_favoriteIcon.paint(painter,
00214 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
00215 FAV_ICON_SIZE, FAV_ICON_SIZE, Qt::AlignCenter, iconMode);
00216
00217 const KIcon * icon = (item->isFavorite())? & m_removeIcon : & m_favoriteAddIcon;
00218
00219 if ((option.state & QStyle::State_MouseOver) && (m_onFavoriteIconItem != item))
00220 icon->paint(painter,
00221 left + width - EMBLEM_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
00222 EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
00223 }
00224
00225 void KCategorizedItemsViewDelegate::paintColRemove(QPainter *painter,
00226 const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const
00227 {
00228
00229 int running = item->running();
00230 if (!running) {
00231 return;
00232 }
00233
00234 int left = option.rect.left();
00235 int top = option.rect.top();
00236 int width = option.rect.width();
00237
00238 QIcon::Mode iconMode = QIcon::Normal;
00239 if (option.state & QStyle::State_MouseOver) {
00240 iconMode = QIcon::Active;
00241 }
00242
00243 m_removeIcon.paint(painter,
00244 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
00245 FAV_ICON_SIZE, FAV_ICON_SIZE, Qt::AlignCenter, iconMode);
00246
00247 if (running == 1) {
00248 return;
00249 }
00250
00251 QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
00252 option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
00253 painter->setPen(foregroundColor);
00254 painter->setFont(option.font);
00255 painter->drawText(
00256 left + UNIVERSAL_PADDING,
00257 top + UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2,
00258 width - 2 * UNIVERSAL_PADDING, MAIN_ICON_SIZE / 2,
00259 Qt::AlignCenter, QString::number(running));
00260 }
00261
00262 bool KCategorizedItemsViewDelegate::editorEvent(QEvent *event,
00263 QAbstractItemModel *model,
00264 const QStyleOptionViewItem &option,
00265 const QModelIndex &index)
00266 {
00267 if (event->type() == QEvent::MouseButtonPress) {
00268 KCategorizedItemsViewModels::AbstractItem * item = getItemByProxyIndex(index);
00269 if (index.column() == 1) {
00270 m_onFavoriteIconItem = item;
00271 item->setFavorite(!item->isFavorite());
00272 return true;
00273 } else if (index.column() == 2 && item->running()) {
00274 item->setRunning(0);
00275 emit destroyApplets(item->name());
00276 return true;
00277 }
00278 }
00279
00280 return QItemDelegate::editorEvent(event, model, option, index);
00281 }
00282
00283 QSize KCategorizedItemsViewDelegate::sizeHint(const QStyleOptionViewItem &option,
00284 const QModelIndex &index ) const
00285 {
00286 int width = (index.column() == 0) ? 0 : FAV_ICON_SIZE;
00287 return QSize(width, calcItemHeight(option));
00288 }
00289
00290 int KCategorizedItemsViewDelegate::columnWidth (int column, int viewWidth) const {
00291 if (column != 0) {
00292 return FAV_ICON_SIZE + 2 * UNIVERSAL_PADDING;
00293 } else return viewWidth - 2 * columnWidth(1, viewWidth);
00294 }
00295
00296
00297 KCategorizedItemsViewModels::AbstractItem * KCategorizedItemsViewDelegate::getItemByProxyIndex(const QModelIndex & index) const {
00298 return (AbstractItem *) m_parent->m_modelItems->itemFromIndex(
00299 m_parent->m_modelFilterItems->mapToSource(index)
00300 );
00301 }
00302
00303
00304
00305
00306 KCategorizedItemsViewFilterDelegate::KCategorizedItemsViewFilterDelegate(QObject *parent)
00307 : QItemDelegate(parent) {
00308 kDebug() << "KCategorizedItemsViewFilterDelegate(QObject *parent)\n";
00309
00310 }
00311
00312 void KCategorizedItemsViewFilterDelegate::paint(QPainter *painter,
00313 const QStyleOptionViewItem &option, const QModelIndex &index) const
00314 {
00315 if (index.flags() & Qt::ItemIsEnabled) {
00316 QItemDelegate::paint(painter, option, index);
00317 } else {
00318 QStyleOptionViewItem separatorOption(option);
00319 int height = QItemDelegate::sizeHint(option, index).height() + 2 * DROPDOWN_PADDING;
00320
00321 separatorOption.state &= ~(QStyle::State_Selected
00322 | QStyle::State_MouseOver | QStyle::State_HasFocus);
00323 separatorOption.rect.setTop(separatorOption.rect.top() + separatorOption.rect.height() - height);
00324 separatorOption.rect.setHeight(height);
00325 QItemDelegate::paint(painter, separatorOption, index);
00326
00327
00328
00329
00330
00331 }
00332 }
00333
00334 QSize KCategorizedItemsViewFilterDelegate::sizeHint(const QStyleOptionViewItem &option,
00335 const QModelIndex &index ) const
00336 {
00337 QSize size = QItemDelegate::sizeHint(option, index);
00338 if (index.flags() & Qt::ItemIsEnabled) {
00339 size.setHeight(size.height() + 2 * DROPDOWN_PADDING);
00340 } else {
00341 size.setHeight(DROPDOWN_SEPARATOR_HEIGHT);
00342 }
00343 return size;
00344 }
00345
00346 #include "kcategorizeditemsviewdelegate_p.moc"
00347