Commit 3d920d81 authored by Anthony Léonard's avatar Anthony Léonard Committed by Olivier SOLDANO

modernize avatar placeholder

Default avatar displayed for new contacts is replaced by a more modern
color circle with a capital letter inside.

The color palette used is the same as in the GNOME client. It comes
from the material.io website and is a 16 color subset of the full one
proposed by Google.

The letter is the first one of the bestName() corresponding to the
current item. The “Segoe UI” font is used as recommended by Windows
design guidelines.

Change-Id: I4c8c5729a77c0ff52d18de33c8e2fb8b5b1d7a88
Reviewed-by: default avatarOlivier Soldano <olivier.soldano@savoirfairelinux.com>
parent 3dad1751
......@@ -26,6 +26,7 @@
#include <QIODevice>
#include <QByteArray>
#include <QBuffer>
#include <QPainter>
#include "person.h"
#include "call.h"
......@@ -34,7 +35,7 @@
#include "profile.h"
#include "utils.h"
#include "ringthemeutils.h"
#undef interface
/*Namespace Interfaces collide with QBuffer*/
......@@ -49,10 +50,6 @@ QByteArray QImageToByteArray(QImage image)
namespace Interfaces {
PixbufManipulator::PixbufManipulator()
: fallbackAvatar_(QImage(":/images/user/btn-default-userpic.svg"))
{}
QImage
PixbufManipulator::scaleAndFrame(const QImage photo, const QSize& size)
{
......@@ -63,7 +60,9 @@ QVariant
PixbufManipulator::callPhoto(Call* c, const QSize& size, bool displayPresence)
{
if (!c || c->type() == Call::Type::CONFERENCE){
return QVariant::fromValue(scaleAndFrame(fallbackAvatar_, size));
return QVariant::fromValue(fallbackAvatar(size,
c->peerContactMethod()->uri().userinfo().at(0).toLatin1(),
c->peerContactMethod()->bestName().at(0).toUpper().toLatin1()));
}
return callPhoto(c->peerContactMethod(), size, displayPresence);
}
......@@ -74,7 +73,9 @@ PixbufManipulator::callPhoto(const ContactMethod* n, const QSize& size, bool dis
if (n && n->contact()) {
return contactPhoto(n->contact(), size, displayPresence);
} else {
return QVariant::fromValue(scaleAndFrame(fallbackAvatar_, size));
return QVariant::fromValue(fallbackAvatar(size,
n->uri().userinfo().at(0).toLatin1(),
n->bestName().at(0).toUpper().toLatin1()));
}
}
......@@ -93,7 +94,9 @@ PixbufManipulator::contactPhoto(Person* c, const QSize& size, bool displayPresen
if (c->photo().isValid()){
photo = c->photo().value<QImage>();
} else {
photo = fallbackAvatar_;
photo = fallbackAvatar(size,
c->phoneNumbers().at(0)->uri().userinfo().at(0).toLatin1(),
c->phoneNumbers().at(0)->bestName().at(0).toUpper().toLatin1());
}
return QVariant::fromValue(scaleAndFrame(photo, size));
}
......@@ -105,7 +108,7 @@ QVariant PixbufManipulator::personPhoto(const QByteArray& data, const QString& t
const char* c_str2 = ba.data();
if (avatar.loadFromData(data.fromBase64(data), c_str2))
return Utils::getCirclePhoto(avatar, avatar.size().width());
return fallbackAvatar_;
return fallbackAvatar(imgSize_, '?', '?');
}
QVariant
......@@ -182,7 +185,9 @@ QVariant PixbufManipulator::decorationRole(const Call* c)
photo = c->peerContactMethod()->contact()->photo().value<QImage>();
}
else
photo = fallbackAvatar_;
photo = fallbackAvatar(imgSize_,
c->peerContactMethod()->uri().userinfo().at(0).toLatin1(),
c->peerContactMethod()->bestName().at(0).toUpper().toLatin1());
return QVariant::fromValue(scaleAndFrame(photo, imgSize_));
}
......@@ -192,7 +197,9 @@ QVariant PixbufManipulator::decorationRole(const ContactMethod* cm)
if (cm && cm->contact() && cm->contact()->photo().isValid())
photo = cm->contact()->photo().value<QImage>();
else
photo = fallbackAvatar_;
photo = fallbackAvatar(imgSize_,
cm->uri().userinfo().at(0).toLatin1(),
cm->bestName().at(0).toUpper().toLatin1());
return QVariant::fromValue(scaleAndFrame(photo, imgSize_));
}
......@@ -202,7 +209,9 @@ QVariant PixbufManipulator::decorationRole(const Person* p)
if (p && p->photo().isValid())
photo = p->photo().value<QImage>();
else
photo = fallbackAvatar_;
photo = fallbackAvatar(imgSize_,
p->phoneNumbers().at(0)->uri().userinfo().at(0).toLatin1(),
p->phoneNumbers().at(0)->bestName().at(0).toUpper().toLatin1());
return QVariant::fromValue(scaleAndFrame(photo, imgSize_));
}
......@@ -214,4 +223,31 @@ QVariant PixbufManipulator::decorationRole(const Account* acc)
imgSize_.width());
}
QImage PixbufManipulator::fallbackAvatar(const QSize size, const char color, const char letter)
{
// We start with a transparent avatar
QImage avatar(size, QImage::Format_ARGB32);
avatar.fill(Qt::transparent);
// We pick a color based on the passed character
QColor avColor = RingTheme::avatarColors_[color % 16];
// We draw a circle with this color
QPainter painter(&avatar);
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
painter.setPen(Qt::transparent);
painter.setBrush(avColor);
painter.drawEllipse(avatar.rect());
// Then we paint a letter in the circle
QFont segoeFont("Segoe UI", avatar.height()/2); // We use Segoe UI as recommended by Windows guidelines
painter.setFont(segoeFont);
painter.setPen(Qt::white);
QRect textRect = avatar.rect();
textRect.moveTop(textRect.top()-(avatar.height()/20)); // Empirical value that seems to correct centering nicely
painter.drawText(textRect, QString(letter), QTextOption(Qt::AlignCenter));
return avatar;
}
} // namespace Interfaces
......@@ -33,8 +33,6 @@ namespace Interfaces {
class PixbufManipulator : public PixmapManipulatorI {
public:
PixbufManipulator();
QVariant callPhoto(Call* c, const QSize& size, bool displayPresence = true) override;
QVariant callPhoto(const ContactMethod* n, const QSize& size, bool displayPresence = true) override;
QVariant contactPhoto(Person* c, const QSize& size, bool displayPresence = true) override;
......@@ -56,9 +54,9 @@ public:
QVariant decorationRole(const Account* acc) override;
private:
QImage fallbackAvatar_;
QImage scaleAndFrame(const QImage photo, const QSize& size);
const QSize imgSize_ {48, 48};
static QImage fallbackAvatar(const QSize size, const char color, const char letter);
};
} // namespace Interfaces
......
......@@ -32,4 +32,23 @@ static const QColor lightRed_ {252, 91, 90};
static const QColor darkRed_ {219, 55, 54};
static const QColor green_ {127, 255, 0};
static const QColor avatarColors_[] {
{"#fff44336"}, //Red
{"#ffe91e63"}, //Pink
{"#ff9c27b0"}, //Purple
{"#ff673ab7"}, //Deep Purple
{"#ff3f51b5"}, //Indigo
{"#ff2196f3"}, //Blue
{"#ff00bcd4"}, //Cyan
{"#ff009688"}, //Teal
{"#ff4caf50"}, //Green
{"#ff8bc34a"}, //Light Green
{"#ff9e9e9e"}, //Grey
{"#ffcddc39"}, //Lime
{"#ffffc107"}, //Amber
{"#ffff5722"}, //Deep Orange
{"#ff795548"}, //Brown
{"#ff607d8b"} //Blue Grey
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment