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: Olivier Soldano <olivier.soldano@savoirfairelinux.com>
diff --git a/src/delegates/ImageManipulationDelegate.mm b/src/delegates/ImageManipulationDelegate.mm
index 2408b82..dcda3c3 100644
--- a/src/delegates/ImageManipulationDelegate.mm
+++ b/src/delegates/ImageManipulationDelegate.mm
@@ -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 @@
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 @@
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 @@
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 @@
return bArray;
}
- QPixmap ImageManipulationDelegate::drawDefaultUserPixmap(const QSize& size, bool displayPresence, bool isPresent) {
+ 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);
- auto index = QStringLiteral("%1%2").arg(size.width()).arg(size.height());
- if (m_hDefaultUserPixmap.contains(index)) {
- return m_hDefaultUserPixmap.value(index);
- }
+ // We pick a color based on the passed character
+ QColor avColor = ImageManipulationDelegate::avatarColors_[color % 16];
- // 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);
+ // 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());
- m_hDefaultUserPixmap.insert(index, finalpxm);
+ // 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 finalpxm;
+ return avatar;
}
CGImageRef ImageManipulationDelegate::resizeCGImage(CGImageRef image, const QSize& size) {
@@ -288,7 +319,9 @@
&& 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 @@
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 @@
Q_UNUSED(acc)
if (auto pro = ProfileModel::instance().selectedProfile())
return contactPhoto(pro->person(), decorationSize);
- return drawDefaultUserPixmap(decorationSize);
+ return drawDefaultUserPixmap(decorationSize, '?', '?');
}
} // namespace Interfaces