mirror of https://github.com/procxx/kepka.git
New empty user/chat photos: with filled background and initials.
This commit is contained in:
parent
204d91d567
commit
1d8e76aa08
|
@ -258,29 +258,22 @@ historyForwardChooseBg: #0000004c;
|
||||||
historyForwardChooseFg: windowFgActive;
|
historyForwardChooseFg: windowFgActive;
|
||||||
|
|
||||||
historyPeer1NameFg: #c03d33; // red
|
historyPeer1NameFg: #c03d33; // red
|
||||||
historyPeer1UserpicBg: #ed9482;
|
historyPeer1UserpicBg: #e57979;
|
||||||
historyPeer1UserpicFg: #d3644b;
|
|
||||||
historyPeer2NameFg: #4fad2d; // green
|
historyPeer2NameFg: #4fad2d; // green
|
||||||
historyPeer2UserpicBg: #a8db92;
|
historyPeer2UserpicBg: #80d066;
|
||||||
historyPeer2UserpicFg: #75c057;
|
|
||||||
historyPeer3NameFg: #d09306; // yellow
|
historyPeer3NameFg: #d09306; // yellow
|
||||||
historyPeer3UserpicBg: #efd289;
|
historyPeer3UserpicBg: #ecd074;
|
||||||
historyPeer3UserpicFg: #e4a861;
|
|
||||||
historyPeer4NameFg: windowActiveTextFg; // blue
|
historyPeer4NameFg: windowActiveTextFg; // blue
|
||||||
historyPeer4UserpicBg: #8fbfe9;
|
historyPeer4UserpicBg: #6fb1e4;
|
||||||
historyPeer4UserpicFg: #649fd3;
|
|
||||||
historyPeer5NameFg: #8544d6; // purple
|
historyPeer5NameFg: #8544d6; // purple
|
||||||
historyPeer5UserpicBg: #9992e4;
|
historyPeer5UserpicBg: #cc90e2;
|
||||||
historyPeer5UserpicFg: #7b72cf;
|
|
||||||
historyPeer6NameFg: #cd4073; // pink
|
historyPeer6NameFg: #cd4073; // pink
|
||||||
historyPeer6UserpicBg: #ffa9c3;
|
historyPeer6UserpicBg: #f078ae;
|
||||||
historyPeer6UserpicFg: #e87497;
|
|
||||||
historyPeer7NameFg: #2996ad; // sea
|
historyPeer7NameFg: #2996ad; // sea
|
||||||
historyPeer7UserpicBg: #8eccdb;
|
historyPeer7UserpicBg: #73cdd0;
|
||||||
historyPeer7UserpicFg: #5eb2c7;
|
|
||||||
historyPeer8NameFg: #ce671b; // orange
|
historyPeer8NameFg: #ce671b; // orange
|
||||||
historyPeer8UserpicBg: #f7b37c;
|
historyPeer8UserpicBg: #fba76f;
|
||||||
historyPeer8UserpicFg: #de8d62;
|
historyPeerUserpicFg: windowFgActive;
|
||||||
|
|
||||||
historyScrollBarBg: #556e837a;
|
historyScrollBarBg: #556e837a;
|
||||||
historyScrollBarBgOver: #556e83bc;
|
historyScrollBarBgOver: #556e83bc;
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
Before Width: | Height: | Size: 8.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB |
Binary file not shown.
Before Width: | Height: | Size: 7.5 KiB |
|
@ -214,29 +214,22 @@ historyUnreadBarFg: #538bb4;
|
||||||
historyForwardChooseBg: #0000004c;
|
historyForwardChooseBg: #0000004c;
|
||||||
historyForwardChooseFg: #ffffff; // windowActiveTextFg;
|
historyForwardChooseFg: #ffffff; // windowActiveTextFg;
|
||||||
historyPeer1NameFg: #c03d33;
|
historyPeer1NameFg: #c03d33;
|
||||||
historyPeer1UserpicBg: #ed9482;
|
historyPeer1UserpicBg: #e57979;
|
||||||
historyPeer1UserpicFg: #d3644b;
|
|
||||||
historyPeer2NameFg: #4fad2d;
|
historyPeer2NameFg: #4fad2d;
|
||||||
historyPeer2UserpicBg: #a8db92;
|
historyPeer2UserpicBg: #80d066;
|
||||||
historyPeer2UserpicFg: #75c057;
|
|
||||||
historyPeer3NameFg: #d09306;
|
historyPeer3NameFg: #d09306;
|
||||||
historyPeer3UserpicBg: #efd289;
|
historyPeer3UserpicBg: #ecd074;
|
||||||
historyPeer3UserpicFg: #e4a861;
|
|
||||||
historyPeer4NameFg: #168acd; // windowShadowFg;
|
historyPeer4NameFg: #168acd; // windowShadowFg;
|
||||||
historyPeer4UserpicBg: #8fbfe9;
|
historyPeer4UserpicBg: #6fb1e4;
|
||||||
historyPeer4UserpicFg: #649fd3;
|
|
||||||
historyPeer5NameFg: #8544d6;
|
historyPeer5NameFg: #8544d6;
|
||||||
historyPeer5UserpicBg: #9992e4;
|
historyPeer5UserpicBg: #cc90e2;
|
||||||
historyPeer5UserpicFg: #7b72cf;
|
|
||||||
historyPeer6NameFg: #cd4073;
|
historyPeer6NameFg: #cd4073;
|
||||||
historyPeer6UserpicBg: #ffa9c3;
|
historyPeer6UserpicBg: #f078ae;
|
||||||
historyPeer6UserpicFg: #e87497;
|
|
||||||
historyPeer7NameFg: #2996ad;
|
historyPeer7NameFg: #2996ad;
|
||||||
historyPeer7UserpicBg: #8eccdb;
|
historyPeer7UserpicBg: #73cdd0;
|
||||||
historyPeer7UserpicFg: #5eb2c7;
|
|
||||||
historyPeer8NameFg: #ce671b;
|
historyPeer8NameFg: #ce671b;
|
||||||
historyPeer8UserpicBg: #f7b37c;
|
historyPeer8UserpicBg: #fba76f;
|
||||||
historyPeer8UserpicFg: #de8d62;
|
historyPeerUserpicFg: #ffffff; // windowActiveTextFg;
|
||||||
historyScrollBarBg: #556e837a;
|
historyScrollBarBg: #556e837a;
|
||||||
historyScrollBarBgOver: #556e83bc;
|
historyScrollBarBgOver: #556e83bc;
|
||||||
historyScrollBg: #556e834c;
|
historyScrollBg: #556e834c;
|
||||||
|
|
|
@ -1201,7 +1201,7 @@ void RevokePublicLinkBox::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selected) const {
|
void RevokePublicLinkBox::paintChat(Painter &p, const ChatRow &row, bool selected) const {
|
||||||
auto peer = row.peer;
|
auto peer = row.peer;
|
||||||
peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
peer->paintUserpicLeft(p, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize);
|
||||||
|
|
||||||
p.setPen(st::contactsNameFg);
|
p.setPen(st::contactsNameFg);
|
||||||
|
|
||||||
|
|
|
@ -462,7 +462,6 @@ void RichDeleteMessageBox::deleteAndClear() {
|
||||||
ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, const MTPChatPhoto &photo, int count, const QVector<UserData*> &participants)
|
ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, const MTPChatPhoto &photo, int count, const QVector<UserData*> &participants)
|
||||||
: _title(this, st::confirmInviteTitle)
|
: _title(this, st::confirmInviteTitle)
|
||||||
, _status(this, st::confirmInviteStatus)
|
, _status(this, st::confirmInviteStatus)
|
||||||
, _photo(chatDefPhoto(0))
|
|
||||||
, _participants(participants) {
|
, _participants(participants) {
|
||||||
_title->setText(title);
|
_title->setText(title);
|
||||||
QString status;
|
QString status;
|
||||||
|
@ -483,6 +482,9 @@ ConfirmInviteBox::ConfirmInviteBox(QWidget*, const QString &title, const MTPChat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!_photo) {
|
||||||
|
_photoEmpty.set(0, title);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfirmInviteBox::prepare() {
|
void ConfirmInviteBox::prepare() {
|
||||||
|
@ -528,12 +530,16 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
if (_photo) {
|
||||||
p.drawPixmap((width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, _photo->pixCircled(st::confirmInvitePhotoSize, st::confirmInvitePhotoSize));
|
p.drawPixmap((width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, _photo->pixCircled(st::confirmInvitePhotoSize, st::confirmInvitePhotoSize));
|
||||||
|
} else {
|
||||||
|
_photoEmpty.paint(p, (width() - st::confirmInvitePhotoSize) / 2, st::confirmInvitePhotoTop, width(), st::confirmInvitePhotoSize);
|
||||||
|
}
|
||||||
|
|
||||||
int sumWidth = _participants.size() * _userWidth;
|
int sumWidth = _participants.size() * _userWidth;
|
||||||
int left = (width() - sumWidth) / 2;
|
int left = (width() - sumWidth) / 2;
|
||||||
for_const (auto user, _participants) {
|
for_const (auto user, _participants) {
|
||||||
user->paintUserpicLeft(p, st::confirmInviteUserPhotoSize, left + (_userWidth - st::confirmInviteUserPhotoSize) / 2, st::confirmInviteUserPhotoTop, width());
|
user->paintUserpicLeft(p, left + (_userWidth - st::confirmInviteUserPhotoSize) / 2, st::confirmInviteUserPhotoTop, width(), st::confirmInviteUserPhotoSize);
|
||||||
left += _userWidth;
|
left += _userWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -207,6 +207,7 @@ private:
|
||||||
object_ptr<Ui::FlatLabel> _title;
|
object_ptr<Ui::FlatLabel> _title;
|
||||||
object_ptr<Ui::FlatLabel> _status;
|
object_ptr<Ui::FlatLabel> _status;
|
||||||
ImagePtr _photo;
|
ImagePtr _photo;
|
||||||
|
EmptyUserpic _photoEmpty;
|
||||||
QVector<UserData*> _participants;
|
QVector<UserData*> _participants;
|
||||||
|
|
||||||
int _userWidth = 0;
|
int _userWidth = 0;
|
||||||
|
|
|
@ -955,7 +955,7 @@ void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, Cont
|
||||||
checkedRatio = data->checkbox->checkedAnimationRatio();
|
checkedRatio = data->checkbox->checkedAnimationRatio();
|
||||||
data->checkbox->paint(p, ms, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
data->checkbox->paint(p, ms, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
||||||
} else {
|
} else {
|
||||||
peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
peer->paintUserpicLeft(p, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
int namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
int namex = st::contactsPadding.left() + st::contactsPhotoSize + st::contactsPadding.left();
|
||||||
|
@ -1013,7 +1013,7 @@ void ContactsBox::Inner::paintDisabledCheckUserpic(Painter &p, PeerData *peer, i
|
||||||
auto iconBorderPen = st::contactsPhotoCheckbox.check.border->p;
|
auto iconBorderPen = st::contactsPhotoCheckbox.check.border->p;
|
||||||
iconBorderPen.setWidth(st::contactsPhotoCheckbox.selectWidth);
|
iconBorderPen.setWidth(st::contactsPhotoCheckbox.selectWidth);
|
||||||
|
|
||||||
peer->paintUserpicLeft(p, userpicRadius * 2, userpicLeft, userpicTop, width());
|
peer->paintUserpicLeft(p, userpicLeft, userpicTop, width(), userpicRadius * 2);
|
||||||
|
|
||||||
{
|
{
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
|
|
|
@ -43,7 +43,7 @@ QString cantInviteError();
|
||||||
|
|
||||||
inline Ui::RoundImageCheckbox::PaintRoundImage PaintUserpicCallback(PeerData *peer) {
|
inline Ui::RoundImageCheckbox::PaintRoundImage PaintUserpicCallback(PeerData *peer) {
|
||||||
return [peer](Painter &p, int x, int y, int outerWidth, int size) {
|
return [peer](Painter &p, int x, int y, int outerWidth, int size) {
|
||||||
peer->paintUserpicLeft(p, size, x, y, outerWidth);
|
peer->paintUserpicLeft(p, x, y, outerWidth, size);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ void MembersBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, Membe
|
||||||
data->ripple.reset();
|
data->ripple.reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
peer->paintUserpicLeft(p, st::contactsPhotoSize, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
peer->paintUserpicLeft(p, st::contactsPadding.left(), st::contactsPadding.top(), width(), st::contactsPhotoSize);
|
||||||
|
|
||||||
p.setPen(st::contactsNameFg);
|
p.setPen(st::contactsNameFg);
|
||||||
|
|
||||||
|
|
|
@ -127,9 +127,11 @@ SendFilesBox::SendFilesBox(QWidget*, const QString &phone, const QString &firstn
|
||||||
: _contactPhone(phone)
|
: _contactPhone(phone)
|
||||||
, _contactFirstName(firstname)
|
, _contactFirstName(firstname)
|
||||||
, _contactLastName(lastname) {
|
, _contactLastName(lastname) {
|
||||||
_nameText.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName), _textNameOptions);
|
auto name = lng_full_name(lt_first_name, _contactFirstName, lt_last_name, _contactLastName);
|
||||||
|
_nameText.setText(st::semiboldTextStyle, name, _textNameOptions);
|
||||||
_statusText = _contactPhone;
|
_statusText = _contactPhone;
|
||||||
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
|
_statusWidth = qMax(_nameText.maxWidth(), st::normalFont->width(_statusText));
|
||||||
|
_contactPhotoEmpty.set(0, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SendFilesBox::prepare() {
|
void SendFilesBox::prepare() {
|
||||||
|
@ -280,7 +282,7 @@ void SendFilesBox::paintEvent(QPaintEvent *e) {
|
||||||
auto &icon = _fileIsImage ? st::historyFileOutImage : st::historyFileOutDocument;
|
auto &icon = _fileIsImage ? st::historyFileOutImage : st::historyFileOutDocument;
|
||||||
icon.paintInCenter(p, inner);
|
icon.paintInCenter(p, inner);
|
||||||
} else {
|
} else {
|
||||||
p.drawPixmapLeft(x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), userDefPhoto(1)->pixCircled(st::msgFileSize));
|
_contactPhotoEmpty.paint(p, x + st::msgFilePadding.left(), y + st::msgFilePadding.top(), width(), st::msgFileSize);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
QRect rthumb(rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
QRect rthumb(rtlrect(x + st::msgFileThumbPadding.left(), y + st::msgFileThumbPadding.top(), st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
||||||
|
|
|
@ -89,6 +89,7 @@ private:
|
||||||
QString _contactPhone;
|
QString _contactPhone;
|
||||||
QString _contactFirstName;
|
QString _contactFirstName;
|
||||||
QString _contactLastName;
|
QString _contactLastName;
|
||||||
|
EmptyUserpic _contactPhotoEmpty;
|
||||||
|
|
||||||
base::lambda<void(const QStringList &files, bool compressed, const QString &caption, bool ctrlShiftEnter)> _confirmedCallback;
|
base::lambda<void(const QStringList &files, bool compressed, const QString &caption, bool ctrlShiftEnter)> _confirmedCallback;
|
||||||
base::lambda<void()> _cancelledCallback;
|
base::lambda<void()> _cancelledCallback;
|
||||||
|
|
|
@ -320,21 +320,24 @@ inline T snap(const T &v, const T &_min, const T &_max) {
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ManagedPtr {
|
class ManagedPtr {
|
||||||
public:
|
public:
|
||||||
ManagedPtr() : ptr(0) {
|
ManagedPtr() = default;
|
||||||
}
|
ManagedPtr(T *p) : _data(p) {
|
||||||
ManagedPtr(T *p) : ptr(p) {
|
|
||||||
}
|
}
|
||||||
T *operator->() const {
|
T *operator->() const {
|
||||||
return ptr;
|
return _data;
|
||||||
}
|
}
|
||||||
T *v() const {
|
T *v() const {
|
||||||
return ptr;
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return _data != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
using Parent = ManagedPtr<T>;
|
||||||
|
T *_data = nullptr;
|
||||||
|
|
||||||
T *ptr;
|
|
||||||
typedef ManagedPtr<T> Parent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QString translitRusEng(const QString &rus);
|
QString translitRusEng(const QString &rus);
|
||||||
|
|
|
@ -66,7 +66,7 @@ void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *i
|
||||||
if (onlyBackground) return;
|
if (onlyBackground) return;
|
||||||
|
|
||||||
auto userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
|
auto userpicPeer = (history->peer->migrateTo() ? history->peer->migrateTo() : history->peer);
|
||||||
userpicPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth);
|
userpicPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth, st::dialogsPhotoSize);
|
||||||
|
|
||||||
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||||
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
|
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
|
||||||
|
|
|
@ -297,7 +297,7 @@ void DialogsInner::paintPeerSearchResult(Painter &p, const PeerSearchResult *res
|
||||||
|
|
||||||
auto peer = result->peer;
|
auto peer = result->peer;
|
||||||
auto userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer);
|
auto userpicPeer = (peer->migrateTo() ? peer->migrateTo() : peer);
|
||||||
userpicPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth());
|
userpicPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth(), st::dialogsPhotoSize);
|
||||||
|
|
||||||
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||||
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
|
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
|
||||||
|
@ -344,7 +344,7 @@ void DialogsInner::paintSearchInPeer(Painter &p, int fullWidth, bool onlyBackgro
|
||||||
p.fillRect(fullRect, st::dialogsBg);
|
p.fillRect(fullRect, st::dialogsBg);
|
||||||
if (onlyBackground) return;
|
if (onlyBackground) return;
|
||||||
|
|
||||||
_searchInPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth());
|
_searchInPeer->paintUserpicLeft(p, st::dialogsPadding.x(), st::dialogsPadding.y(), getFullWidth(), st::dialogsPhotoSize);
|
||||||
|
|
||||||
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||||
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x() * 2 - st::dialogsCancelSearch.width;
|
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x() * 2 - st::dialogsCancelSearch.width;
|
||||||
|
|
|
@ -618,7 +618,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user->loadUserpic();
|
user->loadUserpic();
|
||||||
user->paintUserpicLeft(p, st::mentionPhotoSize, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width());
|
user->paintUserpicLeft(p, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width(), st::mentionPhotoSize);
|
||||||
|
|
||||||
p.setPen(selected ? st::mentionNameFgOver : st::mentionNameFg);
|
p.setPen(selected ? st::mentionNameFgOver : st::mentionNameFg);
|
||||||
user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth);
|
user->nameText.drawElided(p, 2 * st::mentionPadding.left() + st::mentionPhotoSize, i * st::mentionHeight + st::mentionTop, namewidth);
|
||||||
|
@ -663,7 +663,7 @@ void FieldAutocompleteInner::paintEvent(QPaintEvent *e) {
|
||||||
toHighlight += '@' + user->username;
|
toHighlight += '@' + user->username;
|
||||||
}
|
}
|
||||||
user->loadUserpic();
|
user->loadUserpic();
|
||||||
user->paintUserpicLeft(p, st::mentionPhotoSize, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width());
|
user->paintUserpicLeft(p, st::mentionPadding.left(), i * st::mentionHeight + st::mentionPadding.top(), width(), st::mentionPhotoSize);
|
||||||
|
|
||||||
auto commandText = '/' + toHighlight;
|
auto commandText = '/' + toHighlight;
|
||||||
|
|
||||||
|
|
|
@ -145,23 +145,6 @@ historyViewsOutIcon: icon {{ "history_views", historyOutIconFg }};
|
||||||
historyViewsOutSelectedIcon: icon {{ "history_views", historyOutIconFgSelected }};
|
historyViewsOutSelectedIcon: icon {{ "history_views", historyOutIconFgSelected }};
|
||||||
historyViewsInvertedIcon: icon {{ "history_views", historySendingInvertedIconFg }};
|
historyViewsInvertedIcon: icon {{ "history_views", historySendingInvertedIconFg }};
|
||||||
|
|
||||||
historyPeer1UserpicPerson: icon {{ size(120px, 120px), historyPeer1UserpicBg }, { "userpic_person", historyPeer1UserpicFg }};
|
|
||||||
historyPeer1UserpicChat: icon {{ size(120px, 120px), historyPeer1UserpicBg }, { "userpic_chat", historyPeer1UserpicFg }};
|
|
||||||
historyPeer1UserpicChannel: icon {{ size(120px, 120px), historyPeer1UserpicBg }, { "userpic_channel", historyPeer1UserpicFg }};
|
|
||||||
historyPeer2UserpicPerson: icon {{ size(120px, 120px), historyPeer2UserpicBg }, { "userpic_person", historyPeer2UserpicFg }};
|
|
||||||
historyPeer2UserpicChat: icon {{ size(120px, 120px), historyPeer2UserpicBg }, { "userpic_chat", historyPeer2UserpicFg }};
|
|
||||||
historyPeer2UserpicChannel: icon {{ size(120px, 120px), historyPeer2UserpicBg }, { "userpic_channel", historyPeer2UserpicFg }};
|
|
||||||
historyPeer3UserpicPerson: icon {{ size(120px, 120px), historyPeer3UserpicBg }, { "userpic_person", historyPeer3UserpicFg }};
|
|
||||||
historyPeer3UserpicChat: icon {{ size(120px, 120px), historyPeer3UserpicBg }, { "userpic_chat", historyPeer3UserpicFg }};
|
|
||||||
historyPeer3UserpicChannel: icon {{ size(120px, 120px), historyPeer3UserpicBg }, { "userpic_channel", historyPeer3UserpicFg }};
|
|
||||||
historyPeer4UserpicPerson: icon {{ size(120px, 120px), historyPeer4UserpicBg }, { "userpic_person", historyPeer4UserpicFg }};
|
|
||||||
historyPeer4UserpicChat: icon {{ size(120px, 120px), historyPeer4UserpicBg }, { "userpic_chat", historyPeer4UserpicFg }};
|
|
||||||
historyPeer4UserpicChannel: icon {{ size(120px, 120px), historyPeer4UserpicBg }, { "userpic_channel", historyPeer4UserpicFg }};
|
|
||||||
historyPeer5UserpicPerson: icon {{ size(120px, 120px), historyPeer5UserpicBg }, { "userpic_person", historyPeer5UserpicFg }};
|
|
||||||
historyPeer6UserpicPerson: icon {{ size(120px, 120px), historyPeer6UserpicBg }, { "userpic_person", historyPeer6UserpicFg }};
|
|
||||||
historyPeer7UserpicPerson: icon {{ size(120px, 120px), historyPeer7UserpicBg }, { "userpic_person", historyPeer7UserpicFg }};
|
|
||||||
historyPeer8UserpicPerson: icon {{ size(120px, 120px), historyPeer8UserpicBg }, { "userpic_person", historyPeer8UserpicFg }};
|
|
||||||
|
|
||||||
historyComposeField: FlatTextarea {
|
historyComposeField: FlatTextarea {
|
||||||
textColor: historyComposeAreaFg;
|
textColor: historyComposeAreaFg;
|
||||||
bgColor: historyComposeAreaBg;
|
bgColor: historyComposeAreaBg;
|
||||||
|
@ -391,6 +374,8 @@ historyBubbleTailInRightSelected: icon {{ "bubble_tail-flip_horizontal", msgInBg
|
||||||
historyBubbleTailOutRight: icon {{ "bubble_tail-flip_horizontal", msgOutBg }};
|
historyBubbleTailOutRight: icon {{ "bubble_tail-flip_horizontal", msgOutBg }};
|
||||||
historyBubbleTailOutRightSelected: icon {{ "bubble_tail-flip_horizontal", msgOutBgSelected }};
|
historyBubbleTailOutRightSelected: icon {{ "bubble_tail-flip_horizontal", msgOutBgSelected }};
|
||||||
|
|
||||||
|
historyPeerUserpicFont: semiboldFont;
|
||||||
|
|
||||||
historyStatusFg: windowSubTextFg;
|
historyStatusFg: windowSubTextFg;
|
||||||
historyStatusFgActive: windowActiveTextFg;
|
historyStatusFgActive: windowActiveTextFg;
|
||||||
historyStatusFgTyping: historyStatusFgActive;
|
historyStatusFgTyping: historyStatusFgActive;
|
||||||
|
|
|
@ -2235,16 +2235,17 @@ HistoryContact::HistoryContact(HistoryItem *parent, int32 userId, const QString
|
||||||
, _lname(last)
|
, _lname(last)
|
||||||
, _phone(App::formatPhone(phone)) {
|
, _phone(App::formatPhone(phone)) {
|
||||||
_name.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions);
|
_name.setText(st::semiboldTextStyle, lng_full_name(lt_first_name, first, lt_last_name, last).trimmed(), _textNameOptions);
|
||||||
|
|
||||||
_phonew = st::normalFont->width(_phone);
|
_phonew = st::normalFont->width(_phone);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryContact::initDimensions() {
|
void HistoryContact::initDimensions() {
|
||||||
_maxw = st::msgFileMinWidth;
|
_maxw = st::msgFileMinWidth;
|
||||||
|
|
||||||
_contact = _userId ? App::userLoaded(_userId) : 0;
|
_contact = _userId ? App::userLoaded(_userId) : nullptr;
|
||||||
if (_contact) {
|
if (_contact) {
|
||||||
_contact->loadUserpic();
|
_contact->loadUserpic();
|
||||||
|
} else {
|
||||||
|
_photoEmpty.set(qAbs(_userId ? _userId : _parent->id) % kUserColorsCount, _name.originalText());
|
||||||
}
|
}
|
||||||
if (_contact && _contact->contact > 0) {
|
if (_contact && _contact->contact > 0) {
|
||||||
_linkl = sendMessageClickHandler(_contact);
|
_linkl = sendMessageClickHandler(_contact);
|
||||||
|
@ -2305,12 +2306,15 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, T
|
||||||
|
|
||||||
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width));
|
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width));
|
||||||
if (_contact) {
|
if (_contact) {
|
||||||
_contact->paintUserpic(p, st::msgFileThumbSize, rthumb.x(), rthumb.y());
|
_contact->paintUserpic(p, rthumb.x(), rthumb.y(), st::msgFileThumbSize);
|
||||||
} else {
|
} else {
|
||||||
p.drawPixmap(rthumb.topLeft(), userDefPhoto(qAbs(_userId) % kUserColorsCount)->pixCircled(st::msgFileThumbSize, st::msgFileThumbSize));
|
_photoEmpty.paint(p, st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, width, st::msgFileThumbSize);
|
||||||
}
|
}
|
||||||
if (selected) {
|
if (selected) {
|
||||||
App::roundRect(p, rthumb, p.textPalette().selectOverlay, SelectedOverlaySmallCorners);
|
PainterHighQualityEnabler hq(p);
|
||||||
|
p.setBrush(p.textPalette().selectOverlay);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.drawEllipse(rthumb);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool over = ClickHandler::showAsActive(_linkl);
|
bool over = ClickHandler::showAsActive(_linkl);
|
||||||
|
@ -2323,8 +2327,7 @@ void HistoryContact::draw(Painter &p, const QRect &r, TextSelection selection, T
|
||||||
nameright = st::msgFilePadding.left();
|
nameright = st::msgFilePadding.left();
|
||||||
statustop = st::msgFileStatusTop - topMinus;
|
statustop = st::msgFileStatusTop - topMinus;
|
||||||
|
|
||||||
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width));
|
_photoEmpty.paint(p, st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, width, st::msgFileSize);
|
||||||
p.drawPixmap(inner.topLeft(), userDefPhoto(qAbs(_parent->id) % kUserColorsCount)->pixCircled(st::msgFileSize, st::msgFileSize));
|
|
||||||
}
|
}
|
||||||
int32 namewidth = width - nameleft - nameright;
|
int32 namewidth = width - nameleft - nameright;
|
||||||
|
|
||||||
|
|
|
@ -636,6 +636,7 @@ private:
|
||||||
int _phonew = 0;
|
int _phonew = 0;
|
||||||
QString _fname, _lname, _phone;
|
QString _fname, _lname, _phone;
|
||||||
Text _name;
|
Text _name;
|
||||||
|
EmptyUserpic _photoEmpty;
|
||||||
|
|
||||||
ClickHandlerPtr _linkl;
|
ClickHandlerPtr _linkl;
|
||||||
int _linkw = 0;
|
int _linkw = 0;
|
||||||
|
|
|
@ -553,7 +553,7 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
// paint the userpic if it intersects the painted rect
|
// paint the userpic if it intersects the painted rect
|
||||||
if (userpicTop + st::msgPhotoSize > r.top()) {
|
if (userpicTop + st::msgPhotoSize > r.top()) {
|
||||||
message->from()->paintUserpicLeft(p, st::msgPhotoSize, st::historyPhotoLeft, userpicTop, message->history()->width);
|
message->from()->paintUserpicLeft(p, st::historyPhotoLeft, userpicTop, message->history()->width, st::msgPhotoSize);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
|
@ -146,7 +146,11 @@ ImagePtr ItemBase::getResultThumb() const {
|
||||||
|
|
||||||
QPixmap ItemBase::getResultContactAvatar(int width, int height) const {
|
QPixmap ItemBase::getResultContactAvatar(int width, int height) const {
|
||||||
if (_result->_type == Result::Type::Contact) {
|
if (_result->_type == Result::Type::Contact) {
|
||||||
return userDefPhoto(qHash(_result->_id) % kUserColorsCount)->pixCircled(width, height);
|
auto result = EmptyUserpic(qHash(_result->_id) % kUserColorsCount, _result->getLayoutTitle()).generate(width);
|
||||||
|
if (result.height() != height * cIntRetinaFactor()) {
|
||||||
|
result = result.scaled(QSize(width, height) * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
||||||
|
}
|
||||||
|
return std_::move(result);
|
||||||
}
|
}
|
||||||
return QPixmap();
|
return QPixmap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -3874,7 +3874,7 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) {
|
||||||
user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
|
user->inputUser = MTP_inputUser(MTP_int(peerToUser(user->id)), MTP_long((user->access == UserNoAccess) ? 0 : user->access));
|
||||||
}
|
}
|
||||||
|
|
||||||
user->setUserpic(photoLoc.isNull() ? ImagePtr(userDefPhoto(user->colorIndex)) : ImagePtr(photoLoc));
|
user->setUserpic(photoLoc.isNull() ? ImagePtr() : ImagePtr(photoLoc));
|
||||||
}
|
}
|
||||||
} else if (result->isChat()) {
|
} else if (result->isChat()) {
|
||||||
ChatData *chat = result->asChat();
|
ChatData *chat = result->asChat();
|
||||||
|
@ -3902,7 +3902,7 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) {
|
||||||
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id)));
|
chat->input = MTP_inputPeerChat(MTP_int(peerToChat(chat->id)));
|
||||||
chat->inputChat = MTP_int(peerToChat(chat->id));
|
chat->inputChat = MTP_int(peerToChat(chat->id));
|
||||||
|
|
||||||
chat->setUserpic(photoLoc.isNull() ? ImagePtr(chatDefPhoto(chat->colorIndex)) : ImagePtr(photoLoc));
|
chat->setUserpic(photoLoc.isNull() ? ImagePtr() : ImagePtr(photoLoc));
|
||||||
}
|
}
|
||||||
} else if (result->isChannel()) {
|
} else if (result->isChannel()) {
|
||||||
ChannelData *channel = result->asChannel();
|
ChannelData *channel = result->asChannel();
|
||||||
|
@ -3924,7 +3924,7 @@ PeerData *_readPeer(FileReadDescriptor &from, int32 fileVersion = 0) {
|
||||||
channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
|
channel->input = MTP_inputPeerChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
|
||||||
channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
|
channel->inputChannel = MTP_inputChannel(MTP_int(peerToChannel(channel->id)), MTP_long(access));
|
||||||
|
|
||||||
channel->setUserpic(photoLoc.isNull() ? ImagePtr((channel->isMegagroup() ? chatDefPhoto(channel->colorIndex) : channelDefPhoto(channel->colorIndex))) : ImagePtr(photoLoc));
|
channel->setUserpic(photoLoc.isNull() ? ImagePtr() : ImagePtr(photoLoc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!wasLoaded) {
|
if (!wasLoaded) {
|
||||||
|
|
|
@ -96,7 +96,7 @@ void PeerListWidget::paintItem(Painter &p, int x, int y, Item *item, bool select
|
||||||
}
|
}
|
||||||
int skip = st::profileMemberPhotoPosition.x();
|
int skip = st::profileMemberPhotoPosition.x();
|
||||||
|
|
||||||
item->peer->paintUserpicLeft(p, st::profileMemberPhotoSize, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width());
|
item->peer->paintUserpicLeft(p, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width(), st::profileMemberPhotoSize);
|
||||||
|
|
||||||
if (item->name.isEmpty()) {
|
if (item->name.isEmpty()) {
|
||||||
item->name.setText(st::msgNameStyle, App::peerName(item->peer), _textNameOptions);
|
item->name.setText(st::msgNameStyle, App::peerName(item->peer), _textNameOptions);
|
||||||
|
|
|
@ -236,7 +236,7 @@ void InnerWidget::paintRow(Painter &p, int index, TimeMs ms) {
|
||||||
|
|
||||||
x += st::profileCommonGroupsPadding.left();
|
x += st::profileCommonGroupsPadding.left();
|
||||||
y += st::profileCommonGroupsPadding.top();
|
y += st::profileCommonGroupsPadding.top();
|
||||||
item->peer->paintUserpic(p, st::profileCommonGroupsPhotoSize, rtl() ? (width() - x - st::profileCommonGroupsPhotoSize) : x, y);
|
item->peer->paintUserpic(p, rtl() ? (width() - x - st::profileCommonGroupsPhotoSize) : x, y, st::profileCommonGroupsPhotoSize);
|
||||||
|
|
||||||
x += st::profileCommonGroupsPhotoSize + st::profileCommonGroupsNameLeft;
|
x += st::profileCommonGroupsPhotoSize + st::profileCommonGroupsNameLeft;
|
||||||
y += st::profileCommonGroupsNameTop;
|
y += st::profileCommonGroupsNameTop;
|
||||||
|
|
|
@ -115,7 +115,7 @@ QPixmap UserpicButton::prepareUserpicPixmap() const {
|
||||||
image.fill(Qt::transparent);
|
image.fill(Qt::transparent);
|
||||||
{
|
{
|
||||||
Painter p(&image);
|
Painter p(&image);
|
||||||
_peer->paintUserpic(p, width(), 0, 0);
|
_peer->paintUserpic(p, 0, 0, width());
|
||||||
}
|
}
|
||||||
return App::pixmapFromImageInPlace(std_::move(image));
|
return App::pixmapFromImageInPlace(std_::move(image));
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,40 +74,140 @@ style::color peerColor(int index) {
|
||||||
return peerColors[index];
|
return peerColors[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagePtr userDefPhoto(int index) {
|
style::color peerUserpicColor(int index) {
|
||||||
static const ImagePtr userDefPhotos[kUserColorsCount] = {
|
static style::color peerColors[kUserColorsCount] = {
|
||||||
generateUserpicImage(st::historyPeer1UserpicPerson),
|
st::historyPeer1UserpicBg,
|
||||||
generateUserpicImage(st::historyPeer2UserpicPerson),
|
st::historyPeer2UserpicBg,
|
||||||
generateUserpicImage(st::historyPeer3UserpicPerson),
|
st::historyPeer3UserpicBg,
|
||||||
generateUserpicImage(st::historyPeer4UserpicPerson),
|
st::historyPeer4UserpicBg,
|
||||||
generateUserpicImage(st::historyPeer5UserpicPerson),
|
st::historyPeer5UserpicBg,
|
||||||
generateUserpicImage(st::historyPeer6UserpicPerson),
|
st::historyPeer6UserpicBg,
|
||||||
generateUserpicImage(st::historyPeer7UserpicPerson),
|
st::historyPeer7UserpicBg,
|
||||||
generateUserpicImage(st::historyPeer8UserpicPerson),
|
st::historyPeer8UserpicBg,
|
||||||
};
|
};
|
||||||
return userDefPhotos[index];
|
return peerColors[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagePtr chatDefPhoto(int index) {
|
class EmptyUserpic::Impl {
|
||||||
static const ImagePtr chatDefPhotos[kChatColorsCount] = {
|
public:
|
||||||
generateUserpicImage(st::historyPeer1UserpicChat),
|
Impl(int index, const QString &name) : _color(peerUserpicColor(index)) {
|
||||||
generateUserpicImage(st::historyPeer2UserpicChat),
|
fillString(name);
|
||||||
generateUserpicImage(st::historyPeer3UserpicChat),
|
|
||||||
generateUserpicImage(st::historyPeer4UserpicChat),
|
|
||||||
};
|
|
||||||
return chatDefPhotos[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagePtr channelDefPhoto(int index) {
|
void paint(Painter &p, int x, int y, int size);
|
||||||
static const ImagePtr channelDefPhotos[kChannelColorsCount] = {
|
|
||||||
generateUserpicImage(st::historyPeer1UserpicChannel),
|
private:
|
||||||
generateUserpicImage(st::historyPeer2UserpicChannel),
|
void fillString(const QString &name);
|
||||||
generateUserpicImage(st::historyPeer3UserpicChannel),
|
|
||||||
generateUserpicImage(st::historyPeer4UserpicChannel),
|
style::color _color;
|
||||||
|
QString _string;
|
||||||
|
|
||||||
};
|
};
|
||||||
return channelDefPhotos[index];
|
|
||||||
|
void EmptyUserpic::Impl::paint(Painter &p, int x, int y, int size) {
|
||||||
|
auto fontsize = (size * 13) / 33;
|
||||||
|
auto font = st::historyPeerUserpicFont->f;
|
||||||
|
font.setPixelSize(fontsize);
|
||||||
|
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
|
p.setBrush(_color);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.drawEllipse(x, y, size, size);
|
||||||
|
|
||||||
|
p.setFont(font);
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
p.setPen(st::historyPeerUserpicFg);
|
||||||
|
p.drawText(QRect(x, y, size, size), _string, QTextOption(style::al_center));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmptyUserpic::Impl::fillString(const QString &name) {
|
||||||
|
QList<QString> letters;
|
||||||
|
QList<int> levels;
|
||||||
|
auto level = 0;
|
||||||
|
auto letterFound = false;
|
||||||
|
auto ch = name.constData(), end = ch + name.size();
|
||||||
|
while (ch != end) {
|
||||||
|
auto emojiLength = 0;
|
||||||
|
if (auto emoji = emojiFromText(ch, end, &emojiLength)) {
|
||||||
|
ch += emojiLength;
|
||||||
|
} else if (ch->isHighSurrogate()) {
|
||||||
|
++ch;
|
||||||
|
if (ch != end && ch->isLowSurrogate()) {
|
||||||
|
++ch;
|
||||||
|
}
|
||||||
|
} else if (!letterFound && ch->isLetterOrNumber()) {
|
||||||
|
letterFound = true;
|
||||||
|
if (ch + 1 != end && chIsDiac(*(ch + 1))) {
|
||||||
|
letters.push_back(QString(ch, 2));
|
||||||
|
levels.push_back(level);
|
||||||
|
++ch;
|
||||||
|
} else {
|
||||||
|
letters.push_back(QString(ch, 1));
|
||||||
|
levels.push_back(level);
|
||||||
|
}
|
||||||
|
++ch;
|
||||||
|
} else {
|
||||||
|
if (*ch == ' ') {
|
||||||
|
level = 0;
|
||||||
|
letterFound = false;
|
||||||
|
} else if (letterFound && *ch == '-') {
|
||||||
|
level = 1;
|
||||||
|
letterFound = true;
|
||||||
|
}
|
||||||
|
++ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We prefer the second letter to be after ' ', but it can also be after '-'.
|
||||||
|
_string = QString();
|
||||||
|
if (!letters.isEmpty()) {
|
||||||
|
_string += letters.front();
|
||||||
|
auto bestIndex = 0;
|
||||||
|
auto bestLevel = 2;
|
||||||
|
for (auto i = letters.size(); i != 1;) {
|
||||||
|
if (levels[--i] < bestLevel) {
|
||||||
|
bestIndex = i;
|
||||||
|
bestLevel = levels[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestIndex > 0) {
|
||||||
|
_string += letters[bestIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_string = _string.toUpper();
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptyUserpic::EmptyUserpic() = default;
|
||||||
|
|
||||||
|
EmptyUserpic::EmptyUserpic(int index, const QString &name) : _impl(std_::make_unique<Impl>(index, name)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmptyUserpic::set(int index, const QString &name) {
|
||||||
|
_impl = std_::make_unique<Impl>(index, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmptyUserpic::clear() {
|
||||||
|
_impl.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmptyUserpic::paint(Painter &p, int x, int y, int outerWidth, int size) const {
|
||||||
|
t_assert(_impl != nullptr);
|
||||||
|
_impl->paint(p, rtl() ? (outerWidth - x - size) : x, y, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap EmptyUserpic::generate(int size) {
|
||||||
|
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
|
result.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
result.fill(Qt::transparent);
|
||||||
|
{
|
||||||
|
Painter p(&result);
|
||||||
|
paint(p, 0, 0, size, size);
|
||||||
|
}
|
||||||
|
return App::pixmapFromImageInPlace(std_::move(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
EmptyUserpic::~EmptyUserpic() = default;
|
||||||
|
|
||||||
using UpdateFlag = Notify::PeerUpdate::Flag;
|
using UpdateFlag = Notify::PeerUpdate::Flag;
|
||||||
|
|
||||||
NotifySettings globalNotifyAll, globalNotifyUsers, globalNotifyChats;
|
NotifySettings globalNotifyAll, globalNotifyUsers, globalNotifyChats;
|
||||||
|
@ -115,9 +215,9 @@ NotifySettingsPtr globalNotifyAllPtr = UnknownNotifySettings, globalNotifyUsersP
|
||||||
|
|
||||||
PeerData::PeerData(const PeerId &id) : id(id)
|
PeerData::PeerData(const PeerId &id) : id(id)
|
||||||
, colorIndex(peerColorIndex(id))
|
, colorIndex(peerColorIndex(id))
|
||||||
, color(peerColor(colorIndex))
|
, color(peerColor(colorIndex)) {
|
||||||
, _userpic(isUser() ? userDefPhoto(colorIndex) : ((isChat() || isMegagroup()) ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex))) {
|
|
||||||
nameText.setText(st::msgNameStyle, QString(), _textNameOptions);
|
nameText.setText(st::msgNameStyle, QString(), _textNameOptions);
|
||||||
|
_userpicEmpty.set(colorIndex, QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerData::updateNameDelayed(const QString &newName, const QString &newNameOrPhone, const QString &newUsername) {
|
void PeerData::updateNameDelayed(const QString &newName, const QString &newNameOrPhone, const QString &newUsername) {
|
||||||
|
@ -138,6 +238,9 @@ void PeerData::updateNameDelayed(const QString &newName, const QString &newNameO
|
||||||
++nameVersion;
|
++nameVersion;
|
||||||
name = newName;
|
name = newName;
|
||||||
nameText.setText(st::msgNameStyle, name, _textNameOptions);
|
nameText.setText(st::msgNameStyle, name, _textNameOptions);
|
||||||
|
if (!_userpic) {
|
||||||
|
_userpicEmpty.set(colorIndex, name);
|
||||||
|
}
|
||||||
|
|
||||||
Notify::PeerUpdate update(this);
|
Notify::PeerUpdate update(this);
|
||||||
update.flags |= UpdateFlag::NameChanged;
|
update.flags |= UpdateFlag::NameChanged;
|
||||||
|
@ -170,39 +273,55 @@ void PeerData::updateNameDelayed(const QString &newName, const QString &newNameO
|
||||||
|
|
||||||
void PeerData::setUserpic(ImagePtr userpic) {
|
void PeerData::setUserpic(ImagePtr userpic) {
|
||||||
_userpic = userpic;
|
_userpic = userpic;
|
||||||
|
if (!_userpic || !_userpic->loaded()) {
|
||||||
|
_userpicEmpty.set(colorIndex, name);
|
||||||
|
} else {
|
||||||
|
_userpicEmpty.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImagePtr PeerData::currentUserpic() const {
|
ImagePtr PeerData::currentUserpic() const {
|
||||||
|
if (_userpic) {
|
||||||
|
_userpic->load();
|
||||||
if (_userpic->loaded()) {
|
if (_userpic->loaded()) {
|
||||||
|
_userpicEmpty.clear();
|
||||||
return _userpic;
|
return _userpic;
|
||||||
}
|
}
|
||||||
_userpic->load();
|
|
||||||
|
|
||||||
if (isUser()) {
|
|
||||||
return userDefPhoto(colorIndex);
|
|
||||||
} else if (isMegagroup() || isChat()) {
|
|
||||||
return chatDefPhoto(colorIndex);
|
|
||||||
}
|
}
|
||||||
return channelDefPhoto(colorIndex);
|
return ImagePtr();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerData::paintUserpic(Painter &p, int size, int x, int y) const {
|
void PeerData::paintUserpic(Painter &p, int x, int y, int size) const {
|
||||||
p.drawPixmap(x, y, currentUserpic()->pixCircled(size, size));
|
if (auto userpic = currentUserpic()) {
|
||||||
|
p.drawPixmap(x, y, userpic->pixCircled(size, size));
|
||||||
|
} else {
|
||||||
|
_userpicEmpty.paint(p, x, y, x + size + x, size);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StorageKey PeerData::userpicUniqueKey() const {
|
StorageKey PeerData::userpicUniqueKey() const {
|
||||||
if (photoLoc.isNull() || !_userpic->loaded()) {
|
if (photoLoc.isNull() || !_userpic || !_userpic->loaded()) {
|
||||||
return StorageKey(0, (isUser() ? 0x1000 : ((isChat() || isMegagroup()) ? 0x2000 : 0x3000)) | colorIndex);
|
return StorageKey(0, (isUser() ? 0x1000 : ((isChat() || isMegagroup()) ? 0x2000 : 0x3000)) | colorIndex);
|
||||||
}
|
}
|
||||||
return storageKey(photoLoc);
|
return storageKey(photoLoc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerData::saveUserpic(const QString &path, int size) const {
|
void PeerData::saveUserpic(const QString &path, int size) const {
|
||||||
currentUserpic()->pixRounded(size, size, ImageRoundRadius::Small).save(path, "PNG");
|
genUserpic(size).save(path, "PNG");
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap PeerData::genUserpic(int size) const {
|
QPixmap PeerData::genUserpic(int size) const {
|
||||||
return currentUserpic()->pixRounded(size, size, ImageRoundRadius::Small);
|
if (auto userpic = currentUserpic()) {
|
||||||
|
return userpic->pixRounded(size, size, ImageRoundRadius::Small);
|
||||||
|
}
|
||||||
|
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
|
result.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
result.fill(Qt::transparent);
|
||||||
|
{
|
||||||
|
Painter p(&result);
|
||||||
|
paintUserpic(p, 0, 0, size);
|
||||||
|
}
|
||||||
|
return App::pixmapFromImageInPlace(std_::move(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Text &BotCommand::descriptionText() const {
|
const Text &BotCommand::descriptionText() const {
|
||||||
|
@ -225,17 +344,17 @@ void UserData::setPhoto(const MTPUserProfilePhoto &p) { // see Local::readPeer a
|
||||||
const auto &d(p.c_userProfilePhoto());
|
const auto &d(p.c_userProfilePhoto());
|
||||||
newPhotoId = d.vphoto_id.v;
|
newPhotoId = d.vphoto_id.v;
|
||||||
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
||||||
newPhoto = newPhotoLoc.isNull() ? userDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
|
newPhoto = newPhotoLoc.isNull() ? ImagePtr() : ImagePtr(newPhotoLoc);
|
||||||
//App::feedPhoto(App::photoFromUserPhoto(peerToUser(id), MTP_int(unixtime()), p));
|
//App::feedPhoto(App::photoFromUserPhoto(peerToUser(id), MTP_int(unixtime()), p));
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
newPhotoId = 0;
|
newPhotoId = 0;
|
||||||
if (id == ServiceUserId) {
|
if (id == ServiceUserId) {
|
||||||
if (_userpic.v() == userDefPhoto(colorIndex).v()) {
|
if (!_userpic) {
|
||||||
newPhoto = ImagePtr(App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation)), "PNG");
|
newPhoto = ImagePtr(App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaledToWidth(160, Qt::SmoothTransformation)), "PNG");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
newPhoto = userDefPhoto(colorIndex);
|
newPhoto = ImagePtr();
|
||||||
}
|
}
|
||||||
newPhotoLoc = StorageImageLocation();
|
newPhotoLoc = StorageImageLocation();
|
||||||
} break;
|
} break;
|
||||||
|
@ -423,13 +542,13 @@ void ChatData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see Loc
|
||||||
newPhotoId = phId;
|
newPhotoId = phId;
|
||||||
}
|
}
|
||||||
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
||||||
newPhoto = newPhotoLoc.isNull() ? chatDefPhoto(colorIndex) : ImagePtr(newPhotoLoc);
|
newPhoto = newPhotoLoc.isNull() ? ImagePtr() : ImagePtr(newPhotoLoc);
|
||||||
// photoFull = ImagePtr(640, 640, d.vphoto_big, chatDefPhoto(colorIndex));
|
// photoFull = newPhoto ? ImagePtr(640, 640, d.vphoto_big, ImagePtr()) : ImagePtr();
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
newPhotoId = 0;
|
newPhotoId = 0;
|
||||||
newPhotoLoc = StorageImageLocation();
|
newPhotoLoc = StorageImageLocation();
|
||||||
newPhoto = chatDefPhoto(colorIndex);
|
newPhoto = ImagePtr();
|
||||||
// photoFull = ImagePtr();
|
// photoFull = ImagePtr();
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
@ -479,13 +598,13 @@ void ChannelData::setPhoto(const MTPChatPhoto &p, const PhotoId &phId) { // see
|
||||||
newPhotoId = phId;
|
newPhotoId = phId;
|
||||||
}
|
}
|
||||||
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
newPhotoLoc = App::imageLocation(160, 160, d.vphoto_small);
|
||||||
newPhoto = newPhotoLoc.isNull() ? (isMegagroup() ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex)) : ImagePtr(newPhotoLoc);
|
newPhoto = newPhotoLoc.isNull() ? ImagePtr() : ImagePtr(newPhotoLoc);
|
||||||
// photoFull = ImagePtr(640, 640, d.vphoto_big, (isMegagroup() ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex)));
|
// photoFull = newPhoto ? ImagePtr(640, 640, d.vphoto_big, newPhoto) : ImagePtr();
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
newPhotoId = 0;
|
newPhotoId = 0;
|
||||||
newPhotoLoc = StorageImageLocation();
|
newPhotoLoc = StorageImageLocation();
|
||||||
newPhoto = (isMegagroup() ? chatDefPhoto(colorIndex) : channelDefPhoto(colorIndex));
|
newPhoto = ImagePtr();
|
||||||
// photoFull = ImagePtr();
|
// photoFull = ImagePtr();
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,9 +204,30 @@ static constexpr int kChatColorsCount = 4;
|
||||||
static constexpr int kChannelColorsCount = 4;
|
static constexpr int kChannelColorsCount = 4;
|
||||||
|
|
||||||
style::color peerColor(int index);
|
style::color peerColor(int index);
|
||||||
ImagePtr userDefPhoto(int index);
|
|
||||||
ImagePtr chatDefPhoto(int index);
|
class EmptyUserpic {
|
||||||
ImagePtr channelDefPhoto(int index);
|
public:
|
||||||
|
EmptyUserpic();
|
||||||
|
EmptyUserpic(int index, const QString &name);
|
||||||
|
|
||||||
|
void set(int index, const QString &name);
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return (_impl != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void paint(Painter &p, int x, int y, int outerWidth, int size) const;
|
||||||
|
QPixmap generate(int size);
|
||||||
|
|
||||||
|
~EmptyUserpic();
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Impl;
|
||||||
|
std_::unique_ptr<Impl> _impl;
|
||||||
|
friend class Impl;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
|
static const PhotoId UnknownPeerPhotoId = 0xFFFFFFFFFFFFFFFFULL;
|
||||||
|
|
||||||
|
@ -292,9 +313,9 @@ public:
|
||||||
style::color color;
|
style::color color;
|
||||||
|
|
||||||
void setUserpic(ImagePtr userpic);
|
void setUserpic(ImagePtr userpic);
|
||||||
void paintUserpic(Painter &p, int size, int x, int y) const;
|
void paintUserpic(Painter &p, int x, int y, int size) const;
|
||||||
void paintUserpicLeft(Painter &p, int size, int x, int y, int w) const {
|
void paintUserpicLeft(Painter &p, int x, int y, int w, int size) const {
|
||||||
paintUserpic(p, size, rtl() ? (w - x - size) : x, y);
|
paintUserpic(p, rtl() ? (w - x - size) : x, y, size);
|
||||||
}
|
}
|
||||||
void loadUserpic(bool loadFirst = false, bool prior = true) {
|
void loadUserpic(bool loadFirst = false, bool prior = true) {
|
||||||
_userpic->load(loadFirst, prior);
|
_userpic->load(loadFirst, prior);
|
||||||
|
@ -331,6 +352,7 @@ protected:
|
||||||
|
|
||||||
ImagePtr _userpic;
|
ImagePtr _userpic;
|
||||||
ImagePtr currentUserpic() const;
|
ImagePtr currentUserpic() const;
|
||||||
|
mutable EmptyUserpic _userpicEmpty;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fillNames();
|
void fillNames();
|
||||||
|
|
|
@ -36,7 +36,7 @@ PeerAvatarButton::PeerAvatarButton(QWidget *parent, PeerData *peer, const style:
|
||||||
void PeerAvatarButton::paintEvent(QPaintEvent *e) {
|
void PeerAvatarButton::paintEvent(QPaintEvent *e) {
|
||||||
if (_peer) {
|
if (_peer) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
_peer->paintUserpic(p, _st.photoSize, (_st.size - _st.photoSize) / 2, (_st.size - _st.photoSize) / 2);
|
_peer->paintUserpic(p, (_st.size - _st.photoSize) / 2, (_st.size - _st.photoSize) / 2, _st.photoSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -444,6 +444,11 @@ public:
|
||||||
ImagePtr(int32 width, int32 height, const MTPFileLocation &location, ImagePtr def = ImagePtr());
|
ImagePtr(int32 width, int32 height, const MTPFileLocation &location, ImagePtr def = ImagePtr());
|
||||||
ImagePtr(int32 width, int32 height) : Parent(internal::getImage(width, height)) {
|
ImagePtr(int32 width, int32 height) : Parent(internal::getImage(width, height)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const {
|
||||||
|
return (_data != nullptr) && !_data->isNull();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline QSize shrinkToKeepAspect(int32 width, int32 height, int32 towidth, int32 toheight) {
|
inline QSize shrinkToKeepAspect(int32 width, int32 height, int32 towidth, int32 toheight) {
|
||||||
|
|
|
@ -612,7 +612,7 @@ void Notification::updateNotifyDisplay() {
|
||||||
|
|
||||||
if (!options.hideNameAndPhoto) {
|
if (!options.hideNameAndPhoto) {
|
||||||
_history->peer->loadUserpic(true, true);
|
_history->peer->loadUserpic(true, true);
|
||||||
_history->peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width());
|
_history->peer->paintUserpicLeft(p, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width(), st::notifyPhotoSize);
|
||||||
} else {
|
} else {
|
||||||
static QPixmap icon = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
static QPixmap icon = App::pixmapFromImageInPlace(App::wnd()->iconLarge().scaled(st::notifyPhotoSize, st::notifyPhotoSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
|
||||||
icon.setDevicePixelRatio(cRetinaFactor());
|
icon.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
@ -680,7 +680,7 @@ void Notification::updatePeerPhoto() {
|
||||||
auto img = _cache.toImage();
|
auto img = _cache.toImage();
|
||||||
{
|
{
|
||||||
Painter p(&img);
|
Painter p(&img);
|
||||||
_peer->paintUserpicLeft(p, st::notifyPhotoSize, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width());
|
_peer->paintUserpicLeft(p, st::notifyPhotoPos.x(), st::notifyPhotoPos.y(), width(), st::notifyPhotoSize);
|
||||||
}
|
}
|
||||||
_cache = App::pixmapFromImageInPlace(std_::move(img));
|
_cache = App::pixmapFromImageInPlace(std_::move(img));
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -34,6 +34,63 @@ namespace Window {
|
||||||
namespace Theme {
|
namespace Theme {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
QString fillLetters(const QString &name) {
|
||||||
|
QList<QString> letters;
|
||||||
|
QList<int> levels;
|
||||||
|
auto level = 0;
|
||||||
|
auto letterFound = false;
|
||||||
|
auto ch = name.constData(), end = ch + name.size();
|
||||||
|
while (ch != end) {
|
||||||
|
auto emojiLength = 0;
|
||||||
|
if (auto emoji = emojiFromText(ch, end, &emojiLength)) {
|
||||||
|
ch += emojiLength;
|
||||||
|
} else if (ch->isHighSurrogate()) {
|
||||||
|
++ch;
|
||||||
|
if (ch != end && ch->isLowSurrogate()) {
|
||||||
|
++ch;
|
||||||
|
}
|
||||||
|
} else if (!letterFound && ch->isLetterOrNumber()) {
|
||||||
|
letterFound = true;
|
||||||
|
if (ch + 1 != end && chIsDiac(*(ch + 1))) {
|
||||||
|
letters.push_back(QString(ch, 2));
|
||||||
|
levels.push_back(level);
|
||||||
|
++ch;
|
||||||
|
} else {
|
||||||
|
letters.push_back(QString(ch, 1));
|
||||||
|
levels.push_back(level);
|
||||||
|
}
|
||||||
|
++ch;
|
||||||
|
} else {
|
||||||
|
if (*ch == ' ') {
|
||||||
|
level = 0;
|
||||||
|
letterFound = false;
|
||||||
|
} else if (letterFound && *ch == '-') {
|
||||||
|
level = 1;
|
||||||
|
letterFound = true;
|
||||||
|
}
|
||||||
|
++ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We prefer the second letter to be after ' ', but it can also be after '-'.
|
||||||
|
auto result = QString();
|
||||||
|
if (!letters.isEmpty()) {
|
||||||
|
result += letters.front();
|
||||||
|
auto bestIndex = 0;
|
||||||
|
auto bestLevel = 2;
|
||||||
|
for (auto i = letters.size(); i != 1;) {
|
||||||
|
if (levels[--i] < bestLevel) {
|
||||||
|
bestIndex = i;
|
||||||
|
bestLevel = levels[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bestIndex > 0) {
|
||||||
|
result += letters[bestIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.toUpper();
|
||||||
|
}
|
||||||
|
|
||||||
class Generator {
|
class Generator {
|
||||||
public:
|
public:
|
||||||
Generator(const Instance &theme, const CurrentData ¤t);
|
Generator(const Instance &theme, const CurrentData ¤t);
|
||||||
|
@ -48,6 +105,7 @@ private:
|
||||||
};
|
};
|
||||||
struct Row {
|
struct Row {
|
||||||
Text name;
|
Text name;
|
||||||
|
QString letters;
|
||||||
enum class Type {
|
enum class Type {
|
||||||
User,
|
User,
|
||||||
Group,
|
Group,
|
||||||
|
@ -107,7 +165,7 @@ private:
|
||||||
void paintBubble(const Bubble &bubble);
|
void paintBubble(const Bubble &bubble);
|
||||||
void paintService(QString text);
|
void paintService(QString text);
|
||||||
|
|
||||||
void paintUserpic(int x, int y, Row::Type type, int index);
|
void paintUserpic(int x, int y, Row::Type type, int index, QString letters);
|
||||||
|
|
||||||
void setTextPalette(const style::TextPalette &st);
|
void setTextPalette(const style::TextPalette &st);
|
||||||
void restoreTextPalette();
|
void restoreTextPalette();
|
||||||
|
@ -156,6 +214,9 @@ void Generator::prepare() {
|
||||||
void Generator::addRow(QString name, int peerIndex, QString date, QString text) {
|
void Generator::addRow(QString name, int peerIndex, QString date, QString text) {
|
||||||
Row row;
|
Row row;
|
||||||
row.name.setText(st::msgNameStyle, name, _textNameOptions);
|
row.name.setText(st::msgNameStyle, name, _textNameOptions);
|
||||||
|
|
||||||
|
row.letters = fillLetters(name);
|
||||||
|
|
||||||
row.peerIndex = peerIndex;
|
row.peerIndex = peerIndex;
|
||||||
row.date = date;
|
row.date = date;
|
||||||
row.text.setRichText(st::dialogsTextStyle, text, _textDlgOptions);
|
row.text.setRichText(st::dialogsTextStyle, text, _textDlgOptions);
|
||||||
|
@ -503,7 +564,7 @@ void Generator::paintRow(const Row &row) {
|
||||||
if (row.active || row.selected) {
|
if (row.active || row.selected) {
|
||||||
_p->fillRect(fullRect, row.active ? st::dialogsBgActive[_palette] : st::dialogsBgOver[_palette]);
|
_p->fillRect(fullRect, row.active ? st::dialogsBgActive[_palette] : st::dialogsBgOver[_palette]);
|
||||||
}
|
}
|
||||||
paintUserpic(x + st::dialogsPadding.x(), y + st::dialogsPadding.y(), row.type, row.peerIndex);
|
paintUserpic(x + st::dialogsPadding.x(), y + st::dialogsPadding.y(), row.type, row.peerIndex, row.letters);
|
||||||
|
|
||||||
auto nameleft = x + st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
auto nameleft = x + st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||||
auto namewidth = x + fullWidth - nameleft - st::dialogsPadding.x();
|
auto namewidth = x + fullWidth - nameleft - st::dialogsPadding.x();
|
||||||
|
@ -763,38 +824,33 @@ void Generator::paintService(QString text) {
|
||||||
_historyBottom = bubbleTop - st::msgServiceMargin.top();
|
_historyBottom = bubbleTop - st::msgServiceMargin.top();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Generator::paintUserpic(int x, int y, Row::Type type, int index) {
|
void Generator::paintUserpic(int x, int y, Row::Type type, int index, QString letters) {
|
||||||
const style::icon *userIcons[] = {
|
style::color colors[] = {
|
||||||
&st::historyPeer1UserpicPerson,
|
st::historyPeer1UserpicBg,
|
||||||
&st::historyPeer2UserpicPerson,
|
st::historyPeer2UserpicBg,
|
||||||
&st::historyPeer3UserpicPerson,
|
st::historyPeer3UserpicBg,
|
||||||
&st::historyPeer4UserpicPerson,
|
st::historyPeer4UserpicBg,
|
||||||
&st::historyPeer5UserpicPerson,
|
st::historyPeer5UserpicBg,
|
||||||
&st::historyPeer6UserpicPerson,
|
st::historyPeer6UserpicBg,
|
||||||
&st::historyPeer7UserpicPerson,
|
st::historyPeer7UserpicBg,
|
||||||
&st::historyPeer8UserpicPerson,
|
st::historyPeer8UserpicBg,
|
||||||
};
|
};
|
||||||
const style::icon *chatIcons[] = {
|
auto color = colors[index % base::array_size(colors)];
|
||||||
&st::historyPeer1UserpicChat,
|
|
||||||
&st::historyPeer2UserpicChat,
|
|
||||||
&st::historyPeer3UserpicChat,
|
|
||||||
&st::historyPeer4UserpicChat,
|
|
||||||
};
|
|
||||||
const style::icon *channelIcons[] = {
|
|
||||||
&st::historyPeer1UserpicChannel,
|
|
||||||
&st::historyPeer2UserpicChannel,
|
|
||||||
&st::historyPeer3UserpicChannel,
|
|
||||||
&st::historyPeer4UserpicChannel,
|
|
||||||
};
|
|
||||||
auto userpic = (type == Row::Type::User) ? userIcons[index % base::array_size(userIcons)] : (type == Row::Type::Group) ? chatIcons[index % base::array_size(chatIcons)] : channelIcons[index % base::array_size(channelIcons)];
|
|
||||||
|
|
||||||
auto image = QImage(userpic->width() * cIntRetinaFactor(), userpic->height() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
auto image = QImage(st::dialogsPhotoSize * cIntRetinaFactor(), st::dialogsPhotoSize * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
|
||||||
image.setDevicePixelRatio(cRetinaFactor());
|
image.setDevicePixelRatio(cRetinaFactor());
|
||||||
|
image.fill(color[_palette]->c);
|
||||||
{
|
{
|
||||||
Painter p(&image);
|
Painter p(&image);
|
||||||
userpic->paint(p, 0, 0, userpic->width());
|
auto fontsize = (st::dialogsPhotoSize * 13) / 33;
|
||||||
|
auto font = st::historyPeerUserpicFont->f;
|
||||||
|
font.setPixelSize(fontsize);
|
||||||
|
|
||||||
|
p.setFont(font);
|
||||||
|
p.setBrush(Qt::NoBrush);
|
||||||
|
p.setPen(st::historyPeerUserpicFg[_palette]);
|
||||||
|
p.drawText(QRect(0, 0, st::dialogsPhotoSize, st::dialogsPhotoSize), letters, QTextOption(style::al_center));
|
||||||
}
|
}
|
||||||
image = std_::move(image).scaled(st::dialogsPhotoSize * cIntRetinaFactor(), st::dialogsPhotoSize * cIntRetinaFactor(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
|
|
||||||
Images::prepareCircle(image);
|
Images::prepareCircle(image);
|
||||||
_p->drawImage(rtl() ? (_rect.width() - x - st::dialogsPhotoSize) : x, y, image);
|
_p->drawImage(rtl() ? (_rect.width() - x - st::dialogsPhotoSize) : x, y, image);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue