ExtensionManager: Implement badge for recently published items

This adds a "New" onto the upper left card corner for recently published
items. For QtC 15, we mark all remote extensions as recently published.

Fixes: QTCREATORBUG-31587
Change-Id: If460f33ebb76c72bb1af6935deb2db7678dcf550
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
Alessandro Portale
2024-10-02 19:24:15 +02:00
parent 7d75b0a2a7
commit 927bd79488
4 changed files with 53 additions and 4 deletions

View File

@@ -267,6 +267,10 @@ public:
const QPixmap icon = itemIcon(index, SizeSmall);
painter->drawPixmap(iconBgR.topLeft(), icon);
}
{
const QPixmap badge = itemBadge(index, SizeSmall);
painter->drawPixmap(bgR.topLeft(), badge);
}
if (isPack) {
constexpr int circleSize = 18;
constexpr int circleOverlap = 3; // Protrusion from lower right corner of iconRect
@@ -700,6 +704,8 @@ QLabel *tfLabel(const TextFormat &tf, bool singleLine)
return label;
}
const int iconRectRounding = 4;
QPixmap itemIcon(const QModelIndex &index, Size size)
{
const QSize iconBgS = size == SizeSmall ? iconBgSizeSmall : iconBgSizeBig;
@@ -730,7 +736,6 @@ QPixmap itemIcon(const QModelIndex &index, Size size)
const ItemType itemType = index.data(RoleItemType).value<ItemType>();
const QIcon &icon = (itemType == ItemTypePack) ? (size == SizeSmall ? packS : packB)
: (size == SizeSmall ? extensionS : extensionB);
const int iconRectRounding = 4;
const qreal iconOpacityDisabled = 0.6;
QPainter p(&pixmap);
@@ -744,4 +749,33 @@ QPixmap itemIcon(const QModelIndex &index, Size size)
return pixmap;
}
QPixmap itemBadge(const QModelIndex &index, [[maybe_unused]] Size size)
{
const QString badgeText = index.data(RoleBadge).toString();
if (badgeText.isNull())
return {};
constexpr TextFormat badgeTF
{Theme::Token_Basic_White, UiElement::UiElementLabelSmall};
const QFont font = badgeTF.font();
const int textWidth = QFontMetrics(font).horizontalAdvance(badgeText);
const QSize badgeS(ExPaddingGapM + textWidth + ExPaddingGapM,
ExPaddingGapS + badgeTF.lineHeight() + ExPaddingGapS);
const QRect badgeR(QPoint(), badgeS);
const qreal dpr = qApp->devicePixelRatio();
QPixmap pixmap(badgeS * dpr);
pixmap.fill(Qt::transparent);
pixmap.setDevicePixelRatio(dpr);
QPainter p(&pixmap);
WelcomePageHelpers::drawCardBackground(&p, badgeR,
creatorColor(Theme::Token_Notification_Neutral),
Qt::NoPen, iconRectRounding);
p.setFont(font);
p.setPen(badgeTF.color());
p.drawText(badgeR, Qt::AlignCenter, badgeText);
return pixmap;
}
} // ExtensionManager::Internal

View File

@@ -50,5 +50,6 @@ enum Size {
SizeBig,
};
QPixmap itemIcon(const QModelIndex &index, Size size);
QPixmap itemBadge(const QModelIndex &index, Size size);
} // ExtensionManager::Internal

View File

@@ -240,6 +240,13 @@ int ExtensionsModel::rowCount([[maybe_unused]] const QModelIndex &parent) const
return d->responseItems.count() + d->localPlugins.count();
}
static QString badgeText(const QModelIndex &index)
{
if (index.data(RoleDownloadUrl).isNull())
return {};
return Tr::tr("New");
}
ExtensionState extensionState(const QModelIndex &index)
{
if (index.data(RoleItemType) != ItemTypeExtension)
@@ -265,10 +272,16 @@ static QString searchText(const QModelIndex &index)
QVariant ExtensionsModel::data(const QModelIndex &index, int role) const
{
if (role == RoleExtensionState)
switch (role) {
case RoleBadge:
return badgeText(index);
case RoleExtensionState:
return extensionState(index);
if (role == RoleSearchText)
case RoleSearchText:
return searchText(index);
default:
break;
}
const bool isRemoteExtension = index.row() < d->responseItems.count();
const int itemIndex = index.row() - (isRemoteExtension ? 0 : d->responseItems.count());

View File

@@ -27,7 +27,9 @@ enum ExtensionState {
enum Role {
RoleName = Qt::UserRole,
RoleBadge,
RoleCopyright,
RoleDateUpdated,
RoleDependencies,
RoleDescriptionLong,
RoleDescriptionShort,
@@ -39,7 +41,6 @@ enum Role {
RoleLicense,
RolePlatforms,
RolePlugins,
RoleDateUpdated,
RoleSearchText,
RoleTags,
RoleVendor,