Commit c40b3479 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.

Change-Id: Ib5b83c76e73ee8af658b0515b317e4f8ce82be27
Reviewed-by: default avatarOlivier Soldano <olivier.soldano@savoirfairelinux.com>
parent 3b9e17f3
......@@ -60,11 +60,12 @@ namespace Interfaces {
private:
//Helper
QPixmap drawDefaultUserPixmap(const QSize& size, bool displayPresence = false, bool isPresent = false);
QPixmap drawDefaultUserPixmap(const QSize& size, const char color, const char letter);
CGImageRef resizeCGImage(CGImageRef image, const QSize& size);
QHash<QString, QPixmap> m_hDefaultUserPixmap;
QHash<QString, QPair<QMetaObject::Connection, QPixmap>> m_hContactsPixmap;
static const QColor avatarColors_[];
/**
* Return a version of size destSize centered of the bigger photo
......
......@@ -41,6 +41,26 @@
namespace Interfaces {
// Colors from material.io
const QColor ImageManipulationDelegate::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
};
ImageManipulationDelegate::ImageManipulationDelegate() {}
QVariant ImageManipulationDelegate::contactPhoto(Person* c, const QSize& size, bool displayPresence) {
......@@ -110,7 +130,9 @@ namespace Interfaces {
m_hContactsPixmap.insert(index, toInsert);
} else {
return drawDefaultUserPixmap(size);
return drawDefaultUserPixmap(size,
c->phoneNumbers().at(0)->uri().userinfo().at(0).toLatin1(),
c->phoneNumbers().at(0)->bestName().at(0).toUpper().toLatin1());
}
return pxm;
......@@ -156,7 +178,9 @@ namespace Interfaces {
if (n->contact()) {
return contactPhoto(n->contact(), size, displayPresence);
} else {
return drawDefaultUserPixmap(size);
return drawDefaultUserPixmap(size,
n->uri().userinfo().at(0).toLatin1(),
n->bestName().at(0).toUpper().toLatin1());
}
}
......@@ -167,7 +191,7 @@ namespace Interfaces {
const bool ret = image.loadFromData(QByteArray::fromBase64(data),type.toLatin1());
if (!ret) {
qDebug() << "vCard image loading failed";
return drawDefaultUserPixmap(decorationSize);
return drawDefaultUserPixmap(decorationSize, '?', '?');
}
return QPixmap::fromImage(image);
......@@ -187,23 +211,30 @@ namespace Interfaces {
return bArray;
}
QPixmap ImageManipulationDelegate::drawDefaultUserPixmap(const QSize& size, bool displayPresence, bool isPresent) {
auto index = QStringLiteral("%1%2").arg(size.width()).arg(size.height());
if (m_hDefaultUserPixmap.contains(index)) {
return m_hDefaultUserPixmap.value(index);
}
// create the image somehow, load from file, draw into it...
auto sourceImgRef = CGImageSourceCreateWithData((__bridge CFDataRef)[[NSImage imageNamed:@"default_user_icon"] TIFFRepresentation], NULL);
auto imgRef = CGImageSourceCreateImageAtIndex(sourceImgRef, 0, NULL);
auto finalpxm = QtMac::fromCGImageRef(resizeCGImage(imgRef, size));
CFRelease(sourceImgRef);
CFRelease(imgRef);
m_hDefaultUserPixmap.insert(index, finalpxm);
return finalpxm;
QPixmap ImageManipulationDelegate::drawDefaultUserPixmap(const QSize& size, const char color, const char letter) {
// We start with a transparent avatar
QPixmap avatar(size);
avatar.fill(Qt::transparent);
// We pick a color based on the passed character
QColor avColor = ImageManipulationDelegate::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
auto font = painter.font();
font.setPointSize(avatar.height()/2);
painter.setFont(font);
painter.setPen(Qt::white);
QRect textRect = avatar.rect();
painter.drawText(textRect, QString(letter), QTextOption(Qt::AlignCenter));
return avatar;
}
CGImageRef ImageManipulationDelegate::resizeCGImage(CGImageRef image, const QSize& size) {
......@@ -288,7 +319,9 @@ namespace Interfaces {
&& c->peerContactMethod()->contact()) {
return contactPhoto(c->peerContactMethod()->contact(), decorationSize);
} else
return drawDefaultUserPixmap(decorationSize);
return drawDefaultUserPixmap(decorationSize,
c->peerContactMethod()->uri().userinfo().at(0).toLatin1(),
c->peerContactMethod()->bestName().at(0).toUpper().toLatin1());
}
QVariant ImageManipulationDelegate::decorationRole(const ContactMethod* cm)
......@@ -297,7 +330,9 @@ namespace Interfaces {
if (cm && cm->contact() && cm->contact()->photo().isValid())
return contactPhoto(cm->contact(), decorationSize);
else
return drawDefaultUserPixmap(decorationSize);
return drawDefaultUserPixmap(decorationSize,
cm->uri().userinfo().at(0).toLatin1(),
cm->bestName().at(0).toUpper().toLatin1());
}
QVariant ImageManipulationDelegate::decorationRole(const Person* p)
......@@ -310,7 +345,7 @@ namespace Interfaces {
Q_UNUSED(acc)
if (auto pro = ProfileModel::instance().selectedProfile())
return contactPhoto(pro->person(), decorationSize);
return drawDefaultUserPixmap(decorationSize);
return drawDefaultUserPixmap(decorationSize, '?', '?');
}
} // namespace Interfaces
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