Fix size and image quality issues with new user icons (#5546)

This commit is contained in:
RickyRister 2025-02-02 07:08:23 -08:00 committed by GitHub
parent a0b52ce450
commit 1de09deb59
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 50 additions and 18 deletions

View file

@ -809,10 +809,10 @@ void TabSupervisor::processUserJoined(const ServerInfo_User &userInfoJoined)
if (auto *tab = getTabAccount()) {
if (tab != currentWidget()) {
tab->setContentsChanged(true);
QPixmap avatarPixmap = UserLevelPixmapGenerator::generatePixmap(
QIcon avatarIcon = UserLevelPixmapGenerator::generateIcon(
13, (UserLevelFlags)userInfoJoined.user_level(), userInfoJoined.pawn_colors(), true,
QString::fromStdString(userInfoJoined.privlevel()));
setTabIcon(indexOf(tab), QPixmap(avatarPixmap));
setTabIcon(indexOf(tab), avatarIcon);
}
}

View file

@ -129,9 +129,18 @@ void setAttrRecur(QDomElement &elem,
}
/**
* Returns an icon of the svg that has its color filled in
* Loads the usericon svg and fills in its colors.
* The image is kept as a QIcon to preserve the image quality.
*
* Call icon.pixmap(w, h) in order to convert this icon into a pixmap with the given dimensions.
* Avoid scaling the pixmap in other ways, as that destroys image quality.
*
* @param minSize If the dimensions of the source svg is smaller than this, then it will be scaled up to this size
*/
QIcon changeSVGColor(const QString &iconPath, const QString &colorLeft, const std::optional<QString> &colorRight)
static QIcon loadAndColorSvg(const QString &iconPath,
const QString &colorLeft,
const std::optional<QString> &colorRight,
const int minSize)
{
QFile file(iconPath);
if (!file.open(QIODevice::ReadOnly)) {
@ -152,7 +161,7 @@ QIcon changeSVGColor(const QString &iconPath, const QString &colorLeft, const st
QSvgRenderer svgRenderer(doc.toByteArray());
QPixmap pix(svgRenderer.defaultSize());
QPixmap pix(svgRenderer.defaultSize().expandedTo(QSize(minSize, minSize)));
pix.fill(Qt::transparent);
QPainter pixPainter(&pix);
@ -171,7 +180,7 @@ QPixmap UserLevelPixmapGenerator::generatePixmap(int height,
return generateIcon(height, userLevel, pawnColorsOverride, isBuddy, privLevel).pixmap(height, height);
}
QIcon UserLevelPixmapGenerator::generateIcon(int height,
QIcon UserLevelPixmapGenerator::generateIcon(int minHeight,
UserLevelFlags userLevel,
ServerInfo_User::PawnColorsOverride pawnColorsOverride,
bool isBuddy,
@ -189,11 +198,11 @@ QIcon UserLevelPixmapGenerator::generateIcon(int height,
// Has Color Override
if (colorLeft.has_value()) {
return generateIconWithColorOverride(height, isBuddy, privLevel, colorLeft, colorRight);
return generateIconWithColorOverride(minHeight, isBuddy, privLevel, colorLeft, colorRight);
}
// Has No Color Override
return generateIconDefault(height, userLevel, isBuddy, privLevel);
return generateIconDefault(minHeight, userLevel, isBuddy, privLevel);
}
QIcon UserLevelPixmapGenerator::generateIconDefault(int height,
@ -263,7 +272,7 @@ QIcon UserLevelPixmapGenerator::generateIconWithColorOverride(int height,
QString iconPath = QString("theme:usericons/%1_%2.svg").arg(iconType).arg(arity);
QIcon icon(changeSVGColor(iconPath, colorLeft.value(), colorRight));
QIcon icon = loadAndColorSvg(iconPath, colorLeft.value(), colorRight, height);
iconCache.insert(key, icon);
return icon;
}

View file

@ -81,7 +81,7 @@ public:
bool isBuddy,
const QString &privLevel);
static QIcon generateIcon(int height,
static QIcon generateIcon(int minHeight,
UserLevelFlags userLevel,
ServerInfo_User::PawnColorsOverride pawnColors,
bool isBuddy,

View file

@ -50,6 +50,7 @@ GameSelector::GameSelector(AbstractClient *_client,
} else {
gameListView->setModel(gameListModel);
}
gameListView->setIconSize(QSize(13, 13));
gameListView->setSortingEnabled(true);
gameListView->sortByColumn(gameListModel->startTimeColIndex(), Qt::AscendingOrder);
gameListView->setAlternatingRowColors(true);

View file

@ -118,11 +118,10 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const
case Qt::DisplayRole:
return QString::fromStdString(gameentry.creator_info().name());
case Qt::DecorationRole: {
QPixmap avatarPixmap = UserLevelPixmapGenerator::generatePixmap(
13, (UserLevelFlags)gameentry.creator_info().user_level(),
return UserLevelPixmapGenerator::generateIcon(
13, UserLevelFlags(gameentry.creator_info().user_level()),
gameentry.creator_info().pawn_colors(), false,
QString::fromStdString(gameentry.creator_info().privlevel()));
return QIcon(avatarPixmap);
}
default:
return QVariant();

View file

@ -140,9 +140,9 @@ void PlayerListWidget::updatePlayerProperties(const ServerInfo_PlayerProperties
}
if (prop.has_user_info()) {
player->setData(3, Qt::UserRole, prop.user_info().user_level());
player->setIcon(3, QIcon(UserLevelPixmapGenerator::generatePixmap(
player->setIcon(3, UserLevelPixmapGenerator::generateIcon(
12, UserLevelFlags(prop.user_info().user_level()), prop.user_info().pawn_colors(), false,
QString::fromStdString(prop.user_info().privlevel()))));
QString::fromStdString(prop.user_info().privlevel())));
player->setText(4, QString::fromStdString(prop.user_info().name()));
const QString country = QString::fromStdString(prop.user_info().country());
if (!country.isEmpty())

View file

@ -9,6 +9,7 @@
#include "../pending_command.h"
#include "passwordhasher.h"
#include "pb/response_get_user_info.pb.h"
#include "pb/serverinfo_user.pb.h"
#include "pb/session_commands.pb.h"
#include <QDateTime>
@ -84,14 +85,27 @@ void UserInfoBox::retranslateUi()
avatarButton.setText(tr("Change avatar"));
}
/**
* Creates the default profile pic that is used when the user doesn't have a custom pic
*/
static QPixmap createDefaultAvatar(int height, const ServerInfo_User &user)
{
return UserLevelPixmapGenerator::generatePixmap(height, UserLevelFlags(user.user_level()), user.pawn_colors(),
false, QString::fromStdString(user.privlevel()));
}
void UserInfoBox::updateInfo(const ServerInfo_User &user)
{
currentUserInfo = &user;
const UserLevelFlags userLevel(user.user_level());
const std::string &bmp = user.avatar_bmp();
if (!avatarPixmap.loadFromData((const uchar *)bmp.data(), static_cast<uint>(bmp.size()))) {
avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, userLevel, user.pawn_colors(), false,
QString::fromStdString(user.privlevel()));
avatarPixmap = createDefaultAvatar(64, user);
hasAvatar = false;
} else {
hasAvatar = true;
}
nameLabel.setText(QString::fromStdString(user.name()));
@ -363,7 +377,14 @@ void UserInfoBox::processAvatarResponse(const Response &r)
void UserInfoBox::resizeEvent(QResizeEvent *event)
{
QPixmap resizedPixmap = avatarPixmap.scaled(avatarPic.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmap resizedPixmap;
if (hasAvatar) {
resizedPixmap = avatarPixmap.scaled(avatarPic.size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
} else {
int height = qMin(avatarPic.size().width(), avatarPic.size().height());
resizedPixmap = createDefaultAvatar(height, *currentUserInfo);
}
avatarPic.setPixmap(resizedPixmap);
QWidget::resizeEvent(event);
}

View file

@ -20,6 +20,8 @@ private:
countryLabel3, userLevelLabel1, userLevelLabel2, accountAgeLabel1, accountAgeLabel2;
QPushButton editButton, passwordButton, avatarButton;
QPixmap avatarPixmap;
bool hasAvatar;
const ServerInfo_User *currentUserInfo;
static QString getAgeString(int ageSeconds);