mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Some more ripple animations. Now only anim::value (float64).
Also each FloatAnimation now stops MTP responses. Also slide animations done by FloatAnimation. Closed beta 10019012.
This commit is contained in:
parent
a248cef15d
commit
06ed7b8eaf
109 changed files with 2129 additions and 1796 deletions
|
@ -475,17 +475,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
"lng_profile_shared_media" = "Shared media";
|
"lng_profile_shared_media" = "Shared media";
|
||||||
"lng_profile_no_media" = "No media in this conversation.";
|
"lng_profile_no_media" = "No media in this conversation.";
|
||||||
"lng_profile_photos" = "{count:_not_used_|# photo|# photos}";
|
"lng_profile_photos" = "{count:_not_used_|# photo|# photos}";
|
||||||
"lng_profile_photos_header" = "Photos overview";
|
"lng_profile_photos_header" = "Photos";
|
||||||
"lng_profile_videos" = "{count:_not_used_|# video|# videos}";
|
"lng_profile_videos" = "{count:_not_used_|# video|# videos}";
|
||||||
"lng_profile_videos_header" = "Videos overview";
|
"lng_profile_videos_header" = "Videos";
|
||||||
"lng_profile_songs" = "{count:_not_used_|# audio file|# audio files}";
|
"lng_profile_songs" = "{count:_not_used_|# audio file|# audio files}";
|
||||||
"lng_profile_songs_header" = "Audio files overview";
|
"lng_profile_songs_header" = "Audio files";
|
||||||
"lng_profile_files" = "{count:_not_used_|# file|# files}";
|
"lng_profile_files" = "{count:_not_used_|# file|# files}";
|
||||||
"lng_profile_files_header" = "Files overview";
|
"lng_profile_files_header" = "Files";
|
||||||
"lng_profile_audios" = "{count:_not_used_|# voice message|# voice messages}";
|
"lng_profile_audios" = "{count:_not_used_|# voice message|# voice messages}";
|
||||||
"lng_profile_audios_header" = "Voice messages overview";
|
"lng_profile_audios_header" = "Voice messages";
|
||||||
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links}";
|
"lng_profile_shared_links" = "{count:_not_used_|# shared link|# shared links}";
|
||||||
"lng_profile_shared_links_header" = "Shared links overview";
|
"lng_profile_shared_links_header" = "Shared links";
|
||||||
"lng_profile_copy_phone" = "Copy Phone Number";
|
"lng_profile_copy_phone" = "Copy Phone Number";
|
||||||
"lng_profile_copy_fullname" = "Copy Name";
|
"lng_profile_copy_fullname" = "Copy Name";
|
||||||
"lng_profile_drop_area_title" = "Drop your image here";
|
"lng_profile_drop_area_title" = "Drop your image here";
|
||||||
|
|
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,10,19,11
|
FILEVERSION 0,10,19,12
|
||||||
PRODUCTVERSION 0,10,19,11
|
PRODUCTVERSION 0,10,19,12
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -51,10 +51,10 @@ BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "0.10.19.11"
|
VALUE "FileVersion", "0.10.19.12"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.10.19.11"
|
VALUE "ProductVersion", "0.10.19.12"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,10,19,11
|
FILEVERSION 0,10,19,12
|
||||||
PRODUCTVERSION 0,10,19,11
|
PRODUCTVERSION 0,10,19,12
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -43,10 +43,10 @@ BEGIN
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileDescription", "Telegram Updater"
|
VALUE "FileDescription", "Telegram Updater"
|
||||||
VALUE "FileVersion", "0.10.19.11"
|
VALUE "FileVersion", "0.10.19.12"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
VALUE "LegalCopyright", "Copyright (C) 2014-2016"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.10.19.11"
|
VALUE "ProductVersion", "0.10.19.12"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -1246,7 +1246,7 @@ namespace {
|
||||||
if (auto history = App::historyLoaded(peer)) {
|
if (auto history = App::historyLoaded(peer)) {
|
||||||
history->outboxRead(upTo);
|
history->outboxRead(upTo);
|
||||||
if (history->lastMsg && history->lastMsg->out() && history->lastMsg->id <= upTo) {
|
if (history->lastMsg && history->lastMsg->out() && history->lastMsg->id <= upTo) {
|
||||||
if (App::main()) App::main()->dlgUpdated(history, history->lastMsg->id);
|
if (App::main()) App::main()->dlgUpdated(history->peer, history->lastMsg->id);
|
||||||
}
|
}
|
||||||
history->updateChatListEntry();
|
history->updateChatListEntry();
|
||||||
|
|
||||||
|
|
|
@ -711,8 +711,6 @@ AppClass::AppClass() : QObject() {
|
||||||
|
|
||||||
cChangeTimeFormat(QLocale::system().timeFormat(QLocale::ShortFormat));
|
cChangeTimeFormat(QLocale::system().timeFormat(QLocale::ShortFormat));
|
||||||
|
|
||||||
connect(&_mtpUnpauseTimer, SIGNAL(timeout()), this, SLOT(doMtpUnpause()));
|
|
||||||
|
|
||||||
connect(&killDownloadSessionsTimer, SIGNAL(timeout()), this, SLOT(killDownloadSessions()));
|
connect(&killDownloadSessionsTimer, SIGNAL(timeout()), this, SLOT(killDownloadSessions()));
|
||||||
|
|
||||||
DEBUG_LOG(("Application Info: starting app..."));
|
DEBUG_LOG(("Application Info: starting app..."));
|
||||||
|
@ -832,19 +830,6 @@ void AppClass::cancelPhotoUpdate(const PeerId &peer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppClass::mtpPause() {
|
|
||||||
MTP::pause();
|
|
||||||
_mtpUnpauseTimer.start(st::slideDuration * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppClass::mtpUnpause() {
|
|
||||||
_mtpUnpauseTimer.start(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppClass::doMtpUnpause() {
|
|
||||||
MTP::unpause();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppClass::selfPhotoCleared(const MTPUserProfilePhoto &result) {
|
void AppClass::selfPhotoCleared(const MTPUserProfilePhoto &result) {
|
||||||
if (!App::self()) return;
|
if (!App::self()) return;
|
||||||
App::self()->setPhoto(result);
|
App::self()->setPhoto(result);
|
||||||
|
|
|
@ -159,9 +159,6 @@ public:
|
||||||
bool isPhotoUpdating(const PeerId &peer);
|
bool isPhotoUpdating(const PeerId &peer);
|
||||||
void cancelPhotoUpdate(const PeerId &peer);
|
void cancelPhotoUpdate(const PeerId &peer);
|
||||||
|
|
||||||
void mtpPause();
|
|
||||||
void mtpUnpause();
|
|
||||||
|
|
||||||
void selfPhotoCleared(const MTPUserProfilePhoto &result);
|
void selfPhotoCleared(const MTPUserProfilePhoto &result);
|
||||||
void chatPhotoCleared(PeerId peer, const MTPUpdates &updates);
|
void chatPhotoCleared(PeerId peer, const MTPUpdates &updates);
|
||||||
void selfPhotoDone(const MTPphotos_Photo &result);
|
void selfPhotoDone(const MTPphotos_Photo &result);
|
||||||
|
@ -185,9 +182,6 @@ signals:
|
||||||
void adjustSingleTimers();
|
void adjustSingleTimers();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
void doMtpUnpause();
|
|
||||||
|
|
||||||
void photoUpdated(const FullMsgId &msgId, bool silent, const MTPInputFile &file);
|
void photoUpdated(const FullMsgId &msgId, bool silent, const MTPInputFile &file);
|
||||||
|
|
||||||
void onSwitchDebugMode();
|
void onSwitchDebugMode();
|
||||||
|
@ -217,6 +211,4 @@ private:
|
||||||
FileUploader *_uploader = nullptr;
|
FileUploader *_uploader = nullptr;
|
||||||
Translator *_translator = nullptr;
|
Translator *_translator = nullptr;
|
||||||
|
|
||||||
SingleTimer _mtpUnpauseTimer;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -557,7 +557,7 @@ void SetupChannelBox::mousePressEvent(QMouseEvent *e) {
|
||||||
if (_linkOver) {
|
if (_linkOver) {
|
||||||
Application::clipboard()->setText(_channel->inviteLink());
|
Application::clipboard()->setText(_channel->inviteLink());
|
||||||
_goodTextLink = lang(lng_create_channel_link_copied);
|
_goodTextLink = lang(lng_create_channel_link_copied);
|
||||||
a_goodOpacity = anim::fvalue(1, 0);
|
a_goodOpacity = anim::value(1, 0);
|
||||||
_a_goodFade.start();
|
_a_goodFade.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,7 +190,7 @@ private:
|
||||||
QString _sentUsername, _checkUsername, _errorText, _goodText;
|
QString _sentUsername, _checkUsername, _errorText, _goodText;
|
||||||
|
|
||||||
QString _goodTextLink;
|
QString _goodTextLink;
|
||||||
anim::fvalue a_goodOpacity;
|
anim::value a_goodOpacity;
|
||||||
Animation _a_goodFade;
|
Animation _a_goodFade;
|
||||||
|
|
||||||
QTimer _checkTimer;
|
QTimer _checkTimer;
|
||||||
|
|
|
@ -332,6 +332,7 @@ contactsPhotoCheckbox: RoundImageCheckbox {
|
||||||
}
|
}
|
||||||
contactsPhotoDisabledCheckFg: #bbbbbb;
|
contactsPhotoDisabledCheckFg: #bbbbbb;
|
||||||
contactsNameCheckedFg: #2b88b8;
|
contactsNameCheckedFg: #2b88b8;
|
||||||
|
contactsRipple: defaultRippleAnimation;
|
||||||
|
|
||||||
localStorageBoxSkip: 10px;
|
localStorageBoxSkip: 10px;
|
||||||
|
|
||||||
|
@ -381,15 +382,21 @@ sessionWhenFont: msgDateFont;
|
||||||
sessionWhenFg: #aaaaaa;
|
sessionWhenFg: #aaaaaa;
|
||||||
sessionInfoFont: msgFont;
|
sessionInfoFont: msgFont;
|
||||||
sessionInfoFg: #888888;
|
sessionInfoFg: #888888;
|
||||||
sessionTerminateTop: 30px;
|
sessionTerminateTop: 28px;
|
||||||
sessionTerminateSkip: 18px;
|
sessionTerminateSkip: 22px;
|
||||||
sessionTerminate: IconButton {
|
sessionTerminate: IconButton {
|
||||||
width: 16px;
|
width: 20px;
|
||||||
height: 16px;
|
height: 20px;
|
||||||
|
|
||||||
icon: simpleCloseIcon;
|
icon: simpleCloseIcon;
|
||||||
iconOver: simpleCloseIconOver;
|
iconOver: simpleCloseIconOver;
|
||||||
iconPosition: point(3px, 3px);
|
iconPosition: point(5px, 5px);
|
||||||
|
|
||||||
|
rippleAreaPosition: point(0px, 0px);
|
||||||
|
rippleAreaSize: 20px;
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: windowBgOver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sessionTerminateAllButton: LinkButton(boxLinkButton) {
|
sessionTerminateAllButton: LinkButton(boxLinkButton) {
|
||||||
color: #d15948;
|
color: #d15948;
|
||||||
|
|
|
@ -226,7 +226,7 @@ void MaxInviteBox::mousePressEvent(QMouseEvent *e) {
|
||||||
if (_linkOver) {
|
if (_linkOver) {
|
||||||
Application::clipboard()->setText(_link);
|
Application::clipboard()->setText(_link);
|
||||||
_goodTextLink = lang(lng_create_channel_link_copied);
|
_goodTextLink = lang(lng_create_channel_link_copied);
|
||||||
a_goodOpacity = anim::fvalue(1, 0);
|
a_goodOpacity = anim::value(1, 0);
|
||||||
_a_good.start();
|
_a_good.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -178,7 +178,7 @@ private:
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
|
|
||||||
QString _goodTextLink;
|
QString _goodTextLink;
|
||||||
anim::fvalue a_goodOpacity;
|
anim::value a_goodOpacity;
|
||||||
Animation _a_good;
|
Animation _a_good;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/widgets/multi_select.h"
|
#include "ui/widgets/multi_select.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/effects/widget_slide_wrap.h"
|
#include "ui/effects/widget_slide_wrap.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "boxes/photocropbox.h"
|
#include "boxes/photocropbox.h"
|
||||||
#include "boxes/confirmbox.h"
|
#include "boxes/confirmbox.h"
|
||||||
#include "observer_peer.h"
|
#include "observer_peer.h"
|
||||||
|
@ -546,10 +547,14 @@ bool ContactsBox::creationFail(const RPCError &error) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContactsBox::Inner::ContactData::ContactData() = default;
|
||||||
|
|
||||||
ContactsBox::Inner::ContactData::ContactData(PeerData *peer, const base::lambda_copy<void()> &updateCallback)
|
ContactsBox::Inner::ContactData::ContactData(PeerData *peer, const base::lambda_copy<void()> &updateCallback)
|
||||||
: checkbox(std_::make_unique<Ui::RoundImageCheckbox>(st::contactsPhotoCheckbox, updateCallback, PaintUserpicCallback(peer))) {
|
: checkbox(std_::make_unique<Ui::RoundImageCheckbox>(st::contactsPhotoCheckbox, updateCallback, PaintUserpicCallback(peer))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ContactsBox::Inner::ContactData::~ContactData() = default;
|
||||||
|
|
||||||
ContactsBox::Inner::Inner(QWidget *parent, CreatingGroupType creating) : TWidget(parent)
|
ContactsBox::Inner::Inner(QWidget *parent, CreatingGroupType creating) : TWidget(parent)
|
||||||
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
|
||||||
, _creating(creating)
|
, _creating(creating)
|
||||||
|
@ -924,16 +929,16 @@ ContactsBox::Inner::ContactData *ContactsBox::Inner::contactData(Dialogs::Row *r
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, ContactData *data, bool sel) {
|
void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, ContactData *data, bool selected) {
|
||||||
UserData *user = peer->asUser();
|
auto user = peer->asUser();
|
||||||
|
|
||||||
if (_chat && _membersFilter == MembersFilter::Admins) {
|
if (_chat && _membersFilter == MembersFilter::Admins) {
|
||||||
if (_allAdmins->checked() || peer->id == peerFromUser(_chat->creator) || _saving) {
|
if (_allAdmins->checked() || peer->id == peerFromUser(_chat->creator) || _saving) {
|
||||||
sel = false;
|
selected = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (data->disabledChecked || selectedCount() >= Global::MegagroupSizeMax()) {
|
if (data->disabledChecked || selectedCount() >= Global::MegagroupSizeMax()) {
|
||||||
sel = false;
|
selected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,7 +950,13 @@ void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, Cont
|
||||||
}
|
}
|
||||||
|
|
||||||
auto checkedRatio = 0.;
|
auto checkedRatio = 0.;
|
||||||
p.fillRect(0, 0, width(), _rowHeight, sel ? st::contactsBgOver : st::contactsBg);
|
p.fillRect(0, 0, width(), _rowHeight, selected ? st::contactsBgOver : st::contactsBg);
|
||||||
|
if (data->ripple) {
|
||||||
|
data->ripple->paint(p, 0, 0, width(), ms);
|
||||||
|
if (data->ripple->empty()) {
|
||||||
|
data->ripple.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
if (paintDisabledCheck) {
|
if (paintDisabledCheck) {
|
||||||
paintDisabledCheckUserpic(p, peer, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
paintDisabledCheckUserpic(p, peer, st::contactsPadding.left(), st::contactsPadding.top(), width());
|
||||||
} else if (usingMultiSelect()) {
|
} else if (usingMultiSelect()) {
|
||||||
|
@ -979,14 +990,14 @@ void ContactsBox::Inner::paintDialog(Painter &p, TimeMs ms, PeerData *peer, Cont
|
||||||
int32 secondw = st::contactsStatusFont->width(second);
|
int32 secondw = st::contactsStatusFont->width(second);
|
||||||
p.setPen(st::contactsStatusFgOnline);
|
p.setPen(st::contactsStatusFgOnline);
|
||||||
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width() - secondw, first);
|
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width() - secondw, first);
|
||||||
p.setPen(sel ? st::contactsStatusFgOver : st::contactsStatusFg);
|
p.setPen(selected ? st::contactsStatusFgOver : st::contactsStatusFg);
|
||||||
p.drawTextLeft(namex + w, st::contactsPadding.top() + st::contactsStatusTop, width() + w, second);
|
p.drawTextLeft(namex + w, st::contactsPadding.top() + st::contactsStatusTop, width() + w, second);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((user && (uname || data->statusHasOnlineColor)) || (peer->isChannel() && uname)) {
|
if ((user && (uname || data->statusHasOnlineColor)) || (peer->isChannel() && uname)) {
|
||||||
p.setPen(st::contactsStatusFgOnline);
|
p.setPen(st::contactsStatusFgOnline);
|
||||||
} else {
|
} else {
|
||||||
p.setPen(sel ? st::contactsStatusFgOver : st::contactsStatusFg);
|
p.setPen(selected ? st::contactsStatusFgOver : st::contactsStatusFg);
|
||||||
}
|
}
|
||||||
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), data->statusText);
|
p.drawTextLeft(namex, st::contactsPadding.top() + st::contactsStatusTop, width(), data->statusText);
|
||||||
}
|
}
|
||||||
|
@ -1064,7 +1075,8 @@ void ContactsBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
if ((*i)->pos() * _rowHeight >= yTo) {
|
if ((*i)->pos() * _rowHeight >= yTo) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
paintDialog(p, ms, (*i)->history()->peer, contactData(*i), (*i == _sel));
|
auto selected = _pressed ? (*i == _pressed) : (*i == _selected);
|
||||||
|
paintDialog(p, ms, (*i)->history()->peer, contactData(*i), selected);
|
||||||
p.translate(0, _rowHeight);
|
p.translate(0, _rowHeight);
|
||||||
}
|
}
|
||||||
yFrom -= _contacts->size() * _rowHeight;
|
yFrom -= _contacts->size() * _rowHeight;
|
||||||
|
@ -1080,11 +1092,12 @@ void ContactsBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
yTo -= st::searchedBarHeight;
|
yTo -= st::searchedBarHeight;
|
||||||
p.translate(0, st::searchedBarHeight);
|
p.translate(0, st::searchedBarHeight);
|
||||||
|
|
||||||
int32 from = floorclamp(yFrom, _rowHeight, 0, _byUsername.size());
|
auto from = floorclamp(yFrom, _rowHeight, 0, _byUsername.size());
|
||||||
int32 to = ceilclamp(yTo, _rowHeight, 0, _byUsername.size());
|
auto to = ceilclamp(yTo, _rowHeight, 0, _byUsername.size());
|
||||||
p.translate(0, from * _rowHeight);
|
p.translate(0, from * _rowHeight);
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
paintDialog(p, ms, _byUsername[from], d_byUsername[from], (_byUsernameSel == from));
|
auto selected = (_searchedPressed >= 0) ? (_searchedPressed == from) : (_searchedSelected == from);
|
||||||
|
paintDialog(p, ms, _byUsername[from], d_byUsername[from], selected);
|
||||||
p.translate(0, _rowHeight);
|
p.translate(0, _rowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1130,7 +1143,8 @@ void ContactsBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
int32 to = ceilclamp(yTo, _rowHeight, 0, _filtered.size());
|
int32 to = ceilclamp(yTo, _rowHeight, 0, _filtered.size());
|
||||||
p.translate(0, from * _rowHeight);
|
p.translate(0, from * _rowHeight);
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
paintDialog(p, ms, _filtered[from]->history()->peer, contactData(_filtered[from]), (_filteredSel == from));
|
auto selected = (_filteredPressed >= 0) ? (_filteredPressed == from) : (_filteredSelected == from);
|
||||||
|
paintDialog(p, ms, _filtered[from]->history()->peer, contactData(_filtered[from]), selected);
|
||||||
p.translate(0, _rowHeight);
|
p.translate(0, _rowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1147,7 +1161,8 @@ void ContactsBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
int32 to = ceilclamp(yTo, _rowHeight, 0, _byUsernameFiltered.size());
|
int32 to = ceilclamp(yTo, _rowHeight, 0, _byUsernameFiltered.size());
|
||||||
p.translate(0, from * _rowHeight);
|
p.translate(0, from * _rowHeight);
|
||||||
for (; from < to; ++from) {
|
for (; from < to; ++from) {
|
||||||
paintDialog(p, ms, _byUsernameFiltered[from], d_byUsernameFiltered[from], (_byUsernameSel == from));
|
auto selected = (_searchedPressed >= 0) ? (_searchedPressed == from) : (_searchedSelected == from);
|
||||||
|
paintDialog(p, ms, _byUsernameFiltered[from], d_byUsernameFiltered[from], selected);
|
||||||
p.translate(0, _rowHeight);
|
p.translate(0, _rowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1161,16 +1176,16 @@ void ContactsBox::Inner::enterEvent(QEvent *e) {
|
||||||
|
|
||||||
int ContactsBox::Inner::getSelectedRowTop() const {
|
int ContactsBox::Inner::getSelectedRowTop() const {
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
if (_sel) {
|
if (_selected) {
|
||||||
return _aboutHeight + (_sel->pos() * _rowHeight);
|
return _aboutHeight + (_selected->pos() * _rowHeight);
|
||||||
} else if (_byUsernameSel >= 0) {
|
} else if (_searchedSelected >= 0) {
|
||||||
return _aboutHeight + (_contacts->size() * _rowHeight) + st::searchedBarHeight + (_byUsernameSel * _rowHeight);
|
return _aboutHeight + (_contacts->size() * _rowHeight) + st::searchedBarHeight + (_searchedSelected * _rowHeight);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_filteredSel >= 0) {
|
if (_filteredSelected >= 0) {
|
||||||
return (_filteredSel * _rowHeight);
|
return (_filteredSelected * _rowHeight);
|
||||||
} else if (_byUsernameSel >= 0) {
|
} else if (_searchedSelected >= 0) {
|
||||||
return (_filtered.size() * _rowHeight + st::searchedBarHeight + _byUsernameSel * _rowHeight);
|
return (_filtered.size() * _rowHeight + st::searchedBarHeight + _searchedSelected * _rowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1222,53 +1237,130 @@ void ContactsBox::Inner::updateRowWithPeer(PeerData *peer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::leaveEvent(QEvent *e) {
|
void ContactsBox::Inner::leaveEvent(QEvent *e) {
|
||||||
_mouseSel = false;
|
_mouseSelection = false;
|
||||||
setMouseTracking(false);
|
setMouseTracking(false);
|
||||||
if (_sel || _filteredSel >= 0 || _byUsernameSel >= 0) {
|
if (_selected || _filteredSelected >= 0 || _searchedSelected >= 0) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_sel = 0;
|
_selected = nullptr;
|
||||||
_filteredSel = _byUsernameSel = -1;
|
_filteredSelected = _searchedSelected = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
void ContactsBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
_mouseSel = true;
|
_mouseSelection = true;
|
||||||
_lastMousePos = e->globalPos();
|
_lastMousePos = e->globalPos();
|
||||||
updateSelection();
|
updateSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::mousePressEvent(QMouseEvent *e) {
|
void ContactsBox::Inner::mousePressEvent(QMouseEvent *e) {
|
||||||
_mouseSel = true;
|
_mouseSelection = true;
|
||||||
_lastMousePos = e->globalPos();
|
_lastMousePos = e->globalPos();
|
||||||
updateSelection();
|
updateSelection();
|
||||||
if (e->button() == Qt::LeftButton) {
|
|
||||||
chooseParticipant();
|
setPressed(_selected);
|
||||||
|
setFilteredPressed(_filteredSelected);
|
||||||
|
setSearchedPressed(_searchedSelected);
|
||||||
|
if (_pressed) {
|
||||||
|
addRipple(contactData(_selected));
|
||||||
|
} else if (_filteredSelected >= 0 && _filteredSelected < _filtered.size()) {
|
||||||
|
addRipple(contactData(_filtered[_filteredSelected]));
|
||||||
|
} else if (_searchedSelected >= 0) {
|
||||||
|
if (_filter.isEmpty() && _searchedSelected < d_byUsername.size()) {
|
||||||
|
addRipple(d_byUsername[_searchedSelected]);
|
||||||
|
} else if (!_filter.isEmpty() && _searchedSelected < d_byUsernameFiltered.size()) {
|
||||||
|
addRipple(d_byUsernameFiltered[_searchedSelected]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContactsBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
auto pressed = _pressed;
|
||||||
|
setPressed(nullptr);
|
||||||
|
auto filteredPressed = _filteredPressed;
|
||||||
|
setFilteredPressed(-1);
|
||||||
|
auto searchedPressed = _searchedPressed;
|
||||||
|
setSearchedPressed(-1);
|
||||||
|
updateSelectedRow();
|
||||||
|
if (e->button() == Qt::LeftButton) {
|
||||||
|
if (pressed && pressed == _selected) {
|
||||||
|
chooseParticipant();
|
||||||
|
} else if (filteredPressed >= 0 && filteredPressed == _filteredSelected) {
|
||||||
|
chooseParticipant();
|
||||||
|
} else if (searchedPressed >= 0 && searchedPressed == _searchedSelected) {
|
||||||
|
chooseParticipant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactsBox::Inner::addRipple(ContactData *data) {
|
||||||
|
auto rowTop = getSelectedRowTop();
|
||||||
|
if (!data->ripple) {
|
||||||
|
auto mask = Ui::RippleAnimation::rectMask(QSize(width(), _rowHeight));
|
||||||
|
data->ripple = std_::make_unique<Ui::RippleAnimation>(st::contactsRipple, std_::move(mask), [this, data] {
|
||||||
|
updateRowWithTop(data->rippleRowTop);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
data->rippleRowTop = rowTop;
|
||||||
|
data->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(0, rowTop));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactsBox::Inner::stopLastRipple(ContactData *data) {
|
||||||
|
if (data->ripple) {
|
||||||
|
data->ripple->lastStop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactsBox::Inner::setPressed(Dialogs::Row *pressed) {
|
||||||
|
if (_pressed != pressed) {
|
||||||
|
if (_pressed) {
|
||||||
|
stopLastRipple(contactData(_pressed));
|
||||||
|
}
|
||||||
|
_pressed = pressed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactsBox::Inner::setFilteredPressed(int pressed) {
|
||||||
|
if (_filteredPressed >= 0 && _filteredPressed < _filtered.size()) {
|
||||||
|
stopLastRipple(contactData(_filtered[_filteredPressed]));
|
||||||
|
}
|
||||||
|
_filteredPressed = pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContactsBox::Inner::setSearchedPressed(int pressed) {
|
||||||
|
if (_searchedPressed >= 0) {
|
||||||
|
if (_searchedPressed < d_byUsername.size()) {
|
||||||
|
stopLastRipple(d_byUsername[_searchedPressed]);
|
||||||
|
}
|
||||||
|
if (_searchedPressed < d_byUsernameFiltered.size()) {
|
||||||
|
stopLastRipple(d_byUsernameFiltered[_searchedPressed]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_searchedPressed = pressed;
|
||||||
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::chooseParticipant() {
|
void ContactsBox::Inner::chooseParticipant() {
|
||||||
if (_saving) return;
|
if (_saving) return;
|
||||||
bool addingAdmin = (_channel && _membersFilter == MembersFilter::Admins);
|
bool addingAdmin = (_channel && _membersFilter == MembersFilter::Admins);
|
||||||
if (!addingAdmin && usingMultiSelect()) {
|
if (!addingAdmin && usingMultiSelect()) {
|
||||||
_time = unixtime();
|
_time = unixtime();
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsername.size()) {
|
if (_searchedSelected >= 0 && _searchedSelected < _byUsername.size()) {
|
||||||
auto data = d_byUsername[_byUsernameSel];
|
auto data = d_byUsername[_searchedSelected];
|
||||||
auto peer = _byUsername[_byUsernameSel];
|
auto peer = _byUsername[_searchedSelected];
|
||||||
if (data->disabledChecked) return;
|
if (data->disabledChecked) return;
|
||||||
|
|
||||||
changeCheckState(data, peer);
|
changeCheckState(data, peer);
|
||||||
} else if (_sel) {
|
} else if (_selected) {
|
||||||
auto data = contactData(_sel);
|
auto data = contactData(_selected);
|
||||||
auto peer = _sel->history()->peer;
|
auto peer = _selected->history()->peer;
|
||||||
if (data->disabledChecked) return;
|
if (data->disabledChecked) return;
|
||||||
|
|
||||||
changeCheckState(_sel);
|
changeCheckState(_selected);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsernameFiltered.size()) {
|
if (_searchedSelected >= 0 && _searchedSelected < _byUsernameFiltered.size()) {
|
||||||
auto data = d_byUsernameFiltered[_byUsernameSel];
|
auto data = d_byUsernameFiltered[_searchedSelected];
|
||||||
auto peer = _byUsernameFiltered[_byUsernameSel];
|
auto peer = _byUsernameFiltered[_searchedSelected];
|
||||||
if (data->disabledChecked) return;
|
if (data->disabledChecked) return;
|
||||||
|
|
||||||
int i = 0, l = d_byUsername.size();
|
int i = 0, l = d_byUsername.size();
|
||||||
|
@ -1291,9 +1383,9 @@ void ContactsBox::Inner::chooseParticipant() {
|
||||||
}
|
}
|
||||||
|
|
||||||
changeCheckState(data, peer);
|
changeCheckState(data, peer);
|
||||||
} else if (_filteredSel >= 0 && _filteredSel < _filtered.size()) {
|
} else if (_filteredSelected >= 0 && _filteredSelected < _filtered.size()) {
|
||||||
auto data = contactData(_filtered[_filteredSel]);
|
auto data = contactData(_filtered[_filteredSelected]);
|
||||||
auto peer = _filtered[_filteredSel]->history()->peer;
|
auto peer = _filtered[_filteredSelected]->history()->peer;
|
||||||
if (data->disabledChecked) return;
|
if (data->disabledChecked) return;
|
||||||
|
|
||||||
changeCheckState(data, peer);
|
changeCheckState(data, peer);
|
||||||
|
@ -1302,17 +1394,17 @@ void ContactsBox::Inner::chooseParticipant() {
|
||||||
} else {
|
} else {
|
||||||
PeerData *peer = 0;
|
PeerData *peer = 0;
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsername.size()) {
|
if (_searchedSelected >= 0 && _searchedSelected < _byUsername.size()) {
|
||||||
peer = _byUsername[_byUsernameSel];
|
peer = _byUsername[_searchedSelected];
|
||||||
} else if (_sel) {
|
} else if (_selected) {
|
||||||
peer = _sel->history()->peer;
|
peer = _selected->history()->peer;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_byUsernameSel >= 0 && _byUsernameSel < _byUsernameFiltered.size()) {
|
if (_searchedSelected >= 0 && _searchedSelected < _byUsernameFiltered.size()) {
|
||||||
peer = _byUsernameFiltered[_byUsernameSel];
|
peer = _byUsernameFiltered[_searchedSelected];
|
||||||
} else {
|
} else {
|
||||||
if (_filteredSel < 0 || _filteredSel >= _filtered.size()) return;
|
if (_filteredSelected < 0 || _filteredSelected >= _filtered.size()) return;
|
||||||
peer = _filtered[_filteredSel]->history()->peer;
|
peer = _filtered[_filteredSelected]->history()->peer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (peer) {
|
if (peer) {
|
||||||
|
@ -1408,31 +1500,35 @@ int32 ContactsBox::Inner::selectedCount() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::updateSelection() {
|
void ContactsBox::Inner::updateSelection() {
|
||||||
if (!_mouseSel) return;
|
if (!_mouseSelection) return;
|
||||||
|
|
||||||
QPoint p(mapFromGlobal(_lastMousePos));
|
auto p = mapFromGlobal(_lastMousePos);
|
||||||
bool in = parentWidget()->rect().contains(parentWidget()->mapFromGlobal(_lastMousePos));
|
bool in = parentWidget()->rect().contains(parentWidget()->mapFromGlobal(_lastMousePos));
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
|
_filteredSelected = -1;
|
||||||
|
setFilteredPressed(-1);
|
||||||
if (_aboutHeight) {
|
if (_aboutHeight) {
|
||||||
p.setY(p.y() - _aboutHeight);
|
p.setY(p.y() - _aboutHeight);
|
||||||
}
|
}
|
||||||
Dialogs::Row *newSel = (in && (p.y() >= 0) && (p.y() < _contacts->size() * _rowHeight)) ? _contacts->rowAtY(p.y(), _rowHeight) : nullptr;
|
auto selected = (in && (p.y() >= 0) && (p.y() < _contacts->size() * _rowHeight)) ? _contacts->rowAtY(p.y(), _rowHeight) : nullptr;
|
||||||
int32 byUsernameSel = (in && p.y() >= _contacts->size() * _rowHeight + st::searchedBarHeight) ? ((p.y() - _contacts->size() * _rowHeight - st::searchedBarHeight) / _rowHeight) : -1;
|
auto searchedSelected = (in && p.y() >= _contacts->size() * _rowHeight + st::searchedBarHeight) ? ((p.y() - _contacts->size() * _rowHeight - st::searchedBarHeight) / _rowHeight) : -1;
|
||||||
if (byUsernameSel >= _byUsername.size()) byUsernameSel = -1;
|
if (searchedSelected >= _byUsername.size()) searchedSelected = -1;
|
||||||
if (newSel != _sel || byUsernameSel != _byUsernameSel) {
|
if (_selected != selected || _searchedSelected != searchedSelected) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_sel = newSel;
|
_selected = selected;
|
||||||
_byUsernameSel = byUsernameSel;
|
_searchedSelected = searchedSelected;
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int32 newFilteredSel = (in && p.y() >= 0 && p.y() < _filtered.size() * _rowHeight) ? (p.y() / _rowHeight) : -1;
|
_selected = nullptr;
|
||||||
int32 byUsernameSel = (in && p.y() >= _filtered.size() * _rowHeight + st::searchedBarHeight) ? ((p.y() - _filtered.size() * _rowHeight - st::searchedBarHeight) / _rowHeight) : -1;
|
setPressed(nullptr);
|
||||||
if (byUsernameSel >= _byUsernameFiltered.size()) byUsernameSel = -1;
|
auto filteredSelected = (in && p.y() >= 0 && p.y() < _filtered.size() * _rowHeight) ? (p.y() / _rowHeight) : -1;
|
||||||
if (newFilteredSel != _filteredSel || byUsernameSel != _byUsernameSel) {
|
auto searchedSelected = (in && p.y() >= _filtered.size() * _rowHeight + st::searchedBarHeight) ? ((p.y() - _filtered.size() * _rowHeight - st::searchedBarHeight) / _rowHeight) : -1;
|
||||||
|
if (searchedSelected >= _byUsernameFiltered.size()) searchedSelected = -1;
|
||||||
|
if (_filteredSelected != filteredSelected || _searchedSelected != searchedSelected) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_filteredSel = newFilteredSel;
|
_filteredSelected = filteredSelected;
|
||||||
_byUsernameSel = byUsernameSel;
|
_searchedSelected = searchedSelected;
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1461,13 +1557,15 @@ void ContactsBox::Inner::updateFilter(QString filter) {
|
||||||
|
|
||||||
_byUsernameFiltered.clear();
|
_byUsernameFiltered.clear();
|
||||||
d_byUsernameFiltered.clear();
|
d_byUsernameFiltered.clear();
|
||||||
for (int i = 0, l = _byUsernameDatas.size(); i < l; ++i) {
|
clearSearchedContactDatas();
|
||||||
delete _byUsernameDatas[i];
|
|
||||||
}
|
|
||||||
_byUsernameDatas.clear();
|
|
||||||
|
|
||||||
|
_selected = nullptr;
|
||||||
|
setPressed(nullptr);
|
||||||
|
_filteredSelected = -1;
|
||||||
|
setFilteredPressed(-1);
|
||||||
|
_searchedSelected = -1;
|
||||||
|
setSearchedPressed(-1);
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
_sel = 0;
|
|
||||||
refresh();
|
refresh();
|
||||||
} else {
|
} else {
|
||||||
if (!_addContactLnk->isHidden()) _addContactLnk->hide();
|
if (!_addContactLnk->isHidden()) _addContactLnk->hide();
|
||||||
|
@ -1534,21 +1632,19 @@ void ContactsBox::Inner::updateFilter(QString filter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_filteredSel = -1;
|
|
||||||
if (!_filtered.isEmpty()) {
|
if (!_filtered.isEmpty()) {
|
||||||
for (_filteredSel = 0; (_filteredSel < _filtered.size()) && contactData(_filtered[_filteredSel])->disabledChecked;) {
|
for (_filteredSelected = 0; (_filteredSelected < _filtered.size()) && contactData(_filtered[_filteredSelected])->disabledChecked;) {
|
||||||
++_filteredSel;
|
++_filteredSelected;
|
||||||
}
|
}
|
||||||
if (_filteredSel == _filtered.size()) _filteredSel = -1;
|
if (_filteredSelected == _filtered.size()) _filteredSelected = -1;
|
||||||
}
|
}
|
||||||
_byUsernameSel = -1;
|
if (_filteredSelected < 0 && !_byUsernameFiltered.isEmpty()) {
|
||||||
if (_filteredSel < 0 && !_byUsernameFiltered.isEmpty()) {
|
for (_searchedSelected = 0; (_searchedSelected < _byUsernameFiltered.size()) && d_byUsernameFiltered[_searchedSelected]->disabledChecked;) {
|
||||||
for (_byUsernameSel = 0; (_byUsernameSel < _byUsernameFiltered.size()) && d_byUsernameFiltered[_byUsernameSel]->disabledChecked;) {
|
++_searchedSelected;
|
||||||
++_byUsernameSel;
|
|
||||||
}
|
}
|
||||||
if (_byUsernameSel == _byUsernameFiltered.size()) _byUsernameSel = -1;
|
if (_searchedSelected == _byUsernameFiltered.size()) _searchedSelected = -1;
|
||||||
}
|
}
|
||||||
_mouseSel = false;
|
_mouseSelection = false;
|
||||||
refresh();
|
refresh();
|
||||||
|
|
||||||
if ((!bot() || sharingBotGame()) && (!_chat || _membersFilter != MembersFilter::Admins)) {
|
if ((!bot() || sharingBotGame()) && (!_chat || _membersFilter != MembersFilter::Admins)) {
|
||||||
|
@ -1561,9 +1657,15 @@ void ContactsBox::Inner::updateFilter(QString filter) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContactsBox::Inner::clearSearchedContactDatas() {
|
||||||
|
for (auto data : base::take(_byUsernameDatas)) {
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow) {
|
void ContactsBox::Inner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row *newRow) {
|
||||||
if (!_filter.isEmpty()) {
|
if (!_filter.isEmpty()) {
|
||||||
for (FilteredDialogs::iterator i = _filtered.begin(), e = _filtered.end(); i != e;) {
|
for (auto i = _filtered.begin(), e = _filtered.end(); i != e;) {
|
||||||
if (*i == oldRow) { // this row is shown in filtered and maybe is in contacts!
|
if (*i == oldRow) { // this row is shown in filtered and maybe is in contacts!
|
||||||
if (newRow) {
|
if (newRow) {
|
||||||
*i = newRow;
|
*i = newRow;
|
||||||
|
@ -1575,18 +1677,21 @@ void ContactsBox::Inner::onDialogRowReplaced(Dialogs::Row *oldRow, Dialogs::Row
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_filteredSel >= _filtered.size()) {
|
if (_filteredSelected >= _filtered.size()) {
|
||||||
_filteredSel = -1;
|
_filteredSelected = -1;
|
||||||
|
}
|
||||||
|
if (_filteredPressed >= _filtered.size()) {
|
||||||
|
_filteredPressed = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_sel == oldRow) {
|
if (_selected == oldRow) {
|
||||||
_sel = newRow;
|
_selected = newRow;
|
||||||
|
}
|
||||||
|
if (_pressed == oldRow) {
|
||||||
|
setPressed(newRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_mouseSel = false;
|
refresh();
|
||||||
int cnt = (_filter.isEmpty() ? _contacts->size() : _filtered.size());
|
|
||||||
int newh = cnt ? (cnt * _rowHeight) : st::noContactsHeight;
|
|
||||||
resize(width(), newh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContactsBox::Inner::peopleReceived(const QString &query, const QVector<MTPPeer> &people) {
|
void ContactsBox::Inner::peopleReceived(const QString &query, const QVector<MTPPeer> &people) {
|
||||||
|
@ -1707,6 +1812,10 @@ ContactsBox::Inner::~Inner() {
|
||||||
for (auto contactData : base::take(_contactsData)) {
|
for (auto contactData : base::take(_contactsData)) {
|
||||||
delete contactData;
|
delete contactData;
|
||||||
}
|
}
|
||||||
|
clearSearchedContactDatas();
|
||||||
|
for (auto data : base::take(d_byUsername)) {
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
if (_bot) {
|
if (_bot) {
|
||||||
if (auto &info = _bot->botInfo) {
|
if (auto &info = _bot->botInfo) {
|
||||||
info->startGroupToken = QString();
|
info->startGroupToken = QString();
|
||||||
|
@ -1722,127 +1831,127 @@ void ContactsBox::Inner::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
||||||
void ContactsBox::Inner::selectSkip(int32 dir) {
|
void ContactsBox::Inner::selectSkip(int32 dir) {
|
||||||
_time = unixtime();
|
_time = unixtime();
|
||||||
_mouseSel = false;
|
_mouseSelection = false;
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
int cur = 0;
|
int cur = 0;
|
||||||
if (_sel) {
|
if (_selected) {
|
||||||
for (auto i = _contacts->cbegin(); *i != _sel; ++i) {
|
for (auto i = _contacts->cbegin(); *i != _selected; ++i) {
|
||||||
++cur;
|
++cur;
|
||||||
}
|
}
|
||||||
} else if (_byUsernameSel >= 0) {
|
} else if (_searchedSelected >= 0) {
|
||||||
cur = (_contacts->size() + _byUsernameSel);
|
cur = (_contacts->size() + _searchedSelected);
|
||||||
} else {
|
} else {
|
||||||
cur = -1;
|
cur = -1;
|
||||||
}
|
}
|
||||||
cur += dir;
|
cur += dir;
|
||||||
if (cur <= 0) {
|
if (cur <= 0) {
|
||||||
_sel = (!_contacts->isEmpty()) ? *_contacts->cbegin() : nullptr;
|
_selected = (!_contacts->isEmpty()) ? *_contacts->cbegin() : nullptr;
|
||||||
_byUsernameSel = (_contacts->isEmpty() && !_byUsername.isEmpty()) ? 0 : -1;
|
_searchedSelected = (_contacts->isEmpty() && !_byUsername.isEmpty()) ? 0 : -1;
|
||||||
} else if (cur >= _contacts->size()) {
|
} else if (cur >= _contacts->size()) {
|
||||||
if (_byUsername.isEmpty()) {
|
if (_byUsername.isEmpty()) {
|
||||||
_sel = _contacts->isEmpty() ? nullptr : *(_contacts->cend() - 1);
|
_selected = _contacts->isEmpty() ? nullptr : *(_contacts->cend() - 1);
|
||||||
_byUsernameSel = -1;
|
_searchedSelected = -1;
|
||||||
} else {
|
} else {
|
||||||
_sel = nullptr;
|
_selected = nullptr;
|
||||||
_byUsernameSel = cur - _contacts->size();
|
_searchedSelected = cur - _contacts->size();
|
||||||
if (_byUsernameSel >= _byUsername.size()) _byUsernameSel = _byUsername.size() - 1;
|
if (_searchedSelected >= _byUsername.size()) _searchedSelected = _byUsername.size() - 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto i = _contacts->cbegin(); ; ++i) {
|
for (auto i = _contacts->cbegin(); ; ++i) {
|
||||||
_sel = *i;
|
_selected = *i;
|
||||||
if (!cur) {
|
if (!cur) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
--cur;
|
--cur;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_byUsernameSel = -1;
|
_searchedSelected = -1;
|
||||||
}
|
}
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
for (auto i = _contacts->cfind(_sel), end = _contacts->cend(); i != end && contactData(*i)->disabledChecked; ++i) {
|
for (auto i = _contacts->cfind(_selected), end = _contacts->cend(); i != end && contactData(*i)->disabledChecked; ++i) {
|
||||||
_sel = *i;
|
_selected = *i;
|
||||||
}
|
}
|
||||||
if (_sel && contactData(_sel)->disabledChecked) {
|
if (_selected && contactData(_selected)->disabledChecked) {
|
||||||
_sel = nullptr;
|
_selected = nullptr;
|
||||||
}
|
}
|
||||||
if (!_sel) {
|
if (!_selected) {
|
||||||
if (!_byUsername.isEmpty()) {
|
if (!_byUsername.isEmpty()) {
|
||||||
if (_byUsernameSel < 0) _byUsernameSel = 0;
|
if (_searchedSelected < 0) _searchedSelected = 0;
|
||||||
for (; _byUsernameSel < _byUsername.size() && d_byUsername[_byUsernameSel]->disabledChecked;) {
|
for (; _searchedSelected < _byUsername.size() && d_byUsername[_searchedSelected]->disabledChecked;) {
|
||||||
++_byUsernameSel;
|
++_searchedSelected;
|
||||||
}
|
}
|
||||||
if (_byUsernameSel == _byUsername.size()) _byUsernameSel = -1;
|
if (_searchedSelected == _byUsername.size()) _searchedSelected = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (_byUsernameSel >= 0 && d_byUsername[_byUsernameSel]->disabledChecked) {
|
while (_searchedSelected >= 0 && d_byUsername[_searchedSelected]->disabledChecked) {
|
||||||
--_byUsernameSel;
|
--_searchedSelected;
|
||||||
}
|
}
|
||||||
if (_byUsernameSel < 0) {
|
if (_searchedSelected < 0) {
|
||||||
if (!_contacts->isEmpty()) {
|
if (!_contacts->isEmpty()) {
|
||||||
if (!_sel) _sel = *(_contacts->cend() - 1);
|
if (!_selected) _selected = *(_contacts->cend() - 1);
|
||||||
if (_sel) {
|
if (_selected) {
|
||||||
for (auto i = _contacts->cfind(_sel), b = _contacts->cbegin(); i != b && contactData(*i)->disabledChecked; --i) {
|
for (auto i = _contacts->cfind(_selected), b = _contacts->cbegin(); i != b && contactData(*i)->disabledChecked; --i) {
|
||||||
_sel = *i;
|
_selected = *i;
|
||||||
}
|
}
|
||||||
if (contactData(_sel)->disabledChecked) {
|
if (contactData(_selected)->disabledChecked) {
|
||||||
_sel = nullptr;
|
_selected = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_sel) {
|
if (_selected) {
|
||||||
emit mustScrollTo(_aboutHeight + _sel->pos() * _rowHeight, _aboutHeight + (_sel->pos() + 1) * _rowHeight);
|
emit mustScrollTo(_aboutHeight + _selected->pos() * _rowHeight, _aboutHeight + (_selected->pos() + 1) * _rowHeight);
|
||||||
} else if (_byUsernameSel >= 0) {
|
} else if (_searchedSelected >= 0) {
|
||||||
emit mustScrollTo(_aboutHeight + (_contacts->size() + _byUsernameSel) * _rowHeight + st::searchedBarHeight, _aboutHeight + (_contacts->size() + _byUsernameSel + 1) * _rowHeight + st::searchedBarHeight);
|
emit mustScrollTo(_aboutHeight + (_contacts->size() + _searchedSelected) * _rowHeight + st::searchedBarHeight, _aboutHeight + (_contacts->size() + _searchedSelected + 1) * _rowHeight + st::searchedBarHeight);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int cur = (_filteredSel >= 0) ? _filteredSel : ((_byUsernameSel >= 0) ? (_filtered.size() + _byUsernameSel) : -1);
|
int cur = (_filteredSelected >= 0) ? _filteredSelected : ((_searchedSelected >= 0) ? (_filtered.size() + _searchedSelected) : -1);
|
||||||
cur += dir;
|
cur += dir;
|
||||||
if (cur <= 0) {
|
if (cur <= 0) {
|
||||||
_filteredSel = _filtered.isEmpty() ? -1 : 0;
|
_filteredSelected = _filtered.isEmpty() ? -1 : 0;
|
||||||
_byUsernameSel = (_filtered.isEmpty() && !_byUsernameFiltered.isEmpty()) ? 0 : -1;
|
_searchedSelected = (_filtered.isEmpty() && !_byUsernameFiltered.isEmpty()) ? 0 : -1;
|
||||||
} else if (cur >= _filtered.size()) {
|
} else if (cur >= _filtered.size()) {
|
||||||
_filteredSel = -1;
|
_filteredSelected = -1;
|
||||||
_byUsernameSel = cur - _filtered.size();
|
_searchedSelected = cur - _filtered.size();
|
||||||
if (_byUsernameSel >= _byUsernameFiltered.size()) _byUsernameSel = _byUsernameFiltered.size() - 1;
|
if (_searchedSelected >= _byUsernameFiltered.size()) _searchedSelected = _byUsernameFiltered.size() - 1;
|
||||||
} else {
|
} else {
|
||||||
_filteredSel = cur;
|
_filteredSelected = cur;
|
||||||
_byUsernameSel = -1;
|
_searchedSelected = -1;
|
||||||
}
|
}
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
while (_filteredSel >= 0 && _filteredSel < _filtered.size() && contactData(_filtered[_filteredSel])->disabledChecked) {
|
while (_filteredSelected >= 0 && _filteredSelected < _filtered.size() && contactData(_filtered[_filteredSelected])->disabledChecked) {
|
||||||
++_filteredSel;
|
++_filteredSelected;
|
||||||
}
|
}
|
||||||
if (_filteredSel < 0 || _filteredSel >= _filtered.size()) {
|
if (_filteredSelected < 0 || _filteredSelected >= _filtered.size()) {
|
||||||
_filteredSel = -1;
|
_filteredSelected = -1;
|
||||||
if (!_byUsernameFiltered.isEmpty()) {
|
if (!_byUsernameFiltered.isEmpty()) {
|
||||||
if (_byUsernameSel < 0) _byUsernameSel = 0;
|
if (_searchedSelected < 0) _searchedSelected = 0;
|
||||||
for (; _byUsernameSel < _byUsernameFiltered.size() && d_byUsernameFiltered[_byUsernameSel]->disabledChecked;) {
|
for (; _searchedSelected < _byUsernameFiltered.size() && d_byUsernameFiltered[_searchedSelected]->disabledChecked;) {
|
||||||
++_byUsernameSel;
|
++_searchedSelected;
|
||||||
}
|
}
|
||||||
if (_byUsernameSel == _byUsernameFiltered.size()) _byUsernameSel = -1;
|
if (_searchedSelected == _byUsernameFiltered.size()) _searchedSelected = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (_byUsernameSel >= 0 && d_byUsernameFiltered[_byUsernameSel]->disabledChecked) {
|
while (_searchedSelected >= 0 && d_byUsernameFiltered[_searchedSelected]->disabledChecked) {
|
||||||
--_byUsernameSel;
|
--_searchedSelected;
|
||||||
}
|
}
|
||||||
if (_byUsernameSel < 0) {
|
if (_searchedSelected < 0) {
|
||||||
if (!_filtered.isEmpty()) {
|
if (!_filtered.isEmpty()) {
|
||||||
if (_filteredSel < 0) _filteredSel = _filtered.size() - 1;
|
if (_filteredSelected < 0) _filteredSelected = _filtered.size() - 1;
|
||||||
for (; _filteredSel >= 0 && contactData(_filtered[_filteredSel])->disabledChecked;) {
|
for (; _filteredSelected >= 0 && contactData(_filtered[_filteredSelected])->disabledChecked;) {
|
||||||
--_filteredSel;
|
--_filteredSelected;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_filteredSel >= 0) {
|
if (_filteredSelected >= 0) {
|
||||||
emit mustScrollTo(_filteredSel * _rowHeight, (_filteredSel + 1) * _rowHeight);
|
emit mustScrollTo(_filteredSelected * _rowHeight, (_filteredSelected + 1) * _rowHeight);
|
||||||
} else if (_byUsernameSel >= 0) {
|
} else if (_searchedSelected >= 0) {
|
||||||
int skip = _filtered.size() * _rowHeight + st::searchedBarHeight;
|
int skip = _filtered.size() * _rowHeight + st::searchedBarHeight;
|
||||||
emit mustScrollTo(skip + _byUsernameSel * _rowHeight, skip + (_byUsernameSel + 1) * _rowHeight);
|
emit mustScrollTo(skip + _searchedSelected * _rowHeight, skip + (_searchedSelected + 1) * _rowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -31,6 +31,7 @@ class IndexedList;
|
||||||
} // namespace Dialogs
|
} // namespace Dialogs
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
class RippleAnimation;
|
||||||
class RoundButton;
|
class RoundButton;
|
||||||
class LinkButton;
|
class LinkButton;
|
||||||
class Checkbox;
|
class Checkbox;
|
||||||
|
@ -208,19 +209,29 @@ protected:
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEvent(QEvent *e) override;
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ContactData {
|
struct ContactData {
|
||||||
ContactData() = default;
|
ContactData();
|
||||||
ContactData(PeerData *peer, const base::lambda_copy<void()> &updateCallback);
|
ContactData(PeerData *peer, const base::lambda_copy<void()> &updateCallback);
|
||||||
|
~ContactData();
|
||||||
|
|
||||||
std_::unique_ptr<Ui::RoundImageCheckbox> checkbox;
|
std_::unique_ptr<Ui::RoundImageCheckbox> checkbox;
|
||||||
|
std_::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
|
int rippleRowTop = 0;
|
||||||
Text name;
|
Text name;
|
||||||
QString statusText;
|
QString statusText;
|
||||||
bool statusHasOnlineColor = false;
|
bool statusHasOnlineColor = false;
|
||||||
bool disabledChecked = false;
|
bool disabledChecked = false;
|
||||||
};
|
};
|
||||||
|
void addRipple(ContactData *data);
|
||||||
|
void stopLastRipple(ContactData *data);
|
||||||
|
void setPressed(Dialogs::Row *pressed);
|
||||||
|
void setFilteredPressed(int pressed);
|
||||||
|
void setSearchedPressed(int pressed);
|
||||||
|
void clearSearchedContactDatas();
|
||||||
|
|
||||||
void init();
|
void init();
|
||||||
void initList();
|
void initList();
|
||||||
|
@ -277,12 +288,14 @@ private:
|
||||||
|
|
||||||
std_::unique_ptr<Dialogs::IndexedList> _customList;
|
std_::unique_ptr<Dialogs::IndexedList> _customList;
|
||||||
Dialogs::IndexedList *_contacts = nullptr;
|
Dialogs::IndexedList *_contacts = nullptr;
|
||||||
Dialogs::Row *_sel = nullptr;
|
Dialogs::Row *_selected = nullptr;
|
||||||
|
Dialogs::Row *_pressed = nullptr;
|
||||||
QString _filter;
|
QString _filter;
|
||||||
using FilteredDialogs = QVector<Dialogs::Row*>;
|
using FilteredDialogs = QVector<Dialogs::Row*>;
|
||||||
FilteredDialogs _filtered;
|
FilteredDialogs _filtered;
|
||||||
int _filteredSel = -1;
|
int _filteredSelected = -1;
|
||||||
bool _mouseSel = false;
|
int _filteredPressed = -1;
|
||||||
|
bool _mouseSelection = false;
|
||||||
|
|
||||||
using ContactsData = QMap<PeerData*, ContactData*>;
|
using ContactsData = QMap<PeerData*, ContactData*>;
|
||||||
ContactsData _contactsData;
|
ContactsData _contactsData;
|
||||||
|
@ -298,7 +311,8 @@ private:
|
||||||
ByUsernameRows _byUsername, _byUsernameFiltered;
|
ByUsernameRows _byUsername, _byUsernameFiltered;
|
||||||
ByUsernameDatas d_byUsername, d_byUsernameFiltered; // filtered is partly subset of d_byUsername, partly subset of _byUsernameDatas
|
ByUsernameDatas d_byUsername, d_byUsernameFiltered; // filtered is partly subset of d_byUsername, partly subset of _byUsernameDatas
|
||||||
ByUsernameDatas _byUsernameDatas;
|
ByUsernameDatas _byUsernameDatas;
|
||||||
int _byUsernameSel = -1;
|
int _searchedSelected = -1;
|
||||||
|
int _searchedPressed = -1;
|
||||||
|
|
||||||
QPoint _lastMousePos;
|
QPoint _lastMousePos;
|
||||||
ChildWidget<Ui::LinkButton> _addContactLnk;
|
ChildWidget<Ui::LinkButton> _addContactLnk;
|
||||||
|
|
|
@ -44,8 +44,8 @@ void MembersAddButton::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
auto over = (_state & StateOver);
|
auto over = isOver();
|
||||||
auto down = (_state & StateDown);
|
auto down = isDown();
|
||||||
|
|
||||||
((over || down) ? _st.iconBelowOver : _st.iconBelow).paint(p, _st.iconPosition, width());
|
((over || down) ? _st.iconBelowOver : _st.iconBelow).paint(p, _st.iconPosition, width());
|
||||||
paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms);
|
paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms);
|
||||||
|
|
|
@ -311,7 +311,7 @@ void SessionsBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
void SessionsBox::Inner::onTerminate() {
|
void SessionsBox::Inner::onTerminate() {
|
||||||
for (TerminateButtons::iterator i = _terminateButtons.begin(), e = _terminateButtons.end(); i != e; ++i) {
|
for (TerminateButtons::iterator i = _terminateButtons.begin(), e = _terminateButtons.end(); i != e; ++i) {
|
||||||
if (i.value()->getState() & Ui::AbstractButton::StateOver) {
|
if (i.value()->isOver()) {
|
||||||
_terminating = i.key();
|
_terminating = i.key();
|
||||||
|
|
||||||
if (_terminateBox) _terminateBox->deleteLater();
|
if (_terminateBox) _terminateBox->deleteLater();
|
||||||
|
|
|
@ -274,7 +274,7 @@ void ShareBox::onMustScrollTo(int top, int bottom) {
|
||||||
}
|
}
|
||||||
if (from != to) {
|
if (from != to) {
|
||||||
_scrollAnimation.start([this]() {
|
_scrollAnimation.start([this]() {
|
||||||
scrollArea()->scrollToY(_scrollAnimation.current(scrollArea()->scrollTop()));
|
scrollArea()->scrollToY(qRound(_scrollAnimation.current(scrollArea()->scrollTop())));
|
||||||
}, from, to, st::shareScrollDuration, anim::sineInOut);
|
}, from, to, st::shareScrollDuration, anim::sineInOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ private:
|
||||||
using PeopleQueries = QMap<mtpRequestId, QString>;
|
using PeopleQueries = QMap<mtpRequestId, QString>;
|
||||||
PeopleQueries _peopleQueries;
|
PeopleQueries _peopleQueries;
|
||||||
|
|
||||||
IntAnimation _scrollAnimation;
|
FloatAnimation _scrollAnimation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -663,7 +663,7 @@ QRect StickersBox::Inner::relativeButtonRect(bool removeButton) const {
|
||||||
void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
|
void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
|
||||||
auto s = _rows.at(index);
|
auto s = _rows.at(index);
|
||||||
|
|
||||||
auto xadd = 0, yadd = s->yadd.current();
|
auto xadd = 0, yadd = qRound(s->yadd.current());
|
||||||
if (xadd || yadd) p.translate(xadd, yadd);
|
if (xadd || yadd) p.translate(xadd, yadd);
|
||||||
|
|
||||||
if (_section == Section::Installed) {
|
if (_section == Section::Installed) {
|
||||||
|
@ -673,7 +673,7 @@ void StickersBox::Inner::paintRow(Painter &p, int index, TimeMs ms) {
|
||||||
if (_started >= 0) {
|
if (_started >= 0) {
|
||||||
float64 o = aboveShadowOpacity();
|
float64 o = aboveShadowOpacity();
|
||||||
if (o > current) {
|
if (o > current) {
|
||||||
_aboveShadowFadeOpacity = anim::fvalue(o, o);
|
_aboveShadowFadeOpacity = anim::value(o, o);
|
||||||
current = o;
|
current = o;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -858,14 +858,14 @@ void StickersBox::Inner::onUpdateSelected() {
|
||||||
shift = -floorclamp(_dragStart.y() - local.y() + (_rowHeight / 2), _rowHeight, 0, _dragging - firstSetIndex);
|
shift = -floorclamp(_dragStart.y() - local.y() + (_rowHeight / 2), _rowHeight, 0, _dragging - firstSetIndex);
|
||||||
for (int32 from = _dragging, to = _dragging + shift; from > to; --from) {
|
for (int32 from = _dragging, to = _dragging + shift; from > to; --from) {
|
||||||
qSwap(_rows[from], _rows[from - 1]);
|
qSwap(_rows[from], _rows[from - 1]);
|
||||||
_rows.at(from)->yadd = anim::ivalue(_rows.at(from)->yadd.current() - _rowHeight, 0);
|
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() - _rowHeight, 0);
|
||||||
_animStartTimes[from] = ms;
|
_animStartTimes[from] = ms;
|
||||||
}
|
}
|
||||||
} else if (_dragStart.y() < local.y() && _dragging + 1 < _rows.size()) {
|
} else if (_dragStart.y() < local.y() && _dragging + 1 < _rows.size()) {
|
||||||
shift = floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1);
|
shift = floorclamp(local.y() - _dragStart.y() + (_rowHeight / 2), _rowHeight, 0, _rows.size() - _dragging - 1);
|
||||||
for (int32 from = _dragging, to = _dragging + shift; from < to; ++from) {
|
for (int32 from = _dragging, to = _dragging + shift; from < to; ++from) {
|
||||||
qSwap(_rows[from], _rows[from + 1]);
|
qSwap(_rows[from], _rows[from + 1]);
|
||||||
_rows.at(from)->yadd = anim::ivalue(_rows.at(from)->yadd.current() + _rowHeight, 0);
|
_rows[from]->yadd = anim::value(_rows[from]->yadd.current() + _rowHeight, 0);
|
||||||
_animStartTimes[from] = ms;
|
_animStartTimes[from] = ms;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -877,7 +877,7 @@ void StickersBox::Inner::onUpdateSelected() {
|
||||||
_a_shifting.start();
|
_a_shifting.start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_rows.at(_dragging)->yadd = anim::ivalue(local.y() - _dragStart.y(), local.y() - _dragStart.y());
|
_rows[_dragging]->yadd = anim::value(local.y() - _dragStart.y(), local.y() - _dragStart.y());
|
||||||
_animStartTimes[_dragging] = 0;
|
_animStartTimes[_dragging] = 0;
|
||||||
_a_shifting.step(getms(), true);
|
_a_shifting.step(getms(), true);
|
||||||
|
|
||||||
|
@ -926,8 +926,8 @@ void StickersBox::Inner::onUpdateSelected() {
|
||||||
float64 StickersBox::Inner::aboveShadowOpacity() const {
|
float64 StickersBox::Inner::aboveShadowOpacity() const {
|
||||||
if (_above < 0) return 0;
|
if (_above < 0) return 0;
|
||||||
|
|
||||||
int32 dx = 0;
|
auto dx = 0;
|
||||||
int32 dy = qAbs(_above * _rowHeight + _rows.at(_above)->yadd.current() - _started * _rowHeight);
|
auto dy = qAbs(_above * _rowHeight + qRound(_rows[_above]->yadd.current()) - _started * _rowHeight);
|
||||||
return qMin((dx + dy) * 2. / _rowHeight, 1.);
|
return qMin((dx + dy) * 2. / _rowHeight, 1.);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,9 +948,9 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
} else if (_dragging >= 0) {
|
} else if (_dragging >= 0) {
|
||||||
QPoint local(mapFromGlobal(_mouse));
|
QPoint local(mapFromGlobal(_mouse));
|
||||||
_rows[_dragging]->yadd.start(0);
|
_rows[_dragging]->yadd.start(0.);
|
||||||
_aboveShadowFadeStart = _animStartTimes[_dragging] = getms();
|
_aboveShadowFadeStart = _animStartTimes[_dragging] = getms();
|
||||||
_aboveShadowFadeOpacity = anim::fvalue(aboveShadowOpacity(), 0);
|
_aboveShadowFadeOpacity = anim::value(aboveShadowOpacity(), 0);
|
||||||
if (!_a_shifting.animating()) {
|
if (!_a_shifting.animating()) {
|
||||||
_a_shifting.start();
|
_a_shifting.start();
|
||||||
}
|
}
|
||||||
|
@ -994,10 +994,10 @@ void StickersBox::Inner::step_shifting(TimeMs ms, bool timer) {
|
||||||
if (updateMin < 0) updateMin = i;
|
if (updateMin < 0) updateMin = i;
|
||||||
updateMax = i;
|
updateMax = i;
|
||||||
if (start + st::stickersRowDuration > ms && ms >= start) {
|
if (start + st::stickersRowDuration > ms && ms >= start) {
|
||||||
_rows.at(i)->yadd.update(float64(ms - start) / st::stickersRowDuration, anim::sineInOut);
|
_rows[i]->yadd.update(float64(ms - start) / st::stickersRowDuration, anim::sineInOut);
|
||||||
animating = true;
|
animating = true;
|
||||||
} else {
|
} else {
|
||||||
_rows.at(i)->yadd.finish();
|
_rows[i]->yadd.finish();
|
||||||
_animStartTimes[i] = 0;
|
_animStartTimes[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1035,7 +1035,7 @@ void StickersBox::Inner::clear() {
|
||||||
_rows.clear();
|
_rows.clear();
|
||||||
_animStartTimes.clear();
|
_animStartTimes.clear();
|
||||||
_aboveShadowFadeStart = 0;
|
_aboveShadowFadeStart = 0;
|
||||||
_aboveShadowFadeOpacity = anim::fvalue(0, 0);
|
_aboveShadowFadeOpacity = anim::value();
|
||||||
_a_shifting.stop();
|
_a_shifting.stop();
|
||||||
_above = _dragging = _started = -1;
|
_above = _dragging = _started = -1;
|
||||||
_selected = -1;
|
_selected = -1;
|
||||||
|
|
|
@ -229,7 +229,7 @@ private:
|
||||||
int titleWidth;
|
int titleWidth;
|
||||||
bool installed, official, unread, archived, removed;
|
bool installed, official, unread, archived, removed;
|
||||||
int32 pixw, pixh;
|
int32 pixw, pixh;
|
||||||
anim::ivalue yadd;
|
anim::value yadd;
|
||||||
QSharedPointer<Ui::RippleAnimation> ripple;
|
QSharedPointer<Ui::RippleAnimation> ripple;
|
||||||
};
|
};
|
||||||
using Rows = QList<Row*>;
|
using Rows = QList<Row*>;
|
||||||
|
@ -245,7 +245,7 @@ private:
|
||||||
Rows _rows;
|
Rows _rows;
|
||||||
QList<TimeMs> _animStartTimes;
|
QList<TimeMs> _animStartTimes;
|
||||||
TimeMs _aboveShadowFadeStart = 0;
|
TimeMs _aboveShadowFadeStart = 0;
|
||||||
anim::fvalue _aboveShadowFadeOpacity = { 0., 0. };
|
anim::value _aboveShadowFadeOpacity;
|
||||||
Animation _a_shifting;
|
Animation _a_shifting;
|
||||||
|
|
||||||
base::lambda<void(uint64 setId)> _installSetCallback;
|
base::lambda<void(uint64 setId)> _installSetCallback;
|
||||||
|
|
|
@ -200,6 +200,7 @@ public:
|
||||||
}
|
}
|
||||||
~unique_ptr() noexcept {
|
~unique_ptr() noexcept {
|
||||||
if (_p) {
|
if (_p) {
|
||||||
|
static_assert(sizeof(T) > 0, "can't delete an incomplete type");
|
||||||
delete _p;
|
delete _p;
|
||||||
_p = nullptr;
|
_p = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -228,6 +229,7 @@ public:
|
||||||
auto old = _p;
|
auto old = _p;
|
||||||
_p = p;
|
_p = p;
|
||||||
if (old) {
|
if (old) {
|
||||||
|
static_assert(sizeof(T) > 0, "can't delete an incomplete type");
|
||||||
delete old;
|
delete old;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "core/utils.h"
|
#include "core/utils.h"
|
||||||
|
|
||||||
#define BETA_VERSION_MACRO (10019011ULL)
|
#define BETA_VERSION_MACRO (10019012ULL)
|
||||||
|
|
||||||
constexpr int AppVersion = 10020;
|
constexpr int AppVersion = 10020;
|
||||||
constexpr str_const AppVersionStr = "0.10.20";
|
constexpr str_const AppVersionStr = "0.10.20";
|
||||||
|
|
|
@ -27,6 +27,10 @@ dialogsUnreadFont: font(12px bold);
|
||||||
dialogsUnreadHeight: 19px;
|
dialogsUnreadHeight: 19px;
|
||||||
dialogsUnreadPadding: 5px;
|
dialogsUnreadPadding: 5px;
|
||||||
|
|
||||||
|
dialogsRipple: defaultRippleAnimation;
|
||||||
|
dialogsRippleBg: windowBgRipple;
|
||||||
|
dialogsRippleBgActive: activeButtonBgRipple;
|
||||||
|
|
||||||
dialogsTextFont: font(fsize);
|
dialogsTextFont: font(fsize);
|
||||||
dialogsDateFont: font(13px);
|
dialogsDateFont: font(13px);
|
||||||
dialogsDateSkip: 5px;
|
dialogsDateSkip: 5px;
|
||||||
|
|
|
@ -59,20 +59,21 @@ void paintRowDate(Painter &p, const QDateTime &date, QRect &rectForName, bool ac
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename PaintItemCallback>
|
template <typename PaintItemCallback>
|
||||||
void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draft, QDateTime date, int w, bool active, bool selected, bool onlyBackground, TimeMs ms, PaintItemCallback paintItemCallback) {
|
void paintRow(Painter &p, const RippleRow *row, History *history, HistoryItem *item, Data::Draft *draft, QDateTime date, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms, PaintItemCallback paintItemCallback) {
|
||||||
QRect fullRect(0, 0, w, st::dialogsRowHeight);
|
QRect fullRect(0, 0, fullWidth, st::dialogsRowHeight);
|
||||||
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
p.fillRect(fullRect, active ? st::dialogsBgActive : (selected ? st::dialogsBgOver : st::dialogsBg));
|
||||||
|
row->paintRipple(p, 0, 0, fullWidth, ms, &(active ? st::dialogsRippleBgActive : st::dialogsRippleBg)->c);
|
||||||
if (onlyBackground) return;
|
if (onlyBackground) return;
|
||||||
|
|
||||||
PeerData *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(), w);
|
userpicPeer->paintUserpicLeft(p, st::dialogsPhotoSize, st::dialogsPadding.x(), st::dialogsPadding.y(), fullWidth);
|
||||||
|
|
||||||
int32 nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
auto nameleft = st::dialogsPadding.x() + st::dialogsPhotoSize + st::dialogsPhotoPadding;
|
||||||
int32 namewidth = w - nameleft - st::dialogsPadding.x();
|
auto namewidth = fullWidth - nameleft - st::dialogsPadding.x();
|
||||||
QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
|
QRect rectForName(nameleft, st::dialogsPadding.y() + st::dialogsNameTop, namewidth, st::msgNameFont->height);
|
||||||
|
|
||||||
if (auto chatTypeIcon = ChatTypeIcon(history->peer, active, selected)) {
|
if (auto chatTypeIcon = ChatTypeIcon(history->peer, active, selected)) {
|
||||||
chatTypeIcon->paint(p, rectForName.topLeft(), w);
|
chatTypeIcon->paint(p, rectForName.topLeft(), fullWidth);
|
||||||
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
|
rectForName.setLeft(rectForName.left() + st::dialogsChatTypeSkip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +83,7 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
|
||||||
|
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
||||||
if (!history->paintSendAction(p, nameleft, texttop, namewidth, w, color, ms)) {
|
if (!history->paintSendAction(p, nameleft, texttop, namewidth, fullWidth, color, ms)) {
|
||||||
if (history->cloudDraftTextCache.isEmpty()) {
|
if (history->cloudDraftTextCache.isEmpty()) {
|
||||||
auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft)));
|
auto draftWrapped = textcmdLink(1, lng_dialogs_text_from_wrapped(lt_from, lang(lng_from_draft)));
|
||||||
auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text));
|
auto draftText = lng_dialogs_text_with_from(lt_from_part, draftWrapped, lt_message, textClean(draft->textWithTags.text));
|
||||||
|
@ -96,7 +97,7 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
|
||||||
} else if (!item) {
|
} else if (!item) {
|
||||||
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
||||||
p.setFont(st::dialogsTextFont);
|
p.setFont(st::dialogsTextFont);
|
||||||
if (!history->paintSendAction(p, nameleft, texttop, namewidth, w, color, ms)) {
|
if (!history->paintSendAction(p, nameleft, texttop, namewidth, fullWidth, color, ms)) {
|
||||||
p.setPen(color);
|
p.setPen(color);
|
||||||
p.drawText(nameleft, texttop + st::msgNameFont->ascent, lang(lng_empty_history));
|
p.drawText(nameleft, texttop + st::msgNameFont->ascent, lang(lng_empty_history));
|
||||||
}
|
}
|
||||||
|
@ -123,13 +124,13 @@ void paintRow(Painter &p, History *history, HistoryItem *item, Data::Draft *draf
|
||||||
})();
|
})();
|
||||||
if (sendStateIcon) {
|
if (sendStateIcon) {
|
||||||
rectForName.setWidth(rectForName.width() - st::dialogsSendStateSkip);
|
rectForName.setWidth(rectForName.width() - st::dialogsSendStateSkip);
|
||||||
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), w);
|
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (history->peer->isUser() && history->peer->isVerified()) {
|
if (history->peer->isUser() && history->peer->isVerified()) {
|
||||||
auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon));
|
auto icon = &(active ? st::dialogsVerifiedIconActive : (selected ? st::dialogsVerifiedIconOver : st::dialogsVerifiedIcon));
|
||||||
rectForName.setWidth(rectForName.width() - icon->width());
|
rectForName.setWidth(rectForName.width() - icon->width());
|
||||||
icon->paint(p, rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0), w);
|
icon->paint(p, rectForName.topLeft() + QPoint(qMin(history->peer->dialogName().maxWidth(), rectForName.width()), 0), fullWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen(active ? st::dialogsNameFgActive : (selected ? st::dialogsNameFgOver : st::dialogsNameFg));
|
p.setPen(active ? st::dialogsNameFgActive : (selected ? st::dialogsNameFgOver : st::dialogsNameFg));
|
||||||
|
@ -241,7 +242,7 @@ void paintUnreadCount(Painter &p, const QString &text, int x, int y, const Unrea
|
||||||
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + textTop + st.font->ascent, text);
|
p.drawText(unreadRectLeft + (unreadRectWidth - unreadWidth) / 2, unreadRectTop + textTop + st.font->ascent, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms) {
|
void RowPainter::paint(Painter &p, const Row *row, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) {
|
||||||
auto history = row->history();
|
auto history = row->history();
|
||||||
auto item = history->lastMsg;
|
auto item = history->lastMsg;
|
||||||
auto cloudDraft = history->cloudDraft();
|
auto cloudDraft = history->cloudDraft();
|
||||||
|
@ -267,15 +268,15 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
|
||||||
if (item && cloudDraft && unreadCount > 0) {
|
if (item && cloudDraft && unreadCount > 0) {
|
||||||
cloudDraft = nullptr; // Draw item, if draft is older.
|
cloudDraft = nullptr; // Draw item, if draft is older.
|
||||||
}
|
}
|
||||||
paintRow(p, history, item, cloudDraft, displayDate(), w, active, selected, onlyBackground, ms, [&p, w, active, selected, ms, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) {
|
paintRow(p, row, history, item, cloudDraft, displayDate(), fullWidth, active, selected, onlyBackground, ms, [&p, fullWidth, active, selected, ms, history, unreadCount](int nameleft, int namewidth, HistoryItem *item) {
|
||||||
int availableWidth = namewidth;
|
int availableWidth = namewidth;
|
||||||
int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
int texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||||
if (unreadCount) {
|
if (unreadCount) {
|
||||||
auto counter = QString::number(unreadCount);
|
auto counter = QString::number(unreadCount);
|
||||||
auto mutedCounter = history->mute();
|
auto mutedCounter = history->mute();
|
||||||
int unreadRight = w - st::dialogsPadding.x();
|
auto unreadRight = fullWidth - st::dialogsPadding.x();
|
||||||
int unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
|
auto unreadTop = texttop + st::dialogsTextFont->ascent - st::dialogsUnreadFont->ascent - (st::dialogsUnreadHeight - st::dialogsUnreadFont->height) / 2;
|
||||||
int unreadWidth = 0;
|
auto unreadWidth = 0;
|
||||||
|
|
||||||
UnreadBadgeStyle st;
|
UnreadBadgeStyle st;
|
||||||
st.active = active;
|
st.active = active;
|
||||||
|
@ -284,16 +285,16 @@ void RowPainter::paint(Painter &p, const Row *row, int w, bool active, bool sele
|
||||||
availableWidth -= unreadWidth + st.padding;
|
availableWidth -= unreadWidth + st.padding;
|
||||||
}
|
}
|
||||||
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
auto &color = active ? st::dialogsTextFgServiceActive : (selected ? st::dialogsTextFgServiceOver : st::dialogsTextFgService);
|
||||||
if (!history->paintSendAction(p, nameleft, texttop, availableWidth, w, color, ms)) {
|
if (!history->paintSendAction(p, nameleft, texttop, availableWidth, fullWidth, color, ms)) {
|
||||||
item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, selected, history->textCachedFor, history->lastItemTextCache);
|
item->drawInDialog(p, QRect(nameleft, texttop, availableWidth, st::dialogsTextFont->height), active, selected, history->textCachedFor, history->lastItemTextCache);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void RowPainter::paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms) {
|
void RowPainter::paint(Painter &p, const FakeRow *row, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms) {
|
||||||
auto item = row->item();
|
auto item = row->item();
|
||||||
auto history = item->history();
|
auto history = item->history();
|
||||||
paintRow(p, history, item, nullptr, item->date, w, active, selected, onlyBackground, ms, [&p, row, active, selected](int nameleft, int namewidth, HistoryItem *item) {
|
paintRow(p, row, history, item, nullptr, item->date, fullWidth, active, selected, onlyBackground, ms, [&p, row, active, selected](int nameleft, int namewidth, HistoryItem *item) {
|
||||||
int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
int lastWidth = namewidth, texttop = st::dialogsPadding.y() + st::msgNameFont->height + st::dialogsSkip;
|
||||||
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, selected, row->_cacheFor, row->_cache);
|
item->drawInDialog(p, QRect(nameleft, texttop, lastWidth, st::dialogsTextFont->height), active, selected, row->_cacheFor, row->_cache);
|
||||||
});
|
});
|
||||||
|
@ -306,8 +307,8 @@ QRect RowPainter::sendActionAnimationRect(int animationWidth, int animationHeigh
|
||||||
return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight);
|
return QRect(nameleft, texttop, textUpdated ? namewidth : animationWidth, animationHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground) {
|
void paintImportantSwitch(Painter &p, Mode current, int fullWidth, bool selected, bool onlyBackground) {
|
||||||
p.fillRect(0, 0, w, st::dialogsImportantBarHeight, selected ? st::dialogsBgOver : st::dialogsBg);
|
p.fillRect(0, 0, fullWidth, st::dialogsImportantBarHeight, selected ? st::dialogsBgOver : st::dialogsBg);
|
||||||
if (onlyBackground) {
|
if (onlyBackground) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -323,7 +324,7 @@ void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool o
|
||||||
|
|
||||||
if (mutedHidden) {
|
if (mutedHidden) {
|
||||||
if (int32 unread = App::histories().unreadMutedCount()) {
|
if (int32 unread = App::histories().unreadMutedCount()) {
|
||||||
int unreadRight = w - st::dialogsPadding.x();
|
int unreadRight = fullWidth - st::dialogsPadding.x();
|
||||||
UnreadBadgeStyle st;
|
UnreadBadgeStyle st;
|
||||||
st.muted = true;
|
st.muted = true;
|
||||||
paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, st, nullptr);
|
paintUnreadCount(p, QString::number(unread), unreadRight, unreadTop, st, nullptr);
|
||||||
|
|
|
@ -31,13 +31,13 @@ const style::icon *ChatTypeIcon(PeerData *peer, bool active, bool selected);
|
||||||
|
|
||||||
class RowPainter {
|
class RowPainter {
|
||||||
public:
|
public:
|
||||||
static void paint(Painter &p, const Row *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms);
|
static void paint(Painter &p, const Row *row, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms);
|
||||||
static void paint(Painter &p, const FakeRow *row, int w, bool active, bool selected, bool onlyBackground, TimeMs ms);
|
static void paint(Painter &p, const FakeRow *row, int fullWidth, bool active, bool selected, bool onlyBackground, TimeMs ms);
|
||||||
static QRect sendActionAnimationRect(int animationWidth, int animationHeight, int fullWidth, bool textUpdated);
|
static QRect sendActionAnimationRect(int animationWidth, int animationHeight, int fullWidth, bool textUpdated);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void paintImportantSwitch(Painter &p, Mode current, int w, bool selected, bool onlyBackground);
|
void paintImportantSwitch(Painter &p, Mode current, int fullWidth, bool selected, bool onlyBackground);
|
||||||
|
|
||||||
enum UnreadBadgeSize {
|
enum UnreadBadgeSize {
|
||||||
UnreadBadgeInDialogs = 0,
|
UnreadBadgeInDialogs = 0,
|
||||||
|
|
|
@ -201,7 +201,7 @@ bool List::del(PeerId peerId, Row *replacedBy) {
|
||||||
auto i = _rowByPeer.find(peerId);
|
auto i = _rowByPeer.find(peerId);
|
||||||
if (i == _rowByPeer.cend()) return false;
|
if (i == _rowByPeer.cend()) return false;
|
||||||
|
|
||||||
Row *row = i.value();
|
auto row = i.value();
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
emit App::main()->dialogRowReplaced(row, replacedBy);
|
emit App::main()->dialogRowReplaced(row, replacedBy);
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ bool List::del(PeerId peerId, Row *replacedBy) {
|
||||||
if (row == _current) {
|
if (row == _current) {
|
||||||
_current = row->_next;
|
_current = row->_next;
|
||||||
}
|
}
|
||||||
for (Row *change = row->_next; change != _end; change = change->_next) {
|
for (auto change = row->_next; change != _end; change = change->_next) {
|
||||||
--change->_pos;
|
--change->_pos;
|
||||||
}
|
}
|
||||||
--_end->_pos;
|
--_end->_pos;
|
||||||
|
|
|
@ -22,9 +22,37 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "dialogs/dialogs_row.h"
|
#include "dialogs/dialogs_row.h"
|
||||||
|
|
||||||
#include "styles/style_dialogs.h"
|
#include "styles/style_dialogs.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
|
#include "mainwidget.h"
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
|
|
||||||
|
RippleRow::RippleRow() = default;
|
||||||
|
RippleRow::~RippleRow() = default;
|
||||||
|
|
||||||
|
void RippleRow::addRipple(QPoint origin, QSize size, base::lambda_copy<void()> &&updateCallback) {
|
||||||
|
if (!_ripple) {
|
||||||
|
auto mask = Ui::RippleAnimation::rectMask(size);
|
||||||
|
_ripple = std_::make_unique<Ui::RippleAnimation>(st::dialogsRipple, std_::move(mask), std_::move(updateCallback));
|
||||||
|
}
|
||||||
|
_ripple->add(origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RippleRow::stopLastRipple() {
|
||||||
|
if (_ripple) {
|
||||||
|
_ripple->lastStop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RippleRow::paintRipple(Painter &p, int x, int y, int outerWidth, TimeMs ms, const QColor *colorOverride) const {
|
||||||
|
if (_ripple) {
|
||||||
|
_ripple->paint(p, x, y, outerWidth, ms, colorOverride);
|
||||||
|
if (_ripple->empty()) {
|
||||||
|
_ripple.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FakeRow::FakeRow(HistoryItem *item) : _item(item), _cache(st::dialogsTextWidthMin) {
|
FakeRow::FakeRow(HistoryItem *item) : _item(item), _cache(st::dialogsTextWidthMin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,32 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
class History;
|
class History;
|
||||||
class HistoryItem;
|
class HistoryItem;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RippleAnimation;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Dialogs {
|
namespace Dialogs {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
class RowPainter;
|
class RowPainter;
|
||||||
} // namespace Layout
|
} // namespace Layout
|
||||||
|
|
||||||
|
class RippleRow {
|
||||||
|
public:
|
||||||
|
RippleRow();
|
||||||
|
~RippleRow();
|
||||||
|
|
||||||
|
void addRipple(QPoint origin, QSize size, base::lambda_copy<void()> &&updateCallback);
|
||||||
|
void stopLastRipple();
|
||||||
|
|
||||||
|
void paintRipple(Painter &p, int x, int y, int outerWidth, TimeMs ms, const QColor *colorOverride = nullptr) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable std_::unique_ptr<Ui::RippleAnimation> _ripple;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
class List;
|
class List;
|
||||||
class Row {
|
class Row : public RippleRow {
|
||||||
public:
|
public:
|
||||||
Row(History *history, Row *prev, Row *next, int pos)
|
Row(History *history, Row *prev, Row *next, int pos)
|
||||||
: _history(history)
|
: _history(history)
|
||||||
|
@ -57,7 +76,7 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class FakeRow {
|
class FakeRow : public RippleRow {
|
||||||
public:
|
public:
|
||||||
FakeRow(HistoryItem *item);
|
FakeRow(HistoryItem *item);
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -57,25 +57,24 @@ public:
|
||||||
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
void dialogsReceived(const QVector<MTPDialog> &dialogs);
|
||||||
void addSavedPeersAfter(const QDateTime &date);
|
void addSavedPeersAfter(const QDateTime &date);
|
||||||
void addAllSavedPeers();
|
void addAllSavedPeers();
|
||||||
bool searchReceived(const QVector<MTPMessage> &messages, DialogsSearchRequestType type, int32 fullCount);
|
bool searchReceived(const QVector<MTPMessage> &result, DialogsSearchRequestType type, int32 fullCount);
|
||||||
void peopleReceived(const QString &query, const QVector<MTPPeer> &people);
|
void peerSearchReceived(const QString &query, const QVector<MTPPeer> &result);
|
||||||
void showMore(int32 pixels);
|
void showMore(int32 pixels);
|
||||||
|
|
||||||
void activate();
|
void activate();
|
||||||
|
|
||||||
void contactsReceived(const QVector<MTPContact> &contacts);
|
void contactsReceived(const QVector<MTPContact> &result);
|
||||||
|
|
||||||
void selectSkip(int32 direction);
|
void selectSkip(int32 direction);
|
||||||
void selectSkipPage(int32 pixels, int32 direction);
|
void selectSkipPage(int32 pixels, int32 direction);
|
||||||
|
|
||||||
void createDialog(History *history);
|
void createDialog(History *history);
|
||||||
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||||
void dlgUpdated(History *row, MsgId msgId);
|
void dlgUpdated(PeerData *peer, MsgId msgId);
|
||||||
void removeDialog(History *history);
|
void removeDialog(History *history);
|
||||||
|
|
||||||
void dragLeft();
|
void dragLeft();
|
||||||
|
|
||||||
void loadPeerPhotos(int32 yFrom);
|
|
||||||
void clearFilter();
|
void clearFilter();
|
||||||
void refresh(bool toTop = false);
|
void refresh(bool toTop = false);
|
||||||
|
|
||||||
|
@ -88,21 +87,14 @@ public:
|
||||||
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
void peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPeer, MsgId &outMsg) const;
|
||||||
void scrollToPeer(const PeerId &peer, MsgId msgId);
|
void scrollToPeer(const PeerId &peer, MsgId msgId);
|
||||||
|
|
||||||
typedef QVector<Dialogs::Row*> FilteredDialogs;
|
|
||||||
typedef QVector<PeerData*> PeopleResults;
|
|
||||||
typedef QVector<Dialogs::FakeRow*> SearchResults;
|
|
||||||
|
|
||||||
Dialogs::IndexedList *contactsList();
|
Dialogs::IndexedList *contactsList();
|
||||||
Dialogs::IndexedList *dialogsList();
|
Dialogs::IndexedList *dialogsList();
|
||||||
FilteredDialogs &filteredList();
|
|
||||||
PeopleResults &peopleList();
|
|
||||||
SearchResults &searchList();
|
|
||||||
int32 lastSearchDate() const;
|
int32 lastSearchDate() const;
|
||||||
PeerData *lastSearchPeer() const;
|
PeerData *lastSearchPeer() const;
|
||||||
MsgId lastSearchId() const;
|
MsgId lastSearchId() const;
|
||||||
MsgId lastSearchMigratedId() const;
|
MsgId lastSearchMigratedId() const;
|
||||||
|
|
||||||
void setMouseSel(bool msel, bool toTop = false);
|
void setMouseSelection(bool mouseSelection, bool toTop = false);
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
DefaultState = 0,
|
DefaultState = 0,
|
||||||
|
@ -120,7 +112,10 @@ public:
|
||||||
|
|
||||||
PeerData *updateFromParentDrag(QPoint globalPos);
|
PeerData *updateFromParentDrag(QPoint globalPos);
|
||||||
|
|
||||||
void updateNotifySettings(PeerData *peer);
|
void setLoadMoreCallback(base::lambda<void()> &&callback) {
|
||||||
|
_loadMoreCallback = std_::move(callback);
|
||||||
|
}
|
||||||
|
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||||
|
|
||||||
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
void notify_userIsContactChanged(UserData *user, bool fromThisApp);
|
||||||
void notify_historyMuteUpdated(History *history);
|
void notify_historyMuteUpdated(History *history);
|
||||||
|
@ -128,7 +123,6 @@ public:
|
||||||
~DialogsInner();
|
~DialogsInner();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void onUpdateSelected(bool force = false);
|
|
||||||
void onParentGeometryChanged();
|
void onParentGeometryChanged();
|
||||||
void onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
void onPeerNameChanged(PeerData *peer, const PeerData::Names &oldNames, const PeerData::NameFirstChars &oldChars);
|
||||||
void onPeerPhotoChanged(PeerData *peer);
|
void onPeerPhotoChanged(PeerData *peer);
|
||||||
|
@ -149,67 +143,109 @@ protected:
|
||||||
void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther) override;
|
void paintRegion(Painter &p, const QRegion ®ion, bool paintingOther) override;
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
void enterEvent(QEvent *e) override;
|
void enterEvent(QEvent *e) override;
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEvent(QEvent *e) override;
|
||||||
void contextMenuEvent(QContextMenuEvent *e) override;
|
void contextMenuEvent(QContextMenuEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct ImportantSwitch;
|
||||||
|
using DialogsList = std_::unique_ptr<Dialogs::IndexedList>;
|
||||||
|
using FilteredDialogs = QVector<Dialogs::Row*>;
|
||||||
|
using SearchResults = std_::vector_of_moveable<std_::unique_ptr<Dialogs::FakeRow>>;
|
||||||
|
struct HashtagResult;
|
||||||
|
using HashtagResults = std_::vector_of_moveable<std_::unique_ptr<HashtagResult>>;
|
||||||
|
struct PeerSearchResult;
|
||||||
|
using PeerSearchResults = std_::vector_of_moveable<std_::unique_ptr<PeerSearchResult>>;
|
||||||
|
|
||||||
|
void mousePressReleased(Qt::MouseButton button);
|
||||||
|
void clearIrrelevantState();
|
||||||
|
void updateSelected() {
|
||||||
|
updateSelected(mapFromGlobal(QCursor::pos()));
|
||||||
|
}
|
||||||
|
void updateSelected(QPoint localPos);
|
||||||
|
void loadPeerPhotos(int visibleTop);
|
||||||
|
void setImportantSwitchPressed(bool pressed);
|
||||||
|
void setPressed(Dialogs::Row *pressed);
|
||||||
|
void setHashtagPressed(int pressed);
|
||||||
|
void setFilteredPressed(int pressed);
|
||||||
|
void setPeerSearchPressed(int pressed);
|
||||||
|
void setSearchedPressed(int pressed);
|
||||||
|
bool isPressed() const {
|
||||||
|
return _importantSwitchPressed || _pressed || (_hashtagPressed >= 0) || (_filteredPressed >= 0) || (_peerSearchPressed >= 0) || (_searchedPressed >= 0);
|
||||||
|
}
|
||||||
|
bool isSelected() const {
|
||||||
|
return _importantSwitchSelected || _selected || (_hashtagSelected >= 0) || (_filteredSelected>= 0) || (_peerSearchSelected >= 0) || (_searchedSelected >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
void itemRemoved(HistoryItem *item);
|
void itemRemoved(HistoryItem *item);
|
||||||
enum class UpdateRowSection {
|
enum class UpdateRowSection {
|
||||||
Default = 0x01,
|
Default = 0x01,
|
||||||
Filtered = 0x02,
|
Filtered = 0x02,
|
||||||
GlobalSearch = 0x04,
|
PeerSearch = 0x04,
|
||||||
MessageSearch = 0x08,
|
MessageSearch = 0x08,
|
||||||
All = 0x0F,
|
All = 0x0F,
|
||||||
};
|
};
|
||||||
Q_DECLARE_FLAGS(UpdateRowSections, UpdateRowSection);
|
Q_DECLARE_FLAGS(UpdateRowSections, UpdateRowSection);
|
||||||
Q_DECLARE_FRIEND_OPERATORS_FOR_FLAGS(UpdateRowSections);
|
Q_DECLARE_FRIEND_OPERATORS_FOR_FLAGS(UpdateRowSections);
|
||||||
void updateDialogRow(History *history, MsgId msgId, QRect updateRect, UpdateRowSections sections = UpdateRowSection::All);
|
void updateDialogRow(PeerData *peer, MsgId msgId, QRect updateRect, UpdateRowSections sections = UpdateRowSection::All);
|
||||||
|
|
||||||
int dialogsOffset() const;
|
int dialogsOffset() const;
|
||||||
int filteredOffset() const;
|
int filteredOffset() const;
|
||||||
int peopleOffset() const;
|
int peerSearchOffset() const;
|
||||||
int searchedOffset() const;
|
int searchedOffset() const;
|
||||||
|
|
||||||
void peopleResultPaint(PeerData *peer, Painter &p, int32 w, bool active, bool selected, bool onlyBackground) const;
|
void paintDialog(QPainter &p, Dialogs::Row *dialog);
|
||||||
void searchInPeerPaint(Painter &p, int32 w, bool onlyBackground) const;
|
void paintPeerSearchResult(Painter &p, const PeerSearchResult *result, int32 w, bool active, bool selected, bool onlyBackground, TimeMs ms) const;
|
||||||
|
void paintSearchInPeer(Painter &p, int32 w, bool onlyBackground) const;
|
||||||
|
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
void clearSearchResults(bool clearPeople = true);
|
void clearSearchResults(bool clearPeerSearchResults = true);
|
||||||
void updateSelectedRow(PeerData *peer = 0);
|
void updateSelectedRow(PeerData *peer = 0);
|
||||||
|
|
||||||
Dialogs::IndexedList *shownDialogs() const {
|
Dialogs::IndexedList *shownDialogs() const {
|
||||||
return (Global::DialogsMode() == Dialogs::Mode::Important) ? importantDialogs.get() : dialogs.get();
|
return (Global::DialogsMode() == Dialogs::Mode::Important) ? _dialogsImportant.get() : _dialogs.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
using DialogsList = std_::unique_ptr<Dialogs::IndexedList>;
|
DialogsList _dialogs;
|
||||||
DialogsList dialogs;
|
DialogsList _dialogsImportant;
|
||||||
DialogsList importantDialogs;
|
|
||||||
|
|
||||||
DialogsList contactsNoDialogs;
|
DialogsList _contactsNoDialogs;
|
||||||
DialogsList contacts;
|
DialogsList _contacts;
|
||||||
|
|
||||||
bool _importantSwitchSel = false;
|
bool _mouseSelection = false;
|
||||||
Dialogs::Row *_sel = nullptr;
|
Qt::MouseButton _pressButton = Qt::LeftButton;
|
||||||
bool _selByMouse = false;
|
|
||||||
|
|
||||||
|
std_::unique_ptr<ImportantSwitch> _importantSwitch;
|
||||||
|
bool _importantSwitchSelected = false;
|
||||||
|
bool _importantSwitchPressed = false;
|
||||||
|
Dialogs::Row *_selected = nullptr;
|
||||||
|
Dialogs::Row *_pressed = nullptr;
|
||||||
|
|
||||||
|
int _visibleAreaHeight = 0;
|
||||||
QString _filter, _hashtagFilter;
|
QString _filter, _hashtagFilter;
|
||||||
|
|
||||||
QStringList _hashtagResults;
|
HashtagResults _hashtagResults;
|
||||||
int _hashtagSel = -1;
|
int _hashtagSelected = -1;
|
||||||
|
int _hashtagPressed = -1;
|
||||||
|
bool _hashtagDeleteSelected = false;
|
||||||
|
bool _hashtagDeletePressed = false;
|
||||||
|
|
||||||
FilteredDialogs _filterResults;
|
FilteredDialogs _filterResults;
|
||||||
int _filteredSel = -1;
|
int _filteredSelected = -1;
|
||||||
|
int _filteredPressed = -1;
|
||||||
|
|
||||||
|
QString _peerSearchQuery;
|
||||||
|
PeerSearchResults _peerSearchResults;
|
||||||
|
int _peerSearchSelected = -1;
|
||||||
|
int _peerSearchPressed = -1;
|
||||||
|
|
||||||
SearchResults _searchResults;
|
SearchResults _searchResults;
|
||||||
int _searchedCount = 0;
|
int _searchedCount = 0;
|
||||||
int _searchedMigratedCount = 0;
|
int _searchedMigratedCount = 0;
|
||||||
int _searchedSel = -1;
|
int _searchedSelected = -1;
|
||||||
|
int _searchedPressed = -1;
|
||||||
QString _peopleQuery;
|
|
||||||
PeopleResults _peopleResults;
|
|
||||||
int _peopleSel = -1;
|
|
||||||
|
|
||||||
int _lastSearchDate = 0;
|
int _lastSearchDate = 0;
|
||||||
PeerData *_lastSearchPeer = nullptr;
|
PeerData *_lastSearchPeer = nullptr;
|
||||||
|
@ -218,21 +254,17 @@ private:
|
||||||
|
|
||||||
State _state = DefaultState;
|
State _state = DefaultState;
|
||||||
|
|
||||||
QPoint lastMousePos;
|
|
||||||
|
|
||||||
void paintDialog(QPainter &p, Dialogs::Row *dialog);
|
|
||||||
|
|
||||||
ChildWidget<Ui::LinkButton> _addContactLnk;
|
ChildWidget<Ui::LinkButton> _addContactLnk;
|
||||||
ChildWidget<Ui::IconButton> _cancelSearchInPeer;
|
ChildWidget<Ui::IconButton> _cancelSearchInPeer;
|
||||||
|
|
||||||
bool _overDelete = false;
|
|
||||||
|
|
||||||
PeerData *_searchInPeer = nullptr;
|
PeerData *_searchInPeer = nullptr;
|
||||||
PeerData *_searchInMigrated = nullptr;
|
PeerData *_searchInMigrated = nullptr;
|
||||||
PeerData *_menuPeer = nullptr;
|
PeerData *_menuPeer = nullptr;
|
||||||
|
|
||||||
Ui::PopupMenu *_menu = nullptr;
|
Ui::PopupMenu *_menu = nullptr;
|
||||||
|
|
||||||
|
base::lambda<void()> _loadMoreCallback;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_DECLARE_OPERATORS_FOR_FLAGS(DialogsInner::UpdateRowSections);
|
Q_DECLARE_OPERATORS_FOR_FLAGS(DialogsInner::UpdateRowSections);
|
||||||
|
@ -243,27 +275,14 @@ class DialogsWidget : public TWidget, public RPCSender, private base::Subscriber
|
||||||
public:
|
public:
|
||||||
DialogsWidget(QWidget *parent);
|
DialogsWidget(QWidget *parent);
|
||||||
|
|
||||||
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req);
|
|
||||||
void contactsReceived(const MTPcontacts_Contacts &contacts);
|
|
||||||
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
|
|
||||||
void peopleReceived(const MTPcontacts_Found &result, mtpRequestId req);
|
|
||||||
|
|
||||||
void dragEnterEvent(QDragEnterEvent *e) override;
|
|
||||||
void dragMoveEvent(QDragMoveEvent *e) override;
|
|
||||||
void dragLeaveEvent(QDragLeaveEvent *e) override;
|
|
||||||
void dropEvent(QDropEvent *e) override;
|
|
||||||
void updateDragInScroll(bool inScroll);
|
void updateDragInScroll(bool inScroll);
|
||||||
|
|
||||||
void resizeEvent(QResizeEvent *e) override;
|
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
|
||||||
void paintEvent(QPaintEvent *e) override;
|
|
||||||
|
|
||||||
void searchInPeer(PeerData *peer);
|
void searchInPeer(PeerData *peer);
|
||||||
|
|
||||||
void loadDialogs();
|
void loadDialogs();
|
||||||
void createDialog(History *history);
|
void createDialog(History *history);
|
||||||
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||||
void dlgUpdated(History *row, MsgId msgId);
|
void dlgUpdated(PeerData *peer, MsgId msgId);
|
||||||
|
|
||||||
void dialogsToUp();
|
void dialogsToUp();
|
||||||
|
|
||||||
|
@ -272,7 +291,6 @@ public:
|
||||||
}
|
}
|
||||||
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms);
|
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms);
|
||||||
void showFast();
|
void showFast();
|
||||||
void step_show(float64 ms, bool timer);
|
|
||||||
|
|
||||||
void destroyData();
|
void destroyData();
|
||||||
|
|
||||||
|
@ -321,7 +339,22 @@ private slots:
|
||||||
void onCheckUpdateStatus();
|
void onCheckUpdateStatus();
|
||||||
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
#endif // TDESKTOP_DISABLE_AUTOUPDATE
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void dragEnterEvent(QDragEnterEvent *e) override;
|
||||||
|
void dragMoveEvent(QDragMoveEvent *e) override;
|
||||||
|
void dragLeaveEvent(QDragLeaveEvent *e) override;
|
||||||
|
void dropEvent(QDropEvent *e) override;
|
||||||
|
void resizeEvent(QResizeEvent *e) override;
|
||||||
|
void keyPressEvent(QKeyEvent *e) override;
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void animationCallback();
|
||||||
|
void dialogsReceived(const MTPmessages_Dialogs &dialogs, mtpRequestId req);
|
||||||
|
void contactsReceived(const MTPcontacts_Contacts &result);
|
||||||
|
void searchReceived(DialogsSearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
|
||||||
|
void peerSearchReceived(const MTPcontacts_Found &result, mtpRequestId req);
|
||||||
|
|
||||||
void setSearchInPeer(PeerData *peer);
|
void setSearchInPeer(PeerData *peer);
|
||||||
void showMainMenu();
|
void showMainMenu();
|
||||||
void updateLockUnlockVisibility();
|
void updateLockUnlockVisibility();
|
||||||
|
@ -354,31 +387,34 @@ private:
|
||||||
ChildWidget<DialogsInner> _inner;
|
ChildWidget<DialogsInner> _inner;
|
||||||
ChildWidget<Ui::FlatButton> _updateTelegram = { nullptr };
|
ChildWidget<Ui::FlatButton> _updateTelegram = { nullptr };
|
||||||
|
|
||||||
Animation _a_show;
|
FloatAnimation _a_show;
|
||||||
|
Window::SlideDirection _showDirection;
|
||||||
QPixmap _cacheUnder, _cacheOver;
|
QPixmap _cacheUnder, _cacheOver;
|
||||||
anim::ivalue a_coordUnder, a_coordOver;
|
|
||||||
anim::fvalue a_progress;
|
|
||||||
|
|
||||||
PeerData *_searchInPeer = nullptr;
|
PeerData *_searchInPeer = nullptr;
|
||||||
PeerData *_searchInMigrated = nullptr;
|
PeerData *_searchInMigrated = nullptr;
|
||||||
|
|
||||||
QTimer _searchTimer;
|
QTimer _searchTimer;
|
||||||
QString _searchQuery, _peopleQuery;
|
|
||||||
|
QString _peerSearchQuery;
|
||||||
|
bool _peerSearchFull = false;
|
||||||
|
mtpRequestId _peerSearchRequest = 0;
|
||||||
|
|
||||||
|
QString _searchQuery;
|
||||||
bool _searchFull = false;
|
bool _searchFull = false;
|
||||||
bool _searchFullMigrated = false;
|
bool _searchFullMigrated = false;
|
||||||
bool _peopleFull = false;
|
mtpRequestId _searchRequest = 0;
|
||||||
mtpRequestId _searchRequest, _peopleRequest;
|
|
||||||
|
|
||||||
typedef QMap<QString, MTPmessages_Messages> SearchCache;
|
using SearchCache = QMap<QString, MTPmessages_Messages>;
|
||||||
SearchCache _searchCache;
|
SearchCache _searchCache;
|
||||||
|
|
||||||
typedef QMap<mtpRequestId, QString> SearchQueries;
|
using SearchQueries = QMap<mtpRequestId, QString>;
|
||||||
SearchQueries _searchQueries;
|
SearchQueries _searchQueries;
|
||||||
|
|
||||||
typedef QMap<QString, MTPcontacts_Found> PeopleCache;
|
using PeerSearchCache = QMap<QString, MTPcontacts_Found>;
|
||||||
PeopleCache _peopleCache;
|
PeerSearchCache _peerSearchCache;
|
||||||
|
|
||||||
typedef QMap<mtpRequestId, QString> PeopleQueries;
|
using PeerSearchQueries = QMap<mtpRequestId, QString>;
|
||||||
PeopleQueries _peopleQueries;
|
PeerSearchQueries _peerSearchQueries;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -395,7 +395,7 @@ void FieldAutocomplete::hideFast() {
|
||||||
if (_a_appearance.animating()) {
|
if (_a_appearance.animating()) {
|
||||||
_a_appearance.stop();
|
_a_appearance.stop();
|
||||||
}
|
}
|
||||||
a_opacity = anim::fvalue(0, 0);
|
a_opacity = anim::value();
|
||||||
hideFinish();
|
hideFinish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ private:
|
||||||
int32 _width, _height;
|
int32 _width, _height;
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
|
|
||||||
anim::fvalue a_opacity;
|
anim::value a_opacity;
|
||||||
Animation _a_appearance;
|
Animation _a_appearance;
|
||||||
|
|
||||||
friend class internal::FieldAutocompleteInner;
|
friend class internal::FieldAutocompleteInner;
|
||||||
|
|
|
@ -240,8 +240,6 @@ historyAttachEmoji: IconButton(historyAttach) {
|
||||||
icon: icon {{ "send_control_emoji", historyComposeIconFg }};
|
icon: icon {{ "send_control_emoji", historyComposeIconFg }};
|
||||||
iconOver: icon {{ "send_control_emoji", historyComposeIconFgOver }};
|
iconOver: icon {{ "send_control_emoji", historyComposeIconFgOver }};
|
||||||
iconPosition: point(15px, 15px);
|
iconPosition: point(15px, 15px);
|
||||||
|
|
||||||
ripple: emptyRippleAnimation;
|
|
||||||
}
|
}
|
||||||
historyEmojiCircle: size(20px, 20px);
|
historyEmojiCircle: size(20px, 20px);
|
||||||
historyEmojiCirclePeriod: 1500;
|
historyEmojiCirclePeriod: 1500;
|
||||||
|
@ -251,16 +249,16 @@ historyEmojiCircleLine: 2px;
|
||||||
historyEmojiCircleFg: historyComposeIconFg;
|
historyEmojiCircleFg: historyComposeIconFg;
|
||||||
historyEmojiCircleFgOver: historyComposeIconFgOver;
|
historyEmojiCircleFgOver: historyComposeIconFgOver;
|
||||||
historyEmojiCirclePart: 3.5;
|
historyEmojiCirclePart: 3.5;
|
||||||
historyBotKeyboardShow: IconButton(historySend) {
|
historyBotKeyboardShow: IconButton(historyAttach) {
|
||||||
icon: icon {{ "send_control_bot_keyboard", historyComposeIconFg }};
|
icon: icon {{ "send_control_bot_keyboard", historyComposeIconFg }};
|
||||||
iconOver: icon {{ "send_control_bot_keyboard", historyComposeIconFgOver }};
|
iconOver: icon {{ "send_control_bot_keyboard", historyComposeIconFgOver }};
|
||||||
}
|
}
|
||||||
historyBotKeyboardHide: IconButton(historySend) {
|
historyBotKeyboardHide: IconButton(historyAttach) {
|
||||||
icon: icon {{ "send_control_bot_keyboard_hide", historyComposeIconFg }};
|
icon: icon {{ "send_control_bot_keyboard_hide", historyComposeIconFg }};
|
||||||
iconOver: icon {{ "send_control_bot_keyboard_hide", historyComposeIconFgOver }};
|
iconOver: icon {{ "send_control_bot_keyboard_hide", historyComposeIconFgOver }};
|
||||||
iconPosition: point(11px, 16px);
|
iconPosition: point(11px, 16px);
|
||||||
}
|
}
|
||||||
historyBotCommandStart: IconButton(historySend) {
|
historyBotCommandStart: IconButton(historyAttach) {
|
||||||
icon: icon {{ "send_control_bot_command", historyComposeIconFg }};
|
icon: icon {{ "send_control_bot_command", historyComposeIconFg }};
|
||||||
iconOver: icon {{ "send_control_bot_command", historyComposeIconFgOver }};
|
iconOver: icon {{ "send_control_bot_command", historyComposeIconFgOver }};
|
||||||
}
|
}
|
||||||
|
@ -270,6 +268,7 @@ historyRecordVoiceFgActive: windowBgActive;
|
||||||
historyRecordVoice: icon {{ "send_control_record", historyRecordVoiceFg }};
|
historyRecordVoice: icon {{ "send_control_record", historyRecordVoiceFg }};
|
||||||
historyRecordVoiceOver: icon {{ "send_control_record", historyRecordVoiceFgOver }};
|
historyRecordVoiceOver: icon {{ "send_control_record", historyRecordVoiceFgOver }};
|
||||||
historyRecordVoiceActive: icon {{ "send_control_record", historyRecordVoiceFgActive }};
|
historyRecordVoiceActive: icon {{ "send_control_record", historyRecordVoiceFgActive }};
|
||||||
|
historyRecordVoiceRippleBgActive: lightButtonBgOver;
|
||||||
historyRecordSignalColor: #f17077;
|
historyRecordSignalColor: #f17077;
|
||||||
historyRecordSignalMin: 5px;
|
historyRecordSignalMin: 5px;
|
||||||
historyRecordSignalMax: 12px;
|
historyRecordSignalMax: 12px;
|
||||||
|
|
|
@ -133,14 +133,14 @@ void DragArea::hideFast() {
|
||||||
if (_a_appearance.animating()) {
|
if (_a_appearance.animating()) {
|
||||||
_a_appearance.stop();
|
_a_appearance.stop();
|
||||||
}
|
}
|
||||||
a_opacity = anim::fvalue(0, 0);
|
a_opacity = anim::value();
|
||||||
hide();
|
hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DragArea::hideStart() {
|
void DragArea::hideStart() {
|
||||||
_hiding = true;
|
_hiding = true;
|
||||||
_in = false;
|
_in = false;
|
||||||
a_opacity.start(0);
|
a_opacity.start(0.);
|
||||||
a_colorDrop.start(_in ? 1. : 0.);
|
a_colorDrop.start(_in ? 1. : 0.);
|
||||||
_a_appearance.start();
|
_a_appearance.start();
|
||||||
}
|
}
|
||||||
|
@ -148,7 +148,7 @@ void DragArea::hideStart() {
|
||||||
void DragArea::hideFinish() {
|
void DragArea::hideFinish() {
|
||||||
hide();
|
hide();
|
||||||
_in = false;
|
_in = false;
|
||||||
a_colorDrop = anim::fvalue(0.);
|
a_colorDrop = anim::value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DragArea::showStart() {
|
void DragArea::showStart() {
|
||||||
|
|
|
@ -70,8 +70,8 @@ private:
|
||||||
bool _hiding, _in;
|
bool _hiding, _in;
|
||||||
base::lambda<void(const QMimeData *data)> _droppedCallback;
|
base::lambda<void(const QMimeData *data)> _droppedCallback;
|
||||||
|
|
||||||
anim::fvalue a_opacity;
|
anim::value a_opacity;
|
||||||
anim::fvalue a_colorDrop;
|
anim::value a_colorDrop;
|
||||||
Animation _a_appearance;
|
Animation _a_appearance;
|
||||||
|
|
||||||
Ui::RectShadow _shadow;
|
Ui::RectShadow _shadow;
|
||||||
|
|
|
@ -584,7 +584,7 @@ void HistoryItem::finishCreate() {
|
||||||
void HistoryItem::finishEdition(int oldKeyboardTop) {
|
void HistoryItem::finishEdition(int oldKeyboardTop) {
|
||||||
setPendingInitDimensions();
|
setPendingInitDimensions();
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
App::main()->dlgUpdated(history(), id);
|
App::main()->dlgUpdated(history()->peer, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalidate cache for drawInDialog
|
// invalidate cache for drawInDialog
|
||||||
|
|
|
@ -1456,7 +1456,7 @@ bool HistoryDocument::updateStatusText() const {
|
||||||
if (voice->_playback->_position < playbackState.position) {
|
if (voice->_playback->_position < playbackState.position) {
|
||||||
voice->_playback->a_progress.start(prg);
|
voice->_playback->a_progress.start(prg);
|
||||||
} else {
|
} else {
|
||||||
voice->_playback->a_progress = anim::fvalue(0., prg);
|
voice->_playback->a_progress = anim::value(0., prg);
|
||||||
}
|
}
|
||||||
voice->_playback->_position = playbackState.position;
|
voice->_playback->_position = playbackState.position;
|
||||||
voice->_playback->_a_progress.start();
|
voice->_playback->_a_progress.start();
|
||||||
|
|
|
@ -99,7 +99,7 @@ protected:
|
||||||
, _a_thumbOver(std_::move(thumbOverCallbacks))
|
, _a_thumbOver(std_::move(thumbOverCallbacks))
|
||||||
, radial(std_::move(radialCallbacks)) {
|
, radial(std_::move(radialCallbacks)) {
|
||||||
}
|
}
|
||||||
anim::fvalue a_thumbOver;
|
anim::value a_thumbOver;
|
||||||
Animation _a_thumbOver;
|
Animation _a_thumbOver;
|
||||||
|
|
||||||
Ui::RadialAnimation radial;
|
Ui::RadialAnimation radial;
|
||||||
|
@ -306,7 +306,7 @@ struct HistoryDocumentVoicePlayback {
|
||||||
HistoryDocumentVoicePlayback(const HistoryDocument *that);
|
HistoryDocumentVoicePlayback(const HistoryDocument *that);
|
||||||
|
|
||||||
int32 _position;
|
int32 _position;
|
||||||
anim::fvalue a_progress;
|
anim::value a_progress;
|
||||||
Animation _a_progress;
|
Animation _a_progress;
|
||||||
};
|
};
|
||||||
struct HistoryDocumentVoice : public RuntimeComponent<HistoryDocumentVoice> {
|
struct HistoryDocumentVoice : public RuntimeComponent<HistoryDocumentVoice> {
|
||||||
|
|
|
@ -2329,7 +2329,7 @@ bool HistoryService::updateDependentText() {
|
||||||
history()->textCachedFor = 0;
|
history()->textCachedFor = 0;
|
||||||
}
|
}
|
||||||
if (App::main()) {
|
if (App::main()) {
|
||||||
App::main()->dlgUpdated(history(), id);
|
App::main()->dlgUpdated(history()->peer, id);
|
||||||
}
|
}
|
||||||
App::historyUpdateDependent(this);
|
App::historyUpdateDependent(this);
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -34,6 +34,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/inner_dropdown.h"
|
#include "ui/widgets/inner_dropdown.h"
|
||||||
#include "ui/widgets/dropdown_menu.h"
|
#include "ui/widgets/dropdown_menu.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "inline_bots/inline_bot_result.h"
|
#include "inline_bots/inline_bot_result.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
#include "history/history_service_layout.h"
|
#include "history/history_service_layout.h"
|
||||||
|
@ -2971,7 +2972,7 @@ void SilentToggle::mouseMoveEvent(QMouseEvent *e) {
|
||||||
void SilentToggle::setChecked(bool checked) {
|
void SilentToggle::setChecked(bool checked) {
|
||||||
if (_checked != checked) {
|
if (_checked != checked) {
|
||||||
_checked = checked;
|
_checked = checked;
|
||||||
setIcon(_checked ? &st::historySilentToggleOn : nullptr, _checked ? &st::historySilentToggleOnOver : nullptr);
|
setIconOverride(_checked ? &st::historySilentToggleOn : nullptr, _checked ? &st::historySilentToggleOnOver : nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3051,9 +3052,7 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _botCommandStart(this, st::historyBotCommandStart)
|
, _botCommandStart(this, st::historyBotCommandStart)
|
||||||
, _silent(this)
|
, _silent(this)
|
||||||
, _field(this, st::historyComposeField, lang(lng_message_ph))
|
, _field(this, st::historyComposeField, lang(lng_message_ph))
|
||||||
, _a_record(animation(this, &HistoryWidget::step_record))
|
|
||||||
, _a_recording(animation(this, &HistoryWidget::step_recording))
|
, _a_recording(animation(this, &HistoryWidget::step_recording))
|
||||||
, a_recordCancelActive(0, 0)
|
|
||||||
, _recordCancelWidth(st::historyRecordFont->width(lang(lng_record_cancel)))
|
, _recordCancelWidth(st::historyRecordFont->width(lang(lng_record_cancel)))
|
||||||
, _kbScroll(this, st::botKbScroll)
|
, _kbScroll(this, st::botKbScroll)
|
||||||
, _keyboard(this)
|
, _keyboard(this)
|
||||||
|
@ -3061,7 +3060,6 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _attachDragDocument(this)
|
, _attachDragDocument(this)
|
||||||
, _attachDragPhoto(this)
|
, _attachDragPhoto(this)
|
||||||
, _fileLoader(this, FileLoaderQueueStopTimeout)
|
, _fileLoader(this, FileLoaderQueueStopTimeout)
|
||||||
, _a_show(animation(this, &HistoryWidget::step_show))
|
|
||||||
, _topShadow(this, st::shadowColor) {
|
, _topShadow(this, st::shadowColor) {
|
||||||
setAcceptDrops(true);
|
setAcceptDrops(true);
|
||||||
|
|
||||||
|
@ -3318,10 +3316,8 @@ void HistoryWidget::onTextChange() {
|
||||||
_send->show();
|
_send->show();
|
||||||
}
|
}
|
||||||
updateMouseTracking();
|
updateMouseTracking();
|
||||||
_a_record.stop();
|
_a_recordActive.finish();
|
||||||
_inRecord = _inField = false;
|
_inRecord = _inField = false;
|
||||||
a_recordDown = anim::fvalue(0, 0);
|
|
||||||
a_recordCancelActive = anim::fvalue(0, 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (updateCmdStartShown()) {
|
if (updateCmdStartShown()) {
|
||||||
|
@ -4197,7 +4193,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
|
|
||||||
historyLoaded();
|
historyLoaded();
|
||||||
}
|
}
|
||||||
App::main()->dlgUpdated(wasHistory, wasMsgId);
|
App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId);
|
||||||
emit historyShown(_history, _showAtMsgId);
|
emit historyShown(_history, _showAtMsgId);
|
||||||
|
|
||||||
App::main()->topBar()->update();
|
App::main()->topBar()->update();
|
||||||
|
@ -4358,7 +4354,7 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
|
||||||
|
|
||||||
if (App::wnd()) QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus()));
|
if (App::wnd()) QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus()));
|
||||||
|
|
||||||
App::main()->dlgUpdated(wasHistory, wasMsgId);
|
App::main()->dlgUpdated(wasHistory ? wasHistory->peer : nullptr, wasMsgId);
|
||||||
emit historyShown(_history, _showAtMsgId);
|
emit historyShown(_history, _showAtMsgId);
|
||||||
|
|
||||||
App::main()->historyPeerChanged().notify(_peer, true);
|
App::main()->historyPeerChanged().notify(_peer, true);
|
||||||
|
@ -4650,7 +4646,7 @@ void HistoryWidget::updateControlsVisibility() {
|
||||||
} else {
|
} else {
|
||||||
_send->show();
|
_send->show();
|
||||||
}
|
}
|
||||||
_a_record.stop();
|
_a_recordActive.finish();
|
||||||
_inRecord = _inField = false;
|
_inRecord = _inField = false;
|
||||||
}
|
}
|
||||||
if (_recording) {
|
if (_recording) {
|
||||||
|
@ -5441,9 +5437,9 @@ PeerData *HistoryWidget::peer() const {
|
||||||
|
|
||||||
void HistoryWidget::setMsgId(MsgId showAtMsgId) { // sometimes _showAtMsgId is set directly
|
void HistoryWidget::setMsgId(MsgId showAtMsgId) { // sometimes _showAtMsgId is set directly
|
||||||
if (_showAtMsgId != showAtMsgId) {
|
if (_showAtMsgId != showAtMsgId) {
|
||||||
MsgId wasMsgId = _showAtMsgId;
|
auto wasMsgId = _showAtMsgId;
|
||||||
_showAtMsgId = showAtMsgId;
|
_showAtMsgId = showAtMsgId;
|
||||||
App::main()->dlgUpdated(_history, wasMsgId);
|
App::main()->dlgUpdated(_history ? _history->peer : nullptr, wasMsgId);
|
||||||
emit historyShown(_history, _showAtMsgId);
|
emit historyShown(_history, _showAtMsgId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5453,7 +5449,9 @@ MsgId HistoryWidget::msgId() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) {
|
void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) {
|
||||||
if (App::app()) App::app()->mtpPause();
|
_showDirection = direction;
|
||||||
|
|
||||||
|
_a_show.finish();
|
||||||
|
|
||||||
_cacheUnder = params.oldContentCache;
|
_cacheUnder = params.oldContentCache;
|
||||||
show();
|
show();
|
||||||
|
@ -5487,47 +5485,26 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
|
||||||
_pinnedBar->cancel->hide();
|
_pinnedBar->cancel->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
int delta = st::slideShift;
|
if (_showDirection == Window::SlideDirection::FromLeft) {
|
||||||
if (direction == Window::SlideDirection::FromLeft) {
|
|
||||||
a_progress = anim::fvalue(1, 0);
|
|
||||||
std::swap(_cacheUnder, _cacheOver);
|
std::swap(_cacheUnder, _cacheOver);
|
||||||
a_coordUnder = anim::ivalue(-delta, 0);
|
|
||||||
a_coordOver = anim::ivalue(0, width());
|
|
||||||
} else {
|
|
||||||
a_progress = anim::fvalue(0, 1);
|
|
||||||
a_coordUnder = anim::ivalue(0, -delta);
|
|
||||||
a_coordOver = anim::ivalue(width(), 0);
|
|
||||||
}
|
}
|
||||||
_a_show.start();
|
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
|
||||||
|
|
||||||
App::main()->topBar()->update();
|
App::main()->topBar()->update();
|
||||||
|
|
||||||
activate();
|
activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::step_show(float64 ms, bool timer) {
|
void HistoryWidget::animationCallback() {
|
||||||
float64 dt = ms / st::slideDuration;
|
update();
|
||||||
if (dt >= 1) {
|
App::main()->topBar()->update();
|
||||||
_a_show.stop();
|
if (!_a_show.animating()) {
|
||||||
_topShadow->setVisible(_peer ? true : false);
|
_topShadow->setVisible(_peer ? true : false);
|
||||||
_historyToEnd->finishAnimation();
|
_historyToEnd->finishAnimation();
|
||||||
|
|
||||||
a_coordUnder.finish();
|
|
||||||
a_coordOver.finish();
|
|
||||||
a_progress.finish();
|
|
||||||
_cacheUnder = _cacheOver = QPixmap();
|
_cacheUnder = _cacheOver = QPixmap();
|
||||||
App::main()->topBar()->stopAnim();
|
App::main()->topBar()->stopAnim();
|
||||||
doneShow();
|
doneShow();
|
||||||
|
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
|
||||||
} else {
|
|
||||||
a_coordUnder.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_coordOver.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_progress.update(dt, Window::SlideAnimation::transition());
|
|
||||||
}
|
|
||||||
if (timer) {
|
|
||||||
update();
|
|
||||||
App::main()->topBar()->update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5547,29 +5524,21 @@ void HistoryWidget::doneShow() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::animStop() {
|
void HistoryWidget::finishAnimation() {
|
||||||
if (!_a_show.animating()) return;
|
if (!_a_show.animating()) return;
|
||||||
_a_show.stop();
|
_a_show.finish();
|
||||||
_topShadow->setVisible(_peer ? true : false);
|
_topShadow->setVisible(_peer ? true : false);
|
||||||
_historyToEnd->finishAnimation();
|
_historyToEnd->finishAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::step_record(float64 ms, bool timer) {
|
void HistoryWidget::recordActiveCallback() {
|
||||||
float64 dt = ms / st::historyComposeButton.duration;
|
if (_recording) {
|
||||||
if (dt >= 1 || !_send->isHidden() || (_inlineBotCancel && !_inlineBotCancel->isHidden()) || isBotStart() || isBlocked()) {
|
updateField();
|
||||||
_a_record.stop();
|
|
||||||
a_recordDown.finish();
|
|
||||||
a_recordCancelActive.finish();
|
|
||||||
} else {
|
} else {
|
||||||
a_recordDown.update(dt, anim::linear);
|
update(_send->geometry());
|
||||||
a_recordCancelActive.update(dt, anim::linear);
|
|
||||||
}
|
}
|
||||||
if (timer) {
|
if (!_send->isHidden() || (_inlineBotCancel && !_inlineBotCancel->isHidden()) || isBotStart() || isBlocked()) {
|
||||||
if (_recording) {
|
_a_recordActive.finish();
|
||||||
updateField();
|
|
||||||
} else {
|
|
||||||
update(_send->geometry());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5665,9 +5634,7 @@ void HistoryWidget::mouseMoveEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
if (inField != _inField && _recording) {
|
if (inField != _inField && _recording) {
|
||||||
_inField = inField;
|
_inField = inField;
|
||||||
a_recordDown.start(_inField ? 1 : 0);
|
_a_recordActive.start([this] { recordActiveCallback(); }, _inField ? 0. : 1., _inField ? 1. : 0., st::historyComposeButton.duration);
|
||||||
a_recordCancelActive.start(_inField ? 0. : 1.);
|
|
||||||
_a_record.start();
|
|
||||||
}
|
}
|
||||||
_inReplyEdit = inReplyEdit;
|
_inReplyEdit = inReplyEdit;
|
||||||
_inPinnedMsg = inPinnedMsg;
|
_inPinnedMsg = inPinnedMsg;
|
||||||
|
@ -5698,7 +5665,7 @@ void HistoryWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
void HistoryWidget::stopRecording(bool send) {
|
void HistoryWidget::stopRecording(bool send) {
|
||||||
emit audioCapture()->stop(send);
|
emit audioCapture()->stop(send);
|
||||||
|
|
||||||
a_recordingLevel = anim::ivalue(0, 0);
|
a_recordingLevel = anim::value();
|
||||||
_a_recording.stop();
|
_a_recording.stop();
|
||||||
|
|
||||||
_recording = false;
|
_recording = false;
|
||||||
|
@ -5712,9 +5679,13 @@ void HistoryWidget::stopRecording(bool send) {
|
||||||
|
|
||||||
updateField();
|
updateField();
|
||||||
|
|
||||||
a_recordDown.start(0);
|
if (_inField) {
|
||||||
a_recordCancelActive = anim::fvalue(0., 0.);
|
_a_recordActive.start([this] { recordActiveCallback(); }, 1., 0., st::historyComposeButton.duration);
|
||||||
_a_record.start();
|
}
|
||||||
|
|
||||||
|
if (_recordRipple) {
|
||||||
|
_recordRipple->lastStop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::sendBotCommand(PeerData *peer, UserData *bot, const QString &cmd, MsgId replyTo) { // replyTo != 0 from ReplyKeyboardMarkup, == 0 from cmd links
|
void HistoryWidget::sendBotCommand(PeerData *peer, UserData *bot, const QString &cmd, MsgId replyTo) { // replyTo != 0 from ReplyKeyboardMarkup, == 0 from cmd links
|
||||||
|
@ -6202,16 +6173,21 @@ void HistoryWidget::onForwardHere() {
|
||||||
|
|
||||||
bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
|
bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
int retina = cIntRetinaFactor();
|
auto progress = _a_show.current(1.);
|
||||||
if (a_coordOver.current() > 0) {
|
auto retina = cIntRetinaFactor();
|
||||||
p.drawPixmap(QRect(0, 0, a_coordOver.current(), st::topBarHeight), _cacheUnder, QRect(-a_coordUnder.current() * retina, 0, a_coordOver.current() * retina, st::topBarHeight * retina));
|
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
|
||||||
p.setOpacity(a_progress.current());
|
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
p.fillRect(0, 0, a_coordOver.current(), st::topBarHeight, st::slideFadeOutBg);
|
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
|
auto shadow = fromLeft ? (1. - progress) : progress;
|
||||||
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, st::topBarHeight), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, st::topBarHeight * retina));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, st::topBarHeight, st::slideFadeOutBg);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
p.drawPixmap(QRect(a_coordOver.current(), 0, _cacheOver.width() / retina, st::topBarHeight), _cacheOver, QRect(0, 0, _cacheOver.width(), st::topBarHeight * retina));
|
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, st::topBarHeight), _cacheOver, QRect(0, 0, _cacheOver.width(), st::topBarHeight * retina));
|
||||||
p.setOpacity(a_progress.current());
|
p.setOpacity(shadow);
|
||||||
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), st::topBarHeight));
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), st::topBarHeight));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6481,14 +6457,14 @@ void HistoryWidget::onCheckFieldAutocomplete() {
|
||||||
void HistoryWidget::updateFieldPlaceholder() {
|
void HistoryWidget::updateFieldPlaceholder() {
|
||||||
if (_editMsgId) {
|
if (_editMsgId) {
|
||||||
_field->setPlaceholder(lang(lng_edit_message_text));
|
_field->setPlaceholder(lang(lng_edit_message_text));
|
||||||
_send->setIcon(&st::historyEditSaveIcon, &st::historyEditSaveIconOver);
|
_send->setIconOverride(&st::historyEditSaveIcon, &st::historyEditSaveIconOver);
|
||||||
} else {
|
} else {
|
||||||
if (_inlineBot && _inlineBot != Ui::LookingUpInlineBot) {
|
if (_inlineBot && _inlineBot != Ui::LookingUpInlineBot) {
|
||||||
_field->setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2);
|
_field->setPlaceholder(_inlineBot->botInfo->inlinePlaceholder.mid(1), _inlineBot->username.size() + 2);
|
||||||
} else {
|
} else {
|
||||||
_field->setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_silent->checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_message_ph));
|
_field->setPlaceholder(lang((_history && _history->isChannel() && !_history->isMegagroup()) ? (_silent->checked() ? lng_broadcast_silent_ph : lng_broadcast_ph) : lng_message_ph));
|
||||||
}
|
}
|
||||||
_send->setIcon(nullptr);
|
_send->setIconOverride(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7511,8 +7487,13 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
|
|
||||||
updateField();
|
updateField();
|
||||||
|
|
||||||
a_recordDown.start(1);
|
_a_recordActive.start([this] { recordActiveCallback(); }, 0., 1., st::historyComposeButton.duration);
|
||||||
_a_record.start();
|
|
||||||
|
if (!_recordRipple) {
|
||||||
|
auto mask = Ui::RippleAnimation::ellipseMask(QSize(st::historyAttachEmoji.rippleAreaSize, st::historyAttachEmoji.rippleAreaSize));
|
||||||
|
_recordRipple = std_::make_unique<Ui::RippleAnimation>(st::historyAttachEmoji.ripple, std_::move(mask), [this] { update(_send->geometry()); });
|
||||||
|
}
|
||||||
|
_recordRipple->add(mapFromGlobal(QCursor::pos()) - QPoint(_send->x() + (_send->width() - st::historyAttachEmoji.rippleAreaSize) / 2, _send->y() + st::historyAttachEmoji.rippleAreaPosition.y()));
|
||||||
} else if (_inReplyEdit) {
|
} else if (_inReplyEdit) {
|
||||||
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
|
Ui::showPeerHistory(_peer, _editMsgId ? _editMsgId : replyToId());
|
||||||
} else if (_inPinnedMsg) {
|
} else if (_inPinnedMsg) {
|
||||||
|
@ -8582,7 +8563,7 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
||||||
Text *from = 0, *text = 0;
|
Text *from = 0, *text = 0;
|
||||||
bool serviceColor = false, hasForward = readyToForward();
|
bool serviceColor = false, hasForward = readyToForward();
|
||||||
ImagePtr preview;
|
ImagePtr preview;
|
||||||
HistoryItem *drawMsgText = (_editMsgId || _replyToId) ? _replyEditMsg : _kbReplyTo;
|
auto drawMsgText = (_editMsgId || _replyToId) ? _replyEditMsg : _kbReplyTo;
|
||||||
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
|
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
|
||||||
if (!_editMsgId && drawMsgText && drawMsgText->author()->nameVersion > _replyToNameVersion) {
|
if (!_editMsgId && drawMsgText && drawMsgText->author()->nameVersion > _replyToNameVersion) {
|
||||||
updateReplyToName();
|
updateReplyToName();
|
||||||
|
@ -8718,10 +8699,16 @@ void HistoryWidget::paintEditHeader(Painter &p, const QRect &rect, int left, int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::drawRecordButton(Painter &p) {
|
void HistoryWidget::drawRecordButton(Painter &p, float64 recordActive, TimeMs ms) {
|
||||||
auto down = a_recordDown.current();
|
if (_recordRipple) {
|
||||||
auto fastIcon = [down, this] {
|
auto rippleColor = anim::color(st::historyAttachEmoji.ripple.color, st::historyRecordVoiceRippleBgActive, recordActive);
|
||||||
if (down == 1.) {
|
_recordRipple->paint(p, _send->x() + (_send->width() - st::historyAttachEmoji.rippleAreaSize) / 2, _send->y() + st::historyAttachEmoji.rippleAreaPosition.y(), width(), ms, &rippleColor);
|
||||||
|
if (_recordRipple->empty()) {
|
||||||
|
_recordRipple.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
auto fastIcon = [recordActive, this] {
|
||||||
|
if (recordActive == 1.) {
|
||||||
return &st::historyRecordVoiceActive;
|
return &st::historyRecordVoiceActive;
|
||||||
} else if (_inRecord) {
|
} else if (_inRecord) {
|
||||||
return &st::historyRecordVoiceOver;
|
return &st::historyRecordVoiceOver;
|
||||||
|
@ -8729,19 +8716,19 @@ void HistoryWidget::drawRecordButton(Painter &p) {
|
||||||
return &st::historyRecordVoice;
|
return &st::historyRecordVoice;
|
||||||
};
|
};
|
||||||
fastIcon()->paintInCenter(p, _send->geometry());
|
fastIcon()->paintInCenter(p, _send->geometry());
|
||||||
if (down > 0. && down < 1.) {
|
if (recordActive > 0. && recordActive < 1.) {
|
||||||
p.setOpacity(down);
|
p.setOpacity(recordActive);
|
||||||
st::historyRecordVoiceActive.paintInCenter(p, _send->geometry());
|
st::historyRecordVoiceActive.paintInCenter(p, _send->geometry());
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::drawRecording(Painter &p) {
|
void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(st::historyRecordSignalColor);
|
p.setBrush(st::historyRecordSignalColor);
|
||||||
|
|
||||||
float64 delta = qMin(float64(a_recordingLevel.current()) / 0x4000, 1.);
|
auto delta = qMin(a_recordingLevel.current() / 0x4000, 1.);
|
||||||
int32 d = 2 * qRound(st::historyRecordSignalMin + (delta * (st::historyRecordSignalMax - st::historyRecordSignalMin)));
|
auto d = 2 * qRound(st::historyRecordSignalMin + (delta * (st::historyRecordSignalMax - st::historyRecordSignalMin)));
|
||||||
{
|
{
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
p.drawEllipse(_attachToggle->x() + (_attachEmoji->width() - d) / 2, _attachToggle->y() + (_attachToggle->height() - d) / 2, d, d);
|
p.drawEllipse(_attachToggle->x() + (_attachEmoji->width() - d) / 2, _attachToggle->y() + (_attachToggle->height() - d) / 2, d, d);
|
||||||
|
@ -8756,7 +8743,7 @@ void HistoryWidget::drawRecording(Painter &p) {
|
||||||
int32 left = _attachToggle->x() + _attachEmoji->width() + st::historyRecordFont->width(duration) + ((_send->width() - st::historyRecordVoice.width()) / 2);
|
int32 left = _attachToggle->x() + _attachEmoji->width() + st::historyRecordFont->width(duration) + ((_send->width() - st::historyRecordVoice.width()) / 2);
|
||||||
int32 right = width() - _send->width();
|
int32 right = width() - _send->width();
|
||||||
|
|
||||||
p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, a_recordCancelActive.current()));
|
p.setPen(anim::pen(st::historyRecordCancel, st::historyRecordCancelActive, 1. - recordActive));
|
||||||
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, lang(lng_record_cancel));
|
p.drawText(left + (right - left - _recordCancelWidth) / 2, _attachToggle->y() + st::historyRecordTextTop + st::historyRecordFont->ascent, lang(lng_record_cancel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8809,18 +8796,24 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
bool hasTopBar = !App::main()->topBar()->isHidden();
|
bool hasTopBar = !App::main()->topBar()->isHidden();
|
||||||
|
|
||||||
|
auto ms = getms();
|
||||||
|
auto progress = _a_show.current(ms, 1.);
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
int retina = cIntRetinaFactor();
|
auto retina = cIntRetinaFactor();
|
||||||
int inCacheTop = hasTopBar ? st::topBarHeight : 0;
|
auto inCacheTop = hasTopBar ? st::topBarHeight : 0;
|
||||||
if (a_coordOver.current() > 0) {
|
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
|
||||||
p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * retina, inCacheTop * retina, a_coordOver.current() * retina, height() * retina));
|
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
p.setOpacity(a_progress.current());
|
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
p.fillRect(0, 0, a_coordOver.current(), height(), st::slideFadeOutBg);
|
auto shadow = fromLeft ? (1. - progress) : progress;
|
||||||
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * retina, inCacheTop * retina, coordOver * retina, height() * retina));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
p.drawPixmap(QRect(a_coordOver.current(), 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, inCacheTop * retina, _cacheOver.width(), height() * retina));
|
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, inCacheTop * retina, _cacheOver.width(), height() * retina));
|
||||||
p.setOpacity(a_progress.current());
|
p.setOpacity(shadow);
|
||||||
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8854,8 +8847,9 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (!_field->isHidden() || _recording) {
|
if (!_field->isHidden() || _recording) {
|
||||||
drawField(p, r);
|
drawField(p, r);
|
||||||
if (_send->isHidden() && (!_inlineBotCancel || _inlineBotCancel->isHidden())) {
|
if (_send->isHidden() && (!_inlineBotCancel || _inlineBotCancel->isHidden())) {
|
||||||
drawRecordButton(p);
|
auto recordActive = _a_recordActive.current(ms, _inField ? 1. : 0.);
|
||||||
if (_recording) drawRecording(p);
|
drawRecordButton(p, recordActive, ms);
|
||||||
|
if (_recording) drawRecording(p, recordActive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_pinnedBar && !_pinnedBar->cancel->isHidden()) {
|
if (_pinnedBar && !_pinnedBar->cancel->isHidden()) {
|
||||||
|
|
|
@ -510,7 +510,7 @@ private:
|
||||||
ChildWidget<Ui::RoundButton> _cancel;
|
ChildWidget<Ui::RoundButton> _cancel;
|
||||||
PeerData *_offered = nullptr;
|
PeerData *_offered = nullptr;
|
||||||
|
|
||||||
anim::fvalue a_opacity;
|
anim::value a_opacity;
|
||||||
Animation _a_appearance;
|
Animation _a_appearance;
|
||||||
|
|
||||||
QRect _box;
|
QRect _box;
|
||||||
|
@ -613,8 +613,7 @@ public:
|
||||||
return peer() != nullptr;
|
return peer() != nullptr;
|
||||||
}
|
}
|
||||||
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms);
|
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms);
|
||||||
void step_show(float64 ms, bool timer);
|
void finishAnimation();
|
||||||
void animStop();
|
|
||||||
|
|
||||||
void doneShow();
|
void doneShow();
|
||||||
|
|
||||||
|
@ -650,7 +649,6 @@ public:
|
||||||
void updatePreview();
|
void updatePreview();
|
||||||
void previewCancel();
|
void previewCancel();
|
||||||
|
|
||||||
void step_record(float64 ms, bool timer);
|
|
||||||
void step_recording(float64 ms, bool timer);
|
void step_recording(float64 ms, bool timer);
|
||||||
void stopRecording(bool send);
|
void stopRecording(bool send);
|
||||||
|
|
||||||
|
@ -849,6 +847,8 @@ private slots:
|
||||||
void updateField();
|
void updateField();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void animationCallback();
|
||||||
|
void recordActiveCallback();
|
||||||
void chooseAttach();
|
void chooseAttach();
|
||||||
void notifyFileQueryUpdated(const FileDialog::QueryUpdate &update);
|
void notifyFileQueryUpdated(const FileDialog::QueryUpdate &update);
|
||||||
struct SendingFilesLists {
|
struct SendingFilesLists {
|
||||||
|
@ -931,8 +931,8 @@ private:
|
||||||
|
|
||||||
void drawField(Painter &p, const QRect &rect);
|
void drawField(Painter &p, const QRect &rect);
|
||||||
void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const;
|
void paintEditHeader(Painter &p, const QRect &rect, int left, int top) const;
|
||||||
void drawRecordButton(Painter &p);
|
void drawRecordButton(Painter &p, float64 recordActive, TimeMs ms);
|
||||||
void drawRecording(Painter &p);
|
void drawRecording(Painter &p, float64 recordActive);
|
||||||
void drawPinnedBar(Painter &p);
|
void drawPinnedBar(Painter &p);
|
||||||
|
|
||||||
void updateMouseTracking();
|
void updateMouseTracking();
|
||||||
|
@ -1122,18 +1122,18 @@ private:
|
||||||
ChildWidget<SilentToggle> _silent;
|
ChildWidget<SilentToggle> _silent;
|
||||||
bool _cmdStartShown = false;
|
bool _cmdStartShown = false;
|
||||||
ChildWidget<MessageField> _field;
|
ChildWidget<MessageField> _field;
|
||||||
Animation _a_record, _a_recording;
|
Animation _a_recording;
|
||||||
bool _recording = false;
|
bool _recording = false;
|
||||||
bool _inRecord = false;
|
bool _inRecord = false;
|
||||||
bool _inField = false;
|
bool _inField = false;
|
||||||
bool _inReplyEdit = false;
|
bool _inReplyEdit = false;
|
||||||
bool _inPinnedMsg = false;
|
bool _inPinnedMsg = false;
|
||||||
bool _inClickable = false;
|
bool _inClickable = false;
|
||||||
anim::ivalue a_recordingLevel = { 0, 0 };
|
anim::value a_recordingLevel;
|
||||||
int32 _recordingSamples = 0;
|
int _recordingSamples = 0;
|
||||||
anim::fvalue a_recordDown = { 0, 0 };
|
FloatAnimation _a_recordActive;
|
||||||
anim::fvalue a_recordCancelActive;
|
std_::unique_ptr<Ui::RippleAnimation> _recordRipple;
|
||||||
int32 _recordCancelWidth;
|
int _recordCancelWidth;
|
||||||
|
|
||||||
FileDialog::QueryId _attachFilesQueryId = 0;
|
FileDialog::QueryId _attachFilesQueryId = 0;
|
||||||
|
|
||||||
|
@ -1163,10 +1163,9 @@ private:
|
||||||
bool _titlePeerTextOnline = false;
|
bool _titlePeerTextOnline = false;
|
||||||
int _titlePeerTextWidth = 0;
|
int _titlePeerTextWidth = 0;
|
||||||
|
|
||||||
Animation _a_show;
|
FloatAnimation _a_show;
|
||||||
|
Window::SlideDirection _showDirection;
|
||||||
QPixmap _cacheUnder, _cacheOver;
|
QPixmap _cacheUnder, _cacheOver;
|
||||||
anim::ivalue a_coordUnder, a_coordOver;
|
|
||||||
anim::fvalue a_progress;
|
|
||||||
|
|
||||||
QTimer _scrollTimer;
|
QTimer _scrollTimer;
|
||||||
int32 _scrollDelta = 0;
|
int32 _scrollDelta = 0;
|
||||||
|
|
|
@ -786,7 +786,7 @@ void File::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||||
} else {
|
} else {
|
||||||
if (!_animation) {
|
if (!_animation) {
|
||||||
ensureAnimation();
|
ensureAnimation();
|
||||||
_animation->a_thumbOver = anim::fvalue(1, 1);
|
_animation->a_thumbOver = anim::value(1, 1);
|
||||||
}
|
}
|
||||||
_animation->a_thumbOver.start(0);
|
_animation->a_thumbOver.start(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,7 +267,7 @@ private:
|
||||||
, _a_thumbOver(std_::move(thumbOverCallbacks))
|
, _a_thumbOver(std_::move(thumbOverCallbacks))
|
||||||
, radial(std_::move(radialCallbacks)) {
|
, radial(std_::move(radialCallbacks)) {
|
||||||
}
|
}
|
||||||
anim::fvalue a_thumbOver;
|
anim::value a_thumbOver;
|
||||||
Animation _a_thumbOver;
|
Animation _a_thumbOver;
|
||||||
|
|
||||||
Ui::RadialAnimation radial;
|
Ui::RadialAnimation radial;
|
||||||
|
|
|
@ -21,6 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
using "basic.style";
|
using "basic.style";
|
||||||
using "ui/widgets/widgets.style";
|
using "ui/widgets/widgets.style";
|
||||||
|
|
||||||
|
countryRipple: defaultRippleAnimation;
|
||||||
|
|
||||||
introCoverHeight: 208px;
|
introCoverHeight: 208px;
|
||||||
introCoverTopBg: #0f89d0;
|
introCoverTopBg: #0f89d0;
|
||||||
introCoverBottomBg: #39b0f0;
|
introCoverBottomBg: #39b0f0;
|
||||||
|
@ -84,7 +86,7 @@ introStepHeight: 256px;
|
||||||
introStepHeightAdd: 30px;
|
introStepHeightAdd: 30px;
|
||||||
introStepHeightFull: 580px;
|
introStepHeightFull: 580px;
|
||||||
introSlideDuration: 200;
|
introSlideDuration: 200;
|
||||||
introCoverDuration: 200;
|
introCoverDuration: 300;
|
||||||
|
|
||||||
introNextButton: RoundButton(defaultActiveButton) {
|
introNextButton: RoundButton(defaultActiveButton) {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
|
|
@ -47,7 +47,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace Intro {
|
namespace Intro {
|
||||||
|
|
||||||
Widget::Widget(QWidget *parent) : TWidget(parent)
|
Widget::Widget(QWidget *parent) : TWidget(parent)
|
||||||
, _a_show(animation(this, &Widget::step_show))
|
|
||||||
, _back(this, new Ui::IconButton(this, st::introBackButton), base::lambda<void()>(), st::introSlideDuration)
|
, _back(this, new Ui::IconButton(this, st::introBackButton), base::lambda<void()>(), st::introSlideDuration)
|
||||||
, _settings(this, new Ui::RoundButton(this, lang(lng_menu_settings), st::defaultBoxButton), base::lambda<void()>(), st::introCoverDuration)
|
, _settings(this, new Ui::RoundButton(this, lang(lng_menu_settings), st::defaultBoxButton), base::lambda<void()>(), st::introCoverDuration)
|
||||||
, _next(this, QString(), st::introNextButton) {
|
, _next(this, QString(), st::introNextButton) {
|
||||||
|
@ -143,7 +142,7 @@ void Widget::historyMove(Direction direction) {
|
||||||
if (wasStep->hasCover() != getStep()->hasCover()) {
|
if (wasStep->hasCover() != getStep()->hasCover()) {
|
||||||
_nextTopFrom = wasStep->contentTop() + st::introStepHeight;
|
_nextTopFrom = wasStep->contentTop() + st::introStepHeight;
|
||||||
_controlsTopFrom = wasStep->hasCover() ? st::introCoverHeight : 0;
|
_controlsTopFrom = wasStep->hasCover() ? st::introCoverHeight : 0;
|
||||||
_coverShownAnimation.start([this] { updateControlsGeometry(); }, 0., 1., st::introCoverDuration, anim::easeOutCirc);
|
_coverShownAnimation.start([this] { updateControlsGeometry(); }, 0., 1., st::introCoverDuration, wasStep->hasCover() ? anim::linear : anim::easeOutCirc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (direction == Direction::Forward || direction == Direction::Replace) {
|
if (direction == Direction::Forward || direction == Direction::Replace) {
|
||||||
|
@ -302,45 +301,29 @@ void Widget::hideControls() {
|
||||||
_back->hideFast();
|
_back->hideFast();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::animShow(const QPixmap &bgAnimCache, bool back) {
|
void Widget::showAnimated(const QPixmap &bgAnimCache, bool back) {
|
||||||
if (App::app()) App::app()->mtpPause();
|
_showBack = back;
|
||||||
|
|
||||||
(back ? _cacheOver : _cacheUnder) = bgAnimCache;
|
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
|
||||||
|
|
||||||
_a_show.stop();
|
_a_show.finish();
|
||||||
showControls();
|
showControls();
|
||||||
(back ? _cacheUnder : _cacheOver) = myGrab(this);
|
(_showBack ? _cacheUnder : _cacheOver) = myGrab(this);
|
||||||
hideControls();
|
hideControls();
|
||||||
|
|
||||||
a_coordUnder = back ? anim::ivalue(-st::slideShift, 0) : anim::ivalue(0, -st::slideShift);
|
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
|
||||||
a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0);
|
|
||||||
a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1);
|
|
||||||
_a_show.start();
|
|
||||||
|
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::step_show(float64 ms, bool timer) {
|
void Widget::animationCallback() {
|
||||||
float64 dt = ms / st::slideDuration;
|
update();
|
||||||
if (dt >= 1) {
|
if (!_a_show.animating()) {
|
||||||
_a_show.stop();
|
|
||||||
|
|
||||||
a_coordUnder.finish();
|
|
||||||
a_coordOver.finish();
|
|
||||||
a_shadow.finish();
|
|
||||||
|
|
||||||
_cacheUnder = _cacheOver = QPixmap();
|
_cacheUnder = _cacheOver = QPixmap();
|
||||||
|
|
||||||
showControls();
|
showControls();
|
||||||
getStep()->activate();
|
getStep()->activate();
|
||||||
|
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
|
||||||
} else {
|
|
||||||
a_coordUnder.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_coordOver.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_shadow.update(dt, Window::SlideAnimation::transition());
|
|
||||||
}
|
}
|
||||||
if (timer) update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::paintEvent(QPaintEvent *e) {
|
void Widget::paintEvent(QPaintEvent *e) {
|
||||||
|
@ -356,16 +339,20 @@ void Widget::paintEvent(QPaintEvent *e) {
|
||||||
p.setClipRect(e->rect());
|
p.setClipRect(e->rect());
|
||||||
}
|
}
|
||||||
p.fillRect(e->rect(), st::windowBg);
|
p.fillRect(e->rect(), st::windowBg);
|
||||||
|
auto progress = _a_show.current(getms(), 1.);
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
if (a_coordOver.current() > 0) {
|
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * cRetinaFactor(), 0, a_coordOver.current() * cRetinaFactor(), height() * cRetinaFactor()));
|
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
p.setOpacity(a_shadow.current());
|
auto shadow = _showBack ? (1. - progress) : progress;
|
||||||
p.fillRect(0, 0, a_coordOver.current(), height(), st::slideFadeOutBg);
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
|
p.drawPixmap(coordOver, 0, _cacheOver);
|
||||||
p.setOpacity(a_shadow.current());
|
p.setOpacity(shadow);
|
||||||
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -491,7 +478,6 @@ void Widget::Step::showFinished() {
|
||||||
_slideAnimation.reset();
|
_slideAnimation.reset();
|
||||||
prepareCoverMask();
|
prepareCoverMask();
|
||||||
activate();
|
activate();
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Widget::Step::paintAnimated(Painter &p, QRect clip) {
|
bool Widget::Step::paintAnimated(Painter &p, QRect clip) {
|
||||||
|
@ -519,11 +505,11 @@ bool Widget::Step::paintAnimated(Painter &p, QRect clip) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto easeOut = anim::easeOutCirc(1., dt);
|
auto progress = (hasCover() ? anim::easeOutCirc(1., dt) : anim::linear(1., dt));
|
||||||
auto arrivingAlpha = easeOut;
|
auto arrivingAlpha = progress;
|
||||||
auto departingAlpha = 1. - easeOut;
|
auto departingAlpha = 1. - progress;
|
||||||
auto showCoverMethod = easeOut;
|
auto showCoverMethod = progress;
|
||||||
auto hideCoverMethod = easeOut;
|
auto hideCoverMethod = progress;
|
||||||
auto coverTop = (hasCover() ? anim::interpolate(-st::introCoverHeight, 0, showCoverMethod) : anim::interpolate(0, -st::introCoverHeight, hideCoverMethod));
|
auto coverTop = (hasCover() ? anim::interpolate(-st::introCoverHeight, 0, showCoverMethod) : anim::interpolate(0, -st::introCoverHeight, hideCoverMethod));
|
||||||
|
|
||||||
paintCover(p, coverTop);
|
paintCover(p, coverTop);
|
||||||
|
@ -718,7 +704,6 @@ QPixmap Widget::Step::prepareSlideAnimation() {
|
||||||
|
|
||||||
void Widget::Step::showAnimated(Direction direction) {
|
void Widget::Step::showAnimated(Direction direction) {
|
||||||
show();
|
show();
|
||||||
if (App::app()) App::app()->mtpPause();
|
|
||||||
hideChildren();
|
hideChildren();
|
||||||
if (_slideAnimation) {
|
if (_slideAnimation) {
|
||||||
auto slideLeft = (direction == Direction::Back);
|
auto slideLeft = (direction == Direction::Back);
|
||||||
|
|
|
@ -39,7 +39,8 @@ class Widget : public TWidget, public RPCSender {
|
||||||
public:
|
public:
|
||||||
Widget(QWidget *parent);
|
Widget(QWidget *parent);
|
||||||
|
|
||||||
void animShow(const QPixmap &bgAnimCache, bool back = false);
|
void showAnimated(const QPixmap &bgAnimCache, bool back = false);
|
||||||
|
|
||||||
void setInnerFocus();
|
void setInnerFocus();
|
||||||
|
|
||||||
~Widget();
|
~Widget();
|
||||||
|
@ -205,7 +206,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void step_show(float64 ms, bool timer);
|
void animationCallback();
|
||||||
|
|
||||||
void changeLanguage(int32 languageId);
|
void changeLanguage(int32 languageId);
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
|
@ -225,10 +226,9 @@ private:
|
||||||
void resetDone(const MTPBool &result);
|
void resetDone(const MTPBool &result);
|
||||||
bool resetFail(const RPCError &error);
|
bool resetFail(const RPCError &error);
|
||||||
|
|
||||||
Animation _a_show;
|
FloatAnimation _a_show;
|
||||||
|
bool _showBack = false;
|
||||||
QPixmap _cacheUnder, _cacheOver;
|
QPixmap _cacheUnder, _cacheOver;
|
||||||
anim::ivalue a_coordUnder, a_coordOver;
|
|
||||||
anim::fvalue a_shadow;
|
|
||||||
|
|
||||||
QVector<Step*> _stepHistory;
|
QVector<Step*> _stepHistory;
|
||||||
Step *getStep(int skip = 0) {
|
Step *getStep(int skip = 0) {
|
||||||
|
|
|
@ -453,9 +453,6 @@ void LayerStackWidget::prepareForAnimation() {
|
||||||
if (auto layer = currentLayer()) {
|
if (auto layer = currentLayer()) {
|
||||||
layer->hide();
|
layer->hide();
|
||||||
}
|
}
|
||||||
if (auto app = App::app()) {
|
|
||||||
app->mtpPause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerStackWidget::animationDone() {
|
void LayerStackWidget::animationDone() {
|
||||||
|
@ -477,9 +474,6 @@ void LayerStackWidget::animationDone() {
|
||||||
} else {
|
} else {
|
||||||
showFinished();
|
showFinished();
|
||||||
}
|
}
|
||||||
if (auto app = App::app()) {
|
|
||||||
app->mtpUnpause();
|
|
||||||
}
|
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
setAttribute(Qt::WA_OpaquePaintEvent, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,8 +607,6 @@ LayerStackWidget::~LayerStackWidget() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MediaPreviewWidget::MediaPreviewWidget(QWidget *parent) : TWidget(parent)
|
MediaPreviewWidget::MediaPreviewWidget(QWidget *parent) : TWidget(parent)
|
||||||
, a_shown(0, 0)
|
|
||||||
, _a_shown(animation(this, &MediaPreviewWidget::step_shown))
|
|
||||||
, _emojiSize(EmojiSizes[EIndex + 1] / cIntRetinaFactor()) {
|
, _emojiSize(EmojiSizes[EIndex + 1] / cIntRetinaFactor()) {
|
||||||
setAttribute(Qt::WA_TransparentForMouseEvents);
|
setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||||
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
subscribe(FileDownload::ImageLoaded(), [this] { update(); });
|
||||||
|
@ -626,8 +618,13 @@ void MediaPreviewWidget::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
auto image = currentImage();
|
auto image = currentImage();
|
||||||
int w = image.width() / cIntRetinaFactor(), h = image.height() / cIntRetinaFactor();
|
int w = image.width() / cIntRetinaFactor(), h = image.height() / cIntRetinaFactor();
|
||||||
if (_a_shown.animating()) {
|
auto shown = _a_shown.current(getms(), _hiding ? 0. : 1.);
|
||||||
float64 shown = a_shown.current();
|
if (!_a_shown.animating()) {
|
||||||
|
if (_hiding) {
|
||||||
|
hide();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
p.setOpacity(shown);
|
p.setOpacity(shown);
|
||||||
// w = qMax(qRound(w * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(w % 2), 1);
|
// w = qMax(qRound(w * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(w % 2), 1);
|
||||||
// h = qMax(qRound(h * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(h % 2), 1);
|
// h = qMax(qRound(h * (st::stickerPreviewMin + ((1. - st::stickerPreviewMin) * shown)) / 2.) * 2 + int(h % 2), 1);
|
||||||
|
@ -650,18 +647,6 @@ void MediaPreviewWidget::resizeEvent(QResizeEvent *e) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaPreviewWidget::step_shown(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / st::stickerPreviewDuration;
|
|
||||||
if (dt >= 1) {
|
|
||||||
_a_shown.stop();
|
|
||||||
a_shown.finish();
|
|
||||||
if (a_shown.current() < 0.5) hide();
|
|
||||||
} else {
|
|
||||||
a_shown.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MediaPreviewWidget::showPreview(DocumentData *document) {
|
void MediaPreviewWidget::showPreview(DocumentData *document) {
|
||||||
if (!document || (!document->isAnimation() && !document->sticker())) {
|
if (!document || (!document->isAnimation() && !document->sticker())) {
|
||||||
hidePreview();
|
hidePreview();
|
||||||
|
@ -692,8 +677,8 @@ void MediaPreviewWidget::startShow() {
|
||||||
_cache = QPixmap();
|
_cache = QPixmap();
|
||||||
if (isHidden() || _a_shown.animating()) {
|
if (isHidden() || _a_shown.animating()) {
|
||||||
if (isHidden()) show();
|
if (isHidden()) show();
|
||||||
a_shown.start(1);
|
_hiding = false;
|
||||||
_a_shown.start();
|
_a_shown.start([this] { update(); }, 0., 1., st::stickerPreviewDuration);
|
||||||
} else {
|
} else {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -704,8 +689,8 @@ void MediaPreviewWidget::hidePreview() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_gif) _cache = currentImage();
|
if (_gif) _cache = currentImage();
|
||||||
a_shown.start(0);
|
_hiding = true;
|
||||||
_a_shown.start();
|
_a_shown.start([this] { update(); }, 1., 0., st::stickerPreviewDuration);
|
||||||
_photo = nullptr;
|
_photo = nullptr;
|
||||||
_document = nullptr;
|
_document = nullptr;
|
||||||
resetGifAndCache();
|
resetGifAndCache();
|
||||||
|
|
|
@ -144,8 +144,6 @@ public:
|
||||||
void paintEvent(QPaintEvent *e);
|
void paintEvent(QPaintEvent *e);
|
||||||
void resizeEvent(QResizeEvent *e);
|
void resizeEvent(QResizeEvent *e);
|
||||||
|
|
||||||
void step_shown(float64 ms, bool timer);
|
|
||||||
|
|
||||||
void showPreview(DocumentData *document);
|
void showPreview(DocumentData *document);
|
||||||
void showPreview(PhotoData *photo);
|
void showPreview(PhotoData *photo);
|
||||||
void hidePreview();
|
void hidePreview();
|
||||||
|
@ -159,8 +157,8 @@ private:
|
||||||
void fillEmojiString();
|
void fillEmojiString();
|
||||||
void resetGifAndCache();
|
void resetGifAndCache();
|
||||||
|
|
||||||
anim::fvalue a_shown;
|
FloatAnimation _a_shown;
|
||||||
Animation _a_shown;
|
bool _hiding = false;
|
||||||
DocumentData *_document = nullptr;
|
DocumentData *_document = nullptr;
|
||||||
PhotoData *_photo = nullptr;
|
PhotoData *_photo = nullptr;
|
||||||
Media::Clip::ReaderPointer _gif;
|
Media::Clip::ReaderPointer _gif;
|
||||||
|
|
|
@ -69,7 +69,6 @@ StackItemSection::~StackItemSection() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MainWidget::MainWidget(QWidget *parent) : TWidget(parent)
|
MainWidget::MainWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _a_show(animation(this, &MainWidget::step_show))
|
|
||||||
, _dialogsWidth(st::dialogsWidthMin)
|
, _dialogsWidth(st::dialogsWidthMin)
|
||||||
, _sideShadow(this, st::shadowColor)
|
, _sideShadow(this, st::shadowColor)
|
||||||
, _dialogs(this)
|
, _dialogs(this)
|
||||||
|
@ -2231,7 +2230,7 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::SectionSlideParams animationParams;
|
Window::SectionSlideParams animationParams;
|
||||||
if (!_a_show.animating() && ((_history->isHidden() && (_wideSection || _overview)) || (Adaptive::OneColumn() && (_history->isHidden() || !peerId)) || back || (way == Ui::ShowWay::Forward))) {
|
if (!_a_show.animating() && !App::passcoded() && ((_history->isHidden() && (_wideSection || _overview)) || (Adaptive::OneColumn() && (_history->isHidden() || !peerId)) || back || (way == Ui::ShowWay::Forward))) {
|
||||||
animationParams = prepareHistoryAnimation(peerId);
|
animationParams = prepareHistoryAnimation(peerId);
|
||||||
}
|
}
|
||||||
if (_history->peer() && _history->peer()->id != peerId && way != Ui::ShowWay::Forward) {
|
if (_history->peer() && _history->peer()->id != peerId && way != Ui::ShowWay::Forward) {
|
||||||
|
@ -2258,7 +2257,7 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, Ui::Show
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
_history->hide();
|
_history->hide();
|
||||||
if (!_a_show.animating()) {
|
if (!_a_show.animating()) {
|
||||||
if (!animationParams.oldContentCache.isNull() && !App::passcoded()) {
|
if (!animationParams.oldContentCache.isNull()) {
|
||||||
_dialogs->showAnimated(back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight, animationParams);
|
_dialogs->showAnimated(back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight, animationParams);
|
||||||
} else {
|
} else {
|
||||||
_dialogs->showFast();
|
_dialogs->showFast();
|
||||||
|
@ -2408,7 +2407,7 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
|
||||||
} else {
|
} else {
|
||||||
_overview->fastShow();
|
_overview->fastShow();
|
||||||
}
|
}
|
||||||
_history->animStop();
|
_history->finishAnimation();
|
||||||
if (back) {
|
if (back) {
|
||||||
clearBotStartToken(_history->peer());
|
clearBotStartToken(_history->peer());
|
||||||
}
|
}
|
||||||
|
@ -2537,7 +2536,7 @@ void MainWidget::showWideSectionAnimated(const Window::SectionMemento *memento,
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
auto direction = back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight;
|
auto direction = back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight;
|
||||||
_wideSection->showAnimated(direction, animationParams);
|
_wideSection->showAnimated(direction, animationParams);
|
||||||
_history->animStop();
|
_history->finishAnimation();
|
||||||
_history->showHistory(0, 0);
|
_history->showHistory(0, 0);
|
||||||
_history->hide();
|
_history->hide();
|
||||||
if (Adaptive::OneColumn()) _dialogs->hide();
|
if (Adaptive::OneColumn()) _dialogs->hide();
|
||||||
|
@ -2651,7 +2650,7 @@ QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶m
|
||||||
|
|
||||||
void MainWidget::dlgUpdated() {
|
void MainWidget::dlgUpdated() {
|
||||||
if (_peerInStack) {
|
if (_peerInStack) {
|
||||||
_dialogs->dlgUpdated(App::history(_peerInStack->id), _msgIdInStack);
|
_dialogs->dlgUpdated(_peerInStack, _msgIdInStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2661,12 +2660,12 @@ void MainWidget::dlgUpdated(Dialogs::Mode list, Dialogs::Row *row) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::dlgUpdated(History *row, MsgId msgId) {
|
void MainWidget::dlgUpdated(PeerData *peer, MsgId msgId) {
|
||||||
if (!row) return;
|
if (!peer) return;
|
||||||
if (msgId < 0 && -msgId < ServerMaxMsgId && row->peer->migrateFrom()) {
|
if (msgId < 0 && -msgId < ServerMaxMsgId && peer->migrateFrom()) {
|
||||||
_dialogs->dlgUpdated(App::history(row->peer->migrateFrom()->id), -msgId);
|
_dialogs->dlgUpdated(peer->migrateFrom(), -msgId);
|
||||||
} else {
|
} else {
|
||||||
_dialogs->dlgUpdated(row, msgId);
|
_dialogs->dlgUpdated(peer, msgId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2719,66 +2718,49 @@ void MainWidget::historyCleared(History *history) {
|
||||||
_history->historyCleared(history);
|
_history->historyCleared(history);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::animShow(const QPixmap &bgAnimCache, bool back) {
|
void MainWidget::showAnimated(const QPixmap &bgAnimCache, bool back) {
|
||||||
if (App::app()) App::app()->mtpPause();
|
_showBack = back;
|
||||||
|
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
|
||||||
|
|
||||||
(back ? _cacheOver : _cacheUnder) = bgAnimCache;
|
_a_show.finish();
|
||||||
|
|
||||||
_a_show.stop();
|
|
||||||
|
|
||||||
showAll();
|
showAll();
|
||||||
(back ? _cacheUnder : _cacheOver) = myGrab(this);
|
(_showBack ? _cacheUnder : _cacheOver) = myGrab(this);
|
||||||
hideAll();
|
hideAll();
|
||||||
|
|
||||||
a_coordUnder = back ? anim::ivalue(-st::slideShift, 0) : anim::ivalue(0, -st::slideShift);
|
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
|
||||||
a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0);
|
|
||||||
a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1);
|
|
||||||
_a_show.start();
|
|
||||||
|
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::step_show(float64 ms, bool timer) {
|
void MainWidget::animationCallback() {
|
||||||
float64 dt = ms / st::slideDuration;
|
update();
|
||||||
if (dt >= 1) {
|
if (!_a_show.animating()) {
|
||||||
_a_show.stop();
|
|
||||||
|
|
||||||
a_coordUnder.finish();
|
|
||||||
a_coordOver.finish();
|
|
||||||
a_shadow.finish();
|
|
||||||
|
|
||||||
_cacheUnder = _cacheOver = QPixmap();
|
_cacheUnder = _cacheOver = QPixmap();
|
||||||
|
|
||||||
showAll();
|
showAll();
|
||||||
activate();
|
activate();
|
||||||
|
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
|
||||||
} else {
|
|
||||||
a_coordUnder.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_coordOver.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_shadow.update(dt, Window::SlideAnimation::transition());
|
|
||||||
}
|
}
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWidget::animStop_show() {
|
|
||||||
_a_show.stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::paintEvent(QPaintEvent *e) {
|
void MainWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (_background) checkChatBackground();
|
if (_background) checkChatBackground();
|
||||||
|
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
auto progress = _a_show.current(getms(), 1.);
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
if (a_coordOver.current() > 0) {
|
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * cRetinaFactor(), 0, a_coordOver.current() * cRetinaFactor(), height() * cRetinaFactor()));
|
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
p.setOpacity(a_shadow.current());
|
auto shadow = _showBack ? (1. - progress) : progress;
|
||||||
p.fillRect(0, 0, a_coordOver.current(), height(), st::slideFadeOutBg);
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
|
p.drawPixmap(coordOver, 0, _cacheOver);
|
||||||
p.setOpacity(a_shadow.current());
|
p.setOpacity(shadow);
|
||||||
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3048,7 +3030,7 @@ void MainWidget::onHistoryShown(History *history, MsgId atMsgId) {
|
||||||
_topBar->hide();
|
_topBar->hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
dlgUpdated(history, atMsgId);
|
dlgUpdated(history ? history->peer : nullptr, atMsgId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWidget::searchInPeer(PeerData *peer) {
|
void MainWidget::searchInPeer(PeerData *peer) {
|
||||||
|
|
|
@ -152,9 +152,7 @@ public:
|
||||||
|
|
||||||
int contentScrollAddToY() const;
|
int contentScrollAddToY() const;
|
||||||
|
|
||||||
void animShow(const QPixmap &bgAnimCache, bool back = false);
|
void showAnimated(const QPixmap &bgAnimCache, bool back = false);
|
||||||
void step_show(float64 ms, bool timer);
|
|
||||||
void animStop_show();
|
|
||||||
|
|
||||||
void start(const MTPUser &user);
|
void start(const MTPUser &user);
|
||||||
|
|
||||||
|
@ -178,7 +176,7 @@ public:
|
||||||
void removeDialog(History *history);
|
void removeDialog(History *history);
|
||||||
void dlgUpdated();
|
void dlgUpdated();
|
||||||
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
void dlgUpdated(Dialogs::Mode list, Dialogs::Row *row);
|
||||||
void dlgUpdated(History *row, MsgId msgId);
|
void dlgUpdated(PeerData *peer, MsgId msgId);
|
||||||
|
|
||||||
void windowShown();
|
void windowShown();
|
||||||
|
|
||||||
|
@ -483,6 +481,7 @@ protected:
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
void keyPressEvent(QKeyEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void animationCallback();
|
||||||
void updateAdaptiveLayout();
|
void updateAdaptiveLayout();
|
||||||
void handleAudioUpdate(const AudioMsgId &audioId);
|
void handleAudioUpdate(const AudioMsgId &audioId);
|
||||||
void updateMediaPlayerPosition();
|
void updateMediaPlayerPosition();
|
||||||
|
@ -587,10 +586,9 @@ private:
|
||||||
base::Observable<PeerData*> _searchInPeerChanged;
|
base::Observable<PeerData*> _searchInPeerChanged;
|
||||||
base::Observable<PeerData*> _historyPeerChanged;
|
base::Observable<PeerData*> _historyPeerChanged;
|
||||||
|
|
||||||
Animation _a_show;
|
FloatAnimation _a_show;
|
||||||
|
bool _showBack = false;
|
||||||
QPixmap _cacheUnder, _cacheOver;
|
QPixmap _cacheUnder, _cacheOver;
|
||||||
anim::ivalue a_coordUnder, a_coordOver;
|
|
||||||
anim::fvalue a_shadow;
|
|
||||||
|
|
||||||
int _dialogsWidth;
|
int _dialogsWidth;
|
||||||
|
|
||||||
|
|
|
@ -241,9 +241,9 @@ void MainWindow::clearPasscode() {
|
||||||
|
|
||||||
_passcode.destroy();
|
_passcode.destroy();
|
||||||
if (_intro) {
|
if (_intro) {
|
||||||
_intro->animShow(bg, true);
|
_intro->showAnimated(bg, true);
|
||||||
} else {
|
} else {
|
||||||
_main->animShow(bg, true);
|
_main->showAnimated(bg, true);
|
||||||
}
|
}
|
||||||
notifyUpdateAll();
|
notifyUpdateAll();
|
||||||
updateGlobalMenu();
|
updateGlobalMenu();
|
||||||
|
@ -265,7 +265,7 @@ void MainWindow::setupPasscode() {
|
||||||
}
|
}
|
||||||
if (_intro) _intro->hide();
|
if (_intro) _intro->hide();
|
||||||
if (animated) {
|
if (animated) {
|
||||||
_passcode->animShow(bg);
|
_passcode->showAnimated(bg);
|
||||||
} else {
|
} else {
|
||||||
setInnerFocus();
|
setInnerFocus();
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ void MainWindow::setupIntro() {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
_intro->animShow(bg);
|
_intro->showAnimated(bg);
|
||||||
} else {
|
} else {
|
||||||
setInnerFocus();
|
setInnerFocus();
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ void MainWindow::setupMain(const MTPUser *self) {
|
||||||
updateControlsGeometry();
|
updateControlsGeometry();
|
||||||
|
|
||||||
if (animated) {
|
if (animated) {
|
||||||
_main->animShow(bg);
|
_main->showAnimated(bg);
|
||||||
} else {
|
} else {
|
||||||
_main->activate();
|
_main->activate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -991,7 +991,7 @@ void AudioPlayerFader::onTimer() {
|
||||||
float64 wasAudio = suppressAllGain;
|
float64 wasAudio = suppressAllGain;
|
||||||
if (ms >= _suppressAllStart + notifyLengthMs || ms < _suppressAllStart) {
|
if (ms >= _suppressAllStart + notifyLengthMs || ms < _suppressAllStart) {
|
||||||
_suppressAll = _suppressAllAnim = false;
|
_suppressAll = _suppressAllAnim = false;
|
||||||
_suppressAllGain = anim::fvalue(1., 1.);
|
_suppressAllGain = anim::value(1., 1.);
|
||||||
} else if (ms > _suppressAllStart + notifyLengthMs - AudioFadeDuration) {
|
} else if (ms > _suppressAllStart + notifyLengthMs - AudioFadeDuration) {
|
||||||
if (_suppressAllGain.to() != 1.) _suppressAllGain.start(1.);
|
if (_suppressAllGain.to() != 1.) _suppressAllGain.start(1.);
|
||||||
_suppressAllGain.update(1. - ((_suppressAllStart + notifyLengthMs - ms) / float64(AudioFadeDuration)), anim::linear);
|
_suppressAllGain.update(1. - ((_suppressAllStart + notifyLengthMs - ms) / float64(AudioFadeDuration)), anim::linear);
|
||||||
|
|
|
@ -257,7 +257,7 @@ private:
|
||||||
bool _suppressSong = false;
|
bool _suppressSong = false;
|
||||||
bool _suppressSongAnim = false;
|
bool _suppressSongAnim = false;
|
||||||
bool _songVolumeChanged, _videoVolumeChanged;
|
bool _songVolumeChanged, _videoVolumeChanged;
|
||||||
anim::fvalue _suppressAllGain, _suppressSongGain;
|
anim::value _suppressAllGain, _suppressSongGain;
|
||||||
TimeMs _suppressAllStart = 0;
|
TimeMs _suppressAllStart = 0;
|
||||||
TimeMs _suppressSongStart = 0;
|
TimeMs _suppressSongStart = 0;
|
||||||
|
|
||||||
|
|
|
@ -23,17 +23,7 @@ using "basic.style";
|
||||||
using "ui/widgets/widgets.style";
|
using "ui/widgets/widgets.style";
|
||||||
using "overview/overview.style";
|
using "overview/overview.style";
|
||||||
|
|
||||||
MediaPlayerButton {
|
mediaPlayerBg: windowBg;
|
||||||
playPosition: point;
|
|
||||||
playOuter: size;
|
|
||||||
pausePosition: point;
|
|
||||||
pauseOuter: size;
|
|
||||||
pauseStroke: pixels;
|
|
||||||
cancelPosition: point;
|
|
||||||
cancelOuter: size;
|
|
||||||
cancelStroke: pixels;
|
|
||||||
}
|
|
||||||
|
|
||||||
mediaPlayerActiveFg: windowBgActive;
|
mediaPlayerActiveFg: windowBgActive;
|
||||||
mediaPlayerInactiveFg: #dfebf2;
|
mediaPlayerInactiveFg: #dfebf2;
|
||||||
|
|
||||||
|
@ -46,6 +36,12 @@ mediaPlayerButton: MediaPlayerButton {
|
||||||
cancelPosition: point(1px, 1px);
|
cancelPosition: point(1px, 1px);
|
||||||
cancelOuter: size(15px, 15px);
|
cancelOuter: size(15px, 15px);
|
||||||
cancelStroke: 3px;
|
cancelStroke: 3px;
|
||||||
|
|
||||||
|
rippleAreaPosition: point(0px, 5px);
|
||||||
|
rippleAreaSize: 25px;
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: lightButtonBgOver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mediaPlayerButtonSize: size(25px, 30px);
|
mediaPlayerButtonSize: size(25px, 30px);
|
||||||
|
|
||||||
|
@ -76,10 +72,20 @@ mediaPlayerRepeatButton: IconButton {
|
||||||
{ "player_repeat", mediaPlayerActiveFg, point(9px, 11px) }
|
{ "player_repeat", mediaPlayerActiveFg, point(9px, 11px) }
|
||||||
};
|
};
|
||||||
iconPosition: point(0px, 0px);
|
iconPosition: point(0px, 0px);
|
||||||
|
|
||||||
|
rippleAreaPosition: point(3px, 5px);
|
||||||
|
rippleAreaSize: 25px;
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: lightButtonBgOver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mediaPlayerRepeatDisabledIcon: icon {
|
mediaPlayerRepeatDisabledIcon: icon {
|
||||||
{ "player_repeat", #c8c8c8, point(9px, 11px)}
|
{ "player_repeat", menuIconFg, point(9px, 11px)}
|
||||||
};
|
};
|
||||||
|
mediaPlayerRepeatDisabledIconOver: icon {
|
||||||
|
{ "player_repeat", menuIconFgOver, point(9px, 11px)}
|
||||||
|
};
|
||||||
|
mediaPlayerRepeatDisabledRippleBg: windowBgOver;
|
||||||
mediaPlayerRepeatInactiveIcon: icon {
|
mediaPlayerRepeatInactiveIcon: icon {
|
||||||
{ "player_repeat", mediaPlayerInactiveFg, point(9px, 11px)}
|
{ "player_repeat", mediaPlayerInactiveFg, point(9px, 11px)}
|
||||||
};
|
};
|
||||||
|
@ -102,6 +108,12 @@ mediaPlayerVolumeToggle: IconButton {
|
||||||
|
|
||||||
icon: mediaPlayerVolumeIcon0;
|
icon: mediaPlayerVolumeIcon0;
|
||||||
iconPosition: point(8px, 11px);
|
iconPosition: point(8px, 11px);
|
||||||
|
|
||||||
|
rippleAreaPosition: point(3px, 5px);
|
||||||
|
rippleAreaSize: 25px;
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: lightButtonBgOver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mediaPlayerVolumeMargin: 10px;
|
mediaPlayerVolumeMargin: 10px;
|
||||||
mediaPlayerVolumeSize: size(27px, 100px);
|
mediaPlayerVolumeSize: size(27px, 100px);
|
||||||
|
@ -117,6 +129,8 @@ mediaPlayerNextButton: IconButton(mediaPlayerRepeatButton) {
|
||||||
icon: icon {
|
icon: icon {
|
||||||
{ "player_next", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
{ "player_next", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
rippleAreaPosition: point(0px, 5px);
|
||||||
}
|
}
|
||||||
mediaPlayerNextDisabledIcon: icon {
|
mediaPlayerNextDisabledIcon: icon {
|
||||||
{ "player_next", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
{ "player_next", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
||||||
|
@ -125,13 +139,20 @@ mediaPlayerPreviousButton: IconButton(mediaPlayerNextButton) {
|
||||||
icon: icon {
|
icon: icon {
|
||||||
{ "player_next-flip_horizontal", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
{ "player_next-flip_horizontal", mediaPlayerActiveFg, mediaPlayerSkipIconPosition },
|
||||||
};
|
};
|
||||||
|
rippleAreaPosition: point(1px, 5px);
|
||||||
}
|
}
|
||||||
mediaPlayerPreviousDisabledIcon: icon {
|
mediaPlayerPreviousDisabledIcon: icon {
|
||||||
{ "player_next-flip_horizontal", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
{ "player_next-flip_horizontal", mediaPlayerInactiveFg, mediaPlayerSkipIconPosition },
|
||||||
};
|
};
|
||||||
mediaPlayerClose: IconButton(mediaPlayerRepeatButton) {
|
mediaPlayerClose: IconButton(mediaPlayerRepeatButton) {
|
||||||
width: 37px;
|
width: 37px;
|
||||||
icon: icon {{ "player_close", #c8c8c8, point(10px, 12px) }};
|
icon: icon {{ "player_close", menuIconFg, point(10px, 12px) }};
|
||||||
|
iconOver: icon {{ "player_close", menuIconFgOver, point(10px, 12px) }};
|
||||||
|
|
||||||
|
rippleAreaPosition: point(3px, 5px);
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: windowBgOver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mediaPlayerPlayback: FilledSlider {
|
mediaPlayerPlayback: FilledSlider {
|
||||||
fullWidth: 6px;
|
fullWidth: 6px;
|
||||||
|
@ -165,7 +186,8 @@ mediaPlayerCoverHeight: 102px;
|
||||||
mediaPlayerPanelClose: IconButton(mediaPlayerClose) {
|
mediaPlayerPanelClose: IconButton(mediaPlayerClose) {
|
||||||
width: 43px;
|
width: 43px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
icon: icon {{ "player_close", #c8c8c8, point(16px, 14px) }};
|
icon: icon {{ "player_close", menuIconFg, point(16px, 14px) }};
|
||||||
|
iconOver: icon {{ "player_close", menuIconFgOver, point(16px, 14px) }};
|
||||||
}
|
}
|
||||||
|
|
||||||
mediaPlayerPanelNextButton: IconButton(mediaPlayerRepeatButton) {
|
mediaPlayerPanelNextButton: IconButton(mediaPlayerRepeatButton) {
|
||||||
|
|
|
@ -21,6 +21,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "media/player/media_player_button.h"
|
#include "media/player/media_player_button.h"
|
||||||
|
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
namespace Player {
|
namespace Player {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
@ -234,7 +234,7 @@ void CoverWidget::updateLabelPositions() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverWidget::updateRepeatTrackIcon() {
|
void CoverWidget::updateRepeatTrackIcon() {
|
||||||
_repeatTrack->setIcon(instance()->repeatEnabled() ? nullptr : &st::mediaPlayerRepeatInactiveIcon);
|
_repeatTrack->setIconOverride(instance()->repeatEnabled() ? nullptr : &st::mediaPlayerRepeatInactiveIcon);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CoverWidget::handleSongUpdate(const UpdatedEvent &e) {
|
void CoverWidget::handleSongUpdate(const UpdatedEvent &e) {
|
||||||
|
@ -338,9 +338,9 @@ void CoverWidget::handlePlaylistUpdate() {
|
||||||
createPrevNextButtons();
|
createPrevNextButtons();
|
||||||
auto previousEnabled = (index > 0);
|
auto previousEnabled = (index > 0);
|
||||||
auto nextEnabled = (index + 1 < playlist.size());
|
auto nextEnabled = (index + 1 < playlist.size());
|
||||||
_previousTrack->setIcon(previousEnabled ? nullptr : &st::mediaPlayerPanelPreviousDisabledIcon);
|
_previousTrack->setIconOverride(previousEnabled ? nullptr : &st::mediaPlayerPanelPreviousDisabledIcon);
|
||||||
_previousTrack->setCursor(previousEnabled ? style::cur_pointer : style::cur_default);
|
_previousTrack->setCursor(previousEnabled ? style::cur_pointer : style::cur_default);
|
||||||
_nextTrack->setIcon(nextEnabled ? nullptr : &st::mediaPlayerPanelNextDisabledIcon);
|
_nextTrack->setIconOverride(nextEnabled ? nullptr : &st::mediaPlayerPanelNextDisabledIcon);
|
||||||
_nextTrack->setCursor(nextEnabled ? style::cur_pointer : style::cur_default);
|
_nextTrack->setCursor(nextEnabled ? style::cur_pointer : style::cur_default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -386,7 +386,7 @@ void CoverWidget::updateVolumeToggleIcon() {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
_volumeToggle->setIcon(icon());
|
_volumeToggle->setIconOverride(icon());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Player
|
} // namespace Player
|
||||||
|
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/widgets/continuous_sliders.h"
|
#include "ui/widgets/continuous_sliders.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "media/media_audio.h"
|
#include "media/media_audio.h"
|
||||||
#include "media/view/media_clip_playback.h"
|
#include "media/view/media_clip_playback.h"
|
||||||
#include "media/player/media_player_button.h"
|
#include "media/player/media_player_button.h"
|
||||||
|
@ -38,7 +39,7 @@ namespace Player {
|
||||||
|
|
||||||
using State = PlayButtonLayout::State;
|
using State = PlayButtonLayout::State;
|
||||||
|
|
||||||
class Widget::PlayButton : public Ui::AbstractButton {
|
class Widget::PlayButton : public Ui::RippleButton {
|
||||||
public:
|
public:
|
||||||
PlayButton(QWidget *parent);
|
PlayButton(QWidget *parent);
|
||||||
|
|
||||||
|
@ -52,12 +53,15 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
|
QImage prepareRippleMask() const override;
|
||||||
|
QPoint prepareRippleStartPosition() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PlayButtonLayout _layout;
|
PlayButtonLayout _layout;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Widget::PlayButton::PlayButton(QWidget *parent) : Ui::AbstractButton(parent)
|
Widget::PlayButton::PlayButton(QWidget *parent) : Ui::RippleButton(parent, st::mediaPlayerButton.ripple)
|
||||||
, _layout(st::mediaPlayerButton, [this] { update(); }) {
|
, _layout(st::mediaPlayerButton, [this] { update(); }) {
|
||||||
resize(st::mediaPlayerButtonSize);
|
resize(st::mediaPlayerButtonSize);
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
|
@ -66,10 +70,20 @@ Widget::PlayButton::PlayButton(QWidget *parent) : Ui::AbstractButton(parent)
|
||||||
void Widget::PlayButton::paintEvent(QPaintEvent *e) {
|
void Widget::PlayButton::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
|
paintRipple(p, st::mediaPlayerButton.rippleAreaPosition.x(), st::mediaPlayerButton.rippleAreaPosition.y(), getms());
|
||||||
p.translate(st::mediaPlayerButtonPosition.x(), st::mediaPlayerButtonPosition.y());
|
p.translate(st::mediaPlayerButtonPosition.x(), st::mediaPlayerButtonPosition.y());
|
||||||
_layout.paint(p, st::mediaPlayerActiveFg);
|
_layout.paint(p, st::mediaPlayerActiveFg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QImage Widget::PlayButton::prepareRippleMask() const {
|
||||||
|
auto size = QSize(st::mediaPlayerButton.rippleAreaSize, st::mediaPlayerButton.rippleAreaSize);
|
||||||
|
return Ui::RippleAnimation::ellipseMask(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPoint Widget::PlayButton::prepareRippleStartPosition() const {
|
||||||
|
return QPoint(mapFromGlobal(QCursor::pos()) - st::mediaPlayerButton.rippleAreaPosition);
|
||||||
|
}
|
||||||
|
|
||||||
Widget::Widget(QWidget *parent) : TWidget(parent)
|
Widget::Widget(QWidget *parent) : TWidget(parent)
|
||||||
, _nameLabel(this, st::mediaPlayerName)
|
, _nameLabel(this, st::mediaPlayerName)
|
||||||
, _timeLabel(this, st::mediaPlayerTime)
|
, _timeLabel(this, st::mediaPlayerTime)
|
||||||
|
@ -146,7 +160,7 @@ void Widget::updateVolumeToggleIcon() {
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
_volumeToggle->setIcon(icon());
|
_volumeToggle->setIconOverride(icon());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setCloseCallback(CloseCallback &&callback) {
|
void Widget::setCloseCallback(CloseCallback &&callback) {
|
||||||
|
@ -223,7 +237,7 @@ void Widget::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
auto fill = e->rect().intersected(QRect(0, 0, width(), st::mediaPlayerHeight));
|
auto fill = e->rect().intersected(QRect(0, 0, width(), st::mediaPlayerHeight));
|
||||||
if (!fill.isEmpty()) {
|
if (!fill.isEmpty()) {
|
||||||
p.fillRect(fill, st::windowBg);
|
p.fillRect(fill, st::mediaPlayerBg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +304,9 @@ void Widget::updateLabelsGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::updateRepeatTrackIcon() {
|
void Widget::updateRepeatTrackIcon() {
|
||||||
_repeatTrack->setIcon(instance()->repeatEnabled() ? nullptr : &st::mediaPlayerRepeatDisabledIcon);
|
auto repeating = instance()->repeatEnabled();
|
||||||
|
_repeatTrack->setIconOverride(repeating ? nullptr : &st::mediaPlayerRepeatDisabledIcon, repeating ? nullptr : &st::mediaPlayerRepeatDisabledIconOver);
|
||||||
|
_repeatTrack->setRippleColorOverride(repeating ? nullptr : &st::mediaPlayerRepeatDisabledRippleBg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::handleSongUpdate(const UpdatedEvent &e) {
|
void Widget::handleSongUpdate(const UpdatedEvent &e) {
|
||||||
|
@ -393,9 +409,11 @@ void Widget::handlePlaylistUpdate() {
|
||||||
createPrevNextButtons();
|
createPrevNextButtons();
|
||||||
auto previousEnabled = (index > 0);
|
auto previousEnabled = (index > 0);
|
||||||
auto nextEnabled = (index + 1 < playlist.size());
|
auto nextEnabled = (index + 1 < playlist.size());
|
||||||
_previousTrack->setIcon(previousEnabled ? nullptr : &st::mediaPlayerPreviousDisabledIcon);
|
_previousTrack->setIconOverride(previousEnabled ? nullptr : &st::mediaPlayerPreviousDisabledIcon);
|
||||||
|
_previousTrack->setRippleColorOverride(previousEnabled ? nullptr : &st::mediaPlayerBg);
|
||||||
_previousTrack->setCursor(previousEnabled ? style::cur_pointer : style::cur_default);
|
_previousTrack->setCursor(previousEnabled ? style::cur_pointer : style::cur_default);
|
||||||
_nextTrack->setIcon(nextEnabled ? nullptr : &st::mediaPlayerNextDisabledIcon);
|
_nextTrack->setIconOverride(nextEnabled ? nullptr : &st::mediaPlayerNextDisabledIcon);
|
||||||
|
_nextTrack->setRippleColorOverride(nextEnabled ? nullptr : &st::mediaPlayerBg);
|
||||||
_nextTrack->setCursor(nextEnabled ? style::cur_pointer : style::cur_default);
|
_nextTrack->setCursor(nextEnabled ? style::cur_pointer : style::cur_default);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ void Controller::updatePlayPauseResumeState(const AudioPlaybackState &playbackSt
|
||||||
_showPause = showPause;
|
_showPause = showPause;
|
||||||
connect(_playPauseResume, SIGNAL(clicked()), this, _showPause ? SIGNAL(pausePressed()) : SIGNAL(playPressed()));
|
connect(_playPauseResume, SIGNAL(clicked()), this, _showPause ? SIGNAL(pausePressed()) : SIGNAL(playPressed()));
|
||||||
|
|
||||||
_playPauseResume->setIcon(_showPause ? &st::mediaviewPauseIcon : nullptr, _showPause ? &st::mediaviewPauseIconOver : nullptr);
|
_playPauseResume->setIconOverride(_showPause ? &st::mediaviewPauseIcon : nullptr, _showPause ? &st::mediaviewPauseIconOver : nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +169,7 @@ void Controller::refreshTimeTexts() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::setInFullScreen(bool inFullScreen) {
|
void Controller::setInFullScreen(bool inFullScreen) {
|
||||||
_fullScreenToggle->setIcon(inFullScreen ? &st::mediaviewFullScreenOutIcon : nullptr, inFullScreen ? &st::mediaviewFullScreenOutIconOver : nullptr);
|
_fullScreenToggle->setIconOverride(inFullScreen ? &st::mediaviewFullScreenOutIcon : nullptr, inFullScreen ? &st::mediaviewFullScreenOutIconOver : nullptr);
|
||||||
disconnect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed()));
|
disconnect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(toFullScreenPressed()));
|
||||||
disconnect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(fromFullScreenPressed()));
|
disconnect(_fullScreenToggle, SIGNAL(clicked()), this, SIGNAL(fromFullScreenPressed()));
|
||||||
|
|
||||||
|
|
|
@ -2241,7 +2241,7 @@ bool MediaView::updateOverState(OverState newState) {
|
||||||
if (i != _animOpacities.end()) {
|
if (i != _animOpacities.end()) {
|
||||||
i->start(0);
|
i->start(0);
|
||||||
} else {
|
} else {
|
||||||
_animOpacities.insert(_over, anim::fvalue(1, 0));
|
_animOpacities.insert(_over, anim::value(1, 0));
|
||||||
}
|
}
|
||||||
if (!_a_state.animating()) _a_state.start();
|
if (!_a_state.animating()) _a_state.start();
|
||||||
} else {
|
} else {
|
||||||
|
@ -2254,7 +2254,7 @@ bool MediaView::updateOverState(OverState newState) {
|
||||||
if (i != _animOpacities.end()) {
|
if (i != _animOpacities.end()) {
|
||||||
i->start(1);
|
i->start(1);
|
||||||
} else {
|
} else {
|
||||||
_animOpacities.insert(_over, anim::fvalue(0, 1));
|
_animOpacities.insert(_over, anim::value());
|
||||||
}
|
}
|
||||||
if (!_a_state.animating()) _a_state.start();
|
if (!_a_state.animating()) _a_state.start();
|
||||||
}
|
}
|
||||||
|
@ -2492,7 +2492,7 @@ void MediaView::setVisible(bool visible) {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
_controlsHideTimer.stop();
|
_controlsHideTimer.stop();
|
||||||
_controlsState = ControlsShown;
|
_controlsState = ControlsShown;
|
||||||
a_cOpacity = anim::fvalue(1, 1);
|
a_cOpacity = anim::value(1, 1);
|
||||||
}
|
}
|
||||||
TWidget::setVisible(visible);
|
TWidget::setVisible(visible);
|
||||||
if (visible) {
|
if (visible) {
|
||||||
|
|
|
@ -307,7 +307,7 @@ private:
|
||||||
ControlsState _controlsState = ControlsShown;
|
ControlsState _controlsState = ControlsShown;
|
||||||
TimeMs _controlsAnimStarted = 0;
|
TimeMs _controlsAnimStarted = 0;
|
||||||
QTimer _controlsHideTimer;
|
QTimer _controlsHideTimer;
|
||||||
anim::fvalue a_cOpacity;
|
anim::value a_cOpacity;
|
||||||
bool _mousePressed = false;
|
bool _mousePressed = false;
|
||||||
|
|
||||||
Ui::PopupMenu *_menu = nullptr;
|
Ui::PopupMenu *_menu = nullptr;
|
||||||
|
@ -328,14 +328,14 @@ private:
|
||||||
|
|
||||||
QString _saveMsgFilename;
|
QString _saveMsgFilename;
|
||||||
TimeMs _saveMsgStarted = 0;
|
TimeMs _saveMsgStarted = 0;
|
||||||
anim::fvalue _saveMsgOpacity = { 0 };
|
anim::value _saveMsgOpacity;
|
||||||
QRect _saveMsg;
|
QRect _saveMsg;
|
||||||
QTimer _saveMsgUpdater;
|
QTimer _saveMsgUpdater;
|
||||||
Text _saveMsgText;
|
Text _saveMsgText;
|
||||||
|
|
||||||
typedef QMap<OverState, TimeMs> Showing;
|
typedef QMap<OverState, TimeMs> Showing;
|
||||||
Showing _animations;
|
Showing _animations;
|
||||||
typedef QMap<OverState, anim::fvalue> ShowingOpacities;
|
typedef QMap<OverState, anim::value> ShowingOpacities;
|
||||||
ShowingOpacities _animOpacities;
|
ShowingOpacities _animOpacities;
|
||||||
|
|
||||||
int _verticalWheelDelta = 0;
|
int _verticalWheelDelta = 0;
|
||||||
|
|
|
@ -358,7 +358,7 @@ namespace {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _paused = false;
|
int PauseLevel = 0;
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
@ -379,7 +379,20 @@ Session *getSession(ShiftedDcId shiftedDcId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool paused() {
|
bool paused() {
|
||||||
return _paused;
|
return PauseLevel > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pause() {
|
||||||
|
++PauseLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unpause() {
|
||||||
|
--PauseLevel;
|
||||||
|
if (_started) {
|
||||||
|
for_const (auto session, sessions) {
|
||||||
|
session->unpaused();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerRequest(mtpRequestId requestId, int32 dcWithShift) {
|
void registerRequest(mtpRequestId requestId, int32 dcWithShift) {
|
||||||
|
@ -685,19 +698,6 @@ void restart(int32 dcMask) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pause() {
|
|
||||||
if (!_started) return;
|
|
||||||
_paused = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void unpause() {
|
|
||||||
if (!_started) return;
|
|
||||||
_paused = false;
|
|
||||||
for (Sessions::const_iterator i = sessions.cbegin(), e = sessions.cend(); i != e; ++i) {
|
|
||||||
i.value()->unpaused();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void configure(int32 dc, int32 user) {
|
void configure(int32 dc, int32 user) {
|
||||||
if (_started) return;
|
if (_started) return;
|
||||||
internal::setDC(dc);
|
internal::setDC(dc);
|
||||||
|
|
|
@ -25,12 +25,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "core/single_timer.h"
|
#include "core/single_timer.h"
|
||||||
|
|
||||||
namespace MTP {
|
namespace MTP {
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
|
|
||||||
Session *getSession(ShiftedDcId shiftedDcId); // 0 - current set dc
|
Session *getSession(ShiftedDcId shiftedDcId); // 0 - current set dc
|
||||||
|
|
||||||
bool paused();
|
bool paused();
|
||||||
|
void pause();
|
||||||
|
void unpause();
|
||||||
|
|
||||||
void registerRequest(mtpRequestId requestId, int32 dc);
|
void registerRequest(mtpRequestId requestId, int32 dc);
|
||||||
void unregisterRequest(mtpRequestId requestId);
|
void unregisterRequest(mtpRequestId requestId);
|
||||||
|
@ -96,27 +97,32 @@ constexpr ShiftedDcId lgtDcId(DcId dcId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
constexpr ShiftedDcId downloadDcId(DcId dcId, int index) {
|
|
||||||
static_assert(MTPDownloadSessionsCount < 0x10, "Too large MTPDownloadSessionsCount!");
|
constexpr ShiftedDcId downloadDcId(DcId dcId, int index) {
|
||||||
return shiftDcId(dcId, 0x10 + index);
|
static_assert(MTPDownloadSessionsCount < 0x10, "Too large MTPDownloadSessionsCount!");
|
||||||
};
|
return shiftDcId(dcId, 0x10 + index);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
// send(req, callbacks, MTP::dldDcId(dc, index)) - for download shifted dc id
|
// send(req, callbacks, MTP::dldDcId(dc, index)) - for download shifted dc id
|
||||||
inline ShiftedDcId dldDcId(DcId dcId, int index) {
|
inline ShiftedDcId dldDcId(DcId dcId, int index) {
|
||||||
t_assert(index >= 0 && index < MTPDownloadSessionsCount);
|
t_assert(index >= 0 && index < MTPDownloadSessionsCount);
|
||||||
return internal::downloadDcId(dcId, index);
|
return internal::downloadDcId(dcId, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool isDldDcId(ShiftedDcId shiftedDcId) {
|
constexpr bool isDldDcId(ShiftedDcId shiftedDcId) {
|
||||||
return (shiftedDcId >= internal::downloadDcId(0, 0)) && (shiftedDcId < internal::downloadDcId(0, MTPDownloadSessionsCount - 1) + DCShift);
|
return (shiftedDcId >= internal::downloadDcId(0, 0)) && (shiftedDcId < internal::downloadDcId(0, MTPDownloadSessionsCount - 1) + DCShift);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace internal {
|
namespace internal {
|
||||||
constexpr ShiftedDcId uploadDcId(DcId dcId, int index) {
|
|
||||||
static_assert(MTPUploadSessionsCount < 0x10, "Too large MTPUploadSessionsCount!");
|
constexpr ShiftedDcId uploadDcId(DcId dcId, int index) {
|
||||||
return shiftDcId(dcId, 0x20 + index);
|
static_assert(MTPUploadSessionsCount < 0x10, "Too large MTPUploadSessionsCount!");
|
||||||
};
|
return shiftDcId(dcId, 0x20 + index);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
// send(req, callbacks, MTP::uplDcId(index)) - for upload shifted dc id
|
// send(req, callbacks, MTP::uplDcId(index)) - for upload shifted dc id
|
||||||
// uploading always to the main dc so bareDcId == 0
|
// uploading always to the main dc so bareDcId == 0
|
||||||
|
@ -124,6 +130,7 @@ inline ShiftedDcId uplDcId(int index) {
|
||||||
t_assert(index >= 0 && index < MTPUploadSessionsCount);
|
t_assert(index >= 0 && index < MTPUploadSessionsCount);
|
||||||
return internal::uploadDcId(0, index);
|
return internal::uploadDcId(0, index);
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr bool isUplDcId(ShiftedDcId shiftedDcId) {
|
constexpr bool isUplDcId(ShiftedDcId shiftedDcId) {
|
||||||
return (shiftedDcId >= internal::uploadDcId(0, 0)) && (shiftedDcId < internal::uploadDcId(0, MTPUploadSessionsCount - 1) + DCShift);
|
return (shiftedDcId >= internal::uploadDcId(0, 0)) && (shiftedDcId < internal::uploadDcId(0, MTPUploadSessionsCount - 1) + DCShift);
|
||||||
}
|
}
|
||||||
|
@ -133,8 +140,29 @@ bool started();
|
||||||
void restart();
|
void restart();
|
||||||
void restart(int32 dcMask);
|
void restart(int32 dcMask);
|
||||||
|
|
||||||
void pause();
|
class PauseHolder {
|
||||||
void unpause();
|
public:
|
||||||
|
PauseHolder() {
|
||||||
|
restart();
|
||||||
|
}
|
||||||
|
void restart() {
|
||||||
|
if (!base::take(_paused, true)) {
|
||||||
|
internal::pause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void release() {
|
||||||
|
if (base::take(_paused)) {
|
||||||
|
internal::unpause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~PauseHolder() {
|
||||||
|
release();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool _paused = false;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
void configure(int32 dc, int32 user);
|
void configure(int32 dc, int32 user);
|
||||||
|
|
||||||
|
|
|
@ -132,7 +132,7 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
Ui::RadialAnimation *_radial;
|
Ui::RadialAnimation *_radial;
|
||||||
anim::fvalue a_iconOver;
|
anim::value a_iconOver;
|
||||||
Animation _a_iconOver;
|
Animation _a_iconOver;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1878,7 +1878,6 @@ OverviewInner::~OverviewInner() {
|
||||||
OverviewWidget::OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewType type) : TWidget(parent)
|
OverviewWidget::OverviewWidget(QWidget *parent, PeerData *peer, MediaOverviewType type) : TWidget(parent)
|
||||||
, _scroll(this, st::settingsScroll, false)
|
, _scroll(this, st::settingsScroll, false)
|
||||||
, _inner(this, _scroll, peer, type)
|
, _inner(this, _scroll, peer, type)
|
||||||
, _a_show(animation(this, &OverviewWidget::step_show))
|
|
||||||
, _topShadow(this, st::shadowColor) {
|
, _topShadow(this, st::shadowColor) {
|
||||||
_scroll->setOwnedWidget(_inner);
|
_scroll->setOwnedWidget(_inner);
|
||||||
_scroll->move(0, 0);
|
_scroll->move(0, 0);
|
||||||
|
@ -1936,18 +1935,23 @@ void OverviewWidget::paintEvent(QPaintEvent *e) {
|
||||||
if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return;
|
if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return;
|
||||||
|
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
auto progress = _a_show.current(getms(), 1.);
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
int retina = cIntRetinaFactor();
|
auto retina = cIntRetinaFactor();
|
||||||
int inCacheTop = st::topBarHeight;
|
auto inCacheTop = st::topBarHeight;
|
||||||
if (a_coordOver.current() > 0) {
|
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
|
||||||
p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * retina, inCacheTop * retina, a_coordOver.current() * retina, height() * retina));
|
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
p.setOpacity(a_progress.current());
|
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
p.fillRect(0, 0, a_coordOver.current(), height(), st::slideFadeOutBg);
|
auto shadow = fromLeft ? (1. - progress) : progress;
|
||||||
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * retina, inCacheTop * retina, coordOver * retina, height() * retina));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
p.drawPixmap(QRect(a_coordOver.current(), 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, inCacheTop * retina, _cacheOver.width(), height() * retina));
|
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, height()), _cacheOver, QRect(0, inCacheTop * retina, _cacheOver.width(), height() * retina));
|
||||||
p.setOpacity(a_progress.current());
|
p.setOpacity(shadow);
|
||||||
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,16 +1976,21 @@ void OverviewWidget::scrollReset() {
|
||||||
|
|
||||||
bool OverviewWidget::paintTopBar(Painter &p, int decreaseWidth) {
|
bool OverviewWidget::paintTopBar(Painter &p, int decreaseWidth) {
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
int retina = cIntRetinaFactor();
|
auto progress = _a_show.current(1.);
|
||||||
if (a_coordOver.current() > 0) {
|
auto retina = cIntRetinaFactor();
|
||||||
p.drawPixmap(QRect(0, 0, a_coordOver.current(), st::topBarHeight), _cacheUnder, QRect(-a_coordUnder.current() * retina, 0, a_coordOver.current() * retina, st::topBarHeight * retina));
|
auto fromLeft = (_showDirection == Window::SlideDirection::FromLeft);
|
||||||
p.setOpacity(a_progress.current());
|
auto coordUnder = fromLeft ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
p.fillRect(0, 0, a_coordOver.current(), st::topBarHeight, st::slideFadeOutBg);
|
auto coordOver = fromLeft ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
|
auto shadow = fromLeft ? (1. - progress) : progress;
|
||||||
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, st::topBarHeight), _cacheUnder, QRect(-coordUnder * retina, 0, coordOver * retina, st::topBarHeight * retina));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, st::topBarHeight, st::slideFadeOutBg);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
p.drawPixmap(QRect(a_coordOver.current(), 0, _cacheOver.width() / retina, st::topBarHeight), _cacheOver, QRect(0, 0, _cacheOver.width(), st::topBarHeight * retina));
|
p.drawPixmap(QRect(coordOver, 0, _cacheOver.width() / retina, st::topBarHeight), _cacheOver, QRect(0, 0, _cacheOver.width(), st::topBarHeight * retina));
|
||||||
p.setOpacity(a_progress.current());
|
p.setOpacity(shadow);
|
||||||
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), st::topBarHeight));
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), st::topBarHeight));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
st::topBarBack.paint(p, (st::topBarArrowPadding.left() - st::topBarBack.width()) / 2, (st::topBarHeight - st::topBarBack.height()) / 2, width());
|
st::topBarBack.paint(p, (st::topBarArrowPadding.left() - st::topBarBack.width()) / 2, (st::topBarHeight - st::topBarBack.height()) / 2, width());
|
||||||
|
@ -2080,8 +2089,6 @@ void OverviewWidget::fastShow(bool back, int32 lastScrollTop) {
|
||||||
show();
|
show();
|
||||||
_inner->activate();
|
_inner->activate();
|
||||||
doneShow();
|
doneShow();
|
||||||
|
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::setLastScrollTop(int lastScrollTop) {
|
void OverviewWidget::setLastScrollTop(int lastScrollTop) {
|
||||||
|
@ -2090,10 +2097,11 @@ void OverviewWidget::setLastScrollTop(int lastScrollTop) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) {
|
void OverviewWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) {
|
||||||
if (App::app()) App::app()->mtpPause();
|
_showDirection = direction;
|
||||||
|
|
||||||
resizeEvent(0);
|
resizeEvent(0);
|
||||||
|
|
||||||
|
_a_show.finish();
|
||||||
|
|
||||||
_cacheUnder = params.oldContentCache;
|
_cacheUnder = params.oldContentCache;
|
||||||
show();
|
show();
|
||||||
_topShadow->setVisible(params.withTopBarShadow ? false : true);
|
_topShadow->setVisible(params.withTopBarShadow ? false : true);
|
||||||
|
@ -2104,47 +2112,26 @@ void OverviewWidget::showAnimated(Window::SlideDirection direction, const Window
|
||||||
_scrollSetAfterShow = _scroll->scrollTop();
|
_scrollSetAfterShow = _scroll->scrollTop();
|
||||||
_scroll->hide();
|
_scroll->hide();
|
||||||
|
|
||||||
int delta = st::slideShift;
|
if (_showDirection == Window::SlideDirection::FromLeft) {
|
||||||
if (direction == Window::SlideDirection::FromLeft) {
|
|
||||||
a_progress = anim::fvalue(1, 0);
|
|
||||||
std::swap(_cacheUnder, _cacheOver);
|
std::swap(_cacheUnder, _cacheOver);
|
||||||
a_coordUnder = anim::ivalue(-delta, 0);
|
|
||||||
a_coordOver = anim::ivalue(0, width());
|
|
||||||
} else {
|
|
||||||
a_progress = anim::fvalue(0, 1);
|
|
||||||
a_coordUnder = anim::ivalue(0, -delta);
|
|
||||||
a_coordOver = anim::ivalue(width(), 0);
|
|
||||||
}
|
}
|
||||||
_a_show.start();
|
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
|
||||||
|
|
||||||
App::main()->topBar()->update();
|
App::main()->topBar()->update();
|
||||||
|
|
||||||
activate();
|
activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverviewWidget::step_show(float64 ms, bool timer) {
|
void OverviewWidget::animationCallback() {
|
||||||
float64 dt = ms / st::slideDuration;
|
update();
|
||||||
if (dt >= 1) {
|
App::main()->topBar()->update();
|
||||||
_a_show.stop();
|
if (!_a_show.animating()) {
|
||||||
_topShadow->show();
|
_topShadow->show();
|
||||||
|
|
||||||
a_coordUnder.finish();
|
|
||||||
a_coordOver.finish();
|
|
||||||
a_progress.finish();
|
|
||||||
_cacheUnder = _cacheOver = QPixmap();
|
_cacheUnder = _cacheOver = QPixmap();
|
||||||
App::main()->topBar()->stopAnim();
|
App::main()->topBar()->stopAnim();
|
||||||
|
|
||||||
doneShow();
|
doneShow();
|
||||||
|
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
|
||||||
} else {
|
|
||||||
a_coordUnder.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_coordOver.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_progress.update(dt, Window::SlideAnimation::transition());
|
|
||||||
}
|
|
||||||
if (timer) {
|
|
||||||
update();
|
|
||||||
App::main()->topBar()->update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -301,7 +301,6 @@ public:
|
||||||
}
|
}
|
||||||
void setLastScrollTop(int lastScrollTop);
|
void setLastScrollTop(int lastScrollTop);
|
||||||
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms);
|
void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms);
|
||||||
void step_show(float64 ms, bool timer);
|
|
||||||
|
|
||||||
void doneShow();
|
void doneShow();
|
||||||
|
|
||||||
|
@ -355,16 +354,17 @@ public slots:
|
||||||
void onClearSelected();
|
void onClearSelected();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void animationCallback();
|
||||||
|
|
||||||
ChildWidget<Ui::ScrollArea> _scroll;
|
ChildWidget<Ui::ScrollArea> _scroll;
|
||||||
ChildWidget<OverviewInner> _inner;
|
ChildWidget<OverviewInner> _inner;
|
||||||
bool _noDropResizeIndex = false;
|
bool _noDropResizeIndex = false;
|
||||||
|
|
||||||
QString _header;
|
QString _header;
|
||||||
|
|
||||||
Animation _a_show;
|
FloatAnimation _a_show;
|
||||||
|
Window::SlideDirection _showDirection;
|
||||||
QPixmap _cacheUnder, _cacheOver;
|
QPixmap _cacheUnder, _cacheOver;
|
||||||
anim::ivalue a_coordUnder, a_coordOver;
|
|
||||||
anim::fvalue a_progress;
|
|
||||||
|
|
||||||
int32 _scrollSetAfterShow = 0;
|
int32 _scrollSetAfterShow = 0;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "window/window_slide_animation.h"
|
#include "window/window_slide_animation.h"
|
||||||
|
|
||||||
PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent)
|
PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent)
|
||||||
, _a_show(animation(this, &PasscodeWidget::step_show))
|
|
||||||
, _passcode(this, st::passcodeInput)
|
, _passcode(this, st::passcodeInput)
|
||||||
, _submit(this, lang(lng_passcode_submit), st::passcodeSubmit)
|
, _submit(this, lang(lng_passcode_submit), st::passcodeSubmit)
|
||||||
, _logout(this, lang(lng_passcode_logout)) {
|
, _logout(this, lang(lng_passcode_logout)) {
|
||||||
|
@ -104,52 +103,30 @@ void PasscodeWidget::onChanged() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PasscodeWidget::animShow(const QPixmap &bgAnimCache, bool back) {
|
void PasscodeWidget::showAnimated(const QPixmap &bgAnimCache, bool back) {
|
||||||
if (App::app()) App::app()->mtpPause();
|
_showBack = back;
|
||||||
|
(_showBack ? _cacheOver : _cacheUnder) = bgAnimCache;
|
||||||
|
|
||||||
(back ? _cacheOver : _cacheUnder) = bgAnimCache;
|
_a_show.finish();
|
||||||
|
|
||||||
_a_show.stop();
|
|
||||||
|
|
||||||
showAll();
|
showAll();
|
||||||
(back ? _cacheUnder : _cacheOver) = myGrab(this);
|
(_showBack ? _cacheUnder : _cacheOver) = myGrab(this);
|
||||||
hideAll();
|
hideAll();
|
||||||
|
|
||||||
a_coordUnder = back ? anim::ivalue(-st::slideShift, 0) : anim::ivalue(0, -st::slideShift);
|
_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
|
||||||
a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0);
|
|
||||||
a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1);
|
|
||||||
_a_show.start();
|
|
||||||
|
|
||||||
show();
|
show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PasscodeWidget::step_show(float64 ms, bool timer) {
|
void PasscodeWidget::animationCallback() {
|
||||||
float64 dt = ms / st::slideDuration;
|
update();
|
||||||
if (dt >= 1) {
|
if (!_a_show.animating()) {
|
||||||
_a_show.stop();
|
|
||||||
|
|
||||||
a_coordUnder.finish();
|
|
||||||
a_coordOver.finish();
|
|
||||||
a_shadow.finish();
|
|
||||||
|
|
||||||
_cacheUnder = _cacheOver = QPixmap();
|
|
||||||
|
|
||||||
showAll();
|
showAll();
|
||||||
if (App::wnd()) App::wnd()->setInnerFocus();
|
if (App::wnd()) App::wnd()->setInnerFocus();
|
||||||
|
|
||||||
if (App::app()) App::app()->mtpUnpause();
|
|
||||||
|
|
||||||
Ui::showChatsList();
|
Ui::showChatsList();
|
||||||
} else {
|
|
||||||
a_coordUnder.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_coordOver.update(dt, Window::SlideAnimation::transition());
|
|
||||||
a_shadow.update(dt, Window::SlideAnimation::transition());
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PasscodeWidget::stop_show() {
|
_cacheUnder = _cacheOver = QPixmap();
|
||||||
_a_show.stop();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PasscodeWidget::showAll() {
|
void PasscodeWidget::showAll() {
|
||||||
|
@ -173,16 +150,20 @@ void PasscodeWidget::paintEvent(QPaintEvent *e) {
|
||||||
p.setClipRect(e->rect());
|
p.setClipRect(e->rect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto progress = _a_show.current(getms(), 1.);
|
||||||
if (_a_show.animating()) {
|
if (_a_show.animating()) {
|
||||||
if (a_coordOver.current() > 0) {
|
auto coordUnder = _showBack ? anim::interpolate(-st::slideShift, 0, progress) : anim::interpolate(0, -st::slideShift, progress);
|
||||||
p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * cRetinaFactor(), 0, a_coordOver.current() * cRetinaFactor(), height() * cRetinaFactor()));
|
auto coordOver = _showBack ? anim::interpolate(0, width(), progress) : anim::interpolate(width(), 0, progress);
|
||||||
p.setOpacity(a_shadow.current());
|
auto shadow = _showBack ? (1. - progress) : progress;
|
||||||
p.fillRect(0, 0, a_coordOver.current(), height(), st::slideFadeOutBg);
|
if (coordOver > 0) {
|
||||||
|
p.drawPixmap(QRect(0, 0, coordOver, height()), _cacheUnder, QRect(-coordUnder * cRetinaFactor(), 0, coordOver * cRetinaFactor(), height() * cRetinaFactor()));
|
||||||
|
p.setOpacity(shadow);
|
||||||
|
p.fillRect(0, 0, coordOver, height(), st::slideFadeOutBg);
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
|
p.drawPixmap(coordOver, 0, _cacheOver);
|
||||||
p.setOpacity(a_shadow.current());
|
p.setOpacity(shadow);
|
||||||
st::slideShadow.fill(p, QRect(a_coordOver.current() - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
st::slideShadow.fill(p, QRect(coordOver - st::slideShadow.width(), 0, st::slideShadow.width(), height()));
|
||||||
} else {
|
} else {
|
||||||
p.fillRect(rect(), st::windowBg);
|
p.fillRect(rect(), st::windowBg);
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,7 @@ public:
|
||||||
|
|
||||||
void setInnerFocus();
|
void setInnerFocus();
|
||||||
|
|
||||||
void animShow(const QPixmap &bgAnimCache, bool back = false);
|
void showAnimated(const QPixmap &bgAnimCache, bool back = false);
|
||||||
void step_show(float64 ms, bool timer);
|
|
||||||
void stop_show();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
@ -48,13 +46,14 @@ public slots:
|
||||||
void onSubmit();
|
void onSubmit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void animationCallback();
|
||||||
|
|
||||||
void showAll();
|
void showAll();
|
||||||
void hideAll();
|
void hideAll();
|
||||||
|
|
||||||
Animation _a_show;
|
FloatAnimation _a_show;
|
||||||
|
bool _showBack = false;
|
||||||
QPixmap _cacheUnder, _cacheOver;
|
QPixmap _cacheUnder, _cacheOver;
|
||||||
anim::ivalue a_coordUnder, a_coordOver;
|
|
||||||
anim::fvalue a_shadow;
|
|
||||||
|
|
||||||
ChildWidget<Ui::PasswordInput> _passcode;
|
ChildWidget<Ui::PasswordInput> _passcode;
|
||||||
ChildWidget<Ui::RoundButton> _submit;
|
ChildWidget<Ui::RoundButton> _submit;
|
||||||
|
|
|
@ -89,9 +89,9 @@ void TitleWidget::onWindowStateChanged(Qt::WindowState state) {
|
||||||
|
|
||||||
void TitleWidget::updateMaximizeRestoreButton() {
|
void TitleWidget::updateMaximizeRestoreButton() {
|
||||||
if (_maximized) {
|
if (_maximized) {
|
||||||
_maximizeRestore->setIcon(&st::titleButtonRestoreIcon, &st::titleButtonRestoreIconOver);
|
_maximizeRestore->setIconOverride(&st::titleButtonRestoreIcon, &st::titleButtonRestoreIconOver);
|
||||||
} else {
|
} else {
|
||||||
_maximizeRestore->setIcon(nullptr, nullptr);
|
_maximizeRestore->setIconOverride(nullptr, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ profileMemberNamePosition: point(68px, 11px);
|
||||||
profileMemberNameFg: #222222;
|
profileMemberNameFg: #222222;
|
||||||
profileMemberStatusPosition: point(68px, 31px);
|
profileMemberStatusPosition: point(68px, 31px);
|
||||||
profileMemberStatusFg: windowSubTextFg;
|
profileMemberStatusFg: windowSubTextFg;
|
||||||
profileMemberStatusFgOver: windowSubTextFgOver;
|
profileMemberStatusFgOver: #7c99b2;
|
||||||
profileMemberStatusFgActive: windowActiveTextFg;
|
profileMemberStatusFgActive: windowActiveTextFg;
|
||||||
profileMemberAdminIcon: icon {{ "profile_admin_star", windowBgActive, point(4px, 3px) }};
|
profileMemberAdminIcon: icon {{ "profile_admin_star", windowBgActive, point(4px, 3px) }};
|
||||||
profileLimitReachedLabel: FlatLabel(defaultFlatLabel) {
|
profileLimitReachedLabel: FlatLabel(defaultFlatLabel) {
|
||||||
|
|
|
@ -63,7 +63,7 @@ void CommonGroupsWidget::notifyPeerUpdated(const Notify::PeerUpdate &update) {
|
||||||
|
|
||||||
int CommonGroupsWidget::resizeGetHeight(int newWidth) {
|
int CommonGroupsWidget::resizeGetHeight(int newWidth) {
|
||||||
auto result = PeerListWidget::resizeGetHeight(newWidth);
|
auto result = PeerListWidget::resizeGetHeight(newWidth);
|
||||||
return _height.animating() ? _height.current() : result;
|
return qRound(_height.current(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CommonGroupsWidget::paintContents(Painter &p) {
|
void CommonGroupsWidget::paintContents(Painter &p) {
|
||||||
|
|
|
@ -65,7 +65,7 @@ private:
|
||||||
Item *computeItem(PeerData *group);
|
Item *computeItem(PeerData *group);
|
||||||
QMap<PeerData*, Item*> _dataMap;
|
QMap<PeerData*, Item*> _dataMap;
|
||||||
|
|
||||||
IntAnimation _height;
|
FloatAnimation _height;
|
||||||
|
|
||||||
int32 _preloadGroupId = 0;
|
int32 _preloadGroupId = 0;
|
||||||
mtpRequestId _preloadRequestId = 0;
|
mtpRequestId _preloadRequestId = 0;
|
||||||
|
|
|
@ -58,13 +58,17 @@ InfoWidget::InfoWidget(QWidget *parent, PeerData *peer) : BlockWidget(parent, pe
|
||||||
void InfoWidget::showFinished() {
|
void InfoWidget::showFinished() {
|
||||||
_showFinished = true;
|
_showFinished = true;
|
||||||
if (_commonGroups && _commonGroups->isHidden() && getCommonGroupsCount() > 0) {
|
if (_commonGroups && _commonGroups->isHidden() && getCommonGroupsCount() > 0) {
|
||||||
_commonGroups->show();
|
slideCommonGroupsDown();
|
||||||
refreshVisibility();
|
|
||||||
_height.start([this] { contentSizeUpdated(); }, isHidden() ? 0 : height(), resizeGetHeight(width()), st::widgetSlideDuration);
|
|
||||||
contentSizeUpdated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InfoWidget::slideCommonGroupsDown() {
|
||||||
|
_commonGroups->show();
|
||||||
|
refreshVisibility();
|
||||||
|
_height.start([this] { contentSizeUpdated(); }, isHidden() ? 0 : height(), resizeGetHeight(width()), st::widgetSlideDuration);
|
||||||
|
contentSizeUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
void InfoWidget::restoreState(const SectionMemento *memento) {
|
void InfoWidget::restoreState(const SectionMemento *memento) {
|
||||||
if (!memento->getCommonGroups().isEmpty()) {
|
if (!memento->getCommonGroups().isEmpty()) {
|
||||||
onForceHideCommonGroups();
|
onForceHideCommonGroups();
|
||||||
|
@ -152,7 +156,7 @@ int InfoWidget::resizeGetHeight(int newWidth) {
|
||||||
}
|
}
|
||||||
|
|
||||||
newHeight += st::profileBlockMarginBottom;
|
newHeight += st::profileBlockMarginBottom;
|
||||||
return _height.animating() ? _height.current() : newHeight;
|
return qRound(_height.current(newHeight));
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfoWidget::leaveEvent(QEvent *e) {
|
void InfoWidget::leaveEvent(QEvent *e) {
|
||||||
|
@ -258,8 +262,7 @@ void InfoWidget::refreshCommonGroups() {
|
||||||
_commonGroups->setClickedCallback([this] { onShowCommonGroups(); });
|
_commonGroups->setClickedCallback([this] { onShowCommonGroups(); });
|
||||||
_commonGroups->hide();
|
_commonGroups->hide();
|
||||||
if (_showFinished) {
|
if (_showFinished) {
|
||||||
_height.start([this] { contentSizeUpdated(); }, isHidden() ? 0 : height(), resizeGetHeight(width()), st::widgetSlideDuration);
|
slideCommonGroupsDown();
|
||||||
contentSizeUpdated();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_commonGroups) {
|
} else if (_commonGroups) {
|
||||||
|
|
|
@ -68,6 +68,7 @@ private:
|
||||||
int getCommonGroupsCount() const;
|
int getCommonGroupsCount() const;
|
||||||
void onForceHideCommonGroups();
|
void onForceHideCommonGroups();
|
||||||
void onShowCommonGroups();
|
void onShowCommonGroups();
|
||||||
|
void slideCommonGroupsDown();
|
||||||
|
|
||||||
// labelWidget may be nullptr.
|
// labelWidget may be nullptr.
|
||||||
void setLabeledText(ChildWidget<Ui::FlatLabel> *labelWidget, const QString &label,
|
void setLabeledText(ChildWidget<Ui::FlatLabel> *labelWidget, const QString &label,
|
||||||
|
@ -83,7 +84,7 @@ private:
|
||||||
ChildWidget<Ui::FlatLabel> _username = { nullptr };
|
ChildWidget<Ui::FlatLabel> _username = { nullptr };
|
||||||
ChildWidget<Ui::LeftOutlineButton> _commonGroups = { nullptr };
|
ChildWidget<Ui::LeftOutlineButton> _commonGroups = { nullptr };
|
||||||
|
|
||||||
IntAnimation _height;
|
FloatAnimation _height;
|
||||||
bool _showFinished = false;
|
bool _showFinished = false;
|
||||||
|
|
||||||
bool _forceHiddenCommonGroups = false;
|
bool _forceHiddenCommonGroups = false;
|
||||||
|
|
|
@ -21,11 +21,17 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "profile/profile_block_peer_list.h"
|
#include "profile/profile_block_peer_list.h"
|
||||||
|
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "styles/style_profile.h"
|
#include "styles/style_profile.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
|
PeerListWidget::Item::Item(PeerData *peer) : peer(peer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PeerListWidget::Item::~Item() = default;
|
||||||
|
|
||||||
PeerListWidget::PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const QString &removeText)
|
PeerListWidget::PeerListWidget(QWidget *parent, PeerData *peer, const QString &title, const QString &removeText)
|
||||||
: BlockWidget(parent, peer, title)
|
: BlockWidget(parent, peer, title)
|
||||||
, _removeText(removeText)
|
, _removeText(removeText)
|
||||||
|
@ -54,38 +60,39 @@ void PeerListWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListWidget::paintContents(Painter &p) {
|
void PeerListWidget::paintContents(Painter &p) {
|
||||||
int left = getListLeft();
|
auto ms = getms();
|
||||||
int top = getListTop();
|
auto left = getListLeft();
|
||||||
int memberRowWidth = width() - left;
|
auto top = getListTop();
|
||||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
auto memberRowWidth = rowWidth();
|
||||||
|
|
||||||
int from = floorclamp(_visibleTop - top, st::profileMemberHeight, 0, _items.size());
|
auto from = floorclamp(_visibleTop - top, st::profileMemberHeight, 0, _items.size());
|
||||||
int to = ceilclamp(_visibleBottom - top, st::profileMemberHeight, 0, _items.size());
|
auto to = ceilclamp(_visibleBottom - top, st::profileMemberHeight, 0, _items.size());
|
||||||
for (int i = from; i < to; ++i) {
|
for (auto i = from; i < to; ++i) {
|
||||||
int y = top + i * st::profileMemberHeight;
|
auto y = top + i * st::profileMemberHeight;
|
||||||
bool selected = (i == _selected);
|
auto selected = (_pressed >= 0) ? (i == _pressed) : (i == _selected);
|
||||||
bool selectedRemove = selected && _selectedRemove;
|
auto selectedRemove = selected && _selectedRemove;
|
||||||
if (_pressed >= 0) {
|
if (_pressed >= 0 && !_pressedRemove) {
|
||||||
if (_pressed != _selected) {
|
selectedRemove = false;
|
||||||
selected = selectedRemove = false;
|
|
||||||
} else if (!_pressedRemove) {
|
|
||||||
_selectedRemove = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
paintItem(p, left, y, _items[i], selected, selectedRemove);
|
paintItem(p, left, y, _items[i], selected, selectedRemove, ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListWidget::paintItem(Painter &p, int x, int y, Item *item, bool selected, bool selectedKick) {
|
void PeerListWidget::paintItem(Painter &p, int x, int y, Item *item, bool selected, bool selectedKick, TimeMs ms) {
|
||||||
if (_updateItemCallback) {
|
if (_updateItemCallback) {
|
||||||
_updateItemCallback(item);
|
_updateItemCallback(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
int memberRowWidth = width() - x;
|
auto memberRowWidth = rowWidth();
|
||||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
|
||||||
if (selected) {
|
if (selected) {
|
||||||
paintOutlinedRect(p, x, y, memberRowWidth, st::profileMemberHeight);
|
paintOutlinedRect(p, x, y, memberRowWidth, st::profileMemberHeight);
|
||||||
}
|
}
|
||||||
|
if (auto &ripple = item->ripple) {
|
||||||
|
ripple->paint(p, x + st::defaultLeftOutlineButton.outlineWidth, y, width(), ms);
|
||||||
|
if (ripple->empty()) {
|
||||||
|
ripple.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
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, st::profileMemberPhotoSize, x + st::profileMemberPhotoPosition.x(), y + st::profileMemberPhotoPosition.y(), width());
|
||||||
|
@ -136,19 +143,36 @@ void PeerListWidget::mousePressEvent(QMouseEvent *e) {
|
||||||
|
|
||||||
_pressed = _selected;
|
_pressed = _selected;
|
||||||
_pressedRemove = _selectedRemove;
|
_pressedRemove = _selectedRemove;
|
||||||
|
if (_pressed >= 0 && !_pressedRemove) {
|
||||||
|
auto item = _items[_pressed];
|
||||||
|
if (!item->ripple) {
|
||||||
|
auto memberRowWidth = rowWidth();
|
||||||
|
auto mask = Ui::RippleAnimation::rectMask(QSize(memberRowWidth - st::defaultLeftOutlineButton.outlineWidth, st::profileMemberHeight));
|
||||||
|
item->ripple = std_::make_unique<Ui::RippleAnimation>(st::defaultLeftOutlineButton.ripple, std_::move(mask), [this, index = _pressed] {
|
||||||
|
repaintRow(index);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
auto left = getListLeft() + st::defaultLeftOutlineButton.outlineWidth;
|
||||||
|
auto top = getListTop() + st::profileMemberHeight * _pressed;
|
||||||
|
item->ripple->add(e->pos() - QPoint(left, top));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
void PeerListWidget::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
_mousePosition = e->globalPos();
|
_mousePosition = e->globalPos();
|
||||||
updateSelection();
|
updateSelection();
|
||||||
|
|
||||||
auto pressed = _pressed;
|
repaintRow(_pressed);
|
||||||
auto pressedRemove = _pressedRemove;
|
auto pressed = base::take(_pressed, -1);
|
||||||
_pressed = -1;
|
auto pressedRemove = base::take(_pressedRemove);
|
||||||
_pressedRemove = false;
|
if (pressed >= 0 && pressed < _items.size()) {
|
||||||
if (pressed >= 0 && pressed < _items.size() && pressed == _selected && pressedRemove == _selectedRemove) {
|
if (auto &ripple = _items[pressed]->ripple) {
|
||||||
if (auto &callback = (pressedRemove ? _removedCallback : _selectedCallback)) {
|
ripple->lastStop();
|
||||||
callback(_items[pressed]->peer);
|
}
|
||||||
|
if (pressed == _selected && pressedRemove == _selectedRemove) {
|
||||||
|
if (auto &callback = (pressedRemove ? _removedCallback : _selectedCallback)) {
|
||||||
|
callback(_items[pressed]->peer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setCursor(_selectedRemove ? style::cur_pointer : style::cur_default);
|
setCursor(_selectedRemove ? style::cur_pointer : style::cur_default);
|
||||||
|
@ -166,15 +190,14 @@ void PeerListWidget::leaveEvent(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListWidget::updateSelection() {
|
void PeerListWidget::updateSelection() {
|
||||||
int selected = -1;
|
auto selected = -1;
|
||||||
bool selectedKick = false;
|
auto selectedKick = false;
|
||||||
|
|
||||||
auto mouse = mapFromGlobal(_mousePosition);
|
auto mouse = mapFromGlobal(_mousePosition);
|
||||||
if (rtl()) mouse.setX(width() - mouse.x());
|
if (rtl()) mouse.setX(width() - mouse.x());
|
||||||
int left = getListLeft();
|
auto left = getListLeft();
|
||||||
int top = getListTop();
|
auto top = getListTop();
|
||||||
int memberRowWidth = width() - left;
|
auto memberRowWidth = rowWidth();
|
||||||
accumulate_min(memberRowWidth, st::profileBlockWideWidthMax);
|
|
||||||
if (mouse.x() >= left && mouse.x() < left + memberRowWidth && mouse.y() >= top) {
|
if (mouse.x() >= left && mouse.x() < left + memberRowWidth && mouse.y() >= top) {
|
||||||
selected = (mouse.y() - top) / st::profileMemberHeight;
|
selected = (mouse.y() - top) / st::profileMemberHeight;
|
||||||
if (selected >= _items.size()) {
|
if (selected >= _items.size()) {
|
||||||
|
@ -214,9 +237,13 @@ void PeerListWidget::setSelected(int selected, bool selectedRemove) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PeerListWidget::repaintSelectedRow() {
|
void PeerListWidget::repaintSelectedRow() {
|
||||||
if (_selected >= 0) {
|
repaintRow(_selected);
|
||||||
int left = getListLeft();
|
}
|
||||||
rtlupdate(left, getListTop() + _selected * st::profileMemberHeight, width() - left, st::profileMemberHeight);
|
|
||||||
|
void PeerListWidget::repaintRow(int index) {
|
||||||
|
if (index >= 0) {
|
||||||
|
auto left = getListLeft();
|
||||||
|
rtlupdate(left, getListTop() + index * st::profileMemberHeight, width() - left, st::profileMemberHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,6 +251,10 @@ int PeerListWidget::getListLeft() const {
|
||||||
return st::profileBlockTitlePosition.x() - st::profileMemberPaddingLeft;
|
return st::profileBlockTitlePosition.x() - st::profileMemberPaddingLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PeerListWidget::rowWidth() const {
|
||||||
|
return qMin(width() - getListLeft(), st::profileBlockWideWidthMax);
|
||||||
|
}
|
||||||
|
|
||||||
void PeerListWidget::preloadPhotos() {
|
void PeerListWidget::preloadPhotos() {
|
||||||
int top = getListTop();
|
int top = getListTop();
|
||||||
int preloadFor = (_visibleBottom - _visibleTop) * PreloadHeightsCount;
|
int preloadFor = (_visibleBottom - _visibleTop) * PreloadHeightsCount;
|
||||||
|
|
|
@ -22,6 +22,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "profile/profile_block_widget.h"
|
#include "profile/profile_block_widget.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RippleAnimation;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Notify {
|
namespace Notify {
|
||||||
struct PeerUpdate;
|
struct PeerUpdate;
|
||||||
} // namespace Notify
|
} // namespace Notify
|
||||||
|
@ -35,14 +39,16 @@ public:
|
||||||
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
void setVisibleTopBottom(int visibleTop, int visibleBottom) override;
|
||||||
|
|
||||||
struct Item {
|
struct Item {
|
||||||
explicit Item(PeerData *peer) : peer(peer) {
|
explicit Item(PeerData *peer);
|
||||||
}
|
~Item();
|
||||||
|
|
||||||
PeerData * const peer;
|
PeerData * const peer;
|
||||||
Text name;
|
Text name;
|
||||||
QString statusText;
|
QString statusText;
|
||||||
bool statusHasOnlineColor = false;
|
bool statusHasOnlineColor = false;
|
||||||
bool hasAdminStar = false;
|
bool hasAdminStar = false;
|
||||||
bool hasRemoveLink = false;
|
bool hasRemoveLink = false;
|
||||||
|
std_::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
};
|
};
|
||||||
virtual int getListTop() const {
|
virtual int getListTop() const {
|
||||||
return contentTop();
|
return contentTop();
|
||||||
|
@ -111,9 +117,11 @@ private:
|
||||||
void updateSelection();
|
void updateSelection();
|
||||||
void setSelected(int selected, bool selectedRemove);
|
void setSelected(int selected, bool selectedRemove);
|
||||||
void repaintSelectedRow();
|
void repaintSelectedRow();
|
||||||
|
void repaintRow(int index);
|
||||||
void preloadPhotos();
|
void preloadPhotos();
|
||||||
|
int rowWidth() const;
|
||||||
|
|
||||||
void paintItem(Painter &p, int x, int y, Item *item, bool selected, bool selectedRemove);
|
void paintItem(Painter &p, int x, int y, Item *item, bool selected, bool selectedRemove, TimeMs ms);
|
||||||
|
|
||||||
base::lambda<void()> _preloadMoreCallback;
|
base::lambda<void()> _preloadMoreCallback;
|
||||||
base::lambda<void(PeerData*)> _selectedCallback;
|
base::lambda<void(PeerData*)> _selectedCallback;
|
||||||
|
|
|
@ -60,8 +60,8 @@ protected:
|
||||||
|
|
||||||
Window::TopBarWidget::paintUnreadCounter(p, width());
|
Window::TopBarWidget::paintUnreadCounter(p, width());
|
||||||
}
|
}
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override {
|
void onStateChanged(State was, StateChangeSource source) override {
|
||||||
if ((_state & StateDown) && !(oldState & StateDown)) {
|
if (isDown() && !(was & StateFlag::Down)) {
|
||||||
emit clicked();
|
emit clicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,7 +177,7 @@ void EmojiColorPicker::step_appearance(float64 ms, bool timer) {
|
||||||
void EmojiColorPicker::hideFast() {
|
void EmojiColorPicker::hideFast() {
|
||||||
clearSelection();
|
clearSelection();
|
||||||
if (_a_appearance.animating()) _a_appearance.stop();
|
if (_a_appearance.animating()) _a_appearance.stop();
|
||||||
a_opacity = anim::fvalue(0);
|
a_opacity = anim::value();
|
||||||
_cache = QPixmap();
|
_cache = QPixmap();
|
||||||
hide();
|
hide();
|
||||||
emit hidden();
|
emit hidden();
|
||||||
|
@ -2899,7 +2899,9 @@ void EmojiPan::paintContent(Painter &p) {
|
||||||
paintStickerSettingsIcon(p);
|
paintStickerSettingsIcon(p);
|
||||||
|
|
||||||
if (!_icons.isEmpty()) {
|
if (!_icons.isEmpty()) {
|
||||||
int x = _iconsLeft, selxrel = _iconsLeft + _iconSelX.current(), selx = selxrel - _iconsX.current();
|
auto x = _iconsLeft;
|
||||||
|
auto selxrel = _iconsLeft + qRound(_iconSelX.current());
|
||||||
|
auto selx = selxrel - qRound(_iconsX.current());
|
||||||
|
|
||||||
QRect clip(x, _iconsTop, _iconsLeft + 7 * st::emojiCategory.width - x, st::emojiCategory.height);
|
QRect clip(x, _iconsTop, _iconsLeft + 7 * st::emojiCategory.width - x, st::emojiCategory.height);
|
||||||
if (rtl()) clip.moveLeft(width() - x - clip.width());
|
if (rtl()) clip.moveLeft(width() - x - clip.width());
|
||||||
|
@ -2915,9 +2917,10 @@ void EmojiPan::paintContent(Painter &p) {
|
||||||
};
|
};
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
i += _iconsX.current() / int(st::emojiCategory.width);
|
auto iconsX = qRound(_iconsX.current());
|
||||||
x -= _iconsX.current() % int(st::emojiCategory.width);
|
i += iconsX / int(st::emojiCategory.width);
|
||||||
selxrel -= _iconsX.current();
|
x -= iconsX % int(st::emojiCategory.width);
|
||||||
|
selxrel -= iconsX;
|
||||||
for (int l = qMin(_icons.size(), i + 8); i < l; ++i) {
|
for (int l = qMin(_icons.size(), i + 8); i < l; ++i) {
|
||||||
auto &s = _icons.at(i);
|
auto &s = _icons.at(i);
|
||||||
if (s.sticker) {
|
if (s.sticker) {
|
||||||
|
@ -2938,13 +2941,13 @@ void EmojiPan::paintContent(Painter &p) {
|
||||||
if (rtl()) selx = width() - selx - st::emojiCategory.width;
|
if (rtl()) selx = width() - selx - st::emojiCategory.width;
|
||||||
p.fillRect(selx, _iconsTop + st::emojiCategory.height - st::stickerIconPadding, st::emojiCategory.width, st::stickerIconSel, st::stickerIconSelColor);
|
p.fillRect(selx, _iconsTop + st::emojiCategory.height - st::stickerIconPadding, st::emojiCategory.width, st::stickerIconSel, st::stickerIconSelColor);
|
||||||
|
|
||||||
float64 o_left = snap(float64(_iconsX.current()) / st::stickerIconLeft.width(), 0., 1.);
|
auto o_left = snap(_iconsX.current() / st::stickerIconLeft.width(), 0., 1.);
|
||||||
if (o_left > 0) {
|
if (o_left > 0) {
|
||||||
p.setOpacity(o_left);
|
p.setOpacity(o_left);
|
||||||
st::stickerIconLeft.fill(p, rtlrect(_iconsLeft, _iconsTop, st::stickerIconLeft.width(), st::emojiCategory.height, width()));
|
st::stickerIconLeft.fill(p, rtlrect(_iconsLeft, _iconsTop, st::stickerIconLeft.width(), st::emojiCategory.height, width()));
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
float64 o_right = snap(float64(_iconsMax - _iconsX.current()) / st::stickerIconRight.width(), 0., 1.);
|
auto o_right = snap((_iconsMax - _iconsX.current()) / st::stickerIconRight.width(), 0., 1.);
|
||||||
if (o_right > 0) {
|
if (o_right > 0) {
|
||||||
p.setOpacity(o_right);
|
p.setOpacity(o_right);
|
||||||
st::stickerIconRight.fill(p, rtlrect(_iconsLeft + 7 * st::emojiCategory.width - st::stickerIconRight.width(), _iconsTop, st::stickerIconRight.width(), st::emojiCategory.height, width()));
|
st::stickerIconRight.fill(p, rtlrect(_iconsLeft + 7 * st::emojiCategory.width - st::stickerIconRight.width(), _iconsTop, st::stickerIconRight.width(), st::emojiCategory.height, width()));
|
||||||
|
@ -3019,7 +3022,7 @@ void EmojiPan::mousePressEvent(QMouseEvent *e) {
|
||||||
} else {
|
} else {
|
||||||
_iconDown = _iconOver;
|
_iconDown = _iconOver;
|
||||||
_iconsMouseDown = _iconsMousePos;
|
_iconsMouseDown = _iconsMousePos;
|
||||||
_iconsStartX = _iconsX.current();
|
_iconsStartX = qRound(_iconsX.current());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3034,9 +3037,9 @@ void EmojiPan::mouseMoveEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_iconsDragging) {
|
if (_iconsDragging) {
|
||||||
int32 newX = snap(_iconsStartX + (rtl() ? -1 : 1) * (_iconsMouseDown.x() - _iconsMousePos.x()), 0, _iconsMax);
|
auto newX = snap(_iconsStartX + (rtl() ? -1 : 1) * (_iconsMouseDown.x() - _iconsMousePos.x()), 0, _iconsMax);
|
||||||
if (newX != _iconsX.current()) {
|
if (newX != qRound(_iconsX.current())) {
|
||||||
_iconsX = anim::ivalue(newX, newX);
|
_iconsX = anim::value(newX, newX);
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
updateIcons();
|
updateIcons();
|
||||||
|
@ -3052,9 +3055,9 @@ void EmojiPan::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
|
||||||
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
_iconsMousePos = e ? e->globalPos() : QCursor::pos();
|
||||||
if (_iconsDragging) {
|
if (_iconsDragging) {
|
||||||
int32 newX = snap(_iconsStartX + _iconsMouseDown.x() - _iconsMousePos.x(), 0, _iconsMax);
|
auto newX = snap(_iconsStartX + _iconsMouseDown.x() - _iconsMousePos.x(), 0, _iconsMax);
|
||||||
if (newX != _iconsX.current()) {
|
if (newX != qRound(_iconsX.current())) {
|
||||||
_iconsX = anim::ivalue(newX, newX);
|
_iconsX = anim::value(newX, newX);
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
updateIcons();
|
updateIcons();
|
||||||
|
@ -3065,7 +3068,7 @@ void EmojiPan::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
|
||||||
if (wasDown == _iconOver && _iconOver >= 0 && _iconOver < _icons.size()) {
|
if (wasDown == _iconOver && _iconOver >= 0 && _iconOver < _icons.size()) {
|
||||||
_iconSelX = anim::ivalue(_iconOver * st::emojiCategory.width, _iconOver * st::emojiCategory.width);
|
_iconSelX = anim::value(_iconOver * st::emojiCategory.width, _iconOver * st::emojiCategory.width);
|
||||||
s_inner->showStickerSet(_icons.at(_iconOver).setId);
|
s_inner->showStickerSet(_icons.at(_iconOver).setId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3080,14 +3083,14 @@ bool EmojiPan::event(QEvent *e) {
|
||||||
bool hor = (ev->angleDelta().x() != 0 || ev->orientation() == Qt::Horizontal);
|
bool hor = (ev->angleDelta().x() != 0 || ev->orientation() == Qt::Horizontal);
|
||||||
bool ver = (ev->angleDelta().y() != 0 || ev->orientation() == Qt::Vertical);
|
bool ver = (ev->angleDelta().y() != 0 || ev->orientation() == Qt::Vertical);
|
||||||
if (hor) _horizontal = true;
|
if (hor) _horizontal = true;
|
||||||
int32 newX = _iconsX.current();
|
auto newX = qRound(_iconsX.current());
|
||||||
if (/*_horizontal && */hor) {
|
if (/*_horizontal && */hor) {
|
||||||
newX = snap(newX - (rtl() ? -1 : 1) * (ev->pixelDelta().x() ? ev->pixelDelta().x() : ev->angleDelta().x()), 0, _iconsMax);
|
newX = snap(newX - (rtl() ? -1 : 1) * (ev->pixelDelta().x() ? ev->pixelDelta().x() : ev->angleDelta().x()), 0, _iconsMax);
|
||||||
} else if (/*!_horizontal && */ver) {
|
} else if (/*!_horizontal && */ver) {
|
||||||
newX = snap(newX - (ev->pixelDelta().y() ? ev->pixelDelta().y() : ev->angleDelta().y()), 0, _iconsMax);
|
newX = snap(newX - (ev->pixelDelta().y() ? ev->pixelDelta().y() : ev->angleDelta().y()), 0, _iconsMax);
|
||||||
}
|
}
|
||||||
if (newX != _iconsX.current()) {
|
if (newX != qRound(_iconsX.current())) {
|
||||||
_iconsX = anim::ivalue(newX, newX);
|
_iconsX = anim::value(newX, newX);
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
@ -3138,7 +3141,7 @@ void EmojiPan::onRefreshIcons(bool scrollAnimation) {
|
||||||
_iconsMax = qMax(int((_icons.size() - 7) * st::emojiCategory.width), 0);
|
_iconsMax = qMax(int((_icons.size() - 7) * st::emojiCategory.width), 0);
|
||||||
}
|
}
|
||||||
if (_iconsX.current() > _iconsMax) {
|
if (_iconsX.current() > _iconsMax) {
|
||||||
_iconsX = anim::ivalue(_iconsMax, _iconsMax);
|
_iconsX = anim::value(_iconsMax, _iconsMax);
|
||||||
}
|
}
|
||||||
updatePanelsPositions(s_panels, s_scroll->scrollTop());
|
updatePanelsPositions(s_panels, s_scroll->scrollTop());
|
||||||
updateSelected();
|
updateSelected();
|
||||||
|
@ -3178,7 +3181,7 @@ void EmojiPan::updateSelected() {
|
||||||
newOver = _icons.size();
|
newOver = _icons.size();
|
||||||
} else if (!_icons.isEmpty()) {
|
} else if (!_icons.isEmpty()) {
|
||||||
if (y >= _iconsTop && y < _iconsTop + st::emojiCategory.height && x >= 0 && x < 7 * st::emojiCategory.width && x < _icons.size() * st::emojiCategory.width) {
|
if (y >= _iconsTop && y < _iconsTop + st::emojiCategory.height && x >= 0 && x < 7 * st::emojiCategory.width && x < _icons.size() * st::emojiCategory.width) {
|
||||||
x += _iconsX.current();
|
x += qRound(_iconsX.current());
|
||||||
newOver = qFloor(x / st::emojiCategory.width);
|
newOver = qFloor(x / st::emojiCategory.width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3329,8 +3332,8 @@ void EmojiPan::hideFinished() {
|
||||||
s_scroll->scrollToY(0);
|
s_scroll->scrollToY(0);
|
||||||
_iconOver = _iconDown = -1;
|
_iconOver = _iconDown = -1;
|
||||||
_iconSel = 0;
|
_iconSel = 0;
|
||||||
_iconsX = anim::ivalue(0, 0);
|
_iconsX = anim::value();
|
||||||
_iconSelX = anim::ivalue(0, 0);
|
_iconSelX = anim::value();
|
||||||
_iconsStartAnim = 0;
|
_iconsStartAnim = 0;
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
|
|
||||||
|
@ -3512,14 +3515,14 @@ void EmojiPan::onScrollEmoji() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::setCurrentTabIcon(DBIEmojiTab tab) {
|
void EmojiPan::setCurrentTabIcon(DBIEmojiTab tab) {
|
||||||
_recent->setIcon((tab == dbietRecent) ? &st::emojiRecentActive : nullptr);
|
_recent->setIconOverride((tab == dbietRecent) ? &st::emojiRecentActive : nullptr);
|
||||||
_people->setIcon((tab == dbietPeople) ? &st::emojiPeopleActive : nullptr);
|
_people->setIconOverride((tab == dbietPeople) ? &st::emojiPeopleActive : nullptr);
|
||||||
_nature->setIcon((tab == dbietNature) ? &st::emojiNatureActive : nullptr);
|
_nature->setIconOverride((tab == dbietNature) ? &st::emojiNatureActive : nullptr);
|
||||||
_food->setIcon((tab == dbietFood) ? &st::emojiFoodActive : nullptr);
|
_food->setIconOverride((tab == dbietFood) ? &st::emojiFoodActive : nullptr);
|
||||||
_activity->setIcon((tab == dbietActivity) ? &st::emojiActivityActive : nullptr);
|
_activity->setIconOverride((tab == dbietActivity) ? &st::emojiActivityActive : nullptr);
|
||||||
_travel->setIcon((tab == dbietTravel) ? &st::emojiTravelActive : nullptr);
|
_travel->setIconOverride((tab == dbietTravel) ? &st::emojiTravelActive : nullptr);
|
||||||
_objects->setIcon((tab == dbietObjects) ? &st::emojiObjectsActive : nullptr);
|
_objects->setIconOverride((tab == dbietObjects) ? &st::emojiObjectsActive : nullptr);
|
||||||
_symbols->setIcon((tab == dbietSymbols) ? &st::emojiSymbolsActive : nullptr);
|
_symbols->setIconOverride((tab == dbietSymbols) ? &st::emojiSymbolsActive : nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiPan::onScrollStickers() {
|
void EmojiPan::onScrollStickers() {
|
||||||
|
@ -3550,11 +3553,11 @@ void EmojiPan::validateSelectedIcon(ValidateIconAnimations animations) {
|
||||||
if (animations == ValidateIconAnimations::Full) {
|
if (animations == ValidateIconAnimations::Full) {
|
||||||
_iconSelX.start(iconSelXFinal);
|
_iconSelX.start(iconSelXFinal);
|
||||||
} else {
|
} else {
|
||||||
_iconSelX = anim::ivalue(iconSelXFinal, iconSelXFinal);
|
_iconSelX = anim::value(iconSelXFinal, iconSelXFinal);
|
||||||
}
|
}
|
||||||
auto iconsXFinal = snap((2 * newSel - 7) * int(st::emojiCategory.width) / 2, 0, _iconsMax);
|
auto iconsXFinal = snap((2 * newSel - 7) * int(st::emojiCategory.width) / 2, 0, _iconsMax);
|
||||||
if (animations == ValidateIconAnimations::None) {
|
if (animations == ValidateIconAnimations::None) {
|
||||||
_iconsX = anim::ivalue(iconsXFinal, iconsXFinal);
|
_iconsX = anim::value(iconsXFinal, iconsXFinal);
|
||||||
_a_icons.stop();
|
_a_icons.stop();
|
||||||
} else {
|
} else {
|
||||||
_iconsX.start(iconsXFinal);
|
_iconsX.start(iconsXFinal);
|
||||||
|
|
|
@ -108,7 +108,7 @@ private:
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
QPixmap _cache;
|
QPixmap _cache;
|
||||||
|
|
||||||
anim::fvalue a_opacity;
|
anim::value a_opacity;
|
||||||
Animation _a_appearance;
|
Animation _a_appearance;
|
||||||
|
|
||||||
QTimer _hideTimer;
|
QTimer _hideTimer;
|
||||||
|
@ -661,8 +661,8 @@ private:
|
||||||
int _iconsTop = 0;
|
int _iconsTop = 0;
|
||||||
int _iconsStartX = 0;
|
int _iconsStartX = 0;
|
||||||
int _iconsMax = 0;
|
int _iconsMax = 0;
|
||||||
anim::ivalue _iconsX = { 0, 0 };
|
anim::value _iconsX;
|
||||||
anim::ivalue _iconSelX = { 0, 0 };
|
anim::value _iconSelX;
|
||||||
TimeMs _iconsStartAnim = 0;
|
TimeMs _iconsStartAnim = 0;
|
||||||
|
|
||||||
bool _emojiShown = true;
|
bool _emojiShown = true;
|
||||||
|
|
|
@ -190,4 +190,10 @@ hashtagClose: IconButton {
|
||||||
icon: simpleCloseIcon;
|
icon: simpleCloseIcon;
|
||||||
iconOver: simpleCloseIconOver;
|
iconOver: simpleCloseIconOver;
|
||||||
iconPosition: point(10px, 10px);
|
iconPosition: point(10px, 10px);
|
||||||
|
|
||||||
|
rippleAreaPosition: point(5px, 5px);
|
||||||
|
rippleAreaSize: 20px;
|
||||||
|
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||||
|
color: windowBgOver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,15 +24,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
void AbstractButton::leaveEvent(QEvent *e) {
|
void AbstractButton::leaveEvent(QEvent *e) {
|
||||||
if (_state & StateDown) return;
|
if (_state & StateFlag::Down) return;
|
||||||
|
|
||||||
setOver(false, StateChangeSource::ByHover);
|
setOver(false, StateChangeSource::ByHover);
|
||||||
return TWidget::leaveEvent(e);
|
return TWidget::leaveEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractButton::enterEvent(QEvent *e) {
|
void AbstractButton::enterEvent(QEvent *e) {
|
||||||
auto over = rect().marginsRemoved(getMargins()).contains(mapFromGlobal(QCursor::pos()));
|
checkIfOver(mapFromGlobal(QCursor::pos()));
|
||||||
setOver(over, StateChangeSource::ByHover);
|
|
||||||
return TWidget::enterEvent(e);
|
return TWidget::enterEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,12 +39,18 @@ void AbstractButton::setAcceptBoth(bool acceptBoth) {
|
||||||
_acceptBoth = acceptBoth;
|
_acceptBoth = acceptBoth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractButton::checkIfOver(QPoint localPos) {
|
||||||
|
auto over = rect().marginsRemoved(getMargins()).contains(localPos);
|
||||||
|
setOver(over, StateChangeSource::ByHover);
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractButton::mousePressEvent(QMouseEvent *e) {
|
void AbstractButton::mousePressEvent(QMouseEvent *e) {
|
||||||
|
checkIfOver(e->pos());
|
||||||
if (_acceptBoth || (e->buttons() & Qt::LeftButton)) {
|
if (_acceptBoth || (e->buttons() & Qt::LeftButton)) {
|
||||||
if ((_state & StateOver) && !(_state & StateDown)) {
|
if ((_state & StateFlag::Over) && !(_state & StateFlag::Down)) {
|
||||||
int oldState = _state;
|
auto was = _state;
|
||||||
_state |= StateDown;
|
_state |= StateFlag::Down;
|
||||||
onStateChanged(oldState, StateChangeSource::ByPress);
|
onStateChanged(was, StateChangeSource::ByPress);
|
||||||
|
|
||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
@ -61,11 +66,11 @@ void AbstractButton::mouseMoveEvent(QMouseEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractButton::mouseReleaseEvent(QMouseEvent *e) {
|
void AbstractButton::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
if (_state & StateDown) {
|
if (_state & StateFlag::Down) {
|
||||||
int oldState = _state;
|
auto was = _state;
|
||||||
_state &= ~StateDown;
|
_state &= ~State(StateFlag::Down);
|
||||||
onStateChanged(oldState, StateChangeSource::ByPress);
|
onStateChanged(was, StateChangeSource::ByPress);
|
||||||
if (oldState & StateOver) {
|
if (was & StateFlag::Over) {
|
||||||
_modifiers = e->modifiers();
|
_modifiers = e->modifiers();
|
||||||
if (_clickedCallback) {
|
if (_clickedCallback) {
|
||||||
_clickedCallback();
|
_clickedCallback();
|
||||||
|
@ -73,43 +78,39 @@ void AbstractButton::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
emit clicked();
|
emit clicked();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
leaveEvent(e);
|
setOver(false, StateChangeSource::ByHover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractButton::setOver(bool over, StateChangeSource source) {
|
void AbstractButton::setOver(bool over, StateChangeSource source) {
|
||||||
setCursor(over ? style::cur_pointer : style::cur_default);
|
setCursor(over ? style::cur_pointer : style::cur_default);
|
||||||
if (over && !(_state & StateOver)) {
|
if (over && !(_state & StateFlag::Over)) {
|
||||||
int oldState = _state;
|
auto was = _state;
|
||||||
_state |= StateOver;
|
_state |= StateFlag::Over;
|
||||||
onStateChanged(oldState, source);
|
onStateChanged(was, source);
|
||||||
} else if (!over && (_state & StateOver)) {
|
} else if (!over && (_state & StateFlag::Over)) {
|
||||||
int oldState = _state;
|
auto was = _state;
|
||||||
_state &= ~StateOver;
|
_state &= ~State(StateFlag::Over);
|
||||||
onStateChanged(oldState, source);
|
onStateChanged(was, source);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractButton::setDisabled(bool disabled) {
|
void AbstractButton::setDisabled(bool disabled) {
|
||||||
int oldState = _state;
|
auto was = _state;
|
||||||
if (disabled && !(_state & StateDisabled)) {
|
if (disabled && !(_state & StateFlag::Disabled)) {
|
||||||
_state |= StateDisabled;
|
_state |= StateFlag::Disabled;
|
||||||
onStateChanged(oldState, StateChangeSource::ByUser);
|
onStateChanged(was, StateChangeSource::ByUser);
|
||||||
} else if (!disabled && (_state & StateDisabled)) {
|
} else if (!disabled && (_state & StateFlag::Disabled)) {
|
||||||
_state &= ~StateDisabled;
|
_state &= ~State(StateFlag::Disabled);
|
||||||
onStateChanged(oldState, StateChangeSource::ByUser);
|
onStateChanged(was, StateChangeSource::ByUser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractButton::clearState() {
|
void AbstractButton::clearState() {
|
||||||
int oldState = _state;
|
auto was = _state;
|
||||||
_state = StateNone;
|
_state = StateFlag::None;
|
||||||
onStateChanged(oldState, StateChangeSource::ByUser);
|
onStateChanged(was, StateChangeSource::ByUser);
|
||||||
}
|
|
||||||
|
|
||||||
int AbstractButton::getState() const {
|
|
||||||
return _state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -28,34 +28,24 @@ class AbstractButton : public TWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum class StateChangeSource {
|
|
||||||
ByUser = 0x00,
|
|
||||||
ByPress = 0x01,
|
|
||||||
ByHover = 0x02,
|
|
||||||
};
|
|
||||||
|
|
||||||
AbstractButton(QWidget *parent) : TWidget(parent) {
|
AbstractButton(QWidget *parent) : TWidget(parent) {
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
|
||||||
StateNone = 0x00,
|
|
||||||
StateOver = 0x01,
|
|
||||||
StateDown = 0x02,
|
|
||||||
StateDisabled = 0x04,
|
|
||||||
};
|
|
||||||
|
|
||||||
Qt::KeyboardModifiers clickModifiers() const {
|
Qt::KeyboardModifiers clickModifiers() const {
|
||||||
return _modifiers;
|
return _modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clearState();
|
|
||||||
int getState() const;
|
|
||||||
|
|
||||||
void setDisabled(bool disabled = true);
|
void setDisabled(bool disabled = true);
|
||||||
void setOver(bool over, StateChangeSource source = StateChangeSource::ByUser);
|
void clearState();
|
||||||
bool disabled() const {
|
bool isOver() const {
|
||||||
return (_state & StateDisabled);
|
return _state & StateFlag::Over;
|
||||||
|
}
|
||||||
|
bool isDown() const {
|
||||||
|
return _state & StateFlag::Down;
|
||||||
|
}
|
||||||
|
bool isDisabled() {
|
||||||
|
return _state & StateFlag::Disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setAcceptBoth(bool acceptBoth = true);
|
void setAcceptBoth(bool acceptBoth = true);
|
||||||
|
@ -75,15 +65,41 @@ signals:
|
||||||
void clicked();
|
void clicked();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void onStateChanged(int oldState, StateChangeSource source) {
|
enum class StateFlag {
|
||||||
|
None = 0x00,
|
||||||
|
Over = 0x01,
|
||||||
|
Down = 0x02,
|
||||||
|
Disabled = 0x04,
|
||||||
|
};
|
||||||
|
Q_DECLARE_FLAGS(State, StateFlag);
|
||||||
|
Q_DECLARE_FRIEND_OPERATORS_FOR_FLAGS(State);
|
||||||
|
|
||||||
|
State state() const {
|
||||||
|
return _state;
|
||||||
}
|
}
|
||||||
|
|
||||||
Qt::KeyboardModifiers _modifiers;
|
enum class StateChangeSource {
|
||||||
int _state = StateNone;
|
ByUser = 0x00,
|
||||||
|
ByPress = 0x01,
|
||||||
|
ByHover = 0x02,
|
||||||
|
};
|
||||||
|
void setOver(bool over, StateChangeSource source = StateChangeSource::ByUser);
|
||||||
|
|
||||||
|
virtual void onStateChanged(State was, StateChangeSource source) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void checkIfOver(QPoint localPos);
|
||||||
|
|
||||||
|
State _state = StateFlag::None;
|
||||||
|
|
||||||
bool _acceptBoth = false;
|
bool _acceptBoth = false;
|
||||||
|
Qt::KeyboardModifiers _modifiers;
|
||||||
|
|
||||||
base::lambda<void()> _clickedCallback;
|
base::lambda<void()> _clickedCallback;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_OPERATORS_FOR_FLAGS(AbstractButton::State);
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -158,56 +158,6 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using fvalue = value;
|
|
||||||
|
|
||||||
class ivalue { // int animated value
|
|
||||||
public:
|
|
||||||
using ValueType = int;
|
|
||||||
|
|
||||||
ivalue() = default;
|
|
||||||
ivalue(int from) : _cur(from), _from(float64(from)) {
|
|
||||||
}
|
|
||||||
ivalue(int from, int to) : _cur(from), _from(float64(from)), _delta(float64(to - from)) {
|
|
||||||
}
|
|
||||||
void start(int32 to) {
|
|
||||||
_from = float64(_cur);
|
|
||||||
_delta = float64(to) - _from;
|
|
||||||
}
|
|
||||||
void restart() {
|
|
||||||
_delta = _from + _delta - float64(_cur);
|
|
||||||
_from = float64(_cur);
|
|
||||||
}
|
|
||||||
|
|
||||||
int from() const {
|
|
||||||
return _from;
|
|
||||||
}
|
|
||||||
int current() const {
|
|
||||||
return _cur;
|
|
||||||
}
|
|
||||||
int to() const {
|
|
||||||
return qRound(_from + _delta);
|
|
||||||
}
|
|
||||||
void add(int delta) {
|
|
||||||
_from += delta;
|
|
||||||
_cur += delta;
|
|
||||||
}
|
|
||||||
ivalue &update(float64 dt, const transition &func) {
|
|
||||||
_cur = qRound(_from + func(_delta, dt));
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
void finish() {
|
|
||||||
_cur = qRound(_from + _delta);
|
|
||||||
_from = _cur;
|
|
||||||
_delta = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
int _cur = 0;
|
|
||||||
float64 _from = 0.;
|
|
||||||
float64 _delta = 0.;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void startManager();
|
void startManager();
|
||||||
void stopManager();
|
void stopManager();
|
||||||
void registerClipManager(Media::Clip::Manager *manager);
|
void registerClipManager(Media::Clip::Manager *manager);
|
||||||
|
@ -639,7 +589,9 @@ public:
|
||||||
|
|
||||||
template <typename Lambda>
|
template <typename Lambda>
|
||||||
void start(Lambda &&updateCallback, const ValueType &from, const ValueType &to, float64 duration, const anim::transition &transition = anim::linear) {
|
void start(Lambda &&updateCallback, const ValueType &from, const ValueType &to, float64 duration, const anim::transition &transition = anim::linear) {
|
||||||
if (!_data) {
|
if (_data) {
|
||||||
|
_data->pause.restart();
|
||||||
|
} else {
|
||||||
_data = std_::make_unique<Data>(from, std_::forward<Lambda>(updateCallback));
|
_data = std_::make_unique<Data>(from, std_::forward<Lambda>(updateCallback));
|
||||||
}
|
}
|
||||||
_data->value.start(to);
|
_data->value.start(to);
|
||||||
|
@ -674,6 +626,7 @@ private:
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
value.finish();
|
value.finish();
|
||||||
a_animation.stop();
|
a_animation.stop();
|
||||||
|
pause.release();
|
||||||
} else {
|
} else {
|
||||||
value.update(dt, transition);
|
value.update(dt, transition);
|
||||||
}
|
}
|
||||||
|
@ -685,13 +638,13 @@ private:
|
||||||
Callback updateCallback;
|
Callback updateCallback;
|
||||||
float64 duration = 0.;
|
float64 duration = 0.;
|
||||||
anim::transition transition = anim::linear;
|
anim::transition transition = anim::linear;
|
||||||
|
MTP::PauseHolder pause;
|
||||||
};
|
};
|
||||||
mutable std_::unique_ptr<Data> _data;
|
mutable std_::unique_ptr<Data> _data;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
using FloatAnimation = SimpleAnimation<anim::fvalue>;
|
using FloatAnimation = SimpleAnimation<anim::value>;
|
||||||
using IntAnimation = SimpleAnimation<anim::ivalue>;
|
|
||||||
|
|
||||||
class AnimationManager : public QObject {
|
class AnimationManager : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -55,8 +55,8 @@ void HistoryDownButton::paintEvent(QPaintEvent *e) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p.setOpacity(opacity);
|
p.setOpacity(opacity);
|
||||||
auto over = (_state & StateOver);
|
auto over = isOver();
|
||||||
auto down = (_state & StateDown);
|
auto down = isDown();
|
||||||
((over || down) ? _st.iconBelowOver : _st.iconBelow).paint(p, _st.iconPosition, width());
|
((over || down) ? _st.iconBelowOver : _st.iconBelow).paint(p, _st.iconPosition, width());
|
||||||
paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms);
|
paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms);
|
||||||
((over || down) ? _st.iconAboveOver : _st.iconAbove).paint(p, _st.iconPosition, width());
|
((over || down) ? _st.iconAboveOver : _st.iconAbove).paint(p, _st.iconPosition, width());
|
||||||
|
@ -118,7 +118,7 @@ void HistoryDownButton::step_arrowOver(float64 ms, bool timer) {
|
||||||
if (timer) update();
|
if (timer) update();
|
||||||
}
|
}
|
||||||
|
|
||||||
EmojiButton::EmojiButton(QWidget *parent, const style::IconButton &st) : AbstractButton(parent)
|
EmojiButton::EmojiButton(QWidget *parent, const style::IconButton &st) : RippleButton(parent, st.ripple)
|
||||||
, _st(st)
|
, _st(st)
|
||||||
, _a_loading(animation(this, &EmojiButton::step_loading)) {
|
, _a_loading(animation(this, &EmojiButton::step_loading)) {
|
||||||
resize(_st.width, _st.height);
|
resize(_st.width, _st.height);
|
||||||
|
@ -131,11 +131,12 @@ void EmojiButton::paintEvent(QPaintEvent *e) {
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
|
|
||||||
p.fillRect(e->rect(), st::historyComposeAreaBg);
|
p.fillRect(e->rect(), st::historyComposeAreaBg);
|
||||||
|
paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms);
|
||||||
|
|
||||||
auto loading = a_loading.current(ms, _loading ? 1 : 0);
|
auto loading = a_loading.current(ms, _loading ? 1 : 0);
|
||||||
p.setOpacity(1 - loading);
|
p.setOpacity(1 - loading);
|
||||||
|
|
||||||
auto over = (_state & StateOver);
|
auto over = isOver();
|
||||||
auto icon = &(over ? _st.iconOver : _st.icon);
|
auto icon = &(over ? _st.iconOver : _st.icon);
|
||||||
icon->paint(p, _st.iconPosition, width());
|
icon->paint(p, _st.iconPosition, width());
|
||||||
|
|
||||||
|
@ -170,11 +171,20 @@ void EmojiButton::setLoading(bool loading) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmojiButton::onStateChanged(int oldState, StateChangeSource source) {
|
void EmojiButton::onStateChanged(State was, StateChangeSource source) {
|
||||||
auto over = (_state & StateOver);
|
RippleButton::onStateChanged(was, source);
|
||||||
if (over != (oldState & StateOver)) {
|
auto wasOver = static_cast<bool>(was & StateFlag::Over);
|
||||||
|
if (isOver() != wasOver) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPoint EmojiButton::prepareRippleStartPosition() const {
|
||||||
|
return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage EmojiButton::prepareRippleMask() const {
|
||||||
|
return RippleAnimation::ellipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
|
@ -55,7 +55,7 @@ private:
|
||||||
|
|
||||||
bool _shown = false;
|
bool _shown = false;
|
||||||
|
|
||||||
anim::fvalue a_arrowOpacity;
|
anim::value a_arrowOpacity;
|
||||||
Animation _a_arrowOver;
|
Animation _a_arrowOver;
|
||||||
|
|
||||||
FloatAnimation _a_show;
|
FloatAnimation _a_show;
|
||||||
|
@ -64,7 +64,7 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class EmojiButton : public AbstractButton {
|
class EmojiButton : public RippleButton {
|
||||||
public:
|
public:
|
||||||
EmojiButton(QWidget *parent, const style::IconButton &st);
|
EmojiButton(QWidget *parent, const style::IconButton &st);
|
||||||
|
|
||||||
|
@ -72,7 +72,10 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
|
QImage prepareRippleMask() const override;
|
||||||
|
QPoint prepareRippleStartPosition() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const style::IconButton &_st;
|
const style::IconButton &_st;
|
||||||
|
|
|
@ -54,7 +54,7 @@ void NewAvatarButton::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush((_state & StateOver) ? st::defaultActiveButton.textBgOver : st::defaultActiveButton.textBg);
|
p.setBrush(isOver() ? st::defaultActiveButton.textBgOver : st::defaultActiveButton.textBg);
|
||||||
{
|
{
|
||||||
PainterHighQualityEnabler hq(p);
|
PainterHighQualityEnabler hq(p);
|
||||||
p.drawEllipse(rect());
|
p.drawEllipse(rect());
|
||||||
|
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "application.h"
|
#include "application.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
#include "ui/widgets/multi_select.h"
|
#include "ui/widgets/multi_select.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "boxes/contactsbox.h"
|
#include "boxes/contactsbox.h"
|
||||||
#include "countries.h"
|
#include "countries.h"
|
||||||
#include "styles/style_boxes.h"
|
#include "styles/style_boxes.h"
|
||||||
|
@ -283,6 +284,7 @@ void CountrySelectBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
QRect r(e->rect());
|
QRect r(e->rect());
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
|
|
||||||
|
auto ms = getms();
|
||||||
int l = countriesNow->size();
|
int l = countriesNow->size();
|
||||||
if (l) {
|
if (l) {
|
||||||
if (r.intersects(QRect(0, 0, width(), st::countriesSkip))) {
|
if (r.intersects(QRect(0, 0, width(), st::countriesSkip))) {
|
||||||
|
@ -291,10 +293,16 @@ void CountrySelectBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
int32 from = floorclamp(r.y() - st::countriesSkip, _rowHeight, 0, l);
|
int32 from = floorclamp(r.y() - st::countriesSkip, _rowHeight, 0, l);
|
||||||
int32 to = ceilclamp(r.y() + r.height() - st::countriesSkip, _rowHeight, 0, l);
|
int32 to = ceilclamp(r.y() + r.height() - st::countriesSkip, _rowHeight, 0, l);
|
||||||
for (int32 i = from; i < to; ++i) {
|
for (int32 i = from; i < to; ++i) {
|
||||||
bool sel = (i == _sel);
|
auto selected = (i == (_pressed >= 0 ? _pressed : _selected));
|
||||||
int32 y = st::countriesSkip + i * _rowHeight;
|
auto y = st::countriesSkip + i * _rowHeight;
|
||||||
|
|
||||||
p.fillRect(0, y, width(), _rowHeight, sel ? st::countryRowBgOver : st::countryRowBg);
|
p.fillRect(0, y, width(), _rowHeight, selected ? st::countryRowBgOver : st::countryRowBg);
|
||||||
|
if (_ripples.size() > i && _ripples[i]) {
|
||||||
|
_ripples[i]->paint(p, 0, y, width(), ms);
|
||||||
|
if (_ripples[i]->empty()) {
|
||||||
|
_ripples[i].reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString code = QString("+") + (*countriesNow)[i]->code;
|
QString code = QString("+") + (*countriesNow)[i]->code;
|
||||||
int32 codeWidth = st::countryRowCodeFont->width(code);
|
int32 codeWidth = st::countryRowCodeFont->width(code);
|
||||||
|
@ -312,7 +320,7 @@ void CountrySelectBox::Inner::paintEvent(QPaintEvent *e) {
|
||||||
p.drawTextLeft(st::countryRowPadding.left(), y + st::countryRowPadding.top(), width(), name);
|
p.drawTextLeft(st::countryRowPadding.left(), y + st::countryRowPadding.top(), width(), name);
|
||||||
|
|
||||||
p.setFont(st::countryRowCodeFont);
|
p.setFont(st::countryRowCodeFont);
|
||||||
p.setPen(sel ? st::countryRowCodeFgOver : st::countryRowCodeFg);
|
p.setPen(selected ? st::countryRowCodeFgOver : st::countryRowCodeFg);
|
||||||
p.drawTextLeft(st::countryRowPadding.left() + nameWidth + st::countryRowPadding.right(), y + st::countryRowPadding.top(), width(), code);
|
p.drawTextLeft(st::countryRowPadding.left() + nameWidth + st::countryRowPadding.right(), y + st::countryRowPadding.top(), width(), code);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -328,26 +336,49 @@ void CountrySelectBox::Inner::enterEvent(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountrySelectBox::Inner::leaveEvent(QEvent *e) {
|
void CountrySelectBox::Inner::leaveEvent(QEvent *e) {
|
||||||
_mouseSel = false;
|
_mouseSelection = false;
|
||||||
setMouseTracking(false);
|
setMouseTracking(false);
|
||||||
if (_sel >= 0) {
|
if (_selected >= 0) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_sel = -1;
|
_selected = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountrySelectBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
void CountrySelectBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
_mouseSel = true;
|
_mouseSelection = true;
|
||||||
_lastMousePos = e->globalPos();
|
updateSelected(e->pos());
|
||||||
updateSel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountrySelectBox::Inner::mousePressEvent(QMouseEvent *e) {
|
void CountrySelectBox::Inner::mousePressEvent(QMouseEvent *e) {
|
||||||
_mouseSel = true;
|
_mouseSelection = true;
|
||||||
_lastMousePos = e->globalPos();
|
updateSelected(e->pos());
|
||||||
updateSel();
|
|
||||||
|
setPressed(_selected);
|
||||||
|
if (_pressed >= 0 && _pressed < countriesNow->size()) {
|
||||||
|
if (_ripples.size() <= _pressed) {
|
||||||
|
_ripples.reserve(_pressed + 1);
|
||||||
|
while (_ripples.size() <= _pressed) {
|
||||||
|
_ripples.push_back(std_::unique_ptr<Ui::RippleAnimation>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!_ripples[_pressed]) {
|
||||||
|
auto mask = Ui::RippleAnimation::rectMask(QSize(width(), _rowHeight));
|
||||||
|
_ripples[_pressed] = std_::make_unique<Ui::RippleAnimation>(st::countryRipple, std_::move(mask), [this, index = _pressed] {
|
||||||
|
updateRow(index);
|
||||||
|
});
|
||||||
|
_ripples[_pressed]->add(e->pos() - QPoint(0, st::countriesSkip + _pressed * _rowHeight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CountrySelectBox::Inner::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
|
auto pressed = _pressed;
|
||||||
|
setPressed(-1);
|
||||||
|
updateSelectedRow();
|
||||||
if (e->button() == Qt::LeftButton) {
|
if (e->button() == Qt::LeftButton) {
|
||||||
chooseCountry();
|
if ((pressed >= 0) && pressed == _selected) {
|
||||||
|
chooseCountry();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -401,25 +432,25 @@ void CountrySelectBox::Inner::updateFilter(QString filter) {
|
||||||
countriesNow = &countriesFiltered;
|
countriesNow = &countriesFiltered;
|
||||||
}
|
}
|
||||||
refresh();
|
refresh();
|
||||||
_sel = countriesNow->isEmpty() ? -1 : 0;
|
_selected = countriesNow->isEmpty() ? -1 : 0;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountrySelectBox::Inner::selectSkip(int32 dir) {
|
void CountrySelectBox::Inner::selectSkip(int32 dir) {
|
||||||
_mouseSel = false;
|
_mouseSelection = false;
|
||||||
|
|
||||||
int cur = (_sel >= 0) ? _sel : -1;
|
int cur = (_selected >= 0) ? _selected : -1;
|
||||||
cur += dir;
|
cur += dir;
|
||||||
if (cur <= 0) {
|
if (cur <= 0) {
|
||||||
_sel = countriesNow->isEmpty() ? -1 : 0;
|
_selected = countriesNow->isEmpty() ? -1 : 0;
|
||||||
} else if (cur >= countriesNow->size()) {
|
} else if (cur >= countriesNow->size()) {
|
||||||
_sel = -1;
|
_selected = -1;
|
||||||
} else {
|
} else {
|
||||||
_sel = cur;
|
_selected = cur;
|
||||||
}
|
}
|
||||||
if (_sel >= 0) {
|
if (_selected >= 0) {
|
||||||
emit mustScrollTo(st::countriesSkip + _sel * _rowHeight, st::countriesSkip + (_sel + 1) * _rowHeight);
|
emit mustScrollTo(st::countriesSkip + _selected * _rowHeight, st::countriesSkip + (_selected + 1) * _rowHeight);
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
@ -433,12 +464,12 @@ void CountrySelectBox::Inner::selectSkipPage(int32 h, int32 dir) {
|
||||||
void CountrySelectBox::Inner::chooseCountry() {
|
void CountrySelectBox::Inner::chooseCountry() {
|
||||||
QString result;
|
QString result;
|
||||||
if (_filter.isEmpty()) {
|
if (_filter.isEmpty()) {
|
||||||
if (_sel >= 0 && _sel < countriesAll.size()) {
|
if (_selected >= 0 && _selected < countriesAll.size()) {
|
||||||
result = countriesAll[_sel]->iso2;
|
result = countriesAll[_selected]->iso2;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (_sel >= 0 && _sel < countriesFiltered.size()) {
|
if (_selected >= 0 && _selected < countriesFiltered.size()) {
|
||||||
result = countriesFiltered[_sel]->iso2;
|
result = countriesFiltered[_selected]->iso2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
emit countryChosen(result);
|
emit countryChosen(result);
|
||||||
|
@ -448,22 +479,34 @@ void CountrySelectBox::Inner::refresh() {
|
||||||
resize(width(), countriesNow->length() ? (countriesNow->length() * _rowHeight + st::countriesSkip) : st::noContactsHeight);
|
resize(width(), countriesNow->length() ? (countriesNow->length() * _rowHeight + st::countriesSkip) : st::noContactsHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountrySelectBox::Inner::updateSel() {
|
void CountrySelectBox::Inner::updateSelected(QPoint localPos) {
|
||||||
if (!_mouseSel) return;
|
if (!_mouseSelection) return;
|
||||||
|
|
||||||
QPoint p(mapFromGlobal(_lastMousePos));
|
auto in = parentWidget()->rect().contains(parentWidget()->mapFromGlobal(QCursor::pos()));
|
||||||
bool in = parentWidget()->rect().contains(parentWidget()->mapFromGlobal(_lastMousePos));
|
|
||||||
|
|
||||||
int32 newSel = (in && p.y() >= st::countriesSkip && p.y() < st::countriesSkip + countriesNow->size() * _rowHeight) ? ((p.y() - st::countriesSkip) / _rowHeight) : -1;
|
auto selected = (in && localPos.y() >= st::countriesSkip && localPos.y() < st::countriesSkip + countriesNow->size() * _rowHeight) ? ((localPos.y() - st::countriesSkip) / _rowHeight) : -1;
|
||||||
if (newSel != _sel) {
|
if (_selected != selected) {
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
_sel = newSel;
|
_selected = selected;
|
||||||
updateSelectedRow();
|
updateSelectedRow();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CountrySelectBox::Inner::updateSelectedRow() {
|
void CountrySelectBox::Inner::updateSelectedRow() {
|
||||||
if (_sel >= 0) {
|
updateRow(_selected);
|
||||||
update(0, st::countriesSkip + _sel * _rowHeight, width(), _rowHeight);
|
}
|
||||||
|
|
||||||
|
void CountrySelectBox::Inner::updateRow(int index) {
|
||||||
|
if (index >= 0) {
|
||||||
|
update(0, st::countriesSkip + index * _rowHeight, width(), _rowHeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CountrySelectBox::Inner::setPressed(int pressed) {
|
||||||
|
if (_pressed >= 0 && _pressed < _ripples.size() && _ripples[_pressed]) {
|
||||||
|
_ripples[_pressed]->lastStop();
|
||||||
|
}
|
||||||
|
_pressed = pressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
CountrySelectBox::Inner::~Inner() = default;
|
||||||
|
|
|
@ -108,29 +108,36 @@ public:
|
||||||
|
|
||||||
void refresh();
|
void refresh();
|
||||||
|
|
||||||
|
~Inner();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void countryChosen(const QString &iso);
|
void countryChosen(const QString &iso);
|
||||||
void mustScrollTo(int ymin, int ymax);
|
void mustScrollTo(int ymin, int ymax);
|
||||||
|
|
||||||
public slots:
|
|
||||||
void updateSel();
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void enterEvent(QEvent *e) override;
|
void enterEvent(QEvent *e) override;
|
||||||
void leaveEvent(QEvent *e) override;
|
void leaveEvent(QEvent *e) override;
|
||||||
void mouseMoveEvent(QMouseEvent *e) override;
|
void mouseMoveEvent(QMouseEvent *e) override;
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
void mouseReleaseEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateSelected() {
|
||||||
|
updateSelected(mapFromGlobal(QCursor::pos()));
|
||||||
|
}
|
||||||
|
void updateSelected(QPoint localPos);
|
||||||
void updateSelectedRow();
|
void updateSelectedRow();
|
||||||
|
void updateRow(int index);
|
||||||
|
void setPressed(int pressed);
|
||||||
|
|
||||||
int _rowHeight;
|
int _rowHeight;
|
||||||
|
|
||||||
int _sel = 0;
|
int _selected = -1;
|
||||||
|
int _pressed = -1;
|
||||||
QString _filter;
|
QString _filter;
|
||||||
bool _mouseSel = false;
|
bool _mouseSelection = false;
|
||||||
|
|
||||||
QPoint _lastMousePos;
|
std_::vector_of_moveable<std_::unique_ptr<Ui::RippleAnimation>> _ripples;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,45 +24,45 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
RadialAnimation::RadialAnimation(AnimationCallbacks &&callbacks)
|
RadialAnimation::RadialAnimation(AnimationCallbacks &&callbacks)
|
||||||
: a_arcEnd(0, 0)
|
: a_arcStart(0, FullArcLength)
|
||||||
, a_arcStart(0, FullArcLength)
|
|
||||||
, _animation(std_::move(callbacks)) {
|
, _animation(std_::move(callbacks)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialAnimation::start(float64 prg) {
|
void RadialAnimation::start(float64 prg) {
|
||||||
_firstStart = _lastStart = _lastTime = getms();
|
_firstStart = _lastStart = _lastTime = getms();
|
||||||
int32 iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength), iprgstrict = qRound(prg * AlmostFullArcLength);
|
int32 iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength), iprgstrict = qRound(prg * AlmostFullArcLength);
|
||||||
a_arcEnd = anim::ivalue(iprgstrict, iprg);
|
a_arcEnd = anim::value(iprgstrict, iprg);
|
||||||
_animation.start();
|
_animation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialAnimation::update(float64 prg, bool finished, TimeMs ms) {
|
void RadialAnimation::update(float64 prg, bool finished, TimeMs ms) {
|
||||||
int32 iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
|
auto iprg = qRound(qMax(prg, 0.0001) * AlmostFullArcLength);
|
||||||
if (iprg != a_arcEnd.to()) {
|
if (iprg != qRound(a_arcEnd.to())) {
|
||||||
a_arcEnd.start(iprg);
|
a_arcEnd.start(iprg);
|
||||||
_lastStart = _lastTime;
|
_lastStart = _lastTime;
|
||||||
}
|
}
|
||||||
_lastTime = ms;
|
_lastTime = ms;
|
||||||
|
|
||||||
float64 dt = float64(ms - _lastStart), fulldt = float64(ms - _firstStart);
|
auto dt = float64(ms - _lastStart);
|
||||||
|
auto fulldt = float64(ms - _firstStart);
|
||||||
_opacity = qMin(fulldt / st::radialDuration, 1.);
|
_opacity = qMin(fulldt / st::radialDuration, 1.);
|
||||||
if (!finished) {
|
if (!finished) {
|
||||||
a_arcEnd.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
|
a_arcEnd.update(1. - (st::radialDuration / (st::radialDuration + dt)), anim::linear);
|
||||||
} else if (dt >= st::radialDuration) {
|
} else if (dt >= st::radialDuration) {
|
||||||
a_arcEnd.update(1, anim::linear);
|
a_arcEnd.update(1., anim::linear);
|
||||||
stop();
|
stop();
|
||||||
} else {
|
} else {
|
||||||
float64 r = dt / st::radialDuration;
|
auto r = dt / st::radialDuration;
|
||||||
a_arcEnd.update(r, anim::linear);
|
a_arcEnd.update(r, anim::linear);
|
||||||
_opacity *= 1 - r;
|
_opacity *= 1 - r;
|
||||||
}
|
}
|
||||||
float64 fromstart = fulldt / st::radialPeriod;
|
auto fromstart = fulldt / st::radialPeriod;
|
||||||
a_arcStart.update(fromstart - std::floor(fromstart), anim::linear);
|
a_arcStart.update(fromstart - std::floor(fromstart), anim::linear);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadialAnimation::stop() {
|
void RadialAnimation::stop() {
|
||||||
_firstStart = _lastStart = _lastTime = 0;
|
_firstStart = _lastStart = _lastTime = 0;
|
||||||
a_arcEnd = anim::ivalue(0, 0);
|
a_arcEnd = anim::value();
|
||||||
_animation.stop();
|
_animation.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,8 +79,8 @@ void RadialAnimation::draw(Painter &p, const QRect &inner, int32 thickness, cons
|
||||||
pen.setCapStyle(Qt::RoundCap);
|
pen.setCapStyle(Qt::RoundCap);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
|
|
||||||
int32 len = MinArcLength + a_arcEnd.current();
|
auto len = MinArcLength + qRound(a_arcEnd.current());
|
||||||
int32 from = QuarterArcLength - a_arcStart.current() - len;
|
auto from = QuarterArcLength - qRound(a_arcStart.current()) - len;
|
||||||
if (rtl()) {
|
if (rtl()) {
|
||||||
from = QuarterArcLength - (from - QuarterArcLength) - len;
|
from = QuarterArcLength - (from - QuarterArcLength) - len;
|
||||||
if (from < 0) from += FullArcLength;
|
if (from < 0) from += FullArcLength;
|
||||||
|
|
|
@ -49,7 +49,8 @@ private:
|
||||||
TimeMs _lastStart = 0;
|
TimeMs _lastStart = 0;
|
||||||
TimeMs _lastTime = 0;
|
TimeMs _lastTime = 0;
|
||||||
float64 _opacity = 0.;
|
float64 _opacity = 0.;
|
||||||
anim::ivalue a_arcEnd, a_arcStart;
|
anim::value a_arcEnd;
|
||||||
|
anim::value a_arcStart;
|
||||||
Animation _animation;
|
Animation _animation;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -92,7 +92,7 @@ void RippleAnimation::Ripple::paint(QPainter &p, const QPixmap &mask, TimeMs ms,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_cache.isNull()) {
|
if (_cache.isNull() || colorOverride != nullptr) {
|
||||||
auto radius = anim::interpolate(_radiusFrom, _radiusTo, _show.current(ms, 1.));
|
auto radius = anim::interpolate(_radiusFrom, _radiusTo, _show.current(ms, 1.));
|
||||||
_frame.fill(Qt::transparent);
|
_frame.fill(Qt::transparent);
|
||||||
{
|
{
|
||||||
|
@ -110,7 +110,7 @@ void RippleAnimation::Ripple::paint(QPainter &p, const QPixmap &mask, TimeMs ms,
|
||||||
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||||
p.drawPixmap(0, 0, mask);
|
p.drawPixmap(0, 0, mask);
|
||||||
}
|
}
|
||||||
if (radius == _radiusTo) {
|
if (radius == _radiusTo && colorOverride == nullptr) {
|
||||||
_cache = App::pixmapFromImageInPlace(std_::move(_frame));
|
_cache = App::pixmapFromImageInPlace(std_::move(_frame));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,9 +51,9 @@ void WidgetSlideWrap<TWidget>::slideUp() {
|
||||||
if (_a_height.animating()) {
|
if (_a_height.animating()) {
|
||||||
if (_hiding) return;
|
if (_hiding) return;
|
||||||
} else {
|
} else {
|
||||||
a_height = anim::ivalue(_realSize.height());
|
a_height = anim::value(_realSize.height());
|
||||||
}
|
}
|
||||||
a_height.start(0);
|
a_height.start(0.);
|
||||||
_hiding = true;
|
_hiding = true;
|
||||||
_a_height.start();
|
_a_height.start();
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ void WidgetSlideWrap<TWidget>::slideDown() {
|
||||||
if (!_hiding) return;
|
if (!_hiding) return;
|
||||||
}
|
}
|
||||||
a_height.start(_realSize.height());
|
a_height.start(_realSize.height());
|
||||||
_forceHeight = a_height.current();
|
_forceHeight = qRound(a_height.current());
|
||||||
_hiding = false;
|
_hiding = false;
|
||||||
_a_height.start();
|
_a_height.start();
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ void WidgetSlideWrap<TWidget>::showFast() {
|
||||||
|
|
||||||
void WidgetSlideWrap<TWidget>::hideFast() {
|
void WidgetSlideWrap<TWidget>::hideFast() {
|
||||||
_a_height.stop();
|
_a_height.stop();
|
||||||
a_height = anim::ivalue(0);
|
a_height = anim::value();
|
||||||
_forceHeight = 0;
|
_forceHeight = 0;
|
||||||
resizeToWidth(_realSize.width());
|
resizeToWidth(_realSize.width());
|
||||||
hide();
|
hide();
|
||||||
|
@ -144,7 +144,7 @@ void WidgetSlideWrap<TWidget>::step_height(float64 ms, bool timer) {
|
||||||
if (_hiding) hide();
|
if (_hiding) hide();
|
||||||
} else {
|
} else {
|
||||||
a_height.update(dt, anim::linear);
|
a_height.update(dt, anim::linear);
|
||||||
_forceHeight = a_height.current();
|
_forceHeight = qRound(a_height.current());
|
||||||
}
|
}
|
||||||
resizeToWidth(_realSize.width());
|
resizeToWidth(_realSize.width());
|
||||||
if (_updateCallback) {
|
if (_updateCallback) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ private:
|
||||||
|
|
||||||
style::size _realSize;
|
style::size _realSize;
|
||||||
int _forceHeight = -1;
|
int _forceHeight = -1;
|
||||||
anim::ivalue a_height;
|
anim::value a_height;
|
||||||
Animation _a_height;
|
Animation _a_height;
|
||||||
bool _hiding = false;
|
bool _hiding = false;
|
||||||
|
|
||||||
|
|
|
@ -40,8 +40,8 @@ int LinkButton::naturalWidth() const {
|
||||||
|
|
||||||
void LinkButton::paintEvent(QPaintEvent *e) {
|
void LinkButton::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
auto &font = ((_state & StateOver) ? _st.overFont : _st.font);
|
auto &font = (isOver() ? _st.overFont : _st.font);
|
||||||
auto &pen = ((_state & StateDown) ? _st.downColor : ((_state & StateOver) ? _st.overColor : _st.color));
|
auto &pen = (isDown() ? _st.downColor : (isOver() ? _st.overColor : _st.color));
|
||||||
p.setFont(font);
|
p.setFont(font);
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
if (_textWidth > width()) {
|
if (_textWidth > width()) {
|
||||||
|
@ -58,7 +58,7 @@ void LinkButton::setText(const QString &text) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkButton::onStateChanged(int oldState, StateChangeSource source) {
|
void LinkButton::onStateChanged(State was, StateChangeSource source) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,11 +95,11 @@ void RippleButton::paintRipple(QPainter &p, int x, int y, TimeMs ms, const QColo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RippleButton::onStateChanged(int oldState, StateChangeSource source) {
|
void RippleButton::onStateChanged(State was, StateChangeSource source) {
|
||||||
update();
|
update();
|
||||||
|
|
||||||
auto wasDown = (oldState & StateDown);
|
auto wasDown = static_cast<bool>(was & StateFlag::Down);
|
||||||
auto down = (_state & StateDown);
|
auto down = isDown();
|
||||||
if (!_st.showDuration || down == wasDown || _forceRippled) {
|
if (!_st.showDuration || down == wasDown || _forceRippled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -187,10 +187,10 @@ void FlatButton::step_appearance(float64 ms, bool timer) {
|
||||||
if (timer) update();
|
if (timer) update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatButton::onStateChanged(int oldState, StateChangeSource source) {
|
void FlatButton::onStateChanged(State was, StateChangeSource source) {
|
||||||
RippleButton::onStateChanged(oldState, source);
|
RippleButton::onStateChanged(was, source);
|
||||||
|
|
||||||
a_over.start((_state & StateOver) ? 1. : 0.);
|
a_over.start(isOver() ? 1. : 0.);
|
||||||
if (source == StateChangeSource::ByUser || source == StateChangeSource::ByPress) {
|
if (source == StateChangeSource::ByUser || source == StateChangeSource::ByPress) {
|
||||||
_a_appearance.stop();
|
_a_appearance.stop();
|
||||||
a_over.finish();
|
a_over.finish();
|
||||||
|
@ -211,7 +211,7 @@ void FlatButton::paintEvent(QPaintEvent *e) {
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
paintRipple(p, 0, 0, ms);
|
paintRipple(p, 0, 0, ms);
|
||||||
|
|
||||||
p.setFont((_state & StateOver) ? _st.overFont : _st.font);
|
p.setFont(isOver() ? _st.overFont : _st.font);
|
||||||
p.setRenderHint(QPainter::TextAntialiasing);
|
p.setRenderHint(QPainter::TextAntialiasing);
|
||||||
p.setPen(anim::pen(_st.color, _st.overColor, a_over.current()));
|
p.setPen(anim::pen(_st.color, _st.overColor, a_over.current()));
|
||||||
|
|
||||||
|
@ -294,8 +294,8 @@ void RoundButton::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
App::roundRect(p, myrtlrect(rounded), _st.textBg, ImageRoundRadius::Small);
|
App::roundRect(p, myrtlrect(rounded), _st.textBg, ImageRoundRadius::Small);
|
||||||
|
|
||||||
auto over = (_state & StateOver);
|
auto over = isOver();
|
||||||
auto down = (_state & StateDown);
|
auto down = isDown();
|
||||||
if (over || down) {
|
if (over || down) {
|
||||||
App::roundRect(p, myrtlrect(rounded), _st.textBgOver, ImageRoundRadius::Small);
|
App::roundRect(p, myrtlrect(rounded), _st.textBgOver, ImageRoundRadius::Small);
|
||||||
}
|
}
|
||||||
|
@ -340,21 +340,25 @@ IconButton::IconButton(QWidget *parent, const style::IconButton &st) : RippleBut
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconButton::setIcon(const style::icon *icon, const style::icon *iconOver) {
|
void IconButton::setIconOverride(const style::icon *iconOverride, const style::icon *iconOverOverride) {
|
||||||
_iconOverride = icon;
|
_iconOverride = iconOverride;
|
||||||
_iconOverrideOver = iconOver;
|
_iconOverrideOver = iconOverOverride;
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IconButton::setRippleColorOverride(const style::color *colorOverride) {
|
||||||
|
_rippleColorOverride = colorOverride;
|
||||||
|
}
|
||||||
|
|
||||||
void IconButton::paintEvent(QPaintEvent *e) {
|
void IconButton::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
|
|
||||||
paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms);
|
paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms, _rippleColorOverride ? &(*_rippleColorOverride)->c : nullptr);
|
||||||
|
|
||||||
auto down = (_state & StateDown);
|
auto down = isDown();
|
||||||
auto overIconOpacity = (down || forceRippled()) ? 1. : _a_over.current(getms(), (_state & StateOver) ? 1. : 0.);
|
auto overIconOpacity = (down || forceRippled()) ? 1. : _a_over.current(getms(), isOver() ? 1. : 0.);
|
||||||
auto overIcon = [this] {
|
auto overIcon = [this] {
|
||||||
if (_iconOverrideOver) {
|
if (_iconOverrideOver) {
|
||||||
return _iconOverrideOver;
|
return _iconOverrideOver;
|
||||||
|
@ -389,11 +393,12 @@ void IconButton::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IconButton::onStateChanged(int oldState, StateChangeSource source) {
|
void IconButton::onStateChanged(State was, StateChangeSource source) {
|
||||||
RippleButton::onStateChanged(oldState, source);
|
RippleButton::onStateChanged(was, source);
|
||||||
|
|
||||||
auto over = (_state & StateOver);
|
auto over = isOver();
|
||||||
if (over != (oldState & StateOver)) {
|
auto wasOver = static_cast<bool>(was & StateFlag::Over);
|
||||||
|
if (over != wasOver) {
|
||||||
if (_st.duration) {
|
if (_st.duration) {
|
||||||
auto from = over ? 0. : 1.;
|
auto from = over ? 0. : 1.;
|
||||||
auto to = over ? 1. : 0.;
|
auto to = over ? 1. : 0.;
|
||||||
|
@ -443,7 +448,8 @@ int LeftOutlineButton::resizeGetHeight(int newWidth) {
|
||||||
void LeftOutlineButton::paintEvent(QPaintEvent *e) {
|
void LeftOutlineButton::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
bool over = (_state & StateOver), down = (_state & StateDown);
|
auto over = isOver();
|
||||||
|
auto down = isDown();
|
||||||
if (width() > _st.outlineWidth) {
|
if (width() > _st.outlineWidth) {
|
||||||
p.fillRect(rtlrect(_st.outlineWidth, 0, width() - _st.outlineWidth, height(), width()), (over || down) ? _st.textBgOver : _st.textBg);
|
p.fillRect(rtlrect(_st.outlineWidth, 0, width() - _st.outlineWidth, height(), width()), (over || down) ? _st.textBgOver : _st.textBg);
|
||||||
paintRipple(p, 0, 0, getms());
|
paintRipple(p, 0, 0, getms());
|
||||||
|
@ -492,7 +498,7 @@ void CrossButton::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
auto over = (_state & StateOver);
|
auto over = isOver();
|
||||||
auto shown = _a_show.current(ms, _shown ? 1. : 0.);
|
auto shown = _a_show.current(ms, _shown ? 1. : 0.);
|
||||||
p.setOpacity(shown);
|
p.setOpacity(shown);
|
||||||
|
|
||||||
|
@ -501,11 +507,12 @@ void CrossButton::paintEvent(QPaintEvent *e) {
|
||||||
CrossAnimation::paint(p, _st.cross, over ? _st.crossFgOver : _st.crossFg, _st.crossPosition.x(), _st.crossPosition.y(), width(), shown);
|
CrossAnimation::paint(p, _st.cross, over ? _st.crossFgOver : _st.crossFg, _st.crossPosition.x(), _st.crossPosition.y(), width(), shown);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CrossButton::onStateChanged(int oldState, StateChangeSource source) {
|
void CrossButton::onStateChanged(State was, StateChangeSource source) {
|
||||||
RippleButton::onStateChanged(oldState, source);
|
RippleButton::onStateChanged(was, source);
|
||||||
|
|
||||||
auto over = (_state & StateOver);
|
auto over = isOver();
|
||||||
if (over != (oldState & StateOver)) {
|
auto wasOver = static_cast<bool>(was & StateFlag::Over);
|
||||||
|
if (over != wasOver) {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||||
#include "ui/abstract_button.h"
|
#include "ui/abstract_button.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
class RippleAnimation;
|
class RippleAnimation;
|
||||||
|
@ -38,7 +40,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _text;
|
QString _text;
|
||||||
|
@ -66,7 +68,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintRipple(QPainter &p, int x, int y, TimeMs ms, const QColor *colorOverride = nullptr);
|
void paintRipple(QPainter &p, int x, int y, TimeMs ms, const QColor *colorOverride = nullptr);
|
||||||
|
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
virtual QImage prepareRippleMask() const;
|
virtual QImage prepareRippleMask() const;
|
||||||
virtual QPoint prepareRippleStartPosition() const;
|
virtual QPoint prepareRippleStartPosition() const;
|
||||||
|
@ -98,7 +100,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setOpacity(float64 o);
|
void setOpacity(float64 o);
|
||||||
|
@ -109,7 +111,7 @@ private:
|
||||||
|
|
||||||
const style::FlatButton &_st;
|
const style::FlatButton &_st;
|
||||||
|
|
||||||
anim::fvalue a_over;
|
anim::value a_over;
|
||||||
Animation _a_appearance;
|
Animation _a_appearance;
|
||||||
|
|
||||||
float64 _opacity = 1.;
|
float64 _opacity = 1.;
|
||||||
|
@ -162,12 +164,13 @@ public:
|
||||||
IconButton(QWidget *parent, const style::IconButton &st);
|
IconButton(QWidget *parent, const style::IconButton &st);
|
||||||
|
|
||||||
// Pass nullptr to restore the default icon.
|
// Pass nullptr to restore the default icon.
|
||||||
void setIcon(const style::icon *icon, const style::icon *iconOver = nullptr);
|
void setIconOverride(const style::icon *iconOverride, const style::icon *iconOverOverride = nullptr);
|
||||||
|
void setRippleColorOverride(const style::color *colorOverride);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
QImage prepareRippleMask() const override;
|
QImage prepareRippleMask() const override;
|
||||||
QPoint prepareRippleStartPosition() const override;
|
QPoint prepareRippleStartPosition() const override;
|
||||||
|
@ -176,6 +179,7 @@ private:
|
||||||
const style::IconButton &_st;
|
const style::IconButton &_st;
|
||||||
const style::icon *_iconOverride = nullptr;
|
const style::icon *_iconOverride = nullptr;
|
||||||
const style::icon *_iconOverrideOver = nullptr;
|
const style::icon *_iconOverrideOver = nullptr;
|
||||||
|
const style::color *_rippleColorOverride = nullptr;
|
||||||
|
|
||||||
FloatAnimation _a_over;
|
FloatAnimation _a_over;
|
||||||
|
|
||||||
|
@ -215,7 +219,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
|
|
||||||
QImage prepareRippleMask() const override;
|
QImage prepareRippleMask() const override;
|
||||||
QPoint prepareRippleStartPosition() const override;
|
QPoint prepareRippleStartPosition() const override;
|
||||||
|
|
|
@ -163,16 +163,16 @@ void Checkbox::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checkbox::onClicked() {
|
void Checkbox::onClicked() {
|
||||||
if (_state & StateDisabled) return;
|
if (isDisabled()) return;
|
||||||
setChecked(!checked());
|
setChecked(!checked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Checkbox::onStateChanged(int oldState, StateChangeSource source) {
|
void Checkbox::onStateChanged(State was, StateChangeSource source) {
|
||||||
RippleButton::onStateChanged(oldState, source);
|
RippleButton::onStateChanged(was, source);
|
||||||
|
|
||||||
if ((_state & StateDisabled) && !(oldState & StateDisabled)) {
|
if (isDisabled() && !(was & StateFlag::Disabled)) {
|
||||||
setCursor(style::cur_default);
|
setCursor(style::cur_default);
|
||||||
} else if (!(_state & StateDisabled) && (oldState & StateDisabled)) {
|
} else if (!isDisabled() && (was & StateFlag::Disabled)) {
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,16 +284,16 @@ void Radiobutton::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radiobutton::onClicked() {
|
void Radiobutton::onClicked() {
|
||||||
if (_state & StateDisabled) return;
|
if (isDisabled()) return;
|
||||||
setChecked(!checked());
|
setChecked(!checked());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Radiobutton::onStateChanged(int oldState, StateChangeSource source) {
|
void Radiobutton::onStateChanged(State was, StateChangeSource source) {
|
||||||
RippleButton::onStateChanged(oldState, source);
|
RippleButton::onStateChanged(was, source);
|
||||||
|
|
||||||
if ((_state & StateDisabled) && !(oldState & StateDisabled)) {
|
if (isDisabled() && !(was & StateFlag::Disabled)) {
|
||||||
setCursor(style::cur_default);
|
setCursor(style::cur_default);
|
||||||
} else if (!(_state & StateDisabled) && (oldState & StateDisabled)) {
|
} else if (!isDisabled() && (was & StateFlag::Disabled)) {
|
||||||
setCursor(style::cur_pointer);
|
setCursor(style::cur_pointer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
int resizeGetHeight(int newWidth) override;
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
QImage prepareRippleMask() const override;
|
QImage prepareRippleMask() const override;
|
||||||
|
@ -95,7 +95,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
void onStateChanged(int oldState, StateChangeSource source) override;
|
void onStateChanged(State was, StateChangeSource source) override;
|
||||||
int resizeGetHeight(int newWidth) override;
|
int resizeGetHeight(int newWidth) override;
|
||||||
|
|
||||||
QImage prepareRippleMask() const override;
|
QImage prepareRippleMask() const override;
|
||||||
|
|
|
@ -65,7 +65,7 @@ void ContinuousSlider::setValue(float64 value, bool animated) {
|
||||||
a_value.start(value);
|
a_value.start(value);
|
||||||
_a_value.start();
|
_a_value.start();
|
||||||
} else {
|
} else {
|
||||||
a_value = anim::fvalue(value, value);
|
a_value = anim::value(value, value);
|
||||||
_a_value.stop();
|
_a_value.stop();
|
||||||
}
|
}
|
||||||
update();
|
update();
|
||||||
|
@ -116,7 +116,7 @@ void ContinuousSlider::mouseReleaseEvent(QMouseEvent *e) {
|
||||||
if (_changeFinishedCallback) {
|
if (_changeFinishedCallback) {
|
||||||
_changeFinishedCallback(_downValue);
|
_changeFinishedCallback(_downValue);
|
||||||
}
|
}
|
||||||
a_value = anim::fvalue(_downValue, _downValue);
|
a_value = anim::value(_downValue, _downValue);
|
||||||
_a_value.stop();
|
_a_value.stop();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ private:
|
||||||
bool _over = false;
|
bool _over = false;
|
||||||
FloatAnimation _a_over;
|
FloatAnimation _a_over;
|
||||||
|
|
||||||
anim::fvalue a_value = { 0., 0. };
|
anim::value a_value;
|
||||||
Animation _a_value;
|
Animation _a_value;
|
||||||
|
|
||||||
bool _mouseDown = false;
|
bool _mouseDown = false;
|
||||||
|
|
|
@ -1716,11 +1716,6 @@ InputArea::InputArea(QWidget *parent, const style::InputArea &st, const QString
|
||||||
|
|
||||||
, _placeholderFull(ph)
|
, _placeholderFull(ph)
|
||||||
, _placeholderVisible(val.isEmpty())
|
, _placeholderVisible(val.isEmpty())
|
||||||
, a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift)
|
|
||||||
, a_placeholderOpacity(_placeholderVisible ? 1 : 0)
|
|
||||||
, a_placeholderFgActive(0)
|
|
||||||
, _a_placeholderFg(animation(this, &InputArea::step_placeholderFg))
|
|
||||||
, _a_placeholderShift(animation(this, &InputArea::step_placeholderShift))
|
|
||||||
|
|
||||||
, a_borderOpacityActive(0)
|
, a_borderOpacityActive(0)
|
||||||
, a_borderFgActive(0)
|
, a_borderFgActive(0)
|
||||||
|
@ -1878,21 +1873,21 @@ void InputArea::paintEvent(QPaintEvent *e) {
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool drawPlaceholder = _placeholderVisible;
|
auto ms = getms();
|
||||||
if (_a_placeholderShift.animating()) {
|
auto placeholderOpacity = _a_placeholderVisible.current(ms, _placeholderVisible ? 1. : 0.);
|
||||||
p.setOpacity(a_placeholderOpacity.current());
|
if (placeholderOpacity > 0.) {
|
||||||
drawPlaceholder = true;
|
p.setOpacity(placeholderOpacity);
|
||||||
}
|
|
||||||
if (drawPlaceholder) {
|
|
||||||
p.save();
|
p.save();
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
|
|
||||||
|
auto placeholderLeft = anim::interpolate(_st.placeholderShift, 0, placeholderOpacity);
|
||||||
|
|
||||||
QRect r(rect().marginsRemoved(_st.textMargins + _st.placeholderMargins));
|
QRect r(rect().marginsRemoved(_st.textMargins + _st.placeholderMargins));
|
||||||
r.moveLeft(r.left() + a_placeholderLeft.current());
|
r.moveLeft(r.left() + placeholderLeft);
|
||||||
if (rtl()) r.moveLeft(width() - r.left() - r.width());
|
if (rtl()) r.moveLeft(width() - r.left() - r.width());
|
||||||
|
|
||||||
p.setFont(_st.font);
|
p.setFont(_st.font);
|
||||||
p.setPen(anim::pen(_st.placeholderFg, _st.placeholderFgActive, a_placeholderFgActive.current()));
|
p.setPen(anim::pen(_st.placeholderFg, _st.placeholderFgActive, _a_placeholderFocused.current(ms, hasFocus() ? 1. : 0.)));
|
||||||
p.drawText(r, _placeholder, _st.placeholderAlign);
|
p.drawText(r, _placeholder, _st.placeholderAlign);
|
||||||
|
|
||||||
p.restore();
|
p.restore();
|
||||||
|
@ -1929,8 +1924,7 @@ void InputArea::focusInInner() {
|
||||||
if (!_focused) {
|
if (!_focused) {
|
||||||
_focused = true;
|
_focused = true;
|
||||||
|
|
||||||
a_placeholderFgActive.start(1.);
|
_a_placeholderFocused.start([this] { update(); }, 0., 1., _st.duration);
|
||||||
_a_placeholderFg.start();
|
|
||||||
|
|
||||||
startBorderAnimation();
|
startBorderAnimation();
|
||||||
}
|
}
|
||||||
|
@ -1946,8 +1940,7 @@ void InputArea::focusOutInner() {
|
||||||
if (_focused) {
|
if (_focused) {
|
||||||
_focused = false;
|
_focused = false;
|
||||||
|
|
||||||
a_placeholderFgActive.start(0.);
|
_a_placeholderFocused.start([this] { update(); }, 1., 0., _st.duration);
|
||||||
_a_placeholderFg.start();
|
|
||||||
|
|
||||||
startBorderAnimation();
|
startBorderAnimation();
|
||||||
}
|
}
|
||||||
|
@ -2273,30 +2266,6 @@ void InputArea::onRedoAvailable(bool avail) {
|
||||||
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
if (App::wnd()) App::wnd()->updateGlobalMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputArea::step_placeholderFg(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / _st.duration;
|
|
||||||
if (dt >= 1) {
|
|
||||||
_a_placeholderFg.stop();
|
|
||||||
a_placeholderFgActive.finish();
|
|
||||||
} else {
|
|
||||||
a_placeholderFgActive.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputArea::step_placeholderShift(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / _st.duration;
|
|
||||||
if (dt >= 1) {
|
|
||||||
_a_placeholderShift.stop();
|
|
||||||
a_placeholderLeft.finish();
|
|
||||||
a_placeholderOpacity.finish();
|
|
||||||
} else {
|
|
||||||
a_placeholderLeft.update(dt, anim::linear);
|
|
||||||
a_placeholderOpacity.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputArea::step_border(float64 ms, bool timer) {
|
void InputArea::step_border(float64 ms, bool timer) {
|
||||||
float64 dt = ms / _st.duration;
|
float64 dt = ms / _st.duration;
|
||||||
bool res = true;
|
bool res = true;
|
||||||
|
@ -2314,13 +2283,10 @@ void InputArea::step_border(float64 ms, bool timer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputArea::updatePlaceholder() {
|
void InputArea::updatePlaceholder() {
|
||||||
bool placeholderVisible = _oldtext.isEmpty();
|
auto placeholderVisible = _oldtext.isEmpty();
|
||||||
if (placeholderVisible != _placeholderVisible) {
|
if (_placeholderVisible != placeholderVisible) {
|
||||||
_placeholderVisible = placeholderVisible;
|
_placeholderVisible = placeholderVisible;
|
||||||
|
_a_placeholderVisible.start([this] { update(); }, _placeholderVisible ? 0. : 1., _placeholderVisible ? 1. : 0., _st.duration);
|
||||||
a_placeholderLeft.start(_placeholderVisible ? 0 : _st.placeholderShift);
|
|
||||||
a_placeholderOpacity.start(_placeholderVisible ? 1 : 0);
|
|
||||||
_a_placeholderShift.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2445,11 +2411,6 @@ InputField::InputField(QWidget *parent, const style::InputField &st, const QStri
|
||||||
|
|
||||||
, _placeholderFull(ph)
|
, _placeholderFull(ph)
|
||||||
, _placeholderVisible(val.isEmpty())
|
, _placeholderVisible(val.isEmpty())
|
||||||
, a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift)
|
|
||||||
, a_placeholderOpacity(_placeholderVisible ? 1 : 0)
|
|
||||||
, a_placeholderFgActive(0)
|
|
||||||
, _a_placeholderFg(animation(this, &InputField::step_placeholderFg))
|
|
||||||
, _a_placeholderShift(animation(this, &InputField::step_placeholderShift))
|
|
||||||
|
|
||||||
, a_borderOpacityActive(0)
|
, a_borderOpacityActive(0)
|
||||||
, a_borderFgActive(0)
|
, a_borderFgActive(0)
|
||||||
|
@ -2571,13 +2532,6 @@ void InputField::paintEvent(QPaintEvent *e) {
|
||||||
Painter p(this);
|
Painter p(this);
|
||||||
|
|
||||||
auto ms = getms();
|
auto ms = getms();
|
||||||
if (_a_placeholderShift.animating()) {
|
|
||||||
_a_placeholderShift.step(ms);
|
|
||||||
}
|
|
||||||
if (_a_placeholderFg.animating()) {
|
|
||||||
_a_placeholderFg.step(ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect r(rect().intersected(e->rect()));
|
QRect r(rect().intersected(e->rect()));
|
||||||
if (_st.textBg->c.alphaF() > 0.) {
|
if (_st.textBg->c.alphaF() > 0.) {
|
||||||
p.fillRect(r, _st.textBg);
|
p.fillRect(r, _st.textBg);
|
||||||
|
@ -2593,21 +2547,21 @@ void InputField::paintEvent(QPaintEvent *e) {
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool drawPlaceholder = _placeholderVisible;
|
auto placeholderOpacity = _a_placeholderVisible.current(ms, _placeholderVisible ? 1. : 0.);
|
||||||
if (_a_placeholderShift.animating()) {
|
if (placeholderOpacity > 0.) {
|
||||||
p.setOpacity(a_placeholderOpacity.current());
|
p.setOpacity(placeholderOpacity);
|
||||||
drawPlaceholder = true;
|
|
||||||
}
|
|
||||||
if (drawPlaceholder) {
|
|
||||||
p.save();
|
p.save();
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
|
|
||||||
|
auto placeholderLeft = anim::interpolate(_st.placeholderShift, 0, placeholderOpacity);
|
||||||
|
|
||||||
|
|
||||||
QRect r(rect().marginsRemoved(_st.textMargins + _st.placeholderMargins));
|
QRect r(rect().marginsRemoved(_st.textMargins + _st.placeholderMargins));
|
||||||
r.moveLeft(r.left() + a_placeholderLeft.current());
|
r.moveLeft(r.left() + placeholderLeft);
|
||||||
if (rtl()) r.moveLeft(width() - r.left() - r.width());
|
if (rtl()) r.moveLeft(width() - r.left() - r.width());
|
||||||
|
|
||||||
p.setFont(_st.font);
|
p.setFont(_st.font);
|
||||||
p.setPen(anim::pen(_st.placeholderFg, _st.placeholderFgActive, a_placeholderFgActive.current()));
|
p.setPen(anim::pen(_st.placeholderFg, _st.placeholderFgActive, _a_placeholderFocused.current(ms, hasFocus() ? 1. : 0.)));
|
||||||
p.drawText(r, _placeholder, _st.placeholderAlign);
|
p.drawText(r, _placeholder, _st.placeholderAlign);
|
||||||
|
|
||||||
p.restore();
|
p.restore();
|
||||||
|
@ -2644,8 +2598,7 @@ void InputField::focusInInner() {
|
||||||
if (!_focused) {
|
if (!_focused) {
|
||||||
_focused = true;
|
_focused = true;
|
||||||
|
|
||||||
a_placeholderFgActive.start(1.);
|
_a_placeholderFocused.start([this] { update(); }, 0., 1., _st.duration);
|
||||||
_a_placeholderFg.start();
|
|
||||||
|
|
||||||
startBorderAnimation();
|
startBorderAnimation();
|
||||||
}
|
}
|
||||||
|
@ -2661,8 +2614,7 @@ void InputField::focusOutInner() {
|
||||||
if (_focused) {
|
if (_focused) {
|
||||||
_focused = false;
|
_focused = false;
|
||||||
|
|
||||||
a_placeholderFgActive.start(0.);
|
_a_placeholderFocused.start([this] { update(); }, 1., 0., _st.duration);
|
||||||
_a_placeholderFg.start();
|
|
||||||
|
|
||||||
startBorderAnimation();
|
startBorderAnimation();
|
||||||
}
|
}
|
||||||
|
@ -3019,32 +2971,9 @@ void InputField::selectAll() {
|
||||||
_inner.setTextCursor(c);
|
_inner.setTextCursor(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputField::step_placeholderFg(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / _st.duration;
|
|
||||||
if (dt >= 1) {
|
|
||||||
_a_placeholderFg.stop();
|
|
||||||
a_placeholderFgActive.finish();
|
|
||||||
} else {
|
|
||||||
a_placeholderFgActive.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputField::step_placeholderShift(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / _st.duration;
|
|
||||||
if (dt >= 1) {
|
|
||||||
finishPlaceholderAnimation();
|
|
||||||
} else {
|
|
||||||
a_placeholderLeft.update(dt, anim::linear);
|
|
||||||
a_placeholderOpacity.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputField::finishPlaceholderAnimation() {
|
void InputField::finishPlaceholderAnimation() {
|
||||||
_a_placeholderShift.stop();
|
_a_placeholderVisible.finish();
|
||||||
a_placeholderLeft.finish();
|
_a_placeholderFocused.finish();
|
||||||
a_placeholderOpacity.finish();
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3064,13 +2993,10 @@ void InputField::step_border(float64 ms, bool timer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputField::updatePlaceholder() {
|
void InputField::updatePlaceholder() {
|
||||||
bool placeholderVisible = _oldtext.isEmpty() && !_forcePlaceholderHidden;
|
auto placeholderVisible = _oldtext.isEmpty();
|
||||||
if (placeholderVisible != _placeholderVisible) {
|
if (_placeholderVisible != placeholderVisible) {
|
||||||
_placeholderVisible = placeholderVisible;
|
_placeholderVisible = placeholderVisible;
|
||||||
|
_a_placeholderVisible.start([this] { update(); }, _placeholderVisible ? 0. : 1., _placeholderVisible ? 1. : 0., _st.duration);
|
||||||
a_placeholderLeft.start(_placeholderVisible ? 0 : _st.placeholderShift);
|
|
||||||
a_placeholderOpacity.start(_placeholderVisible ? 1 : 0);
|
|
||||||
_a_placeholderShift.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3198,11 +3124,6 @@ MaskedInputField::MaskedInputField(QWidget *parent, const style::InputField &st,
|
||||||
, _placeholderFull(placeholder)
|
, _placeholderFull(placeholder)
|
||||||
, _placeholderVisible(val.isEmpty())
|
, _placeholderVisible(val.isEmpty())
|
||||||
, _placeholderFast(false)
|
, _placeholderFast(false)
|
||||||
, a_placeholderLeft(_placeholderVisible ? 0 : st.placeholderShift)
|
|
||||||
, a_placeholderOpacity(_placeholderVisible ? 1 : 0)
|
|
||||||
, a_placeholderFgActive(0)
|
|
||||||
, _a_placeholderFg(animation(this, &MaskedInputField::step_placeholderFg))
|
|
||||||
, _a_placeholderShift(animation(this, &MaskedInputField::step_placeholderShift))
|
|
||||||
|
|
||||||
, a_borderOpacityActive(0)
|
, a_borderOpacityActive(0)
|
||||||
, a_borderFgActive(0)
|
, a_borderFgActive(0)
|
||||||
|
@ -3345,7 +3266,7 @@ void MaskedInputField::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setClipRect(r);
|
p.setClipRect(r);
|
||||||
paintPlaceholder(p);
|
paintPlaceholder(p, getms());
|
||||||
|
|
||||||
QLineEdit::paintEvent(e);
|
QLineEdit::paintEvent(e);
|
||||||
}
|
}
|
||||||
|
@ -3361,8 +3282,7 @@ void MaskedInputField::focusInEvent(QFocusEvent *e) {
|
||||||
if (!_focused) {
|
if (!_focused) {
|
||||||
_focused = true;
|
_focused = true;
|
||||||
|
|
||||||
a_placeholderFgActive.start(1.);
|
_a_placeholderFocused.start([this] { update(); }, 0., 1., _st.duration);
|
||||||
_a_placeholderFg.start();
|
|
||||||
|
|
||||||
startBorderAnimation();
|
startBorderAnimation();
|
||||||
}
|
}
|
||||||
|
@ -3374,8 +3294,7 @@ void MaskedInputField::focusOutEvent(QFocusEvent *e) {
|
||||||
if (_focused) {
|
if (_focused) {
|
||||||
_focused = false;
|
_focused = false;
|
||||||
|
|
||||||
a_placeholderFgActive.start(0.);
|
_a_placeholderFocused.start([this] { update(); }, 1., 0., _st.duration);
|
||||||
_a_placeholderFg.start();
|
|
||||||
|
|
||||||
startBorderAnimation();
|
startBorderAnimation();
|
||||||
}
|
}
|
||||||
|
@ -3416,30 +3335,6 @@ QSize MaskedInputField::minimumSizeHint() const {
|
||||||
return geometry().size();
|
return geometry().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaskedInputField::step_placeholderFg(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / _st.duration;
|
|
||||||
if (dt >= 1) {
|
|
||||||
_a_placeholderFg.stop();
|
|
||||||
a_placeholderFgActive.finish();
|
|
||||||
} else {
|
|
||||||
a_placeholderFgActive.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaskedInputField::step_placeholderShift(float64 ms, bool timer) {
|
|
||||||
float64 dt = ms / _st.duration;
|
|
||||||
if (dt >= 1) {
|
|
||||||
_a_placeholderShift.stop();
|
|
||||||
a_placeholderLeft.finish();
|
|
||||||
a_placeholderOpacity.finish();
|
|
||||||
} else {
|
|
||||||
a_placeholderLeft.update(dt, anim::linear);
|
|
||||||
a_placeholderOpacity.update(dt, anim::linear);
|
|
||||||
}
|
|
||||||
if (timer) update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MaskedInputField::step_border(float64 ms, bool timer) {
|
void MaskedInputField::step_border(float64 ms, bool timer) {
|
||||||
float64 dt = ms / _st.duration;
|
float64 dt = ms / _st.duration;
|
||||||
if (dt >= 1) {
|
if (dt >= 1) {
|
||||||
|
@ -3467,25 +3362,18 @@ bool MaskedInputField::setPlaceholder(const QString &placeholder) {
|
||||||
void MaskedInputField::setPlaceholderFast(bool fast) {
|
void MaskedInputField::setPlaceholderFast(bool fast) {
|
||||||
_placeholderFast = fast;
|
_placeholderFast = fast;
|
||||||
if (_placeholderFast) {
|
if (_placeholderFast) {
|
||||||
a_placeholderLeft = anim::ivalue(_placeholderVisible ? 0 : _st.placeholderShift, _placeholderVisible ? 0 : _st.placeholderShift);
|
_a_placeholderVisible.finish();
|
||||||
a_placeholderOpacity = anim::fvalue(_placeholderVisible ? 1 : 0, _placeholderVisible ? 1 : 0);
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaskedInputField::updatePlaceholder() {
|
void MaskedInputField::updatePlaceholder() {
|
||||||
bool placeholderVisible = _oldtext.isEmpty();
|
auto placeholderVisible = _oldtext.isEmpty();
|
||||||
if (placeholderVisible != _placeholderVisible) {
|
if (_placeholderVisible != placeholderVisible) {
|
||||||
_placeholderVisible = placeholderVisible;
|
_placeholderVisible = placeholderVisible;
|
||||||
|
_a_placeholderVisible.start([this] { update(); }, _placeholderVisible ? 0. : 1., _placeholderVisible ? 1. : 0., _st.duration);
|
||||||
if (_placeholderFast) {
|
if (_placeholderFast) {
|
||||||
a_placeholderLeft = anim::ivalue(_placeholderVisible ? 0 : _st.placeholderShift, _placeholderVisible ? 0 : _st.placeholderShift);
|
_a_placeholderVisible.finish();
|
||||||
a_placeholderOpacity = anim::fvalue(_placeholderVisible ? 1 : 0, _placeholderVisible ? 1 : 0);
|
|
||||||
update();
|
|
||||||
} else {
|
|
||||||
a_placeholderLeft.start(_placeholderVisible ? 0 : _st.placeholderShift);
|
|
||||||
a_placeholderOpacity.start(_placeholderVisible ? 1 : 0);
|
|
||||||
_a_placeholderShift.start();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3498,29 +3386,28 @@ QRect MaskedInputField::placeholderRect() const {
|
||||||
return rect().marginsRemoved(_st.textMargins + _st.placeholderMargins);
|
return rect().marginsRemoved(_st.textMargins + _st.placeholderMargins);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaskedInputField::paintPlaceholder(Painter &p) {
|
void MaskedInputField::paintPlaceholder(Painter &p, TimeMs ms) {
|
||||||
bool drawPlaceholder = _placeholderVisible;
|
auto placeholderOpacity = _a_placeholderVisible.current(ms, _placeholderVisible ? 1. : 0.);
|
||||||
if (_a_placeholderShift.animating()) {
|
if (placeholderOpacity > 0.) {
|
||||||
p.setOpacity(a_placeholderOpacity.current());
|
p.setOpacity(placeholderOpacity);
|
||||||
drawPlaceholder = true;
|
|
||||||
}
|
|
||||||
if (drawPlaceholder) {
|
|
||||||
p.save();
|
p.save();
|
||||||
|
|
||||||
|
auto placeholderLeft = anim::interpolate(_st.placeholderShift, 0, placeholderOpacity);
|
||||||
|
|
||||||
QRect phRect(placeholderRect());
|
QRect phRect(placeholderRect());
|
||||||
phRect.moveLeft(phRect.left() + a_placeholderLeft.current());
|
phRect.moveLeft(phRect.left() + placeholderLeft);
|
||||||
if (rtl()) phRect.moveLeft(width() - phRect.left() - phRect.width());
|
if (rtl()) phRect.moveLeft(width() - phRect.left() - phRect.width());
|
||||||
|
|
||||||
placeholderPreparePaint(p);
|
placeholderPreparePaint(p, ms);
|
||||||
p.drawText(phRect, _placeholder, _st.placeholderAlign);
|
p.drawText(phRect, _placeholder, _st.placeholderAlign);
|
||||||
|
|
||||||
p.restore();
|
p.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaskedInputField::placeholderPreparePaint(Painter &p) {
|
void MaskedInputField::placeholderPreparePaint(Painter &p, TimeMs ms) {
|
||||||
p.setFont(_st.font);
|
p.setFont(_st.font);
|
||||||
p.setPen(anim::pen(_st.placeholderFg, _st.placeholderFgActive, a_placeholderFgActive.current()));
|
p.setPen(anim::pen(_st.placeholderFg, _st.placeholderFgActive, _a_placeholderFocused.current(ms, hasFocus() ? 1. : 0.)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MaskedInputField::keyPressEvent(QKeyEvent *e) {
|
void MaskedInputField::keyPressEvent(QKeyEvent *e) {
|
||||||
|
@ -3648,7 +3535,7 @@ void CountryCodeInput::correctValue(const QString &was, int32 wasCursor, QString
|
||||||
PhonePartInput::PhonePartInput(QWidget *parent, const style::InputField &st) : MaskedInputField(parent, st, lang(lng_phone_ph)) {
|
PhonePartInput::PhonePartInput(QWidget *parent, const style::InputField &st) : MaskedInputField(parent, st, lang(lng_phone_ph)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhonePartInput::paintPlaceholder(Painter &p) {
|
void PhonePartInput::paintPlaceholder(Painter &p, TimeMs ms) {
|
||||||
auto t = getLastText();
|
auto t = getLastText();
|
||||||
if (!_pattern.isEmpty() && !t.isEmpty()) {
|
if (!_pattern.isEmpty() && !t.isEmpty()) {
|
||||||
auto ph = placeholder().mid(t.size());
|
auto ph = placeholder().mid(t.size());
|
||||||
|
@ -3658,12 +3545,12 @@ void PhonePartInput::paintPlaceholder(Painter &p) {
|
||||||
int tw = phFont()->width(t);
|
int tw = phFont()->width(t);
|
||||||
if (tw < phRect.width()) {
|
if (tw < phRect.width()) {
|
||||||
phRect.setLeft(phRect.left() + tw);
|
phRect.setLeft(phRect.left() + tw);
|
||||||
placeholderPreparePaint(p);
|
placeholderPreparePaint(p, ms);
|
||||||
p.drawText(phRect, ph, style::al_topleft);
|
p.drawText(phRect, ph, style::al_topleft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MaskedInputField::paintPlaceholder(p);
|
MaskedInputField::paintPlaceholder(p, ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3812,9 +3699,9 @@ _linkPlaceholder(isLink ? qsl("telegram.me/") : QString()) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UsernameInput::paintPlaceholder(Painter &p) {
|
void UsernameInput::paintPlaceholder(Painter &p, TimeMs ms) {
|
||||||
if (_linkPlaceholder.isEmpty()) {
|
if (_linkPlaceholder.isEmpty()) {
|
||||||
MaskedInputField::paintPlaceholder(p);
|
MaskedInputField::paintPlaceholder(p, ms);
|
||||||
} else {
|
} else {
|
||||||
p.setFont(_st.font);
|
p.setFont(_st.font);
|
||||||
p.setPen(_st.placeholderFg);
|
p.setPen(_st.placeholderFg);
|
||||||
|
@ -3872,7 +3759,7 @@ void PhoneInput::clearText() {
|
||||||
correctValue(QString(), 0, phone, pos);
|
correctValue(QString(), 0, phone, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhoneInput::paintPlaceholder(Painter &p) {
|
void PhoneInput::paintPlaceholder(Painter &p, TimeMs ms) {
|
||||||
auto t = getLastText();
|
auto t = getLastText();
|
||||||
if (!_pattern.isEmpty() && !t.isEmpty()) {
|
if (!_pattern.isEmpty() && !t.isEmpty()) {
|
||||||
auto ph = placeholder().mid(t.size());
|
auto ph = placeholder().mid(t.size());
|
||||||
|
@ -3882,12 +3769,12 @@ void PhoneInput::paintPlaceholder(Painter &p) {
|
||||||
int tw = phFont()->width(t);
|
int tw = phFont()->width(t);
|
||||||
if (tw < phRect.width()) {
|
if (tw < phRect.width()) {
|
||||||
phRect.setLeft(phRect.left() + tw);
|
phRect.setLeft(phRect.left() + tw);
|
||||||
placeholderPreparePaint(p);
|
placeholderPreparePaint(p, ms);
|
||||||
p.drawText(phRect, ph, style::al_topleft);
|
p.drawText(phRect, ph, style::al_topleft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MaskedInputField::paintPlaceholder(p);
|
MaskedInputField::paintPlaceholder(p, ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -347,8 +347,6 @@ public:
|
||||||
}
|
}
|
||||||
void updatePlaceholder();
|
void updatePlaceholder();
|
||||||
|
|
||||||
void step_placeholderFg(float64 ms, bool timer);
|
|
||||||
void step_placeholderShift(float64 ms, bool timer);
|
|
||||||
void step_border(float64 ms, bool timer);
|
void step_border(float64 ms, bool timer);
|
||||||
|
|
||||||
QSize sizeHint() const override;
|
QSize sizeHint() const override;
|
||||||
|
@ -470,14 +468,12 @@ private:
|
||||||
|
|
||||||
QString _placeholder, _placeholderFull;
|
QString _placeholder, _placeholderFull;
|
||||||
bool _placeholderVisible;
|
bool _placeholderVisible;
|
||||||
anim::ivalue a_placeholderLeft;
|
FloatAnimation _a_placeholderFocused;
|
||||||
anim::fvalue a_placeholderOpacity;
|
FloatAnimation _a_placeholderVisible;
|
||||||
anim::fvalue a_placeholderFgActive;
|
|
||||||
Animation _a_placeholderFg, _a_placeholderShift;
|
|
||||||
|
|
||||||
anim::fvalue a_borderOpacityActive;
|
anim::value a_borderOpacityActive;
|
||||||
anim::fvalue a_borderFgActive;
|
anim::value a_borderFgActive;
|
||||||
anim::fvalue a_borderFgError;
|
anim::value a_borderFgError;
|
||||||
Animation _a_border;
|
Animation _a_border;
|
||||||
|
|
||||||
bool _focused, _error;
|
bool _focused, _error;
|
||||||
|
@ -511,8 +507,6 @@ public:
|
||||||
void setPlaceholderHidden(bool forcePlaceholderHidden);
|
void setPlaceholderHidden(bool forcePlaceholderHidden);
|
||||||
void finishPlaceholderAnimation();
|
void finishPlaceholderAnimation();
|
||||||
|
|
||||||
void step_placeholderFg(float64 ms, bool timer);
|
|
||||||
void step_placeholderShift(float64 ms, bool timer);
|
|
||||||
void step_border(float64 ms, bool timer);
|
void step_border(float64 ms, bool timer);
|
||||||
|
|
||||||
QSize sizeHint() const override;
|
QSize sizeHint() const override;
|
||||||
|
@ -640,14 +634,12 @@ private:
|
||||||
|
|
||||||
QString _placeholder, _placeholderFull;
|
QString _placeholder, _placeholderFull;
|
||||||
bool _placeholderVisible;
|
bool _placeholderVisible;
|
||||||
anim::ivalue a_placeholderLeft;
|
FloatAnimation _a_placeholderFocused;
|
||||||
anim::fvalue a_placeholderOpacity;
|
FloatAnimation _a_placeholderVisible;
|
||||||
anim::fvalue a_placeholderFgActive;
|
|
||||||
Animation _a_placeholderFg, _a_placeholderShift;
|
|
||||||
|
|
||||||
anim::fvalue a_borderOpacityActive;
|
anim::value a_borderOpacityActive;
|
||||||
anim::fvalue a_borderFgActive;
|
anim::value a_borderFgActive;
|
||||||
anim::fvalue a_borderFgError;
|
anim::value a_borderFgError;
|
||||||
Animation _a_border;
|
Animation _a_border;
|
||||||
|
|
||||||
bool _focused, _error;
|
bool _focused, _error;
|
||||||
|
@ -676,8 +668,6 @@ public:
|
||||||
|
|
||||||
QRect getTextRect() const;
|
QRect getTextRect() const;
|
||||||
|
|
||||||
void step_placeholderFg(float64 ms, bool timer);
|
|
||||||
void step_placeholderShift(float64 ms, bool timer);
|
|
||||||
void step_border(float64 ms, bool timer);
|
void step_border(float64 ms, bool timer);
|
||||||
|
|
||||||
QSize sizeHint() const override;
|
QSize sizeHint() const override;
|
||||||
|
@ -736,13 +726,13 @@ protected:
|
||||||
}
|
}
|
||||||
void setCorrectedText(QString &now, int &nowCursor, const QString &newText, int newPos);
|
void setCorrectedText(QString &now, int &nowCursor, const QString &newText, int newPos);
|
||||||
|
|
||||||
virtual void paintPlaceholder(Painter &p);
|
virtual void paintPlaceholder(Painter &p, TimeMs ms);
|
||||||
|
|
||||||
style::font phFont() {
|
style::font phFont() {
|
||||||
return _st.font;
|
return _st.font;
|
||||||
}
|
}
|
||||||
|
|
||||||
void placeholderPreparePaint(Painter &p);
|
void placeholderPreparePaint(Painter &p, TimeMs ms);
|
||||||
const QString &placeholder() const;
|
const QString &placeholder() const;
|
||||||
QRect placeholderRect() const;
|
QRect placeholderRect() const;
|
||||||
|
|
||||||
|
@ -764,14 +754,12 @@ private:
|
||||||
|
|
||||||
QString _placeholder, _placeholderFull;
|
QString _placeholder, _placeholderFull;
|
||||||
bool _placeholderVisible, _placeholderFast;
|
bool _placeholderVisible, _placeholderFast;
|
||||||
anim::ivalue a_placeholderLeft;
|
FloatAnimation _a_placeholderFocused;
|
||||||
anim::fvalue a_placeholderOpacity;
|
FloatAnimation _a_placeholderVisible;
|
||||||
anim::fvalue a_placeholderFgActive;
|
|
||||||
Animation _a_placeholderFg, _a_placeholderShift;
|
|
||||||
|
|
||||||
anim::fvalue a_borderOpacityActive;
|
anim::value a_borderOpacityActive;
|
||||||
anim::fvalue a_borderFgActive;
|
anim::value a_borderFgActive;
|
||||||
anim::fvalue a_borderFgError;
|
anim::value a_borderFgError;
|
||||||
Animation _a_border;
|
Animation _a_border;
|
||||||
|
|
||||||
bool _focused, _error;
|
bool _focused, _error;
|
||||||
|
@ -822,7 +810,7 @@ protected:
|
||||||
void keyPressEvent(QKeyEvent *e) override;
|
void keyPressEvent(QKeyEvent *e) override;
|
||||||
|
|
||||||
void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override;
|
void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override;
|
||||||
void paintPlaceholder(Painter &p) override;
|
void paintPlaceholder(Painter &p, TimeMs ms) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVector<int> _pattern;
|
QVector<int> _pattern;
|
||||||
|
@ -850,7 +838,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override;
|
void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override;
|
||||||
void paintPlaceholder(Painter &p) override;
|
void paintPlaceholder(Painter &p, TimeMs ms) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _linkPlaceholder;
|
QString _linkPlaceholder;
|
||||||
|
@ -867,7 +855,7 @@ protected:
|
||||||
void focusInEvent(QFocusEvent *e) override;
|
void focusInEvent(QFocusEvent *e) override;
|
||||||
|
|
||||||
void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override;
|
void correctValue(const QString &was, int32 wasCursor, QString &now, int32 &nowCursor) override;
|
||||||
void paintPlaceholder(Painter &p) override;
|
void paintPlaceholder(Painter &p, TimeMs ms) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _defaultPlaceholder;
|
QString _defaultPlaceholder;
|
||||||
|
|
|
@ -95,7 +95,7 @@ private:
|
||||||
, y(y) {
|
, y(y) {
|
||||||
x.start(updateCallback, fromX, toX, duration);
|
x.start(updateCallback, fromX, toX, duration);
|
||||||
}
|
}
|
||||||
IntAnimation x;
|
FloatAnimation x;
|
||||||
int fromX, toX;
|
int fromX, toX;
|
||||||
int y;
|
int y;
|
||||||
};
|
};
|
||||||
|
@ -143,7 +143,7 @@ void MultiSelect::Inner::Item::paint(Painter &p, int outerWidth, TimeMs ms) {
|
||||||
paintOnce(p, _x, _y, outerWidth, ms);
|
paintOnce(p, _x, _y, outerWidth, ms);
|
||||||
} else {
|
} else {
|
||||||
for (auto i = _copies.begin(), e = _copies.end(); i != e;) {
|
for (auto i = _copies.begin(), e = _copies.end(); i != e;) {
|
||||||
auto x = i->x.current(getms(), _x);
|
auto x = qRound(i->x.current(getms(), _x));
|
||||||
auto y = i->y;
|
auto y = i->y;
|
||||||
auto animating = i->x.animating();
|
auto animating = i->x.animating();
|
||||||
if (animating || (y == _y)) {
|
if (animating || (y == _y)) {
|
||||||
|
@ -748,7 +748,7 @@ void MultiSelect::Inner::updateItemsGeometry() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiSelect::Inner::updateHeightStep() {
|
void MultiSelect::Inner::updateHeightStep() {
|
||||||
auto newHeight = _height.current(_newHeight);
|
auto newHeight = qRound(_height.current(_newHeight));
|
||||||
if (auto heightDelta = newHeight - height()) {
|
if (auto heightDelta = newHeight - height()) {
|
||||||
resize(width(), newHeight);
|
resize(width(), newHeight);
|
||||||
if (_resizedCallback) {
|
if (_resizedCallback) {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue