1 /*
2 * %kadu copyright begin%
3 * Copyright 2012 Wojciech Treter (juzefwt@gmail.com)
4 * Copyright 2012, 2014 Bartosz Brachaczek (b.brachaczek@gmail.com)
5 * Copyright 2011, 2013, 2014 Rafał Przemysław Malinowski (rafal.przemyslaw.malinowski@gmail.com)
6 * %kadu copyright end%
7 * Copyright 2010 Dariusz Markowicz
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2 of
12 * the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include <QtCore/QModelIndex>
24 #include <QtGui/QPainter>
25 #include <QtGui/QPainterPath>
26 #include <QtGui/QPixmap>
27 #include <QtGui/QPixmapCache>
28 #include <QtWidgets/QStyleOptionViewItem>
29
30 #include "contacts/contact.h"
31 #include "gui/widgets/talkable-delegate-configuration.h"
32 #include "model/roles.h"
33
34 #include "avatar-painter.h"
35
AvatarPainter(TalkableDelegateConfiguration * configuration,const QStyleOptionViewItemV4 & option,const QRect & avatarRect,const QModelIndex & index)36 AvatarPainter::AvatarPainter(TalkableDelegateConfiguration *configuration, const QStyleOptionViewItemV4 &option, const QRect &avatarRect, const QModelIndex &index) :
37 Configuration(configuration), Option(option), AvatarRect(avatarRect), Index(index)
38 {
39 Avatar = Index.data(AvatarRole).value<QPixmap>();
40 }
41
greyOut()42 bool AvatarPainter::greyOut()
43 {
44 if (!Configuration->avatarGreyOut())
45 return false;
46
47 Contact contact = Index.data(ContactRole).value<Contact>();
48 return contact.currentStatus().isDisconnected();
49 }
50
cacheKey()51 QString AvatarPainter::cacheKey()
52 {
53 return QString("msi-%1-%2,%3,%4")
54 .arg(Avatar.cacheKey())
55 .arg(greyOut())
56 .arg(Configuration->avatarBorder())
57 .arg(Option.state & QStyle::State_Selected ? 1 : 0);
58 }
59
getOrCreateCacheItem()60 QPixmap AvatarPainter::getOrCreateCacheItem()
61 {
62 QString key = cacheKey();
63
64 QPixmap cached;
65 if (QPixmapCache::find(key, &cached))
66 return cached;
67
68 QPixmap item = QPixmap(AvatarRect.size());
69 item.fill(QColor(0, 0, 0, 0));
70
71 QPainter cachePainter;
72 cachePainter.begin(&item);
73 doPaint(&cachePainter, item.size());
74 cachePainter.end();
75
76 QPixmapCache::insert(key, item);
77
78 return item;
79 }
80
paintFromCache(QPainter * painter)81 void AvatarPainter::paintFromCache(QPainter *painter)
82 {
83 QPixmap cached = getOrCreateCacheItem();
84
85 painter->drawPixmap(AvatarRect, cached);
86 }
87
cropped()88 QPixmap AvatarPainter::cropped()
89 {
90 int minDimension = Avatar.height() < Avatar.width()
91 ? Avatar.height()
92 : Avatar.width();
93
94 int x = (Avatar.width() - minDimension) / 2;
95 int y = (Avatar.height() - minDimension) / 2;
96
97 QImage cropped = Avatar.toImage().copy(x, y, minDimension, minDimension);
98
99 return QPixmap::fromImage(cropped);
100 }
101
doPaint(QPainter * painter,const QSize & size)102 void AvatarPainter::doPaint(QPainter *painter, const QSize &size)
103 {
104 QPixmap displayAvatar;
105 QPixmap croppedAvatar = cropped();
106
107 if (croppedAvatar.height() > size.height() || croppedAvatar.width() > size.width())
108 displayAvatar = croppedAvatar.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
109 else
110 displayAvatar = croppedAvatar;
111
112 QRect displayRect = displayAvatar.rect();
113 displayRect.moveTop((size.height() - displayRect.height()) / 2);
114 displayRect.moveLeft((size.width() - displayRect.width()) / 2);
115
116 // grey out offline contacts' avatar
117 displayAvatar = greyOut()
118 ? QIcon(displayAvatar).pixmap(displayAvatar.size(), QIcon::Disabled)
119 : displayAvatar;
120
121 int radius = 3;
122 QPainterPath displayRectPath;
123 displayRectPath.addRoundedRect(displayRect, radius, radius);
124
125 painter->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
126 painter->setClipPath(displayRectPath);
127 painter->drawPixmap(displayRect, displayAvatar);
128 painter->setClipping(false);
129
130 // draw avatar border
131 if (Configuration->avatarBorder())
132 painter->drawRoundedRect(displayRect, radius, radius);
133 }
134
paint(QPainter * painter)135 void AvatarPainter::paint(QPainter *painter)
136 {
137 if (!Configuration->showAvatars() || AvatarRect.isEmpty() || Avatar.isNull())
138 return;
139
140 paintFromCache(painter);
141 }
142