void RepoItemDelegate::paintRepoCategoryItem(QPainter *painter, const QStyleOptionViewItem& option, const RepoCategoryItem *item) const { QBrush backBrush; QColor foreColor; bool hover = false; bool selected = false; if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = option.palette.brush(QPalette::Highlight); foreColor = option.palette.color(QPalette::HighlightedText); selected = true; } else if (option.state & QStyle::State_MouseOver) { backBrush = option.palette.color(QPalette::Highlight).lighter(115); foreColor = option.palette.color(QPalette::HighlightedText); hover = true; } else { backBrush = option.palette.brush(QPalette::Base); foreColor = option.palette.color(QPalette::Text); } QStyle *style = QApplication::style(); QStyleOptionViewItemV4 opt(option); opt.backgroundBrush = backBrush; painter->save(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0); painter->restore(); // Paint the expand/collapse indicator RepoTreeModel *model = (RepoTreeModel *)item->model(); RepoTreeView *view = model->treeView(); bool expanded = view->isExpanded(model->indexFromItem(item)); QRect indicator_rect(option.rect.topLeft(), option.rect.bottomLeft() + QPoint(option.rect.height(), 0)); painter->save(); painter->setPen(foreColor); painter->setFont(awesome->font(16)); painter->drawText(indicator_rect, Qt::AlignCenter, QChar(expanded ? icon_caret_down : icon_caret_right), &indicator_rect); painter->restore(); // Paint category name painter->save(); QPoint category_name_pos = indicator_rect.topRight() + QPoint(kMarginBetweenIndicatorAndName, 0); QRect category_name_rect(category_name_pos, option.rect.bottomRight() - QPoint(kPadding, 0)); painter->setPen(foreColor); painter->drawText(category_name_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, fitTextToWidth(item->name() + QString().sprintf(" [%d]", item->rowCount()), option.font, category_name_rect.width())); painter->restore(); }
void RepoItemDelegate::paintRepoCategoryItem(QPainter *painter, const QStyleOptionViewItem& option, const RepoCategoryItem *item) const { QBrush backBrush; bool hover = false; bool selected = false; if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = QColor(kRepoCategoryBackgroundColorHighlighted); selected = true; } else { backBrush = QColor(kRepoCategoryBackgroundColor); } painter->save(); painter->fillRect(option.rect, backBrush); painter->restore(); // Paint the expand/collapse indicator RepoTreeModel *model = (RepoTreeModel *)item->model(); RepoTreeView *view = model->treeView(); bool expanded = view->isExpanded(model->indexFromItem(item)); QRect indicator_rect(option.rect.topLeft(), option.rect.bottomLeft() + QPoint(option.rect.height(), 0)); painter->save(); painter->setPen(QColor(selected ? kRepoCategoryColorHighlighted : kRepoCategoryColor)); painter->setFont(awesome->font(16)); painter->drawText(indicator_rect, Qt::AlignCenter, QChar(expanded ? icon_caret_down : icon_caret_right), &indicator_rect); painter->restore(); // Paint category name painter->save(); QPoint category_name_pos = indicator_rect.topRight() + QPoint(kMarginBetweenIndicatorAndName, 0); QRect category_name_rect(category_name_pos, option.rect.bottomRight() - QPoint(kPadding, 0)); painter->setPen(QColor(selected ? kRepoCategoryColorHighlighted : kRepoCategoryColor)); painter->drawText(category_name_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, fitTextToWidth(item->name() + QString().sprintf(" [%d]", item->rowCount()), option.font, category_name_rect.width())); painter->restore(); }
void RepoItemDelegate::paintRepoCategoryItem(QPainter *painter, const QStyleOptionViewItem& option, const RepoCategoryItem *item) const { QBrush backBrush; //bool hover = false; bool selected = false; backBrush = QColor(kRepoCategoryBackgroundColor); if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { selected = true; } painter->save(); painter->fillRect(option.rect, backBrush); painter->restore(); // Paint the expand/collapse indicator RepoTreeModel *model = (RepoTreeModel *)item->model(); RepoTreeView *view = model->treeView(); bool expanded = view->isExpanded(model->indexFromItem(item)); QRect indicator_rect(option.rect.topLeft() + QPoint(kMarginLeft, 0), QSize(kRepoCategoryIndicatorWidth, kRepoCategoryIndicatorHeight)); painter->save(); QString icon_path = QString(":/images/caret-%1.png").arg(expanded ? "down" : "right"); QString icon_2x_path = QString(":/images/caret-%[email protected]").arg(expanded ? "down" : "right"); QIcon icon = QIcon(); icon.addFile(icon_path, QSize(kRepoCategoryIndicatorWidth, kRepoCategoryIndicatorHeight)); icon.addFile(icon_2x_path, QSize(kRepoCategoryIndicatorWidth * 2, kRepoCategoryIndicatorHeight * 2)); painter->drawPixmap(indicator_rect, icon.pixmap(QSize(kRepoCategoryIndicatorWidth, kRepoCategoryIndicatorHeight))); painter->restore(); // Paint category name painter->save(); QPoint category_name_pos = indicator_rect.topRight() + QPoint(kMarginBetweenIndicatorAndName, 0); QRect category_name_rect(category_name_pos, option.rect.bottomRight() - QPoint(kPadding, 0)); // painter->setPen(QColor(selected ? kRepoCategoryColorHighlighted : kRepoCategoryColor)); painter->setPen(QColor(kRepoCategoryColor)); painter->drawText(category_name_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, fitTextToWidth(item->name() + QString().sprintf(" [%d]", item->rowCount()), option.font, category_name_rect.width())); painter->restore(); }
void SearchResultItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const { const SearchResultListModel *model = static_cast<const SearchResultListModel*>(index.model()); QBrush backBrush; bool selected = false; FileSearchResult file = getSearchResult(index); if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = QColor(kFileItemBackgroundColorHighlighted); selected = true; } else { backBrush = QColor(kFileItemBackgroundColor); } // // draw item's background // painter->save(); painter->fillRect(option.rect, backBrush); painter->restore(); QIcon icon = model->data(index, Qt::DecorationRole).value<QIcon>(); // get the device pixel radio from current painter device int scale_factor = 1; #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) scale_factor = painter->device()->devicePixelRatio(); #endif // QT5 QPixmap pixmap(icon.pixmap(QSize(kFileIconWidth, kFileIconHeight) * scale_factor)); #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) if (pixmap.size() != QSize(kFileIconWidth, kFileIconHeight)) pixmap.setDevicePixelRatio(scale_factor); #endif // QT5 // // paint file icon // QPoint file_icon_pos(kMarginLeft + kPadding, kMarginTop + kPadding); file_icon_pos += option.rect.topLeft(); painter->save(); painter->drawPixmap(file_icon_pos, pixmap); painter->restore(); // Calculate the file column by the delta of mainwindow's width QString title = file.name; const int file_name_width = kFileNameWidth + seafApplet->mainWindow()->width() - seafApplet->mainWindow()->minimumWidth(); painter->save(); QPoint file_name_pos = file_icon_pos + QPoint(kFileIconWidth + kMarginBetweenFileIconAndName, -kPadding); QRect file_name_rect(file_name_pos, QSize(file_name_width, kFileNameHeight)); painter->setPen(QColor(selected ? kFileNameColorHighlighted : kFileNameColor)); painter->setFont(changeFontSize(painter->font(), kFileNameFontSize)); painter->drawText(file_name_rect, Qt::AlignLeft | Qt::AlignTop, fitTextToWidth(title, option.font, file_name_width), &file_name_rect); painter->restore(); // // Paint repo_name // int count_of_splash = file.fullpath.endsWith("/") ? 2 : 1; QString subtitle = file.fullpath.mid(1, file.fullpath.size() - count_of_splash - file.name.size()); if (!subtitle.isEmpty()) subtitle = file.repo_name + "/" + subtitle.left(subtitle.size() - 1); else subtitle = file.repo_name; painter->save(); QPoint file_desc_pos = file_name_rect.bottomLeft() + QPoint(0, kPadding / 2); QRect file_desc_rect(file_desc_pos, QSize(file_name_width, kSubtitleHeight)); painter->setFont(changeFontSize(painter->font(), kSubtitleFontSize)); painter->setPen(QColor(selected ? kSubtitleColorHighlighted : kSubtitleColor)); painter->drawText(file_desc_rect, Qt::AlignLeft | Qt::AlignTop, fitTextToWidth(subtitle, option.font, file_name_width), &file_desc_rect); painter->restore(); // // Paint file description // QString size, mtime; size = readableFileSize(file.size); mtime = translateCommitTime(file.last_modified); QString extra_title = size + " " + mtime; painter->save(); QPoint file_extra_pos = file_desc_rect.bottomLeft() + QPoint(0, kPadding / 2 + 2); QRect file_extra_rect(file_extra_pos, QSize(file_name_width, kSubtitleHeight)); painter->setFont(changeFontSize(painter->font(), kSubtitleFontSize)); painter->setPen(QColor(selected ? kSubtitleColorHighlighted : kSubtitleColor)); painter->drawText(file_extra_rect, Qt::AlignLeft | Qt::AlignTop, fitTextToWidth(extra_title, option.font, file_name_width), &file_extra_rect); painter->restore(); // // Draw the bottom border lines // painter->save(); painter->setPen(QPen(QColor(kItemBottomBorderColor), 1, Qt::SolidLine)); painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); painter->restore(); }
void RepoItemDelegate::paintRepoItem(QPainter *painter, const QStyleOptionViewItem& option, const RepoItem *item) const { const ServerRepo& repo = item->repo(); QBrush backBrush; bool selected = false; if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = QColor(kRepoItemBackgroundColorHighlighted); selected = true; } else { backBrush = QColor(kRepoItemBackgroundColor); } painter->save(); painter->fillRect(option.rect, backBrush); painter->restore(); // Paint repo icon QPoint repo_icon_pos(kMarginLeft + kPadding, kMarginTop + kPadding); repo_icon_pos += option.rect.topLeft(); painter->save(); painter->drawPixmap(repo_icon_pos, repo.getPixmap()); painter->restore(); // Paint repo name painter->save(); QPoint repo_name_pos = repo_icon_pos + QPoint(kRepoIconWidth + kMarginBetweenRepoIconAndName, 0); QRect repo_name_rect(repo_name_pos, QSize(kRepoNameWidth, kRepoNameHeight)); painter->setPen(QColor(selected ? kRepoNameColorHighlighted : kRepoNameColor)); painter->setFont(changeFontSize(painter->font(), kRepoNameFontSize)); painter->drawText(repo_name_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, fitTextToWidth(repo.name, option.font, kRepoNameWidth), &repo_name_rect); // Paint repo description QPoint repo_desc_pos = repo_name_rect.bottomLeft() + QPoint(0, 5); QRect repo_desc_rect(repo_desc_pos, QSize(kRepoNameWidth, kRepoNameHeight)); painter->setFont(changeFontSize(painter->font(), kTimestampFontSize)); painter->setPen(QColor(selected ? kTimestampColorHighlighted : kTimestampColor)); QString description; const LocalRepo& r = item->localRepo(); if (r.isValid() && r.sync_state == LocalRepo::SYNC_STATE_ING) { description = r.sync_state_str; int rate, percent; if (seafApplet->rpcClient()->getRepoTransferInfo(r.id, &rate, &percent) == 0) { description += ", " + QString::number(percent) + "%"; } } else { const CloneTask& task = item->cloneTask(); if (task.isValid() && task.isDisplayable()) { if (task.error_str.length() > 0) { description = task.error_str; } else { description = task.state_str; } } else { description = translateCommitTime(repo.mtime); } } painter->drawText(repo_desc_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, fitTextToWidth(description, option.font, kRepoNameWidth), &repo_desc_rect); painter->restore(); // Paint repo status icon QPoint status_icon_pos = option.rect.topRight() - QPoint(40, 0); status_icon_pos.setY(option.rect.center().y() - (kRepoStatusIconHeight / 2)); QRect status_icon_rect(status_icon_pos, QSize(kRepoStatusIconWidth, kRepoStatusIconHeight)); painter->save(); painter->drawPixmap(status_icon_pos, getSyncStatusIcon(item)); painter->restore(); // Update the metrics of this item RepoItem::Metrics metrics; QPoint shift(-option.rect.topLeft().x(), -option.rect.topLeft().y()); metrics.icon_rect = QRect(repo_icon_pos, QSize(kRepoIconWidth, kRepoIconHeight)); metrics.name_rect = repo_name_rect; metrics.subtitle_rect = repo_desc_rect; metrics.status_icon_rect = status_icon_rect; metrics.icon_rect.translate(shift); metrics.name_rect.translate(shift); metrics.subtitle_rect.translate(shift); metrics.status_icon_rect.translate(shift); item->setMetrics(metrics); }
void EventItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QBrush backBrush; bool selected = false; EventItem *item = getItem(index); if (!item) { return; } const SeafEvent& event = item->event(); QString operation_text = event.op_desc; QString time_text = translateCommitTime(event.timestamp); if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = QColor(kEventItemBackgroundColorHighlighted); selected = true; } else { backBrush = QColor(kEventItemBackgroundColor); } painter->save(); painter->fillRect(option.rect, backBrush); painter->restore(); painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::HighQualityAntialiasing); // get the device pixel radio from current painter device double scale_factor = 1; #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) scale_factor = globalDevicePixelRatio(); #endif // QT5 // paint avatar QImage avatar; if (!event.anonymous) { avatar = AvatarService::instance()->getAvatar(event.author); } QRect actualRect(0, 0, kAvatarWidth * scale_factor , kAvatarHeight * scale_factor); avatar.scaled(actualRect.size()); QImage masked_image(actualRect.size(), QImage::Format_ARGB32_Premultiplied); masked_image.fill(Qt::transparent); QPainter mask_painter; mask_painter.begin(&masked_image); mask_painter.setRenderHint(QPainter::Antialiasing); mask_painter.setRenderHint(QPainter::HighQualityAntialiasing); mask_painter.setCompositionMode(QPainter::CompositionMode_SourceOver); mask_painter.setPen(Qt::NoPen); mask_painter.setBrush(Qt::white); mask_painter.drawEllipse(actualRect); mask_painter.setCompositionMode(QPainter::CompositionMode_SourceIn); mask_painter.drawImage(actualRect, avatar); mask_painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); mask_painter.fillRect(actualRect, Qt::transparent); mask_painter.end(); masked_image.setDevicePixelRatio(scale_factor); QPoint avatar_pos(kMarginLeft + kPadding, kMarginTop + kPadding); avatar_pos += option.rect.topLeft(); painter->save(); painter->drawImage(avatar_pos, masked_image); painter->restore(); auto time_font = changeFontSize(painter->font(), kTimeFontSize); auto nick_font = changeFontSize(painter->font(), kNickFontSize); auto operation_font = changeFontSize(painter->font(), kOperationFontSize); auto desc_font = changeFontSize(painter->font(), kDescriptionFontSize); auto repo_name_font = time_font; const int operation_width = ::textWidthInFont(operation_text, operation_font); const int time_width = qMin(kTimeWidth, ::textWidthInFont(time_text, time_font)); int nick_width; if (event.is_use_new_activities_api) { nick_width = option.rect.width() - kMarginLeft - kAvatarWidth - kMarginBetweenAvatarAndNick - kMarginBetweenNickAndOperation - operation_width - kMarginBetweenOperationAndTime - time_width - kPadding * 2 - kMarginRight; } else { nick_width = option.rect.width() - kMarginLeft - kAvatarWidth - kMarginBetweenAvatarAndNick - time_width - kMarginBetweenNickAndTime - kPadding * 2 - kMarginRight; } nick_width = qMin(nick_width, ::textWidthInFont(event.nick, nick_font)); // Paint nick name QPoint nick_pos = avatar_pos + QPoint(kAvatarWidth + kMarginBetweenAvatarAndNick, 0); QRect nick_rect(nick_pos, QSize(nick_width, kNickHeight)); painter->save(); painter->setPen(QColor(selected ? kNickColorHighlighted : kNickColor)); painter->setFont(nick_font); painter->drawText(nick_rect, Qt::AlignLeft | Qt::AlignTop, fitTextToWidth(event.nick, option.font, nick_width), &nick_rect); painter->restore(); // Paint operation name if (event.is_use_new_activities_api) { QPoint operation_pos = nick_pos + QPoint(nick_width + kMarginBetweenNickAndOperation, 3); QRect operation_rect(operation_pos, QSize(operation_width + 8, kOperationHeight)); painter->save(); QPainterPath path; path.addRoundedRect(operation_rect, kRadius, kRadius); painter->fillPath(path, QColor(kOperRectFillColor)); painter->setPen(QColor(kOperationColor)); painter->setFont(operation_font); painter->drawText(operation_rect, Qt::AlignCenter, fitTextToWidth(operation_text, option.font, operation_width), &operation_rect); painter->restore(); } // Paint event time painter->save(); QPoint time_pos = option.rect.topRight() + QPoint(-time_width - kPadding - kMarginRight, kMarginTop + kPadding); QRect time_rect(time_pos, QSize(time_width, kTimeHeight)); painter->setPen(QColor(selected ? kTimeColorHighlighted : kTimeColor)); painter->setFont(time_font); painter->drawText(time_rect, Qt::AlignRight | Qt::AlignTop, time_text, &time_rect); painter->restore(); // Paint description painter->save(); QString desc = event.desc; int repo_name_width = qMin(kRepoNameWidth, ::textWidthInFont(event.repo_name, repo_name_font)); int desc_width = option.rect.width() - kMarginLeft - kAvatarWidth - kMarginBetweenAvatarAndNick - kMarginBetweenRepoNameAndDesc - repo_name_width - kMarginRight - kPadding * 2; const int desc_height = ::textHeightInFont(desc, desc_font) * 2; // const QPoint event_desc_pos = option.rect.bottomLeft() + QPoint(nick_rect.left(), - desc_height - kExtraPadding - kMarginBottom); const QPoint event_desc_pos = nick_rect.bottomLeft() + QPoint(0, kVerticalMarginBetweenNickAndDesc); QRect event_desc_rect(event_desc_pos, QSize(desc_width, desc_height)); painter->setFont(desc_font); painter->setPen(QColor(selected ? kDescriptionColorHighlighted : kDescriptionColor)); desc.replace(QChar('\n'), QChar(' ')); painter->drawText(event_desc_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere, // we have two lines fitTextToWidth(desc, desc_font, desc_width * 2), &event_desc_rect); painter->restore(); // Paint repo name painter->save(); repo_name_width += desc_width - event_desc_rect.width(); // if (index.row() == 1) { // printf ("width diff = %d\n", desc_width - event_desc_rect.width()); // } const int repo_name_height = ::textHeightInFont(event.repo_name, repo_name_font); const QPoint event_repo_name_pos = option.rect.bottomRight() + QPoint(-repo_name_width - kPadding - kMarginRight, -repo_name_height - kExtraPadding - kMarginBottom); QRect event_repo_name_rect(event_repo_name_pos, QSize(repo_name_width, kNickHeight)); painter->setFont(repo_name_font); painter->setPen(QColor(selected ? kRepoNameColorHighlighted : kRepoNameColor)); painter->drawText( event_repo_name_rect, Qt::AlignRight | Qt::AlignTop | Qt::TextSingleLine, fitTextToWidth(event.repo_name, repo_name_font, repo_name_width), &event_repo_name_rect); painter->restore(); // const EventsListModel *model = (const EventsListModel*)index.model(); // // Draw the bottom border lines except for the last item (if the "load more" is present") // We minus 2 here becase: // 1) the row index starts from 0 // 2) we addded a row for the "load more" data in the end // if (model->loadMoreIndex().isValid() && index.row() == model->rowCount() - 2) { // return; // } painter->save(); painter->setPen(QPen(QColor(kItemBottomBorderColor), 1, Qt::SolidLine)); QPoint left = option.rect.bottomLeft(); left.setY(left.y() + 1); QPoint right = option.rect.bottomRight(); right.setY(right.y() + 1); painter->drawLine(left, right); painter->restore(); }
void RepoItemDelegate::paintRepoItem(QPainter *painter, const QStyleOptionViewItem& option, const RepoItem *item) const { const ServerRepo& repo = item->repo(); QBrush backBrush; QColor foreColor; bool hover = false; bool selected = false; if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = option.palette.brush(QPalette::Highlight); foreColor = option.palette.color(QPalette::HighlightedText); selected = true; } else if (option.state & QStyle::State_MouseOver) { // backBrush = option.palette.color( QPalette::Highlight ).lighter(115); // foreColor = option.palette.color( QPalette::HighlightedText ); // hover = true; } else { backBrush = option.palette.brush( QPalette::Base ); foreColor = option.palette.color( QPalette::Text ); } QStyle *style = QApplication::style(); QStyleOptionViewItemV4 opt(option); if (hover) { Qt::BrushStyle bs = opt.backgroundBrush.style(); if (bs > Qt::NoBrush && bs < Qt::TexturePattern) opt.backgroundBrush = opt.backgroundBrush.color().lighter(115); else opt.backgroundBrush = backBrush; } painter->save(); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, 0); painter->restore(); // Paint repo icon QPoint repo_icon_pos(kMarginLeft + kPadding, kMarginTop + kPadding); repo_icon_pos += option.rect.topLeft(); painter->save(); painter->drawPixmap(repo_icon_pos, repo.getPixmap().scaled(kRepoIconWidth, kRepoIconHeight)); painter->restore(); // Paint repo name painter->save(); QPoint repo_name_pos = repo_icon_pos + QPoint(kRepoIconWidth + kMarginBetweenRepoIconAndName, 0); QRect repo_name_rect(repo_name_pos, QSize(kRepoNameWidth, kRepoNameHeight)); painter->setPen(foreColor); painter->drawText(repo_name_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, fitTextToWidth(repo.name, option.font, kRepoNameWidth), &repo_name_rect); // Paint repo description QPoint repo_desc_pos = repo_name_rect.bottomLeft() + QPoint(0, 5); QRect repo_desc_rect(repo_desc_pos, QSize(kRepoNameWidth, kRepoNameHeight)); painter->setPen(selected ? foreColor.darker(115) : foreColor.lighter(150)); painter->setFont(zoomFont(painter->font(), 0.8)); painter->drawText(repo_desc_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, fitTextToWidth(translateCommitTime(repo.mtime), option.font, kRepoNameWidth), &repo_desc_rect); painter->restore(); // Paint repo status icon QPoint status_icon_pos = option.rect.topRight() - QPoint(80, 0); QRect status_icon_rect(status_icon_pos, option.rect.bottomRight()); if (!item->localRepo().isValid() || item->localRepo().sync_state != LocalRepo::SYNC_STATE_WAITING) { painter->save(); painter->setFont(awesome->font(kRepoStatusIconHeight)); if (selected) painter->setPen(QColor("white")); else painter->setPen(QColor("#f17f49")); painter->drawText(status_icon_rect, Qt::AlignCenter, getSyncStatusIcon(item), &status_icon_rect); painter->restore(); } // Update the metrics of this item RepoItem::Metrics metrics; QPoint shift(-option.rect.topLeft().x(), -option.rect.topLeft().y()); metrics.icon_rect = QRect(repo_icon_pos, QSize(kRepoIconWidth, kRepoIconHeight)); metrics.name_rect = repo_name_rect; metrics.subtitle_rect = repo_desc_rect; metrics.status_icon_rect = status_icon_rect; metrics.icon_rect.translate(shift); metrics.name_rect.translate(shift); metrics.subtitle_rect.translate(shift); metrics.status_icon_rect.translate(shift); item->setMetrics(metrics); }
void EventItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { QBrush backBrush; bool selected = false; EventItem *item = getItem(index); const SeafEvent& event = item->event(); QString time_text = translateCommitTime(event.timestamp); if (option.state & (QStyle::State_HasFocus | QStyle::State_Selected)) { backBrush = QColor(kEventItemBackgroundColorHighlighted); selected = true; } else { backBrush = QColor(kEventItemBackgroundColor); } painter->save(); painter->fillRect(option.rect, backBrush); painter->restore(); painter->setRenderHint(QPainter::Antialiasing); painter->setRenderHint(QPainter::HighQualityAntialiasing); // get the device pixel radio from current painter device int scale_factor = 1; #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) scale_factor = painter->device()->devicePixelRatio(); #endif // QT5 // paint avatar QImage avatar; if (!event.anonymous) { avatar = AvatarService::instance()->getAvatar(event.author); } QRect actualRect(0, 0, kAvatarWidth * scale_factor , kAvatarHeight * scale_factor); avatar.scaled(actualRect.size()); QImage masked_image(actualRect.size(), QImage::Format_ARGB32_Premultiplied); masked_image.fill(Qt::transparent); QPainter mask_painter; mask_painter.begin(&masked_image); mask_painter.setRenderHint(QPainter::Antialiasing); mask_painter.setRenderHint(QPainter::HighQualityAntialiasing); mask_painter.setCompositionMode(QPainter::CompositionMode_SourceOver); mask_painter.setPen(Qt::NoPen); mask_painter.setBrush(Qt::white); mask_painter.drawEllipse(actualRect); mask_painter.setCompositionMode(QPainter::CompositionMode_SourceIn); mask_painter.drawImage(actualRect, avatar); mask_painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); mask_painter.fillRect(actualRect, Qt::transparent); mask_painter.end(); #if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)) masked_image.setDevicePixelRatio(scale_factor); #endif // QT5 QPoint avatar_pos(kMarginLeft + kPadding, kMarginTop + kPadding); avatar_pos += option.rect.topLeft(); painter->save(); painter->drawImage(avatar_pos, masked_image); painter->restore(); const int time_width = qMin(kTimeWidth, ::textWidthInFont(time_text, changeFontSize(painter->font(), kTimeFontSize))); int nick_width = option.rect.width() - kMarginLeft - kAvatarWidth - kMarginBetweenAvatarAndNick - time_width - kMarginBetweenNickAndTime - kPadding * 2 - kMarginRight; nick_width = qMin(nick_width, ::textWidthInFont(event.nick, changeFontSize(painter->font(), kNickFontSize))); // Paint nick name QPoint nick_pos = avatar_pos + QPoint(kAvatarWidth + kMarginBetweenAvatarAndNick, 0); QRect nick_rect(nick_pos, QSize(nick_width, kNickHeight)); painter->save(); painter->setPen(QColor(selected ? kNickColorHighlighted : kNickColor)); painter->setFont(changeFontSize(painter->font(), kNickFontSize)); painter->drawText(nick_rect, Qt::AlignLeft | Qt::AlignTop, fitTextToWidth(event.nick, option.font, nick_width), &nick_rect); painter->restore(); // Paint event time painter->save(); QPoint time_pos = option.rect.topRight() + QPoint(-time_width - kPadding - kMarginRight, kMarginTop + kPadding); QRect time_rect(time_pos, QSize(time_width, kTimeHeight)); painter->setPen(QColor(selected ? kTimeColorHighlighted : kTimeColor)); painter->setFont(changeFontSize(painter->font(), kTimeFontSize)); painter->drawText(time_rect, Qt::AlignRight | Qt::AlignTop, time_text, &time_rect); painter->restore(); // Paint description painter->save(); const int repo_name_width = qMin(kRepoNameWidth, ::textWidthInFont(event.repo_name, changeFontSize(painter->font(), kTimeFontSize))); const int repo_name_height = ::textHeightInFont(event.repo_name, changeFontSize(painter->font(), kTimeFontSize)); int desc_width = option.rect.width() - kMarginLeft - kAvatarWidth - kMarginBetweenAvatarAndNick - kPadding * 3 - kMarginBetweenRepoNameAndDesc - repo_name_width - kMarginRight; desc_width = qMin(desc_width, ::textWidthInFont(event.desc, changeFontSize(painter->font(), kDescriptionFontSize))); const int desc_height = ::textHeightInFont(event.desc, changeFontSize(painter->font(), kDescriptionFontSize)) * 2; const QPoint event_desc_pos = option.rect.bottomLeft() + QPoint(nick_rect.left(), - desc_height - kExtraPadding - kMarginBottom); QRect event_desc_rect(event_desc_pos, QSize(desc_width, desc_height)); painter->setFont(changeFontSize(painter->font(), kDescriptionFontSize)); painter->setPen(QColor(selected ? kDescriptionColorHighlighted : kDescriptionColor)); QString desc = event.desc; desc.replace(QChar('\n'), QChar(' ')); painter->drawText(event_desc_rect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWrapAnywhere, // we have two lines fitTextToWidth(desc, option.font, desc_width * 2), &event_desc_rect); painter->restore(); // Paint repo name painter->save(); const QPoint event_repo_name_pos = option.rect.bottomRight() + QPoint(-repo_name_width - kPadding - kMarginRight, -repo_name_height - kExtraPadding - kMarginBottom); QRect event_repo_name_rect(event_repo_name_pos, QSize(repo_name_width, kNickHeight)); painter->setFont(changeFontSize(painter->font(), kTimeFontSize)); painter->setPen(QColor(selected ? kRepoNameColorHighlighted : kRepoNameColor)); painter->drawText(event_repo_name_rect, Qt::AlignRight | Qt::AlignTop | Qt::TextSingleLine, fitTextToWidth(event.repo_name, option.font, repo_name_width), &event_repo_name_rect); painter->restore(); // Draw the bottom border lines painter->save(); painter->setPen(QPen(QColor(kItemBottomBorderColor), 1, Qt::SolidLine)); painter->drawLine(option.rect.bottomLeft(), option.rect.bottomRight()); painter->restore(); }