Buddy stars

Buddies will show as a star in the chat.

Please test. Does the chat feel slower? Mine feels slow, though I am
overseas.
This commit is contained in:
Matt Lowe 2015-01-28 21:09:02 +01:00
parent 739ca6a02e
commit 748e8ce75f
12 changed files with 501 additions and 92 deletions

View file

@ -323,6 +323,10 @@
<file>resources/userlevels/moderator.svg</file>
<file>resources/userlevels/admin.svg</file>
<file>resources/userlevels/registered_buddy.svg</file>
<file>resources/userlevels/admin_buddy.svg</file>
<file>resources/userlevels/moderator_buddy.svg</file>
<file>resources/news/exclamation_mark.svg</file>
<file>resources/news/question_mark.svg</file>
</qresource>

View file

@ -0,0 +1,125 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 64 64"
enable-background="new 0 0 64 64"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
width="100%"
height="100%"
sodipodi:docname="admin_buddy.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10">
<linearGradient
id="linearGradient5225">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5227" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop5229" />
</linearGradient>
<linearGradient
id="linearGradient5219"
osb:paint="solid">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5221" />
</linearGradient>
<linearGradient
id="linearGradient3758">
<stop
id="stop3760"
offset="0"
style="stop-color:#0fbb00;stop-opacity:1;" />
<stop
id="stop3762"
offset="1"
style="stop-color:#064400;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3750">
<stop
style="stop-color:#ece400;stop-opacity:1;"
offset="0"
id="stop3752" />
<stop
style="stop-color:#ece400;stop-opacity:0;"
offset="1"
id="stop3754" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3758-7"
id="linearGradient3756-1"
x1="1.960216"
y1="31.261461"
x2="60.456024"
y2="31.261461"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3758-7">
<stop
id="stop3760-4"
offset="0"
style="stop-color:#ece400;stop-opacity:1;" />
<stop
id="stop3762-0"
offset="1"
style="stop-color:#ec8b00;stop-opacity:1;" />
</linearGradient>
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1028"
id="namedview8"
showgrid="false"
inkscape:zoom="5.2149125"
inkscape:cx="21.988178"
inkscape:cy="51.245759"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
id="path4-9"
style="fill:#000000;fill-opacity:1"
inkscape:connector-curvature="0" />
<path
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
id="path4"
style="fill:#ff0000;fill-opacity:1;fill-rule:nonzero"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

View file

@ -0,0 +1,147 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 64 64"
enable-background="new 0 0 64 64"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
width="100%"
height="100%"
sodipodi:docname="registered_buddy - Copy.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10">
<pattern
inkscape:stockid="Stripes 1:1 white"
id="Strips1_1white"
patternTransform="translate(0,0) scale(10,10)"
height="1"
width="2"
patternUnits="userSpaceOnUse"
inkscape:collect="always">
<rect
id="rect4484"
height="2"
width="1"
y="-0.5"
x="0"
style="fill:white;stroke:none" />
</pattern>
<linearGradient
id="linearGradient5225">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5227" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop5229" />
</linearGradient>
<linearGradient
id="linearGradient5219"
osb:paint="solid">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop5221" />
</linearGradient>
<linearGradient
id="linearGradient3758">
<stop
id="stop3760"
offset="0"
style="stop-color:#0fbb00;stop-opacity:1;" />
<stop
id="stop3762"
offset="1"
style="stop-color:#064400;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3750">
<stop
style="stop-color:#ece400;stop-opacity:1;"
offset="0"
id="stop3752" />
<stop
style="stop-color:#ece400;stop-opacity:0;"
offset="1"
id="stop3754" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3758-7"
id="linearGradient3756-1"
x1="1.960216"
y1="31.261461"
x2="60.456024"
y2="31.261461"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3758-7">
<stop
id="stop3760-4"
offset="0"
style="stop-color:#ece400;stop-opacity:1;" />
<stop
id="stop3762-0"
offset="1"
style="stop-color:#ec8b00;stop-opacity:1;" />
</linearGradient>
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1028"
id="namedview8"
showgrid="false"
inkscape:zoom="5.2149125"
inkscape:cx="51.90239"
inkscape:cy="51.245759"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
id="path4-9"
style="fill:#000000;fill-opacity:1"
inkscape:connector-curvature="0" />
<path
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
id="path4"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero"
inkscape:connector-curvature="0" />
<path
d="M 57.165891,25.072777 37.520125,24.981707 31.537924,5.1008868 c 0.05101,40.5880862 0.05344,-0.1118618 0,40.5561512 L 49.290236,59.413412 41.216824,37.764038 z"
id="path4-1"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
viewBox="0 0 64 64"
enable-background="new 0 0 64 64"
id="svg2"
version="1.1"
inkscape:version="0.48.5 r10040"
width="100%"
height="100%"
sodipodi:docname="buddy_icon.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10">
<linearGradient
id="linearGradient3758">
<stop
id="stop3760"
offset="0"
style="stop-color:#0fbb00;stop-opacity:1;" />
<stop
id="stop3762"
offset="1"
style="stop-color:#064400;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient3750">
<stop
style="stop-color:#ece400;stop-opacity:1;"
offset="0"
id="stop3752" />
<stop
style="stop-color:#ece400;stop-opacity:0;"
offset="1"
id="stop3754" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3758"
id="linearGradient3756"
x1="1.960216"
y1="31.261461"
x2="60.456024"
y2="31.261461"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.87626222,0,0,0.87626222,4.174756,4.8555263)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3758-7"
id="linearGradient3756-1"
x1="1.960216"
y1="31.261461"
x2="60.456024"
y2="31.261461"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient3758-7">
<stop
id="stop3760-4"
offset="0"
style="stop-color:#ece400;stop-opacity:1;" />
<stop
id="stop3762-0"
offset="1"
style="stop-color:#ec8b00;stop-opacity:1;" />
</linearGradient>
</defs>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1600"
inkscape:window-height="1178"
id="namedview8"
showgrid="false"
inkscape:zoom="7.375"
inkscape:cx="-14.986549"
inkscape:cy="23.31428"
inkscape:window-x="1912"
inkscape:window-y="227"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<path
d="M 61.442826,23.621762 38.532402,23.515555 31.556101,0.331013 24.578789,23.515555 1.6673502,23.621765 20.267785,38.422001 10.863888,63.668987 31.556101,47.626631 52.258426,63.668987 42.843404,38.422001 z"
id="path4-9"
style="fill:#000000;fill-opacity:1"
inkscape:connector-curvature="0" />
<path
d="M 57.150089,25.064396 37.504323,24.973324 31.522122,5.092503 25.539054,24.973324 5.8924192,25.064399 21.842354,37.75565 13.778482,59.405024 31.522122,45.64865 49.274434,59.405024 41.201022,37.75565 z"
id="path4"
style="fill:url(#linearGradient3756);fill-opacity:1"
inkscape:connector-curvature="0" />
</svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

View file

@ -9,8 +9,10 @@
#include "pixmapgenerator.h"
#include "settingscache.h"
#include "main.h"
#include "userlist.h"
#include "tab_userlists.h"
const QColor OTHER_USER_MENTION_COLOR = QColor(145, 210, 255); // light blue
const QColor MENTION_COLOR = QColor(190, 25, 85); // maroon
const QColor OTHER_USER_COLOR = QColor(0, 65, 255); // dark blue
@ -30,6 +32,7 @@ ChatView::ChatView(const TabSupervisor *_tabSupervisor, TabGame *_game, bool _sh
mentionFormatOtherUser.setFontWeight(QFont::Bold);
mentionFormatOtherUser.setForeground(Qt::blue);
mentionFormatOtherUser.setBackground(QBrush(OTHER_USER_MENTION_COLOR));
mentionFormatOtherUser.setAnchor(true);
viewport()->setCursor(Qt::IBeamCursor);
@ -129,7 +132,8 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
if (!sameSender) {
if (!sender.isEmpty()) {
const int pixelSize = QFontInfo(cursor.charFormat().font()).pixelSize();
cursor.insertImage(UserLevelPixmapGenerator::generatePixmap(pixelSize, userLevel).toImage(), QString::number(pixelSize) + "_" + QString::number((int) userLevel));
QMap<QString, UserListTWI *> buddyList = tabSupervisor->getUserListsTab()->getBuddyList()->getUsers();
cursor.insertImage(UserLevelPixmapGenerator::generatePixmap(pixelSize, userLevel, buddyList.contains(sender)).toImage(), QString::number(pixelSize) + "_" + QString::number((int) userLevel));
cursor.insertText(" ");
}
cursor.setCharFormat(senderFormat);
@ -187,7 +191,8 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
if (settingsCache->getChatMention()) {
index = 0;
while((index = message.indexOf('@')) != -1) {
from = 0;
while((index = message.indexOf('@', from)) != -1) {
cursor.insertText(message.left(index), defaultFormat);
message = message.mid(index);
if (message.isEmpty())
@ -205,40 +210,24 @@ void ChatView::appendMessage(QString message, QString sender, UserLevelFlags use
QString userMention = message.left(mentionEndIndex);
QString userName = userMention.right(userMention.size()-1).normalized(QString::NormalizationForm_D);
QMap<QString, UserListTWI *> userList = tabSupervisor->getUserListsTab()->getAllUsersList()->getUsers();
QString correctUserName = getNameFromUserList(userList, userName);
if (!correctUserName.isEmpty()) {
UserListTWI *vlu = userList.value(correctUserName);
mentionFormatOtherUser.setAnchorHref("user://" + QString::number(vlu->getUserInfo().user_level()) + "_" + correctUserName);
cursor.insertText("@" + correctUserName, mentionFormatOtherUser);
if (userList.contains(userName)) {
UserListTWI *vlu = userList.value(userName);
mentionFormatOtherUser.setAnchorHref("user://" + QString::number(vlu->getUserInfo().user_level()) + "_" + userName);
cursor.insertText("@" + userName, mentionFormatOtherUser);
} else
cursor.insertText("@" + userName, defaultFormat);
message = message.mid(userName.size() + 1);
}
cursor.setCharFormat(defaultFormat); // reset format after each itteration
}
}
if (!message.isEmpty())
cursor.insertText(message);
cursor.insertText(message, defaultFormat);
if (atBottom)
verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
/**
Returns the correct case version of the provided username, if no correct casing version
was found then the provided name is not available and will return an empty QString.
*/
QString ChatView::getNameFromUserList(QMap<QString, UserListTWI *> &userList, QString &userName) {
QMap<QString, UserListTWI *>::iterator i;
QString lowerUserName = userName.toLower();
for (i = userList.begin(); i != userList.end(); ++i) {
if (i.key().toLower() == lowerUserName)
return i.key();
}
return QString();
}
void ChatView::clearChat() {
document()->clear();
}

View file

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

View file

@ -134,8 +134,9 @@ QPixmap CountryPixmapGenerator::generatePixmap(int height, const QString &countr
QMap<QString, QPixmap> CountryPixmapGenerator::pmCache;
QPixmap UserLevelPixmapGenerator::generatePixmap(int height, UserLevelFlags userLevel)
QPixmap UserLevelPixmapGenerator::generatePixmap(int height, UserLevelFlags userLevel, bool isBuddy)
{
int key = height * 10000 + (int) userLevel;
if (pmCache.contains(key))
return pmCache.value(key);
@ -149,6 +150,10 @@ QPixmap UserLevelPixmapGenerator::generatePixmap(int height, UserLevelFlags user
levelString = "registered";
else
levelString = "normal";
if (isBuddy)
levelString.append("_buddy");
QSvgRenderer svg(QString(":/resources/userlevels/" + levelString + ".svg"));
int width = (int) round(height * (double) svg.defaultSize().width() / (double) svg.defaultSize().height());
QPixmap pixmap(width, height);
@ -160,4 +165,20 @@ QPixmap UserLevelPixmapGenerator::generatePixmap(int height, UserLevelFlags user
return pixmap;
}
QMap<QString, QPixmap> PixmapGenerator::pmCache;
QPixmap PixmapGenerator::generatePixmap(int height, QString resourceName) {
if (pmCache.contains(resourceName))
return pmCache.value(resourceName);
QSvgRenderer svg(resourceName);
int width = (int) round(height * (double) svg.defaultSize().width() / (double) svg.defaultSize().height());
QPixmap pixmap(width, height);
pixmap.fill(Qt::transparent);
QPainter painter(&pixmap);
svg.render(&painter, QRectF(0, 0, width, height));
pmCache.insert(resourceName, pixmap);
return pixmap;
}
QMap<int, QPixmap> UserLevelPixmapGenerator::pmCache;

View file

@ -50,7 +50,15 @@ class UserLevelPixmapGenerator {
private:
static QMap<int, QPixmap> pmCache;
public:
static QPixmap generatePixmap(int height, UserLevelFlags userLevel);
static QPixmap generatePixmap(int height, UserLevelFlags userLevel, bool isBuddy);
static void clear() { pmCache.clear(); }
};
class PixmapGenerator {
private:
static QMap<QString, QPixmap> pmCache;
public:
static QPixmap generatePixmap(int height, QString resourceName);
static void clear() { pmCache.clear(); }
};

View file

@ -118,7 +118,7 @@ void PlayerListWidget::updatePlayerProperties(const ServerInfo_PlayerProperties
player->setIcon(2, gameStarted ? (prop.conceded() ? concededIcon : QIcon()) : (prop.ready_start() ? readyIcon : notReadyIcon));
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()))));
player->setIcon(3, QIcon(UserLevelPixmapGenerator::generatePixmap(12, UserLevelFlags(prop.user_info().user_level()), false)));
player->setText(4, QString::fromStdString(prop.user_info().name()));
const QString country = QString::fromStdString(prop.user_info().country());
if (!country.isEmpty())

View file

@ -98,7 +98,7 @@ void PlayerTarget::paint(QPainter *painter, const QStyleOptionGraphicsItem * /*o
QPixmap tempPixmap;
if (fullPixmap.isNull())
tempPixmap = UserLevelPixmapGenerator::generatePixmap(translatedSize.height(), UserLevelFlags(info->user_level()));
tempPixmap = UserLevelPixmapGenerator::generatePixmap(translatedSize.height(), UserLevelFlags(info->user_level()), false);
else
tempPixmap = fullPixmap.scaled(translatedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);

View file

@ -59,14 +59,14 @@ void UserInfoBox::updateInfo(const ServerInfo_User &user)
QPixmap avatarPixmap;
const std::string bmp = user.avatar_bmp();
if (!avatarPixmap.loadFromData((const uchar *) bmp.data(), bmp.size()))
avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, userLevel);
avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, userLevel, false);
avatarLabel.setPixmap(avatarPixmap);
nameLabel.setText(QString::fromStdString(user.name()));
realNameLabel2.setText(QString::fromStdString(user.real_name()));
genderLabel2.setPixmap(GenderPixmapGenerator::generatePixmap(15, user.gender()));
countryLabel2.setPixmap(CountryPixmapGenerator::generatePixmap(15, QString::fromStdString(user.country())));
userLevelLabel2.setPixmap(UserLevelPixmapGenerator::generatePixmap(15, userLevel));
userLevelLabel2.setPixmap(UserLevelPixmapGenerator::generatePixmap(15, userLevel, false));
QString userLevelText;
if (userLevel.testFlag(ServerInfo_User::IsAdmin))
userLevelText = tr("Administrator");

View file

@ -181,7 +181,7 @@ void UserListTWI::setUserInfo(const ServerInfo_User &_userInfo)
userInfo = _userInfo;
setData(0, Qt::UserRole, userInfo.user_level());
setIcon(0, QIcon(UserLevelPixmapGenerator::generatePixmap(12, UserLevelFlags(userInfo.user_level()))));
setIcon(0, QIcon(UserLevelPixmapGenerator::generatePixmap(12, UserLevelFlags(userInfo.user_level()), false)));
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()));