diff --git a/cockatrice/resources/usericons/pawn_double.svg b/cockatrice/resources/usericons/pawn_double.svg index 4f1541180..b9f72d385 100644 --- a/cockatrice/resources/usericons/pawn_double.svg +++ b/cockatrice/resources/usericons/pawn_double.svg @@ -2,293 +2,267 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - + width="100" + height="100" + id="svg5322" + version="1.1" + inkscape:version="1.4 (86a8ad7, 2024-10-11)" + sodipodi:docname="pawn_double.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + - - - - - - - - - - - + id="g5249" + transform="translate(0.53874115,0.90502985)"> + + + + diff --git a/cockatrice/resources/usericons/pawn_single.svg b/cockatrice/resources/usericons/pawn_single.svg index a6b5f9a15..2f0c94ae8 100644 --- a/cockatrice/resources/usericons/pawn_single.svg +++ b/cockatrice/resources/usericons/pawn_single.svg @@ -2,249 +2,252 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - + width="100" + height="100" + id="svg5322" + version="1.1" + inkscape:version="1.4 (86a8ad7, 2024-10-11)" + sodipodi:docname="pawn_single.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + diff --git a/cockatrice/src/client/tabs/tab_supervisor.cpp b/cockatrice/src/client/tabs/tab_supervisor.cpp index a665d8df2..49090d1fc 100644 --- a/cockatrice/src/client/tabs/tab_supervisor.cpp +++ b/cockatrice/src/client/tabs/tab_supervisor.cpp @@ -809,9 +809,9 @@ void TabSupervisor::processUserJoined(const ServerInfo_User &userInfoJoined) if (auto *tab = getTabAccount()) { if (tab != currentWidget()) { tab->setContentsChanged(true); - QPixmap avatarPixmap = - UserLevelPixmapGenerator::generatePixmap(13, (UserLevelFlags)userInfoJoined.user_level(), true, - QString::fromStdString(userInfoJoined.privlevel())); + QPixmap avatarPixmap = UserLevelPixmapGenerator::generatePixmap( + 13, (UserLevelFlags)userInfoJoined.user_level(), userInfoJoined.pawn_colors(), true, + QString::fromStdString(userInfoJoined.privlevel())); setTabIcon(indexOf(tab), QPixmap(avatarPixmap)); } } diff --git a/cockatrice/src/client/ui/pixel_map_generator.cpp b/cockatrice/src/client/ui/pixel_map_generator.cpp index 4564b7ad2..304944290 100644 --- a/cockatrice/src/client/ui/pixel_map_generator.cpp +++ b/cockatrice/src/client/ui/pixel_map_generator.cpp @@ -100,90 +100,153 @@ QPixmap CountryPixmapGenerator::generatePixmap(int height, const QString &countr QMap CountryPixmapGenerator::pmCache; -void SetAttrRecur(QDomElement &elem, QString tagName, QString attrName, QString attrValue) +void SetAttrRecur(QDomElement &elem, + const QString &tagName, + const QString &attrName, + const QString &idName, + const QString &attrValue) { - // if it has the tagname then overwritte desired attribute if (elem.tagName().compare(tagName) == 0) { - elem.setAttribute(attrName, attrValue); + if (elem.attribute("id").compare(idName) == 0) { + elem.setAttribute(attrName, attrValue); + } } - // loop all children + for (int i = 0; i < elem.childNodes().count(); i++) { if (!elem.childNodes().at(i).isElement()) { continue; } - QDomElement docElem = elem.childNodes().at(i).toElement(); //<-- make const "variable" - SetAttrRecur(docElem, tagName, attrName, attrValue); + auto docElem = elem.childNodes().at(i).toElement(); + SetAttrRecur(docElem, tagName, attrName, idName, attrValue); } } -QIcon changeSVGColor(const QString &iconPath, const QString &color) +QIcon changeSVGColor(const QString &iconPath, const QString &colorLeft, const std::optional &colorRight) { - // open svg resource load contents to qbytearray QFile file(iconPath); - if (!file.open(QIODevice::ReadOnly)) + if (!file.open(QIODevice::ReadOnly)) { return {}; - QByteArray baData = file.readAll(); - // load svg contents to xml document and edit contents + } + + const auto &baData = file.readAll(); QDomDocument doc; doc.setContent(baData); - // recurivelly change color - QDomElement docElem = doc.documentElement(); //<-- make const "variable" - qDebug() << docElem.text(); - SetAttrRecur(docElem, "path", "fill", color); - // create svg renderer with edited contents + + auto docElem = doc.documentElement(); + + SetAttrRecur(docElem, "path", "fill", "left", colorLeft); + if (colorRight.has_value()) { + SetAttrRecur(docElem, "path", "fill", "right", colorRight.value()); + } + + qDebug() << "ZACH" << doc.toString(); + QSvgRenderer svgRenderer(doc.toByteArray()); - // create pixmap target (could be a QImage) + QPixmap pix(svgRenderer.defaultSize()); pix.fill(Qt::transparent); - // create painter to act over pixmap + QPainter pixPainter(&pix); - // use renderer to render over painter which paints on pixmap svgRenderer.render(&pixPainter); QIcon myicon(pix); + return myicon; } -QPixmap UserLevelPixmapGenerator::generatePixmap(int height, UserLevelFlags userLevel, bool isBuddy, QString privLevel) +QPixmap UserLevelPixmapGenerator::generatePixmap(int height, + UserLevelFlags userLevel, + ServerInfo_User::PawnColorsOverride pawnColorsOverride, + bool isBuddy, + QString privLevel) { - return generateIcon(height, userLevel, isBuddy, privLevel).pixmap(QSize()); + return generateIcon(height, userLevel, pawnColorsOverride, isBuddy, privLevel).pixmap(height, height); } -QIcon UserLevelPixmapGenerator::generateIcon(int height, UserLevelFlags userLevel, bool isBuddy, QString privLevel) +QIcon UserLevelPixmapGenerator::generateIcon(int height, + UserLevelFlags userLevel, + ServerInfo_User::PawnColorsOverride pawnColorsOverride, + bool isBuddy, + QString privLevel) { + QString singlePawnPath = + "C:\\Users\\ZaHal\\Documents\\Development\\cockatrice\\cockatrice\\resources\\usericons\\pawn_single.svg"; + QString doublePawnPath = + "C:\\Users\\ZaHal\\Documents\\Development\\cockatrice\\cockatrice\\resources\\usericons\\pawn_double.svg"; + const auto &r = rand() > (RAND_MAX / 2); + + pawnColorsOverride.set_left_side("#ff0000"); + + if (r == 0) { + pawnColorsOverride.set_right_side("#00ff00"); + } + + std::optional colorLeft = std::nullopt; + if (pawnColorsOverride.has_left_side()) { + colorLeft = QString::fromStdString(pawnColorsOverride.left_side()); + } + + std::optional colorRight = std::nullopt; + if (pawnColorsOverride.has_right_side()) { + colorRight = QString::fromStdString(pawnColorsOverride.right_side()); + } + + // Has Color Override + if (colorLeft.has_value() || colorRight.has_value()) { + QString key = QString::number(height * 10000) + ":" + colorLeft.value_or("") + ":" + colorRight.value_or(""); + if (iconCache.contains(key)) { + return iconCache.value(key); + } + + QIcon icon; + if (colorRight.has_value()) { + icon = changeSVGColor(doublePawnPath, colorLeft.value(), colorRight); + } else { + icon = changeSVGColor(singlePawnPath, colorLeft.value(), std::nullopt); + } + + iconCache.insert(key, icon); + return icon; + } + + // Has No Color Override QString key = QString::number(height * 10000) + ":" + (short)userLevel + ":" + (short)isBuddy + ":" + privLevel; - /*if (pmCache.contains(key)) - return pmCache.value(key); - */ + if (iconCache.contains(key)) { + return iconCache.value(key); + } QString levelString; if (userLevel.testFlag(ServerInfo_User::IsAdmin)) { levelString = "admin"; - if (privLevel.toLower() == "vip") + if (privLevel.toLower() == "vip") { levelString.append("_" + privLevel.toLower()); + } } else if (userLevel.testFlag(ServerInfo_User::IsModerator)) { levelString = "moderator"; - if (privLevel.toLower() == "vip") + if (privLevel.toLower() == "vip") { levelString.append("_" + privLevel.toLower()); + } } else if (userLevel.testFlag(ServerInfo_User::IsRegistered)) { levelString = "registered"; - if (privLevel.toLower() != "none") + if (privLevel.toLower() != "none") { levelString.append("_" + privLevel.toLower()); - } else + } + } else { levelString = "normal"; + } - if (isBuddy) + if (isBuddy) { levelString.append("_buddy"); + } - QString color = "#FF3399"; - - QIcon icon = - changeSVGColor("/Users/Ricky/Documents/GitHub/Cockatrice/cockatrice/resources/userlevels/base.svg", color); - + auto pixmap = QPixmap("theme:userlevels/" + levelString) + .scaled(height, height, Qt::KeepAspectRatio, Qt::SmoothTransformation); + QIcon icon(pixmap); + iconCache.insert(key, icon); return icon; } -QMap UserLevelPixmapGenerator::pmCache; +QMap UserLevelPixmapGenerator::iconCache; QPixmap LockPixmapGenerator::generatePixmap(int height) { diff --git a/cockatrice/src/client/ui/pixel_map_generator.h b/cockatrice/src/client/ui/pixel_map_generator.h index 5444249b8..d1297cded 100644 --- a/cockatrice/src/client/ui/pixel_map_generator.h +++ b/cockatrice/src/client/ui/pixel_map_generator.h @@ -62,14 +62,22 @@ public: class UserLevelPixmapGenerator { private: - static QMap pmCache; + static QMap iconCache; public: - static QPixmap generatePixmap(int height, UserLevelFlags userLevel, bool isBuddy, QString privLevel = "NONE"); - static QIcon generateIcon(int height, UserLevelFlags userLevel, bool isBuddy, QString privLevel = "NONE"); + static QPixmap generatePixmap(int height, + UserLevelFlags userLevel, + ServerInfo_User::PawnColorsOverride pawnColors, + bool isBuddy, + QString privLevel = "NONE"); + static QIcon generateIcon(int height, + UserLevelFlags userLevel, + ServerInfo_User::PawnColorsOverride pawnColors, + bool isBuddy, + QString privLevel = "NONE"); static void clear() { - pmCache.clear(); + iconCache.clear(); } }; diff --git a/cockatrice/src/game/games_model.cpp b/cockatrice/src/game/games_model.cpp index a0cf15fbc..319aa2c57 100644 --- a/cockatrice/src/game/games_model.cpp +++ b/cockatrice/src/game/games_model.cpp @@ -119,7 +119,8 @@ QVariant GamesModel::data(const QModelIndex &index, int role) const return QString::fromStdString(gameentry.creator_info().name()); case Qt::DecorationRole: { QPixmap avatarPixmap = UserLevelPixmapGenerator::generatePixmap( - 13, (UserLevelFlags)gameentry.creator_info().user_level(), false, + 13, (UserLevelFlags)gameentry.creator_info().user_level(), + gameentry.creator_info().pawn_colors(), false, QString::fromStdString(gameentry.creator_info().privlevel())); return QIcon(avatarPixmap); } diff --git a/cockatrice/src/game/player/player_list_widget.cpp b/cockatrice/src/game/player/player_list_widget.cpp index 930b36d69..c8771968d 100644 --- a/cockatrice/src/game/player/player_list_widget.cpp +++ b/cockatrice/src/game/player/player_list_widget.cpp @@ -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(12, UserLevelFlags(prop.user_info().user_level()), false, - QString::fromStdString(prop.user_info().privlevel())))); + player->setIcon(3, QIcon(UserLevelPixmapGenerator::generatePixmap( + 12, UserLevelFlags(prop.user_info().user_level()), prop.user_info().pawn_colors(), false, + 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()) diff --git a/cockatrice/src/game/player/player_target.cpp b/cockatrice/src/game/player/player_target.cpp index a4542225b..ba1c3d52d 100644 --- a/cockatrice/src/game/player/player_target.cpp +++ b/cockatrice/src/game/player/player_target.cpp @@ -103,9 +103,9 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o QPixmap tempPixmap; if (fullPixmap.isNull()) - tempPixmap = - UserLevelPixmapGenerator::generatePixmap(translatedSize.height(), UserLevelFlags(info->user_level()), - false, QString::fromStdString(info->privlevel())); + tempPixmap = UserLevelPixmapGenerator::generatePixmap( + translatedSize.height(), UserLevelFlags(info->user_level()), info->pawn_colors(), false, + QString::fromStdString(info->privlevel())); else tempPixmap = fullPixmap.scaled(translatedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); diff --git a/cockatrice/src/server/chat_view/chat_view.cpp b/cockatrice/src/server/chat_view/chat_view.cpp index 29a4a7dfc..33249829d 100644 --- a/cockatrice/src/server/chat_view/chat_view.cpp +++ b/cockatrice/src/server/chat_view/chat_view.cpp @@ -191,8 +191,9 @@ void ChatView::appendMessage(QString message, const int pixelSize = QFontInfo(cursor.charFormat().font()).pixelSize(); bool isBuddy = userListProxy->isUserBuddy(userName); const QString privLevel = userInfo.has_privlevel() ? QString::fromStdString(userInfo.privlevel()) : "NONE"; - cursor.insertImage( - UserLevelPixmapGenerator::generatePixmap(pixelSize, userLevel, isBuddy, privLevel).toImage()); + cursor.insertImage(UserLevelPixmapGenerator::generatePixmap(pixelSize, userLevel, userInfo.pawn_colors(), + isBuddy, privLevel) + .toImage()); cursor.insertText(" "); cursor.setCharFormat(senderFormat); cursor.insertText(userName); diff --git a/cockatrice/src/server/user/user_info_box.cpp b/cockatrice/src/server/user/user_info_box.cpp index 53c1881ad..53e1d3379 100644 --- a/cockatrice/src/server/user/user_info_box.cpp +++ b/cockatrice/src/server/user/user_info_box.cpp @@ -90,8 +90,8 @@ void UserInfoBox::updateInfo(const ServerInfo_User &user) const std::string &bmp = user.avatar_bmp(); if (!avatarPixmap.loadFromData((const uchar *)bmp.data(), static_cast(bmp.size()))) { - avatarPixmap = - UserLevelPixmapGenerator::generatePixmap(64, userLevel, false, QString::fromStdString(user.privlevel())); + avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, userLevel, user.pawn_colors(), false, + QString::fromStdString(user.privlevel())); } nameLabel.setText(QString::fromStdString(user.name())); @@ -106,8 +106,8 @@ void UserInfoBox::updateInfo(const ServerInfo_User &user) countryLabel3.setText(""); } - userLevelIcon.setPixmap( - UserLevelPixmapGenerator::generatePixmap(15, userLevel, false, QString::fromStdString(user.privlevel()))); + userLevelIcon.setPixmap(UserLevelPixmapGenerator::generatePixmap(15, userLevel, user.pawn_colors(), false, + QString::fromStdString(user.privlevel()))); QString userLevelText; if (userLevel.testFlag(ServerInfo_User::IsAdmin)) userLevelText = tr("Administrator"); diff --git a/cockatrice/src/server/user/user_list_widget.cpp b/cockatrice/src/server/user/user_list_widget.cpp index e427d4d69..c4a5cdf46 100644 --- a/cockatrice/src/server/user/user_list_widget.cpp +++ b/cockatrice/src/server/user/user_list_widget.cpp @@ -344,8 +344,9 @@ void UserListTWI::setUserInfo(const ServerInfo_User &_userInfo) userInfo = _userInfo; setData(0, Qt::UserRole, userInfo.user_level()); - setIcon(0, UserLevelPixmapGenerator::generateIcon(12, UserLevelFlags(userInfo.user_level()), false, - QString::fromStdString(userInfo.privlevel()))); + setIcon(0, QIcon(UserLevelPixmapGenerator::generatePixmap(12, UserLevelFlags(userInfo.user_level()), + userInfo.pawn_colors(), false, + QString::fromStdString(userInfo.privlevel())))); setIcon(1, QIcon(CountryPixmapGenerator::generatePixmap(12, QString::fromStdString(userInfo.country())))); setData(2, Qt::UserRole, QString::fromStdString(userInfo.name())); setData(2, Qt::DisplayRole, QString::fromStdString(userInfo.name())); diff --git a/common/pb/serverinfo_user.proto b/common/pb/serverinfo_user.proto index c74ed8ee6..10add611f 100644 --- a/common/pb/serverinfo_user.proto +++ b/common/pb/serverinfo_user.proto @@ -8,6 +8,11 @@ message ServerInfo_User { IsAdmin = 8; IsJudge = 16; }; + message PawnColorsOverride { + optional string left_side = 1; + optional string right_side = 2; + }; + optional string name = 1; optional uint32 user_level = 2; optional string address = 3; @@ -22,4 +27,5 @@ message ServerInfo_User { optional string email = 12; optional string clientid = 13; optional string privlevel = 14; + optional PawnColorsOverride pawn_colors = 15; }