Changeset View
Changeset View
Standalone View
Standalone View
src/widgets/kfileitemdelegate.cpp
| Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Line(s) | 102 | void drawTextItems(QPainter *painter, const QTextLayout &labelLayout, const QTextLayout &infoLayout, | |||
|---|---|---|---|---|---|
| 103 | const QRect &textBoundingRect) const; | 103 | const QRect &textBoundingRect) const; | ||
| 104 | KIO::AnimationState *animationState(const QStyleOptionViewItem &option, const QModelIndex &index, | 104 | KIO::AnimationState *animationState(const QStyleOptionViewItem &option, const QModelIndex &index, | ||
| 105 | const QAbstractItemView *view) const; | 105 | const QAbstractItemView *view) const; | ||
| 106 | void restartAnimation(KIO::AnimationState *state); | 106 | void restartAnimation(KIO::AnimationState *state); | ||
| 107 | QPixmap applyHoverEffect(const QPixmap &icon) const; | 107 | QPixmap applyHoverEffect(const QPixmap &icon) const; | ||
| 108 | QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount) const; | 108 | QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount) const; | ||
| 109 | void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const; | 109 | void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const; | ||
| 110 | void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const; | 110 | void drawFocusRect(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const; | ||
| 111 | void drawColumnArrow(QPainter *painter, const QStyleOptionViewItem &option, int width) const; | ||||
| 111 | 112 | | |||
| 112 | void gotNewIcon(const QModelIndex &index); | 113 | void gotNewIcon(const QModelIndex &index); | ||
| 113 | 114 | | |||
| 114 | void paintJobTransfers(QPainter *painter, const qreal &jobAnimationAngle, const QPoint &iconPos, const QStyleOptionViewItem &opt); | 115 | void paintJobTransfers(QPainter *painter, const qreal &jobAnimationAngle, const QPoint &iconPos, const QStyleOptionViewItem &opt); | ||
| 115 | 116 | | |||
| 116 | public: | 117 | public: | ||
| 117 | KFileItemDelegate::InformationList informationList; | 118 | KFileItemDelegate::InformationList informationList; | ||
| 118 | QColor shadowColor; | 119 | QColor shadowColor; | ||
| ▲ Show 20 Lines • Show All 1057 Lines • ▼ Show 20 Line(s) | 1162 | { | |||
| 1176 | painter->setRenderHint(QPainter::Antialiasing, false); | 1177 | painter->setRenderHint(QPainter::Antialiasing, false); | ||
| 1177 | 1178 | | |||
| 1178 | QStyle *style = option.widget ? option.widget->style() : QApplication::style(); | 1179 | QStyle *style = option.widget ? option.widget->style() : QApplication::style(); | ||
| 1179 | style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget); | 1180 | style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget); | ||
| 1180 | 1181 | | |||
| 1181 | painter->setRenderHint(QPainter::Antialiasing); | 1182 | painter->setRenderHint(QPainter::Antialiasing); | ||
| 1182 | } | 1183 | } | ||
| 1183 | 1184 | | |||
| 1185 | void KFileItemDelegate::Private::drawColumnArrow(QPainter *painter, const QStyleOptionViewItem &option, int width) const | ||||
| 1186 | { | ||||
| 1187 | auto arrowOpt = option; | ||||
| 1188 | if (option.direction == Qt::RightToLeft) { | ||||
| 1189 | arrowOpt.rect = QRect(option.rect.x(), option.rect.y(), width, option.rect.height()); | ||||
| 1190 | } else { | ||||
| 1191 | arrowOpt.rect = QRect(option.rect.x() + option.rect.width() - width, option.rect.y(), | ||||
| 1192 | width, option.rect.height()); | ||||
| 1193 | } | ||||
| 1194 | | ||||
| 1195 | QStyle *style = option.widget ? option.widget->style() : QApplication::style(); | ||||
| 1196 | style->drawPrimitive(QStyle::PE_IndicatorColumnViewArrow, &arrowOpt, painter, arrowOpt.widget); | ||||
| 1197 | } | ||||
| 1198 | | ||||
| 1184 | void KFileItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, | 1199 | void KFileItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, | ||
| 1185 | const QModelIndex &index) const | 1200 | const QModelIndex &index) const | ||
| 1186 | { | 1201 | { | ||
| 1187 | if (!index.isValid()) { | 1202 | if (!index.isValid()) { | ||
| 1188 | return; | 1203 | return; | ||
| 1189 | } | 1204 | } | ||
| 1190 | 1205 | | |||
| 1191 | QStyleOptionViewItem opt(option); | 1206 | QStyleOptionViewItem opt(option); | ||
| 1192 | d->initStyleOption(&opt, index); | 1207 | d->initStyleOption(&opt, index); | ||
| 1193 | d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal); | 1208 | d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal); | ||
| 1194 | 1209 | | |||
| 1195 | if (!(option.state & QStyle::State_Enabled)) { | 1210 | if (!(option.state & QStyle::State_Enabled)) { | ||
| 1196 | opt.palette.setCurrentColorGroup(QPalette::Disabled); | 1211 | opt.palette.setCurrentColorGroup(QPalette::Disabled); | ||
| 1197 | } | 1212 | } | ||
| 1198 | 1213 | | |||
| 1199 | // Unset the mouse over bit if we're not drawing the first column | 1214 | // Unset the mouse over bit if we're not drawing the first column | ||
| 1200 | if (index.column() > 0) { | 1215 | if (index.column() > 0) { | ||
| 1201 | opt.state &= ~QStyle::State_MouseOver; | 1216 | opt.state &= ~QStyle::State_MouseOver; | ||
| 1202 | } else { | 1217 | } else { | ||
| 1203 | opt.viewItemPosition = QStyleOptionViewItem::OnlyOne; | 1218 | opt.viewItemPosition = QStyleOptionViewItem::OnlyOne; | ||
| 1204 | } | 1219 | } | ||
| 1205 | 1220 | | |||
| 1206 | const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(opt.widget); | 1221 | const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(opt.widget); | ||
| 1207 | 1222 | | |||
| 1223 | bool isColumnView = view && view->parentWidget() && view->parentWidget()->parentWidget() | ||||
| 1224 | && (view->parentWidget()->parentWidget()->inherits("KColumnView") || view->parentWidget()->parentWidget()->inherits("QColumnView")); | ||||
| 1225 | | ||||
| 1208 | // Check if the item is being animated | 1226 | // Check if the item is being animated | ||
| 1209 | // ======================================================================== | 1227 | // ======================================================================== | ||
| 1210 | KIO::AnimationState *state = d->animationState(opt, index, view); | 1228 | KIO::AnimationState *state = d->animationState(opt, index, view); | ||
| 1211 | KIO::CachedRendering *cache = nullptr; | 1229 | KIO::CachedRendering *cache = nullptr; | ||
| 1212 | qreal progress = ((opt.state & QStyle::State_MouseOver) && | 1230 | qreal progress = ((opt.state & QStyle::State_MouseOver) && | ||
| 1213 | index.column() == KDirModel::Name) ? 1.0 : 0.0; | 1231 | index.column() == KDirModel::Name) ? 1.0 : 0.0; | ||
| 1214 | const QPoint iconPos = d->iconPosition(opt); | 1232 | const QPoint iconPos = d->iconPosition(opt); | ||
| 1215 | QIcon::Mode iconMode; | 1233 | QIcon::Mode iconMode; | ||
| Show All 12 Lines | |||||
| 1228 | if (state && !state->hasJobAnimation()) { | 1246 | if (state && !state->hasJobAnimation()) { | ||
| 1229 | cache = state->cachedRendering(); | 1247 | cache = state->cachedRendering(); | ||
| 1230 | progress = state->hoverProgress(); | 1248 | progress = state->hoverProgress(); | ||
| 1231 | // Clear the mouse over bit temporarily | 1249 | // Clear the mouse over bit temporarily | ||
| 1232 | opt.state &= ~QStyle::State_MouseOver; | 1250 | opt.state &= ~QStyle::State_MouseOver; | ||
| 1233 | 1251 | | |||
| 1234 | // If we have a cached rendering, draw the item from the cache | 1252 | // If we have a cached rendering, draw the item from the cache | ||
| 1235 | if (cache) { | 1253 | if (cache) { | ||
| 1236 | if (cache->checkValidity(opt.state) && cache->regular.size() == opt.rect.size()) { | 1254 | if (cache->checkValidity(opt.state, isColumnView) && cache->regular.size() == opt.rect.size()) { | ||
| 1237 | QPixmap pixmap = d->transition(cache->regular, cache->hover, progress); | 1255 | QPixmap pixmap = d->transition(cache->regular, cache->hover, progress); | ||
| 1238 | 1256 | | |||
| 1239 | if (state->cachedRenderingFadeFrom() && state->fadeProgress() != 1.0) { | 1257 | if (state->cachedRenderingFadeFrom() && state->fadeProgress() != 1.0) { | ||
| 1240 | // Apply icon fading animation | 1258 | // Apply icon fading animation | ||
| 1241 | KIO::CachedRendering *fadeFromCache = state->cachedRenderingFadeFrom(); | 1259 | KIO::CachedRendering *fadeFromCache = state->cachedRenderingFadeFrom(); | ||
| 1242 | const QPixmap fadeFromPixmap = d->transition(fadeFromCache->regular, fadeFromCache->hover, progress); | 1260 | const QPixmap fadeFromPixmap = d->transition(fadeFromCache->regular, fadeFromCache->hover, progress); | ||
| 1243 | 1261 | | |||
| 1244 | pixmap = d->transition(fadeFromPixmap, pixmap, state->fadeProgress()); | 1262 | pixmap = d->transition(fadeFromPixmap, pixmap, state->fadeProgress()); | ||
| 1245 | } | 1263 | } | ||
| 1246 | painter->drawPixmap(option.rect.topLeft(), pixmap); | 1264 | painter->drawPixmap(option.rect.topLeft(), pixmap); | ||
| 1247 | if (d->jobTransfersVisible && index.column() == 0) { | 1265 | if (d->jobTransfersVisible && index.column() == 0) { | ||
| 1248 | if (index.data(KDirModel::HasJobRole).toBool()) { | 1266 | if (index.data(KDirModel::HasJobRole).toBool()) { | ||
| 1249 | d->paintJobTransfers(painter, state->jobAnimationAngle(), iconPos, opt); | 1267 | d->paintJobTransfers(painter, state->jobAnimationAngle(), iconPos, opt); | ||
| 1250 | } | 1268 | } | ||
| 1251 | } | 1269 | } | ||
| 1252 | return; | 1270 | return; | ||
| 1253 | } | 1271 | } | ||
| 1254 | 1272 | | |||
| 1255 | if (!cache->checkValidity(opt.state)) { | 1273 | if (!cache->checkValidity(opt.state, isColumnView)) { | ||
| 1256 | if (opt.widget->style()->styleHint(QStyle::SH_Widget_Animate, nullptr, opt.widget)) { | 1274 | if (opt.widget->style()->styleHint(QStyle::SH_Widget_Animate, nullptr, opt.widget)) { | ||
| 1257 | // Fade over from the old icon to the new one | 1275 | // Fade over from the old icon to the new one | ||
| 1258 | // Only start a new fade if the previous one is ready | 1276 | // Only start a new fade if the previous one is ready | ||
| 1259 | // Else we may start racing when checkValidity() always returns false | 1277 | // Else we may start racing when checkValidity() always returns false | ||
| 1260 | if (state->fadeProgress() == 1) { | 1278 | if (state->fadeProgress() == 1) { | ||
| 1261 | state->setCachedRenderingFadeFrom(state->takeCachedRendering()); | 1279 | state->setCachedRenderingFadeFrom(state->takeCachedRendering()); | ||
| 1262 | } | 1280 | } | ||
| 1263 | } | 1281 | } | ||
| 1264 | d->gotNewIcon(index); | 1282 | d->gotNewIcon(index); | ||
| 1265 | } | 1283 | } | ||
| 1266 | // If it wasn't valid, delete it | 1284 | // If it wasn't valid, delete it | ||
| 1267 | state->setCachedRendering(nullptr); | 1285 | state->setCachedRendering(nullptr); | ||
| 1268 | } else { | 1286 | } else { | ||
| 1269 | // The cache may have been discarded, but the animation handler still needs to know about new icons | 1287 | // The cache may have been discarded, but the animation handler still needs to know about new icons | ||
| 1270 | d->gotNewIcon(index); | 1288 | d->gotNewIcon(index); | ||
| 1271 | } | 1289 | } | ||
| 1272 | } | 1290 | } | ||
| 1273 | 1291 | | |||
| 1274 | // Compute the metrics, and lay out the text items | 1292 | // Compute the metrics, and lay out the text items | ||
| 1275 | // ======================================================================== | 1293 | // ======================================================================== | ||
| 1276 | const QPen pen = QPen(d->foregroundBrush(opt, index), 0); | 1294 | const QPen pen = QPen(d->foregroundBrush(opt, index), 0); | ||
| 1277 | 1295 | | |||
| 1296 | bool drawArrow = isColumnView && index.model() && index.model()->hasChildren(index); | ||||
| 1297 | bool reverse = (option.direction == Qt::RightToLeft); | ||||
| 1298 | int arrowWidth = ((option.rect.height() * 2) / 3); | ||||
| 1299 | QStyleOptionViewItem textOpt = opt; | ||||
| 1300 | if (isColumnView) { | ||||
| 1301 | // Modify the options to give us room to add an arrow | ||||
| 1302 | if (reverse) { | ||||
| 1303 | textOpt.rect.adjust(arrowWidth,0,0,0); | ||||
| 1304 | } else { | ||||
| 1305 | textOpt.rect.adjust(0,0,-arrowWidth,0); | ||||
| 1306 | } | ||||
| 1307 | } | ||||
| 1308 | | ||||
| 1278 | //### Apply the selection effect to the icon when the item is selected and | 1309 | //### Apply the selection effect to the icon when the item is selected and | ||
| 1279 | // showDecorationSelected is false. | 1310 | // showDecorationSelected is false. | ||
| 1280 | 1311 | | |||
| 1281 | QTextLayout labelLayout, infoLayout; | 1312 | QTextLayout labelLayout, infoLayout; | ||
| 1282 | QRect textBoundingRect; | 1313 | QRect textBoundingRect; | ||
| 1283 | 1314 | | |||
| 1284 | d->layoutTextItems(opt, index, &labelLayout, &infoLayout, &textBoundingRect); | 1315 | d->layoutTextItems(textOpt, index, &labelLayout, &infoLayout, &textBoundingRect); | ||
| 1285 | 1316 | | |||
| 1286 | QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); | 1317 | QStyle *style = opt.widget ? opt.widget->style() : QApplication::style(); | ||
| 1287 | 1318 | | |||
| 1288 | int focusHMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin); | 1319 | int focusHMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin); | ||
| 1289 | int focusVMargin = style->pixelMetric(QStyle::PM_FocusFrameVMargin); | 1320 | int focusVMargin = style->pixelMetric(QStyle::PM_FocusFrameVMargin); | ||
| 1321 | | ||||
| 1290 | QRect focusRect = textBoundingRect.adjusted(-focusHMargin, -focusVMargin, | 1322 | QRect focusRect = textBoundingRect.adjusted(-focusHMargin, -focusVMargin, | ||
| 1291 | +focusHMargin, +focusVMargin); | 1323 | +focusHMargin, +focusVMargin); | ||
| 1292 | 1324 | | |||
| 1293 | // Create a new cached rendering of a hovered and an unhovered item. | 1325 | // Create a new cached rendering of a hovered and an unhovered item. | ||
| 1294 | // We don't create a new cache for a fully hovered item, since we don't | 1326 | // We don't create a new cache for a fully hovered item, since we don't | ||
| 1295 | // know yet if a hover out animation will be run. | 1327 | // know yet if a hover out animation will be run. | ||
| 1296 | // ======================================================================== | 1328 | // ======================================================================== | ||
| 1297 | if (state && (state->hoverProgress() < 1 || state->fadeProgress() < 1)) { | 1329 | if (state && (state->hoverProgress() < 1 || state->fadeProgress() < 1)) { | ||
| 1298 | #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) | 1330 | #if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) | ||
| 1299 | const qreal dpr = painter->device()->devicePixelRatioF(); | 1331 | const qreal dpr = painter->device()->devicePixelRatioF(); | ||
| 1300 | #else | 1332 | #else | ||
| 1301 | const qreal dpr = painter->device()->devicePixelRatio(); | 1333 | const qreal dpr = painter->device()->devicePixelRatio(); | ||
| 1302 | #endif | 1334 | #endif | ||
| 1303 | 1335 | | |||
| 1304 | cache = new KIO::CachedRendering(opt.state, option.rect.size(), index, dpr); | 1336 | cache = new KIO::CachedRendering(opt.state, option.rect.size(), index, isColumnView, dpr); | ||
| 1305 | 1337 | | |||
| 1306 | QPainter p; | 1338 | QPainter p; | ||
| 1307 | p.begin(&cache->regular); | 1339 | p.begin(&cache->regular); | ||
| 1308 | p.translate(-option.rect.topLeft()); | 1340 | p.translate(-option.rect.topLeft()); | ||
| 1309 | p.setRenderHint(QPainter::Antialiasing); | 1341 | p.setRenderHint(QPainter::Antialiasing); | ||
| 1310 | p.setPen(pen); | 1342 | p.setPen(pen); | ||
| 1311 | style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget); | 1343 | style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget); | ||
| 1312 | p.drawPixmap(iconPos, icon); | 1344 | p.drawPixmap(iconPos, icon); | ||
| 1345 | if (drawArrow) { | ||||
| 1346 | d->drawColumnArrow(&p, opt, arrowWidth); | ||||
| 1347 | } | ||||
| 1313 | d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect); | 1348 | d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect); | ||
| 1314 | d->drawFocusRect(&p, opt, focusRect); | 1349 | d->drawFocusRect(&p, opt, focusRect); | ||
| 1315 | p.end(); | 1350 | p.end(); | ||
| 1316 | 1351 | | |||
| 1317 | opt.state |= QStyle::State_MouseOver; | 1352 | opt.state |= QStyle::State_MouseOver; | ||
| 1318 | icon = d->applyHoverEffect(icon); | 1353 | icon = d->applyHoverEffect(icon); | ||
| 1319 | 1354 | | |||
| 1320 | p.begin(&cache->hover); | 1355 | p.begin(&cache->hover); | ||
| 1321 | p.translate(-option.rect.topLeft()); | 1356 | p.translate(-option.rect.topLeft()); | ||
| 1322 | p.setRenderHint(QPainter::Antialiasing); | 1357 | p.setRenderHint(QPainter::Antialiasing); | ||
| 1323 | p.setPen(pen); | 1358 | p.setPen(pen); | ||
| 1324 | style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget); | 1359 | style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget); | ||
| 1325 | p.drawPixmap(iconPos, icon); | 1360 | p.drawPixmap(iconPos, icon); | ||
| 1361 | if (drawArrow) { | ||||
| 1362 | d->drawColumnArrow(&p, opt, arrowWidth); | ||||
| 1363 | } | ||||
| 1326 | d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect); | 1364 | d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect); | ||
| 1327 | d->drawFocusRect(&p, opt, focusRect); | 1365 | d->drawFocusRect(&p, opt, focusRect); | ||
| 1328 | p.end(); | 1366 | p.end(); | ||
| 1329 | 1367 | | |||
| 1330 | state->setCachedRendering(cache); | 1368 | state->setCachedRendering(cache); | ||
| 1331 | 1369 | | |||
| 1332 | QPixmap pixmap = d->transition(cache->regular, cache->hover, progress); | 1370 | QPixmap pixmap = d->transition(cache->regular, cache->hover, progress); | ||
| 1333 | 1371 | | |||
| Show All 26 Lines | |||||
| 1360 | if (progress > 0 && !(opt.state & QStyle::State_MouseOver)) { | 1398 | if (progress > 0 && !(opt.state & QStyle::State_MouseOver)) { | ||
| 1361 | opt.state |= QStyle::State_MouseOver; | 1399 | opt.state |= QStyle::State_MouseOver; | ||
| 1362 | icon = d->applyHoverEffect(icon); | 1400 | icon = d->applyHoverEffect(icon); | ||
| 1363 | } | 1401 | } | ||
| 1364 | 1402 | | |||
| 1365 | style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); | 1403 | style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget); | ||
| 1366 | painter->drawPixmap(iconPos, icon); | 1404 | painter->drawPixmap(iconPos, icon); | ||
| 1367 | 1405 | | |||
| 1406 | if (drawArrow) { | ||||
| 1407 | d->drawColumnArrow(painter, opt, arrowWidth); | ||||
| 1408 | } | ||||
| 1409 | | ||||
| 1368 | d->drawTextItems(painter, labelLayout, infoLayout, textBoundingRect); | 1410 | d->drawTextItems(painter, labelLayout, infoLayout, textBoundingRect); | ||
| 1369 | d->drawFocusRect(painter, opt, focusRect); | 1411 | d->drawFocusRect(painter, opt, focusRect); | ||
| 1370 | 1412 | | |||
| 1371 | if (d->jobTransfersVisible && index.column() == 0 && state) { | 1413 | if (d->jobTransfersVisible && index.column() == 0 && state) { | ||
| 1372 | if (index.data(KDirModel::HasJobRole).toBool()) { | 1414 | if (index.data(KDirModel::HasJobRole).toBool()) { | ||
| 1373 | d->paintJobTransfers(painter, state->jobAnimationAngle(), iconPos, opt); | 1415 | d->paintJobTransfers(painter, state->jobAnimationAngle(), iconPos, opt); | ||
| 1374 | } | 1416 | } | ||
| 1375 | } | 1417 | } | ||
| ▲ Show 20 Lines • Show All 243 Lines • Show Last 20 Lines | |||||