new slide animations

This commit is contained in:
John Preston 2015-10-17 16:52:26 +02:00
parent a9450956c3
commit e211268158
33 changed files with 717 additions and 468 deletions

View File

@ -307,10 +307,11 @@ versionColor: #777;
shadowColor: rgba(0, 0, 0, 24); shadowColor: rgba(0, 0, 0, 24);
slideDuration: 4000; slideDuration: 240;
slideShift: 0.3; slideShift: 0.3;
slideShadowLeft: sprite(348px, 70px, 48px, 1px); slideFadeOut: 0.3;
slideShadowRight: sprite(348px, 71px, 48px, 1px); slideShadow: sprite(348px, 71px, 48px, 1px);
slideFunction: transition(easeOutCirc);
btnDefIconed: iconedButton { btnDefIconed: iconedButton {
color: white; color: white;
@ -605,7 +606,7 @@ introPointHideAlphaT: transition(easeOutCirc);
introStepSize: size(400px, 200px); introStepSize: size(400px, 200px);
introSize: size(400px, 400px); introSize: size(400px, 400px);
introSlideShift: 500px; // intro hiding animation introSlideShift: 500px; // intro hiding animation
introSlideDuration: 4000; introSlideDuration: 200;
introSlideDelta: 0; // between hide start and show start introSlideDelta: 0; // between hide start and show start
introHideFunc: transition(easeInCirc); introHideFunc: transition(easeInCirc);
introShowFunc: transition(easeOutCirc); introShowFunc: transition(easeOutCirc);

View File

@ -298,7 +298,7 @@ void Application::cancelPhotoUpdate(const PeerId &peer) {
void Application::mtpPause() { void Application::mtpPause() {
MTP::pause(); MTP::pause();
_mtpUnpauseTimer.start(1000); _mtpUnpauseTimer.start(st::slideDuration * 2);
} }
void Application::mtpUnpause() { void Application::mtpUnpause() {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 177 KiB

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 236 KiB

View File

@ -88,7 +88,7 @@ AbstractBox::AbstractBox(int32 w) : LayeredWidget()
void AbstractBox::prepare() { void AbstractBox::prepare() {
showAll(); showAll();
_cache = myGrab(this, rect()); _cache = myGrab(this);
hideAll(); hideAll();
} }
@ -197,7 +197,7 @@ void AbstractBox::onClose() {
void AbstractBox::startHide() { void AbstractBox::startHide() {
_hiding = true; _hiding = true;
if (_cache.isNull()) { if (_cache.isNull()) {
_cache = myGrab(this, rect()); _cache = myGrab(this);
hideAll(); hideAll();
} }
a_opacity.start(0); a_opacity.start(0);

View File

@ -1503,6 +1503,7 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent)
, _cancelSearch(this, st::btnCancelSearch) , _cancelSearch(this, st::btnCancelSearch)
, _scroll(this, st::dlgScroll) , _scroll(this, st::dlgScroll)
, _inner(&_scroll, parent) , _inner(&_scroll, parent)
, _a_show(animFunc(this, &DialogsWidget::animStep_show))
, _searchInPeer(0) , _searchInPeer(0)
, _searchFull(false) , _searchFull(false)
, _peopleFull(false) , _peopleFull(false)
@ -1574,30 +1575,39 @@ void DialogsWidget::dialogsToUp() {
void DialogsWidget::animShow(const QPixmap &bgAnimCache) { void DialogsWidget::animShow(const QPixmap &bgAnimCache) {
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
_bgAnimCache = bgAnimCache; bool back = true;
_animCache = myGrab(this, rect()); (back ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
(back ? _cacheUnder : _cacheOver) = myGrab(this);
_scroll.hide(); _scroll.hide();
_filter.hide(); _filter.hide();
_cancelSearch.hide(); _cancelSearch.hide();
_newGroup.hide(); _newGroup.hide();
a_coord = anim::ivalue(-st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1); a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
a_bgCoord = anim::ivalue(0, st::introSlideShift); a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0);
a_bgAlpha = anim::fvalue(1, 0); a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1);
anim::start(this); _a_show.start();
show();
} }
bool DialogsWidget::animStep(float64 ms) { bool DialogsWidget::animStep_show(float64 ms) {
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 dt = ms / st::slideDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; bool res = true;
if (dt2 >= 1) { if (dt >= 1) {
_a_show.stop();
res = false; res = false;
a_bgCoord.finish(); a_coordUnder.finish();
a_bgAlpha.finish(); a_coordOver.finish();
a_coord.finish(); a_shadow.finish();
a_alpha.finish();
_bgAnimCache = _animCache = QPixmap(); _cacheUnder = _cacheOver = QPixmap();
_scroll.show(); _scroll.show();
_filter.show(); _filter.show();
onFilterUpdate(true); onFilterUpdate(true);
@ -1605,10 +1615,9 @@ bool DialogsWidget::animStep(float64 ms) {
if (App::app()) App::app()->mtpUnpause(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
a_bgCoord.update(dt1, st::introHideFunc); a_coordUnder.update(dt, st::slideFunction);
a_bgAlpha.update(dt1, st::introAlphaHideFunc); a_coordOver.update(dt, st::slideFunction);
a_coord.update(dt2, st::introShowFunc); a_shadow.update(dt, st::slideFunction);
a_alpha.update(dt2, st::introAlphaShowFunc);
} }
update(); update();
return res; return res;
@ -2063,7 +2072,7 @@ void DialogsWidget::onListScroll() {
} }
void DialogsWidget::onFilterUpdate(bool force) { void DialogsWidget::onFilterUpdate(bool force) {
if (animating() && !force) return; if (_a_show.animating() && !force) return;
QString filterText = _filter.getLastText(); QString filterText = _filter.getLastText();
_inner.onFilterUpdate(filterText); _inner.onFilterUpdate(filterText);
@ -2190,11 +2199,16 @@ void DialogsWidget::paintEvent(QPaintEvent *e) {
if (r != rect()) { if (r != rect()) {
p.setClipRect(r); p.setClipRect(r);
} }
if (animating()) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); if (a_coordOver.current() > 0) {
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.drawPixmap(a_coord.current(), 0, _animCache); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
return; return;
} }
QRect above(0, 0, width(), _scroll.y()); QRect above(0, 0, width(), _scroll.y());

View File

@ -176,7 +176,7 @@ private:
}; };
class DialogsWidget : public TWidget, public Animated, public RPCSender { class DialogsWidget : public TWidget, public RPCSender {
Q_OBJECT Q_OBJECT
public: public:
@ -208,7 +208,7 @@ public:
void dialogsToUp(); void dialogsToUp();
void animShow(const QPixmap &bgAnimCache); void animShow(const QPixmap &bgAnimCache);
bool animStep(float64 ms); bool animStep_show(float64 ms);
void destroyData(); void destroyData();
@ -271,9 +271,10 @@ private:
ScrollArea _scroll; ScrollArea _scroll;
DialogsInner _inner; DialogsInner _inner;
QPixmap _animCache, _bgAnimCache; Animation _a_show;
anim::ivalue a_coord, a_bgCoord; QPixmap _cacheUnder, _cacheOver;
anim::fvalue a_alpha, a_bgAlpha; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_shadow;
PeerData *_searchInPeer; PeerData *_searchInPeer;

View File

@ -2913,7 +2913,7 @@ void MentionsInner::onParentGeometryChanged() {
} }
} }
MentionsDropdown::MentionsDropdown(QWidget *parent) : QWidget(parent), MentionsDropdown::MentionsDropdown(QWidget *parent) : TWidget(parent),
_scroll(this, st::mentionScroll), _inner(this, &_rows, &_hrows, &_crows), _chat(0), _user(0), _channel(0), _hiding(false), a_opacity(0), _shadow(st::dropdownDef.shadow) { _scroll(this, st::mentionScroll), _inner(this, &_rows, &_hrows, &_crows), _chat(0), _user(0), _channel(0), _hiding(false), a_opacity(0), _shadow(st::dropdownDef.shadow) {
_hideTimer.setSingleShot(true); _hideTimer.setSingleShot(true);
connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart())); connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart()));
@ -3138,7 +3138,7 @@ void MentionsDropdown::hideStart() {
if (!_hiding) { if (!_hiding) {
if (_cache.isNull()) { if (_cache.isNull()) {
_scroll.show(); _scroll.show();
_cache = myGrab(this, rect()); _cache = myGrab(this);
} }
_scroll.hide(); _scroll.hide();
_hiding = true; _hiding = true;
@ -3161,7 +3161,7 @@ void MentionsDropdown::showStart() {
} }
if (_cache.isNull()) { if (_cache.isNull()) {
_scroll.show(); _scroll.show();
_cache = myGrab(this, rect()); _cache = myGrab(this);
} }
_scroll.hide(); _scroll.hide();
_hiding = false; _hiding = false;

View File

@ -629,7 +629,7 @@ private:
bool _overDelete; bool _overDelete;
}; };
class MentionsDropdown : public QWidget, public Animated { class MentionsDropdown : public TWidget, public Animated {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -68,7 +68,17 @@ _touchPress(false), _touchRightButton(false), _touchMove(false), _correcting(fal
if (App::wnd()) connect(this, SIGNAL(selectionChanged()), App::wnd(), SLOT(updateGlobalMenu())); if (App::wnd()) connect(this, SIGNAL(selectionChanged()), App::wnd(), SLOT(updateGlobalMenu()));
if (!v.isEmpty()) { if (!v.isEmpty()) {
setPlainText(v); setTextFast(v);
}
}
void FlatTextarea::setTextFast(const QString &text) {
setPlainText(text);
if (animating()) {
a_phLeft.finish();
a_phAlpha.finish();
anim::stop(this);
update();
} }
} }

View File

@ -76,6 +76,8 @@ public:
QMimeData *createMimeDataFromSelection() const; QMimeData *createMimeDataFromSelection() const;
void setCtrlEnterSubmit(bool ctrlEnterSubmit); void setCtrlEnterSubmit(bool ctrlEnterSubmit);
void setTextFast(const QString &text);
public slots: public slots:
void onTouchTimer(); void onTouchTimer();

View File

@ -43,12 +43,18 @@ void myEnsureResized(QWidget *target) {
} }
} }
QPixmap myGrab(QWidget *target, const QRect &rect) { QPixmap myGrab(TWidget *target, QRect rect) {
myEnsureResized(target); myEnsureResized(target);
qreal dpr = App::app()->devicePixelRatio(); if (rect.isNull()) rect = target->rect();
qreal dpr = App::app()->devicePixelRatio();
QPixmap result(rect.size() * dpr); QPixmap result(rect.size() * dpr);
result.setDevicePixelRatio(dpr); result.setDevicePixelRatio(dpr);
result.fill(Qt::transparent); result.fill(Qt::transparent);
target->grabStart();
target->render(&result, QPoint(), QRegion(rect), QWidget::DrawChildren | QWidget::IgnoreMask); target->render(&result, QPoint(), QRegion(rect), QWidget::DrawChildren | QWidget::IgnoreMask);
target->grabFinish();
return result; return result;
} }

View File

@ -202,13 +202,17 @@ public:
bool event(QEvent *e) { bool event(QEvent *e) {
return QWidget::event(e); return QWidget::event(e);
} }
virtual void grabStart() {
}
virtual void grabFinish() {
}
private: private:
}; };
void myEnsureResized(QWidget *target); void myEnsureResized(QWidget *target);
QPixmap myGrab(QWidget *target, const QRect &rect); QPixmap myGrab(TWidget *target, QRect rect = QRect());
class PlainShadow : public TWidget { class PlainShadow : public TWidget {
public: public:

View File

@ -2381,12 +2381,13 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent)
, _confirmImageId(0) , _confirmImageId(0)
, _confirmWithText(false) , _confirmWithText(false)
, _titlePeerTextWidth(0) , _titlePeerTextWidth(0)
, _showAnim(animFunc(this, &HistoryWidget::showStep)) , _a_show(animFunc(this, &HistoryWidget::animStep_show))
, _scrollDelta(0) , _scrollDelta(0)
, _saveDraftStart(0) , _saveDraftStart(0)
, _saveDraftText(false) , _saveDraftText(false)
, _sideShadow(this, st::shadowColor) , _sideShadow(this, st::shadowColor)
, _topShadow(this, st::shadowColor) { , _topShadow(this, st::shadowColor)
, _inGrab(false) {
_scroll.setFocusPolicy(Qt::NoFocus); _scroll.setFocusPolicy(Qt::NoFocus);
setAcceptDrops(true); setAcceptDrops(true);
@ -2844,7 +2845,7 @@ void HistoryWidget::setKbWasHidden() {
if (_kbWasHidden || (!_keyboard.hasMarkup() && !_keyboard.forceReply())) return; if (_kbWasHidden || (!_keyboard.hasMarkup() && !_keyboard.forceReply())) return;
_kbWasHidden = true; _kbWasHidden = true;
if (!_showAnim.animating()) { if (!_a_show.animating()) {
_kbScroll.hide(); _kbScroll.hide();
_attachEmoji.show(); _attachEmoji.show();
_kbHide.hide(); _kbHide.hide();
@ -3186,7 +3187,7 @@ void HistoryWidget::updateReportSpamStatus() {
} }
void HistoryWidget::updateControlsVisibility() { void HistoryWidget::updateControlsVisibility() {
if (!_history || _showAnim.animating()) { if (!_history || _a_show.animating()) {
_reportSpamPanel.hide(); _reportSpamPanel.hide();
_scroll.hide(); _scroll.hide();
_kbScroll.hide(); _kbScroll.hide();
@ -3595,7 +3596,7 @@ void HistoryWidget::windowShown() {
bool HistoryWidget::isActive() const { bool HistoryWidget::isActive() const {
if (!_history) return true; if (!_history) return true;
if (_firstLoadRequest || _showAnim.animating()) return false; if (_firstLoadRequest || _a_show.animating()) return false;
if (_history->loadedAtBottom()) return true; if (_history->loadedAtBottom()) return true;
if (_history->showFrom && !_history->showFrom->detached() && _history->unreadBar) return true; if (_history->showFrom && !_history->showFrom->detached() && _history->unreadBar) return true;
return false; return false;
@ -3772,7 +3773,7 @@ void HistoryWidget::onHistoryToEnd() {
void HistoryWidget::onCollapseComments() { void HistoryWidget::onCollapseComments() {
MsgId switchAt = SwitchAtTopMsgId; MsgId switchAt = SwitchAtTopMsgId;
bool collapseCommentsVisible = !_showAnim.animating() && _history && !_firstLoadRequest && _history->isChannel() && !_history->asChannelHistory()->onlyImportant(); bool collapseCommentsVisible = !_a_show.animating() && _history && !_firstLoadRequest && _history->isChannel() && !_history->asChannelHistory()->onlyImportant();
if (collapseCommentsVisible) { if (collapseCommentsVisible) {
if (HistoryItem *collapse = _history->asChannelHistory()->collapse()) { if (HistoryItem *collapse = _history->asChannelHistory()->collapse()) {
if (!collapse->detached()) { if (!collapse->detached()) {
@ -3993,12 +3994,13 @@ HistoryItem *HistoryWidget::atTopImportantMsg(int32 &bottomUnderScrollTop) const
void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back) { void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back) {
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
_bgAnimCache = bgAnimCache; (back ? _cacheOver : _cacheUnder) = bgAnimCache;
_bgAnimTopBarCache = bgAnimTopBarCache; (back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache;
_animCache = myGrab(this, rect()); (back ? _cacheUnder : _cacheOver) = myGrab(this);
App::main()->topBar()->stopAnim(); App::main()->topBar()->stopAnim();
_animTopBarCache = myGrab(App::main()->topBar(), QRect(0, 0, width(), st::topBarHeight)); (back ? _cacheTopBarUnder : _cacheTopBarOver) = myGrab(App::main()->topBar());
App::main()->topBar()->startAnim(); App::main()->topBar()->startAnim();
_scroll.hide(); _scroll.hide();
_kbScroll.hide(); _kbScroll.hide();
_reportSpamPanel.hide(); _reportSpamPanel.hide();
@ -4019,43 +4021,38 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
_botStart.hide(); _botStart.hide();
_joinChannel.hide(); _joinChannel.hide();
_muteUnmute.hide(); _muteUnmute.hide();
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1);
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
a_bgAlpha = anim::fvalue(1, 0);
_sideShadow.hide();
_topShadow.hide(); _topShadow.hide();
_showAnim.start();
a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
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();
App::main()->topBar()->update(); App::main()->topBar()->update();
activate(); activate();
} }
bool HistoryWidget::showStep(float64 ms) { bool HistoryWidget::animStep_show(float64 ms) {
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 dt = ms / st::slideDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; bool res = true;
if (dt2 >= 1) { if (dt >= 1) {
_showAnim.stop(); _a_show.stop();
_sideShadow.show(); _sideShadow.setVisible(cWideMode());
_topShadow.show(); _topShadow.show();
res = false; res = false;
a_bgCoord.finish(); a_coordUnder.finish();
a_bgAlpha.finish(); a_coordOver.finish();
a_coord.finish(); a_shadow.finish();
a_alpha.finish(); _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap();
_bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap();
App::main()->topBar()->stopAnim(); App::main()->topBar()->stopAnim();
doneShow(); doneShow();
if (App::app()) App::app()->mtpUnpause(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
a_bgCoord.update(dt1, st::introHideFunc); a_coordUnder.update(dt, st::slideFunction);
a_bgAlpha.update(dt1, st::introAlphaHideFunc); a_coordOver.update(dt, st::slideFunction);
a_coord.update(dt2, st::introShowFunc); a_shadow.update(dt, st::slideFunction);
a_alpha.update(dt2, st::introAlphaShowFunc);
} }
update(); update();
App::main()->topBar()->update(); App::main()->topBar()->update();
@ -4074,10 +4071,14 @@ void HistoryWidget::doneShow() {
} }
} }
void HistoryWidget::updateWideMode() {
_sideShadow.setVisible(cWideMode());
}
void HistoryWidget::animStop() { void HistoryWidget::animStop() {
if (!_showAnim.animating()) return; if (!_a_show.animating()) return;
_showAnim.stop(); _a_show.stop();
_sideShadow.show(); _sideShadow.setVisible(cWideMode());
_topShadow.show(); _topShadow.show();
} }
@ -4616,11 +4617,11 @@ void HistoryWidget::selectMessage() {
} }
void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) { void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
if (_showAnim.animating()) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); p.drawPixmap(a_coordUnder.current(), 0, _cacheTopBarUnder);
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimTopBarCache); p.drawPixmap(a_coordOver.current(), 0, _cacheTopBarOver);
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current());
p.drawPixmap(a_coord.current(), 0, _animTopBarCache); p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), st::topBarHeight), App::sprite(), st::slideShadow);
return; return;
} }
@ -4757,7 +4758,7 @@ void HistoryWidget::onFieldFocused() {
} }
void HistoryWidget::checkMentionDropdown() { void HistoryWidget::checkMentionDropdown() {
if (!_history || _showAnim.animating()) return; if (!_history || _a_show.animating()) return;
QString start; QString start;
_field.getMentionHashtagBotCommandStart(start); _field.getMentionHashtagBotCommandStart(start);
@ -5275,8 +5276,8 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) {
break; break;
} }
_topShadow.resize(width() - (cWideMode() ? st::lineWidth : 0), st::lineWidth); _topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth);
_topShadow.moveToLeft(cWideMode() ? st::lineWidth : 0, 0); _topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0);
_sideShadow.resize(st::lineWidth, height()); _sideShadow.resize(st::lineWidth, height());
_sideShadow.moveToLeft(0, 0); _sideShadow.moveToLeft(0, 0);
} }
@ -5481,7 +5482,7 @@ void HistoryWidget::updateBotKeyboard() {
if (hasMarkup || forceReply) { if (hasMarkup || forceReply) {
if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) _kbWasHidden = true; if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) _kbWasHidden = true;
if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (!_field.hasSendText() && !_kbWasHidden))) { if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (!_field.hasSendText() && !_kbWasHidden))) {
if (!_showAnim.animating()) { if (!_a_show.animating()) {
if (hasMarkup) { if (hasMarkup) {
_kbScroll.show(); _kbScroll.show();
_attachEmoji.hide(); _attachEmoji.hide();
@ -5504,7 +5505,7 @@ void HistoryWidget::updateBotKeyboard() {
_replyForwardPreviewCancel.show(); _replyForwardPreviewCancel.show();
} }
} else { } else {
if (!_showAnim.animating()) { if (!_a_show.animating()) {
_kbScroll.hide(); _kbScroll.hide();
_attachEmoji.show(); _attachEmoji.show();
_kbHide.hide(); _kbHide.hide();
@ -5538,7 +5539,7 @@ void HistoryWidget::updateBotKeyboard() {
} }
void HistoryWidget::updateToEndVisibility() { void HistoryWidget::updateToEndVisibility() {
bool toEndVisible = !_showAnim.animating() && _history && !_firstLoadRequest && (!_history->loadedAtBottom() || _replyReturn || _scroll.scrollTop() + st::wndMinHeight < _scroll.scrollTopMax()); bool toEndVisible = !_a_show.animating() && _history && !_firstLoadRequest && (!_history->loadedAtBottom() || _replyReturn || _scroll.scrollTop() + st::wndMinHeight < _scroll.scrollTopMax());
if (toEndVisible && _toHistoryEnd.isHidden()) { if (toEndVisible && _toHistoryEnd.isHidden()) {
_toHistoryEnd.show(); _toHistoryEnd.show();
} else if (!toEndVisible && !_toHistoryEnd.isHidden()) { } else if (!toEndVisible && !_toHistoryEnd.isHidden()) {
@ -5548,7 +5549,7 @@ void HistoryWidget::updateToEndVisibility() {
void HistoryWidget::updateCollapseCommentsVisibility() { void HistoryWidget::updateCollapseCommentsVisibility() {
int32 collapseCommentsLeft = (width() - _collapseComments.width()) / 2, collapseCommentsTop = st::msgServiceMargin.top(); int32 collapseCommentsLeft = (width() - _collapseComments.width()) / 2, collapseCommentsTop = st::msgServiceMargin.top();
bool collapseCommentsVisible = !_showAnim.animating() && _history && !_firstLoadRequest && _history->isChannel() && !_history->asChannelHistory()->onlyImportant(); bool collapseCommentsVisible = !_a_show.animating() && _history && !_firstLoadRequest && _history->isChannel() && !_history->asChannelHistory()->onlyImportant();
if (collapseCommentsVisible) { if (collapseCommentsVisible) {
if (HistoryItem *collapse = _history->asChannelHistory()->collapse()) { if (HistoryItem *collapse = _history->asChannelHistory()->collapse()) {
if (!collapse->detached()) { if (!collapse->detached()) {
@ -5706,7 +5707,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) {
void HistoryWidget::setFieldText(const QString &text) { void HistoryWidget::setFieldText(const QString &text) {
_synthedTextUpdate = true; _synthedTextUpdate = true;
_field.setPlainText(text); _field.setTextFast(text);
_synthedTextUpdate = false; _synthedTextUpdate = false;
_previewCancelled = false; _previewCancelled = false;
@ -5970,7 +5971,7 @@ void HistoryWidget::peerUpdated(PeerData *data) {
App::api()->requestFullPeer(data); App::api()->requestFullPeer(data);
} }
} }
if (!_showAnim.animating()) { if (!_a_show.animating()) {
bool resize = (_unblock.isHidden() == isBlocked() || (!isBlocked() && _joinChannel.isHidden() == isJoinChannel())); bool resize = (_unblock.isHidden() == isBlocked() || (!isBlocked() && _joinChannel.isHidden() == isJoinChannel()));
bool newCanSendMessages = canSendMessages(_peer); bool newCanSendMessages = canSendMessages(_peer);
if (newCanSendMessages != _canSendMessages) { if (newCanSendMessages != _canSendMessages) {
@ -6281,11 +6282,16 @@ void HistoryWidget::paintEvent(QPaintEvent *e) {
if (r != rect()) { if (r != rect()) {
p.setClipRect(r); p.setClipRect(r);
} }
if (_showAnim.animating()) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); if (a_coordOver.current() > 0) {
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.drawPixmap(a_coord.current(), 0, _animCache); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
return; return;
} }

View File

@ -463,8 +463,10 @@ public:
HistoryItem *atTopImportantMsg(int32 &bottomUnderScrollTop) const; HistoryItem *atTopImportantMsg(int32 &bottomUnderScrollTop) const;
void animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false); void animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false);
bool showStep(float64 ms); bool animStep_show(float64 ms);
void animStop(); void animStop();
void updateWideMode();
void doneShow(); void doneShow();
QPoint clampMousePosition(QPoint point); QPoint clampMousePosition(QPoint point);
@ -536,6 +538,17 @@ public:
bool contentOverlapped(const QRect &globalRect); bool contentOverlapped(const QRect &globalRect);
void grabStart() {
_sideShadow.hide();
_inGrab = true;
resizeEvent(0);
}
void grabFinish() {
_sideShadow.setVisible(cWideMode());
_inGrab = false;
resizeEvent(0);
}
~HistoryWidget(); ~HistoryWidget();
signals: signals:
@ -772,10 +785,10 @@ private:
QString _titlePeerText; QString _titlePeerText;
int32 _titlePeerTextWidth; int32 _titlePeerTextWidth;
Animation _showAnim; Animation _a_show;
QPixmap _animCache, _bgAnimCache, _animTopBarCache, _bgAnimTopBarCache; QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver;
anim::ivalue a_coord, a_bgCoord; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_alpha, a_bgAlpha; anim::fvalue a_shadow;
QTimer _scrollTimer; QTimer _scrollTimer;
int32 _scrollDelta; int32 _scrollDelta;
@ -791,6 +804,7 @@ private:
QTimer _saveDraftTimer; QTimer _saveDraftTimer;
PlainShadow _sideShadow, _topShadow; PlainShadow _sideShadow, _topShadow;
bool _inGrab;
}; };

View File

@ -52,10 +52,12 @@ namespace {
} }
} }
IntroWidget::IntroWidget(Window *window) : QWidget(window), IntroWidget::IntroWidget(Window *window) : TWidget(window),
_langChangeTo(0), _langChangeTo(0),
cacheForHideInd(0), _a_stage(animFunc(this, &IntroWidget::animStep_stage)),
cacheForShowInd(0), _cacheHideIndex(0),
_cacheShowIndex(0),
_a_show(animFunc(this, &IntroWidget::animStep_show)),
wnd(window), wnd(window),
steps(new IntroSteps(this)), steps(new IntroSteps(this)),
phone(0), phone(0),
@ -64,7 +66,6 @@ signup(0),
pwdcheck(0), pwdcheck(0),
current(0), current(0),
moving(0), moving(0),
visibilityChanging(0),
_callTimeout(60), _callTimeout(60),
_registered(false), _registered(false),
_hasRecovery(false), _hasRecovery(false),
@ -85,7 +86,7 @@ _backFrom(0), _backTo(0) {
memset(stages + 1, 0, sizeof(QWidget*) * 3); memset(stages + 1, 0, sizeof(QWidget*) * 3);
_back.raise(); _back.raise();
connect(window, SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &))); connect(window, SIGNAL(resized(const QSize&)), this, SLOT(onParentResize(const QSize&)));
show(); show();
setFocus(); setFocus();
@ -147,21 +148,21 @@ bool IntroWidget::createNext() {
void IntroWidget::prepareMove() { void IntroWidget::prepareMove() {
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
if (cacheForHide.isNull() || cacheForHideInd != current) makeHideCache(); if (_cacheHide.isNull() || _cacheHideIndex != current) makeHideCache();
stages[current + moving]->prepareShow(); stages[current + moving]->prepareShow();
if (cacheForShow.isNull() || cacheForShowInd != current + moving) makeShowCache(); if (_cacheShow.isNull() || _cacheShowIndex != current + moving) makeShowCache();
int32 m = (moving > 0) ? 1 : -1; int32 m = (moving > 0) ? 1 : -1;
xCoordHide = anim::ivalue(0, -m * st::introSlideShift); a_coordHide = anim::ivalue(0, -m * st::introSlideShift);
cAlphaHide = anim::fvalue(1, 0); a_opacityHide = anim::fvalue(1, 0);
xCoordShow = anim::ivalue(m * st::introSlideShift, 0); a_coordShow = anim::ivalue(m * st::introSlideShift, 0);
cAlphaShow = anim::fvalue(0, 1); a_opacityShow = anim::fvalue(0, 1);
anim::start(this); _a_stage.start();
_backTo = stages[current + moving]->hasBack() ? 1 : 0; _backTo = stages[current + moving]->hasBack() ? 1 : 0;
_backFrom = stages[current]->hasBack() ? 1 : 0; _backFrom = stages[current]->hasBack() ? 1 : 0;
animStep(0); animStep_stage(0);
if (_backFrom > 0 || _backTo > 0) { if (_backFrom > 0 || _backTo > 0) {
_back.show(); _back.show();
} else { } else {
@ -172,39 +173,39 @@ void IntroWidget::prepareMove() {
} }
void IntroWidget::onDoneStateChanged(int oldState, ButtonStateChangeSource source) { void IntroWidget::onDoneStateChanged(int oldState, ButtonStateChangeSource source) {
if (animating()) return; if (_a_stage.animating()) return;
if (source == ButtonByPress) { if (source == ButtonByPress) {
if (oldState & Button::StateDown) { if (oldState & Button::StateDown) {
cacheForHide = QPixmap(); _cacheHide = QPixmap();
} else { } else {
makeHideCache(); makeHideCache();
} }
} else if (source == ButtonByHover && current != 2) { } else if (source == ButtonByHover && current != 2) {
if (!createNext()) return; if (!createNext()) return;
if (!cacheForShow) makeShowCache(current + 1); if (!_cacheShow) makeShowCache(current + 1);
} }
} }
void IntroWidget::makeHideCache(int stage) { void IntroWidget::makeHideCache(int stage) {
if (stage < 0) stage = current; if (stage < 0) stage = current;
int w = st::introSize.width(), h = st::introSize.height(); int w = st::introSize.width(), h = st::introSize.height();
cacheForHide = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h)); _cacheHide = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h));
cacheForHideInd = stage; _cacheHideIndex = stage;
} }
void IntroWidget::makeShowCache(int stage) { void IntroWidget::makeShowCache(int stage) {
if (stage < 0) stage = current + moving; if (stage < 0) stage = current + moving;
int w = st::introSize.width(), h = st::introSize.height(); int w = st::introSize.width(), h = st::introSize.height();
cacheForShow = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h)); _cacheShow = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h));
cacheForShowInd = stage; _cacheShowIndex = stage;
} }
void IntroWidget::animShow(const QPixmap &bgAnimCache, bool back) { void IntroWidget::animShow(const QPixmap &bgAnimCache, bool back) {
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
_bgAnimCache = bgAnimCache; (back ? _cacheOver : _cacheUnder) = bgAnimCache;
anim::stop(this); _a_show.stop();
stages[current]->show(); stages[current]->show();
if (stages[current]->hasBack()) { if (stages[current]->hasBack()) {
_back.setOpacity(1); _back.setOpacity(1);
@ -212,56 +213,65 @@ void IntroWidget::animShow(const QPixmap &bgAnimCache, bool back) {
} else { } else {
_back.hide(); _back.hide();
} }
_animCache = myGrab(this, rect()); (back ? _cacheUnder : _cacheOver) = myGrab(this);
visibilityChanging = 1;
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1);
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
a_bgAlpha = anim::fvalue(1, 0);
stages[current]->deactivate(); stages[current]->deactivate();
stages[current]->hide(); stages[current]->hide();
_back.hide(); _back.hide();
anim::start(this);
a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
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();
} }
bool IntroWidget::animStep(float64 ms) { bool IntroWidget::animStep_show(float64 ms) {
float64 dt = ms / st::slideDuration;
bool res = true;
if (dt >= 1) {
_a_show.stop();
res = false;
a_coordUnder.finish();
a_coordOver.finish();
a_shadow.finish();
_cacheUnder = _cacheOver = QPixmap();
setFocus();
stages[current]->show();
stages[current]->activate();
if (stages[current]->hasBack()) {
_back.setOpacity(1);
_back.show();
}
if (App::app()) App::app()->mtpUnpause();
} else {
a_coordUnder.update(dt, st::slideFunction);
a_coordOver.update(dt, st::slideFunction);
a_shadow.update(dt, st::slideFunction);
}
update();
return res;
}
void IntroWidget::animStop_show() {
_a_show.stop();
}
bool IntroWidget::animStep_stage(float64 ms) {
bool res = true;
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0; float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; if (dt >= 1) {
if (visibilityChanging) {
if (dt2 >= 1) {
res = false;
a_bgCoord.finish();
a_bgAlpha.finish();
a_coord.finish();
a_alpha.finish();
_animCache = _bgAnimCache = QPixmap();
visibilityChanging = 0;
setFocus();
stages[current]->show();
stages[current]->activate();
if (stages[current]->hasBack()) {
_back.setOpacity(1);
_back.show();
}
if (App::app()) App::app()->mtpUnpause();
} else {
a_bgCoord.update(dt1, st::introHideFunc);
a_bgAlpha.update(dt1, st::introAlphaHideFunc);
a_coord.update(dt2, st::introShowFunc);
a_alpha.update(dt2, st::introAlphaShowFunc);
}
} else if (dt >= 1) {
res = false; res = false;
xCoordShow.finish(); a_coordShow.finish();
cAlphaShow.finish(); a_opacityShow.finish();
cacheForHide = cacheForShow = QPixmap(); _cacheHide = _cacheShow = QPixmap();
current += moving; current += moving;
moving = 0; moving = 0;
@ -272,12 +282,12 @@ bool IntroWidget::animStep(float64 ms) {
} }
if (App::app()) App::app()->mtpUnpause(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
xCoordShow.update(dt2, st::introShowFunc); a_coordShow.update(dt2, st::introShowFunc);
cAlphaShow.update(dt2, st::introAlphaShowFunc); a_opacityShow.update(dt2, st::introAlphaShowFunc);
xCoordHide.update(dt1, st::introHideFunc); a_coordHide.update(dt1, st::introHideFunc);
cAlphaHide.update(dt1, st::introAlphaHideFunc); a_opacityHide.update(dt1, st::introAlphaHideFunc);
if (_backFrom != _backTo) { if (_backFrom != _backTo) {
_back.setOpacity((_backFrom > _backTo) ? cAlphaHide.current() : cAlphaShow.current()); _back.setOpacity((_backFrom > _backTo) ? a_opacityHide.current() : a_opacityShow.current());
} else { } else {
_back.setOpacity(1); _back.setOpacity(1);
} }
@ -295,18 +305,21 @@ void IntroWidget::paintEvent(QPaintEvent *e) {
p.setClipRect(e->rect()); p.setClipRect(e->rect());
} }
p.fillRect(e->rect(), st::white->b); p.fillRect(e->rect(), st::white->b);
if (animating()) { if (_a_show.animating()) {
if (visibilityChanging) { if (a_coordOver.current() > 0) {
p.setOpacity(a_bgAlpha.current()); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.setOpacity(a_alpha.current()); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.drawPixmap(a_coord.current(), 0, _animCache); p.setOpacity(1);
} else {
p.setOpacity(cAlphaHide.current());
p.drawPixmap(stages[current]->x() + st::introSlideShift + xCoordHide.current(), stages[current]->y(), cacheForHide);
p.setOpacity(cAlphaShow.current());
p.drawPixmap(stages[current + moving]->x() + st::introSlideShift + xCoordShow.current(), stages[current + moving]->y(), cacheForShow);
} }
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
} else if (_a_stage.animating()) {
p.setOpacity(a_opacityHide.current());
p.drawPixmap(stages[current]->x() + st::introSlideShift + a_coordHide.current(), stages[current]->y(), _cacheHide);
p.setOpacity(a_opacityShow.current());
p.drawPixmap(stages[current + moving]->x() + st::introSlideShift + a_coordShow.current(), stages[current + moving]->y(), _cacheShow);
} }
} }
@ -408,7 +421,8 @@ void IntroWidget::finish(const MTPUser &user, const QImage &photo) {
} }
void IntroWidget::keyPressEvent(QKeyEvent *e) { void IntroWidget::keyPressEvent(QKeyEvent *e) {
if (animating()) return; if (_a_show.animating() || _a_stage.animating()) return;
if (e->key() == Qt::Key_Escape) { if (e->key() == Qt::Key_Escape) {
stages[current]->onBack(); stages[current]->onBack();
} else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return || e->key() == Qt::Key_Space) { } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return || e->key() == Qt::Key_Space) {

View File

@ -29,7 +29,7 @@ class IntroPwdCheck;
class IntroStage; class IntroStage;
class Text; class Text;
class IntroWidget : public QWidget, public Animated { class IntroWidget : public TWidget {
Q_OBJECT Q_OBJECT
public: public:
@ -44,7 +44,10 @@ public:
void updateWideMode(); void updateWideMode();
void animShow(const QPixmap &bgAnimCache, bool back = false); void animShow(const QPixmap &bgAnimCache, bool back = false);
bool animStep(float64 ms); bool animStep_show(float64 ms);
void animStop_show();
bool animStep_stage(float64 ms);
QRect innerRect() const; QRect innerRect() const;
QString currentCountry() const; QString currentCountry() const;
@ -94,14 +97,16 @@ private:
int32 _langChangeTo; int32 _langChangeTo;
QPixmap cacheForHide, cacheForShow; Animation _a_stage;
int cacheForHideInd, cacheForShowInd; QPixmap _cacheHide, _cacheShow;
anim::ivalue xCoordHide, xCoordShow; int _cacheHideIndex, _cacheShowIndex;
anim::fvalue cAlphaHide, cAlphaShow; anim::ivalue a_coordHide, a_coordShow;
anim::fvalue a_opacityHide, a_opacityShow;
QPixmap _animCache, _bgAnimCache; Animation _a_show;
anim::ivalue a_coord, a_bgCoord; QPixmap _cacheUnder, _cacheOver;
anim::fvalue a_alpha, a_bgAlpha; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_shadow;
Window *wnd; Window *wnd;
IntroSteps *steps; IntroSteps *steps;
@ -110,7 +115,7 @@ private:
IntroSignup *signup; IntroSignup *signup;
IntroPwdCheck *pwdcheck; IntroPwdCheck *pwdcheck;
IntroStage *stages[5]; IntroStage *stages[5];
int current, moving, visibilityChanging; int current, moving;
QString _phone, _phone_hash; QString _phone, _phone_hash;
int32 _callTimeout; int32 _callTimeout;
@ -129,10 +134,10 @@ private:
}; };
class IntroStage : public QWidget { class IntroStage : public TWidget {
public: public:
IntroStage(IntroWidget *parent) : QWidget(parent) { IntroStage(IntroWidget *parent) : TWidget(parent) {
} }
virtual void activate() = 0; // show and activate virtual void activate() = 0; // show and activate

View File

@ -71,7 +71,7 @@ IntroPhone::IntroPhone(IntroWidget *parent) : IntroStage(parent),
_signup.setLink(1, TextLinkPtr(new SignUpLink(this))); _signup.setLink(1, TextLinkPtr(new SignUpLink(this)));
_signup.hide(); _signup.hide();
_signupCache = myGrab(&_signup, _signup.rect()); _signupCache = myGrab(&_signup);
if (!country.onChooseCountry(intro()->currentCountry())) { if (!country.onChooseCountry(intro()->currentCountry())) {
country.onChooseCountry(qsl("US")); country.onChooseCountry(qsl("US"));

View File

@ -277,12 +277,11 @@ void TopBarWidget::startAnim() {
_mediaType.hide(); _mediaType.hide();
_animating = true; _animating = true;
_sideShadow.hide();
} }
void TopBarWidget::stopAnim() { void TopBarWidget::stopAnim() {
_animating = false; _animating = false;
_sideShadow.show(); _sideShadow.setVisible(cWideMode());
showAll(); showAll();
} }
@ -352,6 +351,7 @@ void TopBarWidget::showAll() {
_info.hide(); _info.hide();
} }
} }
_sideShadow.setVisible(cWideMode());
resizeEvent(0); resizeEvent(0);
} }
@ -366,6 +366,10 @@ void TopBarWidget::showSelected(uint32 selCount, bool canDelete) {
showAll(); showAll();
} }
void TopBarWidget::updateWideMode() {
showAll();
}
FlatButton *TopBarWidget::mediaTypeButton() { FlatButton *TopBarWidget::mediaTypeButton() {
return &_mediaType; return &_mediaType;
} }
@ -374,21 +378,49 @@ MainWidget *TopBarWidget::main() {
return static_cast<MainWidget*>(parentWidget()); return static_cast<MainWidget*>(parentWidget());
} }
MainWidget::MainWidget(Window *window) : TWidget(window), MainWidget::MainWidget(Window *window) : TWidget(window)
_started(0), failedObjId(0), _toForwardNameVersion(0), _dialogsWidth(st::dlgMinWidth), , _started(0)
dialogs(this), history(this), profile(0), overview(0), _player(this), _topBar(this), , failedObjId(0)
_forwardConfirm(0), _hider(0), _peerInStack(0), _msgIdInStack(0), , _toForwardNameVersion(0)
_playerHeight(0), _contentScrollAddToY(0), _mediaType(this), _mediaTypeMask(0), , _dialogsWidth(st::dlgMinWidth)
updDate(0), updQts(-1), updSeq(0), _getDifferenceTimeByPts(0), _getDifferenceTimeAfterFail(0), , _a_show(animFunc(this, &MainWidget::animStep_show))
_onlineRequest(0), _lastWasOnline(false), _lastSetOnline(0), _isIdle(false), , dialogs(this)
_failDifferenceTimeout(1), _lastUpdateTime(0), _handlingChannelDifference(false), _cachedX(0), _cachedY(0), _background(0), _api(new ApiWrap(this)) { , history(this)
, profile(0)
, overview(0)
, _player(this)
, _topBar(this)
, _forwardConfirm(0)
, _hider(0)
, _peerInStack(0)
, _msgIdInStack(0)
, _playerHeight(0)
, _contentScrollAddToY(0)
, _mediaType(this)
, _mediaTypeMask(0)
, updDate(0)
, updQts(-1)
, updSeq(0)
, _getDifferenceTimeByPts(0)
, _getDifferenceTimeAfterFail(0)
, _onlineRequest(0)
, _lastWasOnline(false)
, _lastSetOnline(0)
, _isIdle(false)
, _failDifferenceTimeout(1)
, _lastUpdateTime(0)
, _handlingChannelDifference(false)
, _cachedX(0)
, _cachedY(0)
, _background(0)
, _api(new ApiWrap(this)) {
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight)); setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
MTP::setGlobalDoneHandler(rpcDone(&MainWidget::updateReceived)); MTP::setGlobalDoneHandler(rpcDone(&MainWidget::updateReceived));
_ptsWaiter.setRequesting(true); _ptsWaiter.setRequesting(true);
updateScrollColors(); updateScrollColors();
connect(window, SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &))); connect(window, SIGNAL(resized(const QSize&)), this, SLOT(onParentResize(const QSize&)));
connect(&dialogs, SIGNAL(cancelled()), this, SLOT(dialogsCancelled())); connect(&dialogs, SIGNAL(cancelled()), this, SLOT(dialogsCancelled()));
connect(&history, SIGNAL(cancelled()), &dialogs, SLOT(activate())); connect(&history, SIGNAL(cancelled()), &dialogs, SLOT(activate()));
connect(this, SIGNAL(peerPhotoChanged(PeerData*)), this, SIGNAL(dialogsUpdated())); connect(this, SIGNAL(peerPhotoChanged(PeerData*)), this, SIGNAL(dialogsUpdated()));
@ -644,6 +676,30 @@ void MainWidget::onFilesOrForwardDrop(const PeerId &peer, const QMimeData *data)
} }
} }
QPixmap MainWidget::grabInner() {
if (overview && !overview->isHidden()) {
return myGrab(overview);
} else if (profile && !profile->isHidden()) {
return myGrab(profile);
} else if (!cWideMode() && history.isHidden()) {
return myGrab(&dialogs, QRect(0, st::topBarHeight, dialogs.width(), dialogs.height() - st::topBarHeight));
} else if (history.peer()) {
return myGrab(&history);
} else {
return myGrab(&history, QRect(0, st::topBarHeight, history.width(), history.height() - st::topBarHeight));
}
}
QPixmap MainWidget::grabTopBar() {
if (!_topBar.isHidden()) {
return myGrab(&_topBar);
} else if (!cWideMode() && history.isHidden()) {
return myGrab(&dialogs, QRect(0, 0, dialogs.width(), st::topBarHeight));
} else {
return myGrab(&history, QRect(0, 0, history.width(), st::topBarHeight));
}
}
void MainWidget::noHider(HistoryHider *destroyed) { void MainWidget::noHider(HistoryHider *destroyed) {
if (_hider == destroyed) { if (_hider == destroyed) {
_hider = 0; _hider = 0;
@ -659,8 +715,7 @@ void MainWidget::noHider(HistoryHider *destroyed) {
} }
onHistoryShown(history.history(), history.msgId()); onHistoryShown(history.history(), history.msgId());
if (profile || overview || (history.peer() && history.peer()->id)) { if (profile || overview || (history.peer() && history.peer()->id)) {
QPixmap animCache = myGrab(this, QRect(0, _playerHeight + st::topBarHeight, _dialogsWidth, height() - _playerHeight - st::topBarHeight)), QPixmap animCache = grabInner(), animTopBarCache = grabTopBar();
animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight));
dialogs.hide(); dialogs.hide();
if (overview) { if (overview) {
overview->show(); overview->show();
@ -1837,7 +1892,7 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) {
if (playing == songId) { if (playing == songId) {
_player.updateState(playing, playingState, playingPosition, playingDuration, playingFrequency); _player.updateState(playing, playingState, playingPosition, playingDuration, playingFrequency);
if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing && !animating()) { if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing && !_a_show.animating()) {
if (_player.isHidden()) { if (_player.isHidden()) {
_player.clearSelection(); _player.clearSelection();
_player.show(); _player.show();
@ -2328,20 +2383,16 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back)
} }
QPixmap animCache, animTopBarCache; QPixmap animCache, animTopBarCache;
if (!animating() && ((history.isHidden() && (profile || overview)) || (!cWideMode() && (history.isHidden() || !peerId)))) { if (!_a_show.animating() && ((history.isHidden() && (profile || overview)) || (!cWideMode() && (history.isHidden() || !peerId)))) {
if (peerId) { if (peerId) {
if (cWideMode()) { animCache = grabInner();
animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight + st::topBarHeight, width() - _dialogsWidth, height() - _playerHeight - st::topBarHeight));
} else {
animCache = myGrab(this, QRect(0, _playerHeight + st::topBarHeight, _dialogsWidth, height() - _playerHeight - st::topBarHeight));
}
} else if (cWideMode()) { } else if (cWideMode()) {
animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight)); animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight));
} else { } else {
animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight));
} }
if (peerId || cWideMode()) { if (peerId || cWideMode()) {
animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight)); animTopBarCache = grabTopBar();
} }
history.show(); history.show();
} }
@ -2373,7 +2424,7 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back)
if (onlyDialogs) { if (onlyDialogs) {
_topBar.hide(); _topBar.hide();
history.hide(); history.hide();
if (!animating()) { if (!_a_show.animating()) {
dialogs.show(); dialogs.show();
if (!animCache.isNull()) { if (!animCache.isNull()) {
dialogs.animShow(animCache); dialogs.animShow(animCache);
@ -2390,7 +2441,7 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back)
_viewsIncremented.remove(activePeer()); _viewsIncremented.remove(activePeer());
} }
if (!cWideMode() && !dialogs.isHidden()) dialogs.hide(); if (!cWideMode() && !dialogs.isHidden()) dialogs.hide();
if (!animating()) { if (!_a_show.animating()) {
if (history.isHidden()) history.show(); if (history.isHidden()) history.show();
if (!animCache.isNull()) { if (!animCache.isNull()) {
history.animShow(animCache, animTopBarCache, back); history.animShow(animCache, animTopBarCache, back);
@ -2477,9 +2528,9 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool
QRect topBarRect = QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight); QRect topBarRect = QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight);
QRect historyRect = QRect(history.x(), topBarRect.y() + topBarRect.height(), history.width(), history.y() + history.height() - topBarRect.y() - topBarRect.height()); QRect historyRect = QRect(history.x(), topBarRect.y() + topBarRect.height(), history.width(), history.y() + history.height() - topBarRect.y() - topBarRect.height());
QPixmap animCache, animTopBarCache; QPixmap animCache, animTopBarCache;
if (!animating() && (!cWideMode() || profile || overview || history.peer())) { if (!_a_show.animating() && (!cWideMode() || profile || overview || history.peer())) {
animCache = myGrab(this, historyRect); animCache = grabInner();
animTopBarCache = myGrab(this, topBarRect); animTopBarCache = grabTopBar();
} }
if (!back) { if (!back) {
if (overview) { if (overview) {
@ -2532,7 +2583,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop)
App::wnd()->hideSettings(); App::wnd()->hideSettings();
if (profile && profile->peer() == peer) return; if (profile && profile->peer() == peer) return;
QPixmap animCache = myGrab(this, history.geometry()), animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight)); QPixmap animCache = grabInner(), animTopBarCache = grabTopBar();
if (!back) { if (!back) {
if (overview) { if (overview) {
_stack.push_back(new StackItemOverview(overview->peer(), overview->type(), overview->lastWidth(), overview->lastScrollTop())); _stack.push_back(new StackItemOverview(overview->peer(), overview->type(), overview->lastWidth(), overview->lastScrollTop()));
@ -2686,60 +2737,66 @@ void MainWidget::historyCleared(History *hist) {
void MainWidget::animShow(const QPixmap &bgAnimCache, bool back) { void MainWidget::animShow(const QPixmap &bgAnimCache, bool back) {
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
_bgAnimCache = bgAnimCache; (back ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
anim::stop(this);
showAll(); showAll();
_animCache = myGrab(this, rect()); (back ? _cacheUnder : _cacheOver) = myGrab(this);
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1);
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
a_bgAlpha = anim::fvalue(1, 0);
hideAll(); hideAll();
anim::start(this);
a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
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();
} }
bool MainWidget::animStep(float64 ms) { bool MainWidget::animStep_show(float64 ms) {
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 dt = ms / st::slideDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; bool res = true;
if (dt2 >= 1) { if (dt >= 1) {
_a_show.stop();
res = false; res = false;
a_bgCoord.finish(); a_coordUnder.finish();
a_bgAlpha.finish(); a_coordOver.finish();
a_coord.finish(); a_shadow.finish();
a_alpha.finish();
_animCache = _bgAnimCache = QPixmap(); _cacheUnder = _cacheOver = QPixmap();
anim::stop(this);
showAll(); showAll();
activate(); activate();
if (App::app()) App::app()->mtpUnpause(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
a_bgCoord.update(dt1, st::introHideFunc); a_coordUnder.update(dt, st::slideFunction);
a_bgAlpha.update(dt1, st::introAlphaHideFunc); a_coordOver.update(dt, st::slideFunction);
a_coord.update(dt2, st::introShowFunc); a_shadow.update(dt, st::slideFunction);
a_alpha.update(dt2, st::introAlphaShowFunc);
} }
update(); update();
return res; return res;
} }
void MainWidget::animStop_show() {
_a_show.stop();
}
void MainWidget::paintEvent(QPaintEvent *e) { void MainWidget::paintEvent(QPaintEvent *e) {
if (_background) checkChatBackground(); if (_background) checkChatBackground();
QPainter p(this); Painter p(this);
if (animating()) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); if (a_coordOver.current() > 0) {
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.drawPixmap(a_coord.current(), 0, _animCache); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
} else { p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
} }
} }
@ -2872,7 +2929,11 @@ void MainWidget::keyPressEvent(QKeyEvent *e) {
void MainWidget::updateWideMode() { void MainWidget::updateWideMode() {
showAll(); showAll();
_topBar.showAll(); _topBar.updateWideMode();
history.updateWideMode();
if (overview) overview->updateWideMode();
if (profile) profile->updateWideMode();
_player.updateWideMode();
} }
bool MainWidget::needBackButton() { bool MainWidget::needBackButton() {
@ -2943,7 +3004,7 @@ void MainWidget::onHistoryShown(History *history, MsgId atMsgId) {
_topBar.hide(); _topBar.hide();
} }
resizeEvent(0); resizeEvent(0);
if (animating()) { if (_a_show.animating()) {
_topBar.hide(); _topBar.hide();
} }
dlgUpdated(history, atMsgId); dlgUpdated(history, atMsgId);
@ -3907,6 +3968,7 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
} }
void MainWidget::activate() { void MainWidget::activate() {
if (_a_show.animating()) return;
if (!profile && !overview) { if (!profile && !overview) {
if (_hider) { if (_hider) {
if (_hider->wasOffered()) { if (_hider->wasOffered()) {
@ -3943,7 +4005,7 @@ void MainWidget::addNewContact(int32 uid, bool show) {
} }
bool MainWidget::isActive() const { bool MainWidget::isActive() const {
return !_isIdle && isVisible() && !animating(); return !_isIdle && isVisible() && !_a_show.animating();
} }
bool MainWidget::historyIsActive() const { bool MainWidget::historyIsActive() const {

View File

@ -55,8 +55,17 @@ public:
void showAll(); void showAll();
void showSelected(uint32 selCount, bool canDelete = false); void showSelected(uint32 selCount, bool canDelete = false);
void updateWideMode();
FlatButton *mediaTypeButton(); FlatButton *mediaTypeButton();
void grabStart() {
_sideShadow.hide();
}
void grabFinish() {
_sideShadow.setVisible(cWideMode());
}
public slots: public slots:
void onForwardSelection(); void onForwardSelection();
@ -177,7 +186,7 @@ enum ForwardWhatMessages {
ForwardPressedLinkMessage ForwardPressedLinkMessage
}; };
class MainWidget : public TWidget, public Animated, public RPCSender { class MainWidget : public TWidget, public RPCSender {
Q_OBJECT Q_OBJECT
public: public:
@ -199,7 +208,8 @@ public:
int32 contentScrollAddToY() const; int32 contentScrollAddToY() const;
void animShow(const QPixmap &bgAnimCache, bool back = false); void animShow(const QPixmap &bgAnimCache, bool back = false);
bool animStep(float64 ms); bool animStep_show(float64 ms);
void animStop_show();
void start(const MTPUser &user); void start(const MTPUser &user);
@ -403,6 +413,9 @@ public:
bool contentOverlapped(const QRect &globalRect); bool contentOverlapped(const QRect &globalRect);
QPixmap grabTopBar();
QPixmap grabInner();
~MainWidget(); ~MainWidget();
signals: signals:
@ -539,9 +552,10 @@ private:
void overviewPreloaded(PeerData *data, const MTPmessages_Messages &result, mtpRequestId req); void overviewPreloaded(PeerData *data, const MTPmessages_Messages &result, mtpRequestId req);
bool overviewFailed(PeerData *data, const RPCError &error, mtpRequestId req); bool overviewFailed(PeerData *data, const RPCError &error, mtpRequestId req);
QPixmap _animCache, _bgAnimCache; Animation _a_show;
anim::ivalue a_coord, a_bgCoord; QPixmap _cacheUnder, _cacheOver;
anim::fvalue a_alpha, a_bgAlpha; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_shadow;
int32 _dialogsWidth; int32 _dialogsWidth;

View File

@ -2544,17 +2544,20 @@ OverviewWidget::OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverv
, _scroll(this, st::historyScroll, false) , _scroll(this, st::historyScroll, false)
, _inner(this, &_scroll, peer, type) , _inner(this, &_scroll, peer, type)
, _noDropResizeIndex(false) , _noDropResizeIndex(false)
, _showing(false) , _a_show(animFunc(this, &OverviewWidget::animStep_show))
, _scrollSetAfterShow(0) , _scrollSetAfterShow(0)
, _scrollDelta(0) , _scrollDelta(0)
, _selCount(0) , _selCount(0)
, _sideShadow(this, st::shadowColor) , _sideShadow(this, st::shadowColor)
, _topShadow(this, st::shadowColor) { , _topShadow(this, st::shadowColor)
, _inGrab(false) {
_scroll.setFocusPolicy(Qt::NoFocus); _scroll.setFocusPolicy(Qt::NoFocus);
_scroll.setWidget(&_inner); _scroll.setWidget(&_inner);
_scroll.move(0, 0); _scroll.move(0, 0);
_inner.move(0, 0); _inner.move(0, 0);
_sideShadow.setVisible(cWideMode());
updateScrollColors(); updateScrollColors();
_scroll.show(); _scroll.show();
@ -2604,8 +2607,8 @@ void OverviewWidget::resizeEvent(QResizeEvent *e) {
_noDropResizeIndex = false; _noDropResizeIndex = false;
} }
_topShadow.resize(width() - (cWideMode() ? st::lineWidth : 0), st::lineWidth); _topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth);
_topShadow.moveToLeft(cWideMode() ? st::lineWidth : 0, 0); _topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0);
_sideShadow.resize(st::lineWidth, height()); _sideShadow.resize(st::lineWidth, height());
_sideShadow.moveToLeft(0, 0); _sideShadow.moveToLeft(0, 0);
} }
@ -2614,11 +2617,16 @@ 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);
if (animating() && _showing) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); if (a_coordOver.current() > 0) {
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.drawPixmap(a_coord.current(), 0, _animCache); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
return; return;
} }
@ -2675,18 +2683,18 @@ void OverviewWidget::scrollReset() {
} }
void OverviewWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) { void OverviewWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
if (animating() && _showing) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); p.drawPixmap(a_coordUnder.current(), 0, _cacheTopBarUnder);
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimTopBarCache); p.drawPixmap(a_coordOver.current(), 0, _cacheTopBarOver);
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current());
p.drawPixmap(a_coord.current(), 0, _animTopBarCache); p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), st::topBarHeight), App::sprite(), st::slideShadow);
} else { return;
p.setOpacity(st::topBarBackAlpha + (1 - st::topBarBackAlpha) * over);
p.drawPixmap(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), App::sprite(), st::topBarBackImg);
p.setFont(st::topBarBackFont->f);
p.setPen(st::topBarBackColor->p);
p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, _header);
} }
p.setOpacity(st::topBarBackAlpha + (1 - st::topBarBackAlpha) * over);
p.drawPixmap(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), App::sprite(), st::topBarBackImg);
p.setFont(st::topBarBackFont->f);
p.setPen(st::topBarBackColor->p);
p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, _header);
} }
void OverviewWidget::topBarClick() { void OverviewWidget::topBarClick() {
@ -2784,60 +2792,63 @@ void OverviewWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimT
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
stopGif(); stopGif();
_bgAnimCache = bgAnimCache;
_bgAnimTopBarCache = bgAnimTopBarCache; (back ? _cacheOver : _cacheUnder) = bgAnimCache;
(back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache;
resizeEvent(0); resizeEvent(0);
_scroll.scrollToY(lastScrollTop < 0 ? countBestScroll() : lastScrollTop); _scroll.scrollToY(lastScrollTop < 0 ? countBestScroll() : lastScrollTop);
_animCache = myGrab(this, rect()); (back ? _cacheUnder : _cacheOver) = myGrab(this);
App::main()->topBar()->stopAnim(); App::main()->topBar()->stopAnim();
_animTopBarCache = myGrab(App::main()->topBar(), QRect(0, 0, width(), st::topBarHeight)); (back ? _cacheTopBarUnder : _cacheTopBarOver) = myGrab(App::main()->topBar());
App::main()->topBar()->startAnim(); App::main()->topBar()->startAnim();
_scrollSetAfterShow = _scroll.scrollTop(); _scrollSetAfterShow = _scroll.scrollTop();
_scroll.hide(); _scroll.hide();
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1);
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
a_bgAlpha = anim::fvalue(1, 0);
anim::start(this);
_sideShadow.hide();
_topShadow.hide(); _topShadow.hide();
_showing = true; a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
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();
_inner.activate();
App::main()->topBar()->update(); App::main()->topBar()->update();
_inner.activate();
} }
bool OverviewWidget::animStep(float64 ms) { bool OverviewWidget::animStep_show(float64 ms) {
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 dt = ms / st::slideDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; bool res = true;
if (dt2 >= 1) { if (dt >= 1) {
res = _showing = false; _a_show.stop();
_sideShadow.show(); _sideShadow.setVisible(cWideMode());
_topShadow.show(); _topShadow.show();
a_bgCoord.finish(); res = false;
a_bgAlpha.finish(); a_coordUnder.finish();
a_coord.finish(); a_coordOver.finish();
a_alpha.finish(); a_shadow.finish();
_bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap(); _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap();
App::main()->topBar()->stopAnim(); App::main()->topBar()->stopAnim();
doneShow(); doneShow();
if (App::app()) App::app()->mtpUnpause(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
a_bgCoord.update(dt1, st::introHideFunc); a_coordUnder.update(dt, st::slideFunction);
a_bgAlpha.update(dt1, st::introAlphaHideFunc); a_coordOver.update(dt, st::slideFunction);
a_coord.update(dt2, st::introShowFunc); a_shadow.update(dt, st::slideFunction);
a_alpha.update(dt2, st::introAlphaShowFunc);
} }
update(); update();
App::main()->topBar()->update(); App::main()->topBar()->update();
return res; return res;
} }
void OverviewWidget::updateWideMode() {
_sideShadow.setVisible(cWideMode());
}
void OverviewWidget::doneShow() { void OverviewWidget::doneShow() {
_scroll.show(); _scroll.show();
_scroll.scrollToY(_scrollSetAfterShow); _scroll.scrollToY(_scrollSetAfterShow);

View File

@ -263,7 +263,7 @@ private:
ContextMenu *_menu; ContextMenu *_menu;
}; };
class OverviewWidget : public TWidget, public RPCSender, public Animated { class OverviewWidget : public TWidget, public RPCSender {
Q_OBJECT Q_OBJECT
public: public:
@ -293,8 +293,9 @@ public:
void fastShow(bool back = false, int32 lastScrollTop = -1); void fastShow(bool back = false, int32 lastScrollTop = -1);
void animShow(const QPixmap &oldAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false, int32 lastScrollTop = -1); void animShow(const QPixmap &oldAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false, int32 lastScrollTop = -1);
bool animStep(float64 ms); bool animStep_show(float64 ms);
void updateWideMode();
void doneShow(); void doneShow();
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type); void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
@ -316,6 +317,17 @@ public:
void updateAfterDrag(); void updateAfterDrag();
void grabStart() {
_sideShadow.hide();
_inGrab = true;
resizeEvent(0);
}
void grabFinish() {
_sideShadow.setVisible(cWideMode());
_inGrab = false;
resizeEvent(0);
}
~OverviewWidget(); ~OverviewWidget();
public slots: public slots:
@ -340,10 +352,10 @@ private:
QString _header; QString _header;
bool _showing; Animation _a_show;
QPixmap _animCache, _bgAnimCache, _animTopBarCache, _bgAnimTopBarCache; QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver;
anim::ivalue a_coord, a_bgCoord; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_alpha, a_bgAlpha; anim::fvalue a_shadow;
int32 _scrollSetAfterShow; int32 _scrollSetAfterShow;
@ -353,6 +365,7 @@ private:
int32 _selCount; int32 _selCount;
PlainShadow _sideShadow, _topShadow; PlainShadow _sideShadow, _topShadow;
bool _inGrab;
}; };

View File

@ -29,10 +29,11 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
#include "application.h" #include "application.h"
#include "gui/text.h" #include "gui/text.h"
PasscodeWidget::PasscodeWidget(QWidget *parent) : QWidget(parent), PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent)
_passcode(this, st::passcodeInput), , _a_show(animFunc(this, &PasscodeWidget::animStep_show))
_submit(this, lang(lng_passcode_submit), st::passcodeSubmit), , _passcode(this, st::passcodeInput)
_logout(this, lang(lng_passcode_logout)) { , _submit(this, lang(lng_passcode_submit), st::passcodeSubmit)
, _logout(this, lang(lng_passcode_logout)) {
setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight)); setGeometry(QRect(0, st::titleHeight, App::wnd()->width(), App::wnd()->height() - st::titleHeight));
connect(App::wnd(), SIGNAL(resized(const QSize&)), this, SLOT(onParentResize(const QSize&))); connect(App::wnd(), SIGNAL(resized(const QSize&)), this, SLOT(onParentResize(const QSize&)));
@ -114,49 +115,52 @@ void PasscodeWidget::onChanged() {
void PasscodeWidget::animShow(const QPixmap &bgAnimCache, bool back) { void PasscodeWidget::animShow(const QPixmap &bgAnimCache, bool back) {
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
_bgAnimCache = bgAnimCache; (back ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
anim::stop(this);
showAll(); showAll();
_animCache = myGrab(this, rect()); (back ? _cacheUnder : _cacheOver) = myGrab(this);
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1);
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
a_bgAlpha = anim::fvalue(1, 0);
hideAll(); hideAll();
anim::start(this);
a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
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();
} }
bool PasscodeWidget::animStep(float64 ms) { bool PasscodeWidget::animStep_show(float64 ms) {
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 dt = ms / st::slideDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; bool res = true;
if (dt2 >= 1) { if (dt >= 1) {
res = false; _a_show.stop();
a_bgCoord.finish();
a_bgAlpha.finish();
a_coord.finish();
a_alpha.finish();
_animCache = _bgAnimCache = QPixmap(); res = false;
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(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
a_bgCoord.update(dt1, st::introHideFunc); a_coordUnder.update(dt, st::slideFunction);
a_bgAlpha.update(dt1, st::introAlphaHideFunc); a_coordOver.update(dt, st::slideFunction);
a_coord.update(dt2, st::introShowFunc); a_shadow.update(dt, st::slideFunction);
a_alpha.update(dt2, st::introAlphaShowFunc);
} }
update(); update();
return res; return res;
} }
void PasscodeWidget::animStop_show() {
_a_show.stop();
}
void PasscodeWidget::showAll() { void PasscodeWidget::showAll() {
_passcode.show(); _passcode.show();
_submit.show(); _submit.show();
@ -178,11 +182,16 @@ void PasscodeWidget::paintEvent(QPaintEvent *e) {
p.setClipRect(e->rect()); p.setClipRect(e->rect());
} }
if (animating()) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); if (a_coordOver.current() > 0) {
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.drawPixmap(a_coord.current(), 0, _animCache); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
} else { } else {
p.fillRect(rect(), st::setBG->b); p.fillRect(rect(), st::setBG->b);

View File

@ -20,7 +20,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
*/ */
#pragma once #pragma once
class PasscodeWidget : public QWidget, public Animated { class PasscodeWidget : public TWidget {
Q_OBJECT Q_OBJECT
public: public:
@ -34,7 +34,8 @@ public:
void setInnerFocus(); void setInnerFocus();
void animShow(const QPixmap &bgAnimCache, bool back = false); void animShow(const QPixmap &bgAnimCache, bool back = false);
bool animStep(float64 ms); bool animStep_show(float64 ms);
void animStop_show();
~PasscodeWidget(); ~PasscodeWidget();
@ -45,16 +46,15 @@ public slots:
void onChanged(); void onChanged();
void onSubmit(); void onSubmit();
signals:
private: private:
void showAll(); void showAll();
void hideAll(); void hideAll();
QPixmap _animCache, _bgAnimCache; Animation _a_show;
anim::ivalue a_coord, a_bgCoord; QPixmap _cacheUnder, _cacheOver;
anim::fvalue a_alpha, a_bgAlpha; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_shadow;
FlatInput _passcode; FlatInput _passcode;
FlatButton _submit; FlatButton _submit;

View File

@ -57,6 +57,7 @@ PlayerWidget::PlayerWidget(QWidget *parent) : TWidget(parent)
resize(st::wndMinWidth, st::playerHeight); resize(st::wndMinWidth, st::playerHeight);
setMouseTracking(true); setMouseTracking(true);
memset(_stateHovers, 0, sizeof(_stateHovers)); memset(_stateHovers, 0, sizeof(_stateHovers));
_sideShadow.setVisible(cWideMode());
} }
void PlayerWidget::paintEvent(QPaintEvent *e) { void PlayerWidget::paintEvent(QPaintEvent *e) {
@ -337,6 +338,10 @@ void PlayerWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type)
} }
} }
void PlayerWidget::updateWideMode() {
_sideShadow.setVisible(cWideMode());
}
bool PlayerWidget::seekingSong(const SongMsgId &song) const { bool PlayerWidget::seekingSong(const SongMsgId &song) const {
return (_down == OverPlayback) && (song == _song); return (_down == OverPlayback) && (song == _song);
} }

View File

@ -51,6 +51,7 @@ public:
void clearSelection(); void clearSelection();
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type); void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
void updateWideMode();
bool seekingSong(const SongMsgId &song) const; bool seekingSong(const SongMsgId &song) const;

View File

@ -1526,13 +1526,17 @@ QString ProfileInner::overviewLinkText(int32 type, int32 count) {
ProfileWidget::ProfileWidget(QWidget *parent, const PeerData *peer) : TWidget(parent) ProfileWidget::ProfileWidget(QWidget *parent, const PeerData *peer) : TWidget(parent)
, _scroll(this, st::setScroll) , _scroll(this, st::setScroll)
, _inner(this, &_scroll, peer) , _inner(this, &_scroll, peer)
, _showing(false) , _a_show(animFunc(this, &ProfileWidget::animStep_show))
, _sideShadow(this, st::shadowColor) , _sideShadow(this, st::shadowColor)
, _topShadow(this, st::shadowColor) { , _topShadow(this, st::shadowColor)
, _inGrab(false) {
_scroll.setWidget(&_inner); _scroll.setWidget(&_inner);
_scroll.move(0, 0); _scroll.move(0, 0);
_inner.move(0, 0); _inner.move(0, 0);
_scroll.show(); _scroll.show();
_sideShadow.setVisible(cWideMode());
connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSelected())); connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSelected()));
connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); connect(&_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
} }
@ -1558,8 +1562,8 @@ void ProfileWidget::resizeEvent(QResizeEvent *e) {
} }
} }
_topShadow.resize(width() - (cWideMode() ? st::lineWidth : 0), st::lineWidth); _topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth);
_topShadow.moveToLeft(cWideMode() ? st::lineWidth : 0, 0); _topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0);
_sideShadow.resize(st::lineWidth, height()); _sideShadow.resize(st::lineWidth, height());
_sideShadow.moveToLeft(0, 0); _sideShadow.moveToLeft(0, 0);
} }
@ -1571,11 +1575,16 @@ void ProfileWidget::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);
if (animating() && _showing) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); if (a_coordOver.current() > 0) {
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.drawPixmap(a_coord.current(), 0, _animCache); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
} else { } else {
p.fillRect(e->rect(), st::white->b); p.fillRect(e->rect(), st::white->b);
} }
@ -1588,18 +1597,19 @@ void ProfileWidget::dropEvent(QDropEvent *e) {
} }
void ProfileWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) { void ProfileWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) {
if (animating() && _showing) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); p.drawPixmap(a_coordUnder.current(), 0, _cacheTopBarUnder);
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimTopBarCache); p.drawPixmap(a_coordOver.current(), 0, _cacheTopBarOver);
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current());
p.drawPixmap(a_coord.current(), 0, _animTopBarCache); p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), st::topBarHeight), App::sprite(), st::slideShadow);
} else { return;
p.setOpacity(st::topBarBackAlpha + (1 - st::topBarBackAlpha) * over);
p.drawPixmap(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), App::sprite(), st::topBarBackImg);
p.setFont(st::topBarBackFont->f);
p.setPen(st::topBarBackColor->p);
p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, lang(peer()->isUser() ? lng_profile_info : (peer()->isChat() ? lng_profile_group_info : lng_profile_channel_info)));
} }
p.setOpacity(st::topBarBackAlpha + (1 - st::topBarBackAlpha) * over);
p.drawPixmap(QPoint(st::topBarBackPadding.left(), (st::topBarHeight - st::topBarBackImg.pxHeight()) / 2), App::sprite(), st::topBarBackImg);
p.setFont(st::topBarBackFont->f);
p.setPen(st::topBarBackColor->p);
p.drawText(st::topBarBackPadding.left() + st::topBarBackImg.pxWidth() + st::topBarBackPadding.right(), (st::topBarHeight - st::topBarBackFont->height) / 2 + st::topBarBackFont->ascent, lang(peer()->isUser() ? lng_profile_info : (peer()->isChat() ? lng_profile_group_info : lng_profile_channel_info)));
} }
void ProfileWidget::topBarClick() { void ProfileWidget::topBarClick() {
@ -1618,54 +1628,53 @@ void ProfileWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
stopGif(); stopGif();
_bgAnimCache = bgAnimCache;
_bgAnimTopBarCache = bgAnimTopBarCache;
if (lastScrollTop >= 0) _scroll.scrollToY(lastScrollTop);
_animCache = myGrab(this, rect());
App::main()->topBar()->stopAnim();
_animTopBarCache = myGrab(App::main()->topBar(), QRect(0, 0, width(), st::topBarHeight));
App::main()->topBar()->startAnim();
_scroll.hide();
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1);
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
a_bgAlpha = anim::fvalue(1, 0);
anim::start(this); (back ? _cacheOver : _cacheUnder) = bgAnimCache;
_sideShadow.hide(); (back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache;
if (lastScrollTop >= 0) _scroll.scrollToY(lastScrollTop);
(back ? _cacheUnder : _cacheOver) = myGrab(this);
App::main()->topBar()->stopAnim();
(back ? _cacheTopBarUnder : _cacheTopBarOver) = myGrab(App::main()->topBar());
App::main()->topBar()->startAnim();
_scroll.hide();
_topShadow.hide(); _topShadow.hide();
_showing = true; a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
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();
_inner.setFocus();
App::main()->topBar()->update(); App::main()->topBar()->update();
_inner.setFocus();
} }
bool ProfileWidget::animStep(float64 ms) { bool ProfileWidget::animStep_show(float64 ms) {
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 dt = ms / st::slideDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; bool res = true;
if (dt2 >= 1) { if (dt >= 1) {
res = _showing = false; _a_show.stop();
_sideShadow.show(); _sideShadow.setVisible(cWideMode());
_topShadow.show(); _topShadow.show();
a_bgCoord.finish(); res = false;
a_bgAlpha.finish(); a_coordUnder.finish();
a_coord.finish(); a_coordOver.finish();
a_alpha.finish(); a_shadow.finish();
_bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap(); _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap();
App::main()->topBar()->stopAnim(); App::main()->topBar()->stopAnim();
_scroll.show(); _scroll.show();
_inner.start(); _inner.start();
activate(); activate();
if (App::app()) App::app()->mtpUnpause(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
a_bgCoord.update(dt1, st::introHideFunc); a_coordUnder.update(dt, st::slideFunction);
a_bgAlpha.update(dt1, st::introAlphaHideFunc); a_coordOver.update(dt, st::slideFunction);
a_coord.update(dt2, st::introShowFunc); a_shadow.update(dt, st::slideFunction);
a_alpha.update(dt2, st::introAlphaShowFunc);
} }
update(); update();
App::main()->topBar()->update(); App::main()->topBar()->update();
@ -1699,6 +1708,10 @@ void ProfileWidget::mediaOverviewUpdated(PeerData *peer, MediaOverviewType type)
} }
} }
void ProfileWidget::updateWideMode() {
_sideShadow.setVisible(cWideMode());
}
void ProfileWidget::clear() { void ProfileWidget::clear() {
if (_inner.peer() && _inner.peer()->isUser() && _inner.peer()->asUser()->botInfo) { if (_inner.peer() && _inner.peer()->isUser() && _inner.peer()->asUser()->botInfo) {
_inner.peer()->asUser()->botInfo->startGroupToken = QString(); _inner.peer()->asUser()->botInfo->startGroupToken = QString();

View File

@ -201,7 +201,7 @@ private:
}; };
class ProfileWidget : public TWidget, public RPCSender, public Animated { class ProfileWidget : public TWidget, public RPCSender {
Q_OBJECT Q_OBJECT
public: public:
@ -221,7 +221,7 @@ public:
int32 lastScrollTop() const; int32 lastScrollTop() const;
void animShow(const QPixmap &oldAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false, int32 lastScrollTop = -1); void animShow(const QPixmap &oldAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false, int32 lastScrollTop = -1);
bool animStep(float64 ms); bool animStep_show(float64 ms);
void updateOnlineDisplay(); void updateOnlineDisplay();
void updateOnlineDisplayTimer(); void updateOnlineDisplayTimer();
@ -230,6 +230,18 @@ public:
void updateNotifySettings(); void updateNotifySettings();
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type); void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
void updateWideMode();
void grabStart() {
_sideShadow.hide();
_inGrab = true;
resizeEvent(0);
}
void grabFinish() {
_sideShadow.setVisible(cWideMode());
_inGrab = false;
resizeEvent(0);
}
void clear(); void clear();
~ProfileWidget(); ~ProfileWidget();
@ -244,12 +256,13 @@ private:
ScrollArea _scroll; ScrollArea _scroll;
ProfileInner _inner; ProfileInner _inner;
bool _showing; Animation _a_show;
QPixmap _animCache, _bgAnimCache, _animTopBarCache, _bgAnimTopBarCache; QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver;
anim::ivalue a_coord, a_bgCoord; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_alpha, a_bgAlpha; anim::fvalue a_shadow;
PlainShadow _sideShadow, _topShadow; PlainShadow _sideShadow, _topShadow;
bool _inGrab;
}; };

View File

@ -1751,11 +1751,14 @@ void SettingsInner::onPhotoUpdateDone(PeerId peer) {
update(); update();
} }
SettingsWidget::SettingsWidget(Window *parent) : QWidget(parent), SettingsWidget::SettingsWidget(Window *parent) : TWidget(parent)
_scroll(this, st::setScroll), _inner(this), _close(this, st::setClose) { , _a_show(animFunc(this, &SettingsWidget::animStep_show))
, _scroll(this, st::setScroll)
, _inner(this)
, _close(this, st::setClose) {
_scroll.setWidget(&_inner); _scroll.setWidget(&_inner);
connect(App::wnd(), SIGNAL(resized(const QSize &)), this, SLOT(onParentResize(const QSize &))); connect(App::wnd(), SIGNAL(resized(const QSize&)), this, SLOT(onParentResize(const QSize&)));
connect(&_close, SIGNAL(clicked()), App::wnd(), SLOT(showSettings())); connect(&_close, SIGNAL(clicked()), App::wnd(), SLOT(showSettings()));
setGeometry(QRect(0, st::titleHeight, Application::wnd()->width(), Application::wnd()->height() - st::titleHeight)); setGeometry(QRect(0, st::titleHeight, Application::wnd()->width(), Application::wnd()->height() - st::titleHeight));
@ -1770,62 +1773,70 @@ void SettingsWidget::onParentResize(const QSize &newSize) {
void SettingsWidget::animShow(const QPixmap &bgAnimCache, bool back) { void SettingsWidget::animShow(const QPixmap &bgAnimCache, bool back) {
if (App::app()) App::app()->mtpPause(); if (App::app()) App::app()->mtpPause();
_bgAnimCache = bgAnimCache; (back ? _cacheOver : _cacheUnder) = bgAnimCache;
_a_show.stop();
anim::stop(this);
showAll(); showAll();
_animCache = myGrab(this, rect()); (back ? _cacheUnder : _cacheOver) = myGrab(this);
a_coord = back ? anim::ivalue(-st::introSlideShift, 0) : anim::ivalue(st::introSlideShift, 0);
a_alpha = anim::fvalue(0, 1);
a_bgCoord = back ? anim::ivalue(0, st::introSlideShift) : anim::ivalue(0, -st::introSlideShift);
a_bgAlpha = anim::fvalue(1, 0);
hideAll(); hideAll();
anim::start(this);
a_coordUnder = back ? anim::ivalue(-qFloor(st::slideShift * width()), 0) : anim::ivalue(0, -qFloor(st::slideShift * width()));
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();
} }
bool SettingsWidget::animStep(float64 ms) { bool SettingsWidget::animStep_show(float64 ms) {
float64 fullDuration = st::introSlideDelta + st::introSlideDuration, dt = ms / fullDuration; float64 dt = ms / st::slideDuration;
float64 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0;
bool res = true; bool res = true;
if (dt2 >= 1) { if (dt >= 1) {
res = false; _a_show.stop();
a_bgCoord.finish();
a_bgAlpha.finish();
a_coord.finish();
a_alpha.finish();
_animCache = _bgAnimCache = QPixmap(); res = false;
a_coordUnder.finish();
a_coordOver.finish();
a_shadow.finish();
_cacheUnder = _cacheOver = QPixmap();
showAll(); showAll();
_inner.setFocus(); _inner.setFocus();
if (App::app()) App::app()->mtpUnpause(); if (App::app()) App::app()->mtpUnpause();
} else { } else {
a_bgCoord.update(dt1, st::introHideFunc); a_coordUnder.update(dt, st::slideFunction);
a_bgAlpha.update(dt1, st::introAlphaHideFunc); a_coordOver.update(dt, st::slideFunction);
a_coord.update(dt2, st::introShowFunc); a_shadow.update(dt, st::slideFunction);
a_alpha.update(dt2, st::introAlphaShowFunc);
} }
update(); update();
return res; return res;
} }
void SettingsWidget::animStop_show() {
_a_show.stop();
}
void SettingsWidget::paintEvent(QPaintEvent *e) { void SettingsWidget::paintEvent(QPaintEvent *e) {
QRect r(e->rect()); QRect r(e->rect());
bool trivial = (rect() == r); bool trivial = (rect() == r);
QPainter p(this); Painter p(this);
if (!trivial) { if (!trivial) {
p.setClipRect(r); p.setClipRect(r);
} }
if (animating()) { if (_a_show.animating()) {
p.setOpacity(a_bgAlpha.current()); if (a_coordOver.current() > 0) {
p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height()));
p.setOpacity(a_alpha.current()); p.setOpacity(a_shadow.current() * st::slideFadeOut);
p.drawPixmap(a_coord.current(), 0, _animCache); p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b);
p.setOpacity(1);
}
p.drawPixmap(a_coordOver.current(), 0, _cacheOver);
p.setOpacity(a_shadow.current());
p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), height()), App::sprite(), st::slideShadow);
} else { } else {
p.fillRect(rect(), st::setBG->b); p.fillRect(rect(), st::setBG->b);
} }

View File

@ -299,7 +299,7 @@ private:
}; };
class SettingsWidget : public QWidget, public Animated { class SettingsWidget : public TWidget {
Q_OBJECT Q_OBJECT
public: public:
@ -314,7 +314,8 @@ public:
void updateWideMode(); void updateWideMode();
void animShow(const QPixmap &bgAnimCache, bool back = false); void animShow(const QPixmap &bgAnimCache, bool back = false);
bool animStep(float64 ms); bool animStep_show(float64 ms);
void animStop_show();
void updateOnlineDisplay(); void updateOnlineDisplay();
void updateConnectionType(); void updateConnectionType();
@ -338,9 +339,10 @@ private:
void showAll(); void showAll();
void hideAll(); void hideAll();
QPixmap _animCache, _bgAnimCache; Animation _a_show;
anim::ivalue a_coord, a_bgCoord; QPixmap _cacheUnder, _cacheOver;
anim::fvalue a_alpha, a_bgAlpha; anim::ivalue a_coordUnder, a_coordOver;
anim::fvalue a_shadow;
ScrollArea _scroll; ScrollArea _scroll;
SettingsInner _inner; SettingsInner _inner;

View File

@ -480,21 +480,21 @@ void Window::clearWidgets() {
_passcode = 0; _passcode = 0;
} }
if (settings) { if (settings) {
anim::stop(settings); settings->animStop_show();
settings->hide(); settings->hide();
settings->deleteLater(); settings->deleteLater();
settings->rpcInvalidate(); settings->rpcInvalidate();
settings = 0; settings = 0;
} }
if (main) { if (main) {
anim::stop(main); main->animStop_show();
main->hide(); main->hide();
main->deleteLater(); main->deleteLater();
main->rpcInvalidate(); main->rpcInvalidate();
main = 0; main = 0;
} }
if (intro) { if (intro) {
anim::stop(intro); intro->animStop_show();
intro->hide(); intro->hide();
intro->deleteLater(); intro->deleteLater();
intro->rpcInvalidate(); intro->rpcInvalidate();
@ -504,12 +504,26 @@ void Window::clearWidgets() {
updateGlobalMenu(); updateGlobalMenu();
} }
QPixmap Window::grabInner() {
QPixmap result;
if (settings) {
result = myGrab(settings);
} else if (intro) {
result = myGrab(intro);
} else if (main) {
result = myGrab(main);
} else if (_passcode) {
result = myGrab(_passcode);
}
return result;
}
void Window::clearPasscode() { void Window::clearPasscode() {
if (!_passcode) return; if (!_passcode) return;
QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); QPixmap bg = grabInner();
anim::stop(_passcode); _passcode->animStop_show();
_passcode->hide(); _passcode->hide();
_passcode->deleteLater(); _passcode->deleteLater();
_passcode = 0; _passcode = 0;
@ -526,9 +540,10 @@ void Window::clearPasscode() {
} }
void Window::setupPasscode(bool anim) { void Window::setupPasscode(bool anim) {
QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); QPixmap bg = grabInner();
if (_passcode) { if (_passcode) {
anim::stop(_passcode); _passcode->animStop_show();
_passcode->hide(); _passcode->hide();
_passcode->deleteLater(); _passcode->deleteLater();
} }
@ -572,9 +587,9 @@ void Window::checkAutoLock() {
void Window::setupIntro(bool anim) { void Window::setupIntro(bool anim) {
cSetContactsReceived(false); cSetContactsReceived(false);
cSetDialogsReceived(false); cSetDialogsReceived(false);
if (intro && (intro->animating() || intro->isVisible()) && !main) return; if (intro && !intro->isHidden() && !main) return;
QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap(); QPixmap bg = anim ? grabInner() : QPixmap();
clearWidgets(); clearWidgets();
intro = new IntroWidget(this); intro = new IntroWidget(this);
@ -630,7 +645,7 @@ void Window::sendServiceHistoryRequest() {
void Window::setupMain(bool anim, const MTPUser *self) { void Window::setupMain(bool anim, const MTPUser *self) {
Local::readStickers(); Local::readStickers();
QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap(); QPixmap bg = anim ? grabInner() : QPixmap();
clearWidgets(); clearWidgets();
main = new MainWidget(this); main = new MainWidget(this);
main->move(0, st::titleHeight); main->move(0, st::titleHeight);
@ -667,13 +682,13 @@ void Window::showSettings() {
if (settings) { if (settings) {
return hideSettings(); return hideSettings();
} }
QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); QPixmap bg = grabInner();
if (intro) { if (intro) {
anim::stop(intro); intro->animStop_show();
intro->hide(); intro->hide();
} else if (main) { } else if (main) {
anim::stop(main); main->animStop_show();
main->hide(); main->hide();
} }
settings = new SettingsWidget(this); settings = new SettingsWidget(this);
@ -687,7 +702,7 @@ void Window::hideSettings(bool fast) {
if (!settings || _passcode) return; if (!settings || _passcode) return;
if (fast) { if (fast) {
anim::stop(settings); settings->animStop_show();
settings->hide(); settings->hide();
settings->deleteLater(); settings->deleteLater();
settings->rpcInvalidate(); settings->rpcInvalidate();
@ -698,9 +713,9 @@ void Window::hideSettings(bool fast) {
main->show(); main->show();
} }
} else { } else {
QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); QPixmap bg = grabInner();
anim::stop(settings); settings->animStop_show();
settings->hide(); settings->hide();
settings->deleteLater(); settings->deleteLater();
settings->rpcInvalidate(); settings->rpcInvalidate();
@ -1750,7 +1765,7 @@ void Window::sendPaths() {
if (layerShown()) { if (layerShown()) {
hideLayer(); hideLayer();
} }
if (main && !main->animating()) { if (main) {
main->activate(); main->activate();
} }
} }

View File

@ -293,6 +293,8 @@ signals:
private: private:
QPixmap grabInner();
void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color); void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color);
QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64; QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64;

View File

@ -106,6 +106,7 @@
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<AdditionalOptions>/Zm110 %(AdditionalOptions)</AdditionalOptions>
</ClCompile> </ClCompile>
<Link> <Link>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>