diff --git a/src/delegates/ImageManipulationDelegate.h b/src/delegates/ImageManipulationDelegate.h index 1bafeb58e6eeec982e4f8f2cdf31b05942fc01a6..59acf1e2b48ccd57f913eee77dcc7a8ed861e29f 100644 --- a/src/delegates/ImageManipulationDelegate.h +++ b/src/delegates/ImageManipulationDelegate.h @@ -36,10 +36,16 @@ namespace Interfaces { class ImageManipulationDelegate : public PixmapManipulatorI { public: + static constexpr int IMG_SIZE = 80; + ImageManipulationDelegate(); QVariant contactPhoto(Person* c, const QSize& size, bool displayPresence = true) override; virtual QByteArray toByteArray(const QVariant& pxm) override; virtual QVariant personPhoto(const QByteArray& data, const QString& type = "PNG") override; + QVariant conversationPhoto(const lrc::api::conversation::Info& conversation, + const lrc::api::account::Info& accountInfo, + const QSize& size = QSize(IMG_SIZE, IMG_SIZE), + bool displayPresence = true) override; QVariant callPhoto(Call* c, const QSize& size, bool displayPresence = true) override; QVariant callPhoto(const ContactMethod* n, const QSize& size, bool displayPresence = true) override; @@ -65,6 +71,7 @@ namespace Interfaces { QHash m_hDefaultUserPixmap; QHash> m_hContactsPixmap; + QHash convPixmCache; static const QColor avatarColors_[]; /** diff --git a/src/delegates/ImageManipulationDelegate.mm b/src/delegates/ImageManipulationDelegate.mm index dcda3c33fe5490410007694722455fbbbca068c0..b25c39ff5ad16b3db2943f0ffe33f2a8ad19578e 100644 --- a/src/delegates/ImageManipulationDelegate.mm +++ b/src/delegates/ImageManipulationDelegate.mm @@ -33,11 +33,16 @@ #import #import -//Ring +//LRC #import #import #import #import +#import +#import +#import +#import +#import namespace Interfaces { @@ -197,6 +202,86 @@ namespace Interfaces { return QPixmap::fromImage(image); } + char letterForDefaultUserPixmap(const lrc::api::contact::Info& contact) + { + if (!contact.profileInfo.alias.empty()) + return std::toupper(contact.profileInfo.alias.at(0)); + else if(contact.profileInfo.type == lrc::api::profile::Type::RING && !contact.registeredName.empty()) + return std::toupper(contact.registeredName.at(0)); + else + return std::toupper(contact.profileInfo.uri.at(0)); + } + + QVariant ImageManipulationDelegate::conversationPhoto(const lrc::api::conversation::Info& conversation, + const lrc::api::account::Info& accountInfo, + const QSize& size, + bool displayPresence) + { + Q_UNUSED(displayPresence) + + try { + auto contact = accountInfo.contactModel->getContact(conversation.participants[0]); + auto& avatar = contact.profileInfo.avatar; + if (!avatar.empty()) { + QPixmap pxm; + const int radius = size.height() / 2; + + // Check cache + auto index = QStringLiteral("%1%2%3").arg(size.width()) + .arg(size.height()) + .arg(QString::fromStdString(conversation.uid)); + + if (convPixmCache.contains(index)) { + return convPixmCache.value(index); + } + + auto contactPhoto = qvariant_cast(personPhoto(QByteArray::fromStdString(avatar))); + contactPhoto = contactPhoto.scaled(size, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); + + QPixmap finalImg; + // We crop the avatar if picture is not squared as scaled() keep ratio of original picture + if (contactPhoto.size() != size) { + finalImg = crop(contactPhoto, size); + } else + finalImg = contactPhoto; + + // Creating clean QPixmap + pxm = QPixmap(size); + pxm.fill(Qt::transparent); + + //Add corner radius to the Pixmap + QPainter painter(&pxm); + painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + painter.setCompositionMode(QPainter::CompositionMode_SourceOver); + QRect pxRect = finalImg.rect(); + QBitmap mask(pxRect.size()); + QPainter customPainter(&mask); + customPainter.setRenderHints (QPainter::Antialiasing | QPainter::SmoothPixmapTransform); + customPainter.fillRect (pxRect , Qt::white ); + customPainter.setBackground (Qt::black ); + customPainter.setBrush (Qt::black ); + customPainter.drawRoundedRect(pxRect,radius,radius ); + finalImg.setMask (mask ); + painter.drawPixmap (0,0,finalImg ); + painter.setBrush (Qt::NoBrush ); + painter.setPen (Qt::black ); + painter.setCompositionMode (QPainter::CompositionMode_SourceIn); + painter.drawRoundedRect(0,0,pxm.height(),pxm.height(),radius,radius); + + // Save in cache + convPixmCache.insert(index, pxm); + + return pxm; + } else { + char color = contact.profileInfo.uri.at(0); + char letter = letterForDefaultUserPixmap(contact); + return drawDefaultUserPixmap(size, color, letter); + } + } catch (const std::out_of_range& e) { + return drawDefaultUserPixmap(size, '?', '?'); + } + } + QByteArray ImageManipulationDelegate::toByteArray(const QVariant& pxm) { //Preparation of our QPixmap