diff --git a/Telegram/Resources/style.txt b/Telegram/Resources/style.txt index 9b5461146f..9580d0ae26 100644 --- a/Telegram/Resources/style.txt +++ b/Telegram/Resources/style.txt @@ -307,10 +307,11 @@ versionColor: #777; shadowColor: rgba(0, 0, 0, 24); -slideDuration: 4000; +slideDuration: 240; slideShift: 0.3; -slideShadowLeft: sprite(348px, 70px, 48px, 1px); -slideShadowRight: sprite(348px, 71px, 48px, 1px); +slideFadeOut: 0.3; +slideShadow: sprite(348px, 71px, 48px, 1px); +slideFunction: transition(easeOutCirc); btnDefIconed: iconedButton { color: white; @@ -605,7 +606,7 @@ introPointHideAlphaT: transition(easeOutCirc); introStepSize: size(400px, 200px); introSize: size(400px, 400px); introSlideShift: 500px; // intro hiding animation -introSlideDuration: 4000; +introSlideDuration: 200; introSlideDelta: 0; // between hide start and show start introHideFunc: transition(easeInCirc); introShowFunc: transition(easeOutCirc); diff --git a/Telegram/SourceFiles/application.cpp b/Telegram/SourceFiles/application.cpp index 54f0c178a9..f153087c49 100644 --- a/Telegram/SourceFiles/application.cpp +++ b/Telegram/SourceFiles/application.cpp @@ -298,7 +298,7 @@ void Application::cancelPhotoUpdate(const PeerId &peer) { void Application::mtpPause() { MTP::pause(); - _mtpUnpauseTimer.start(1000); + _mtpUnpauseTimer.start(st::slideDuration * 2); } void Application::mtpUnpause() { diff --git a/Telegram/SourceFiles/art/sprite.png b/Telegram/SourceFiles/art/sprite.png index 2a8b4f83f8..d671af200d 100644 Binary files a/Telegram/SourceFiles/art/sprite.png and b/Telegram/SourceFiles/art/sprite.png differ diff --git a/Telegram/SourceFiles/art/sprite_200x.png b/Telegram/SourceFiles/art/sprite_200x.png index 93f74d78a2..77dd5422dd 100644 Binary files a/Telegram/SourceFiles/art/sprite_200x.png and b/Telegram/SourceFiles/art/sprite_200x.png differ diff --git a/Telegram/SourceFiles/boxes/abstractbox.cpp b/Telegram/SourceFiles/boxes/abstractbox.cpp index 9cb73b1a7b..6a218b8d27 100644 --- a/Telegram/SourceFiles/boxes/abstractbox.cpp +++ b/Telegram/SourceFiles/boxes/abstractbox.cpp @@ -88,7 +88,7 @@ AbstractBox::AbstractBox(int32 w) : LayeredWidget() void AbstractBox::prepare() { showAll(); - _cache = myGrab(this, rect()); + _cache = myGrab(this); hideAll(); } @@ -197,7 +197,7 @@ void AbstractBox::onClose() { void AbstractBox::startHide() { _hiding = true; if (_cache.isNull()) { - _cache = myGrab(this, rect()); + _cache = myGrab(this); hideAll(); } a_opacity.start(0); diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 0898d7588f..7dc5d751ee 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -1503,6 +1503,7 @@ DialogsWidget::DialogsWidget(MainWidget *parent) : TWidget(parent) , _cancelSearch(this, st::btnCancelSearch) , _scroll(this, st::dlgScroll) , _inner(&_scroll, parent) +, _a_show(animFunc(this, &DialogsWidget::animStep_show)) , _searchInPeer(0) , _searchFull(false) , _peopleFull(false) @@ -1574,30 +1575,39 @@ void DialogsWidget::dialogsToUp() { void DialogsWidget::animShow(const QPixmap &bgAnimCache) { if (App::app()) App::app()->mtpPause(); - _bgAnimCache = bgAnimCache; - _animCache = myGrab(this, rect()); + bool back = true; + (back ? _cacheOver : _cacheUnder) = bgAnimCache; + + _a_show.stop(); + + (back ? _cacheUnder : _cacheOver) = myGrab(this); + _scroll.hide(); _filter.hide(); _cancelSearch.hide(); _newGroup.hide(); - a_coord = anim::ivalue(-st::introSlideShift, 0); - a_alpha = anim::fvalue(0, 1); - a_bgCoord = anim::ivalue(0, st::introSlideShift); - a_bgAlpha = anim::fvalue(1, 0); - 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(); } -bool DialogsWidget::animStep(float64 ms) { - 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; +bool DialogsWidget::animStep_show(float64 ms) { + float64 dt = ms / st::slideDuration; bool res = true; - if (dt2 >= 1) { + if (dt >= 1) { + _a_show.stop(); + res = false; - a_bgCoord.finish(); - a_bgAlpha.finish(); - a_coord.finish(); - a_alpha.finish(); - _bgAnimCache = _animCache = QPixmap(); + a_coordUnder.finish(); + a_coordOver.finish(); + a_shadow.finish(); + + _cacheUnder = _cacheOver = QPixmap(); + _scroll.show(); _filter.show(); onFilterUpdate(true); @@ -1605,10 +1615,9 @@ bool DialogsWidget::animStep(float64 ms) { 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); + a_coordUnder.update(dt, st::slideFunction); + a_coordOver.update(dt, st::slideFunction); + a_shadow.update(dt, st::slideFunction); } update(); return res; @@ -2063,7 +2072,7 @@ void DialogsWidget::onListScroll() { } void DialogsWidget::onFilterUpdate(bool force) { - if (animating() && !force) return; + if (_a_show.animating() && !force) return; QString filterText = _filter.getLastText(); _inner.onFilterUpdate(filterText); @@ -2190,11 +2199,16 @@ void DialogsWidget::paintEvent(QPaintEvent *e) { if (r != rect()) { p.setClipRect(r); } - if (animating()) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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; } QRect above(0, 0, width(), _scroll.y()); diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index 85b1f65c53..0aa9c8deed 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -176,7 +176,7 @@ private: }; -class DialogsWidget : public TWidget, public Animated, public RPCSender { +class DialogsWidget : public TWidget, public RPCSender { Q_OBJECT public: @@ -208,7 +208,7 @@ public: void dialogsToUp(); void animShow(const QPixmap &bgAnimCache); - bool animStep(float64 ms); + bool animStep_show(float64 ms); void destroyData(); @@ -271,9 +271,10 @@ private: ScrollArea _scroll; DialogsInner _inner; - QPixmap _animCache, _bgAnimCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; PeerData *_searchInPeer; diff --git a/Telegram/SourceFiles/dropdown.cpp b/Telegram/SourceFiles/dropdown.cpp index 125e72d2f0..4de039af0e 100644 --- a/Telegram/SourceFiles/dropdown.cpp +++ b/Telegram/SourceFiles/dropdown.cpp @@ -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) { _hideTimer.setSingleShot(true); connect(&_hideTimer, SIGNAL(timeout()), this, SLOT(hideStart())); @@ -3138,7 +3138,7 @@ void MentionsDropdown::hideStart() { if (!_hiding) { if (_cache.isNull()) { _scroll.show(); - _cache = myGrab(this, rect()); + _cache = myGrab(this); } _scroll.hide(); _hiding = true; @@ -3161,7 +3161,7 @@ void MentionsDropdown::showStart() { } if (_cache.isNull()) { _scroll.show(); - _cache = myGrab(this, rect()); + _cache = myGrab(this); } _scroll.hide(); _hiding = false; diff --git a/Telegram/SourceFiles/dropdown.h b/Telegram/SourceFiles/dropdown.h index aa20f40b11..6daff98221 100644 --- a/Telegram/SourceFiles/dropdown.h +++ b/Telegram/SourceFiles/dropdown.h @@ -629,7 +629,7 @@ private: bool _overDelete; }; -class MentionsDropdown : public QWidget, public Animated { +class MentionsDropdown : public TWidget, public Animated { Q_OBJECT public: diff --git a/Telegram/SourceFiles/gui/flattextarea.cpp b/Telegram/SourceFiles/gui/flattextarea.cpp index f605af98c4..b2ed133915 100644 --- a/Telegram/SourceFiles/gui/flattextarea.cpp +++ b/Telegram/SourceFiles/gui/flattextarea.cpp @@ -68,7 +68,17 @@ _touchPress(false), _touchRightButton(false), _touchMove(false), _correcting(fal if (App::wnd()) connect(this, SIGNAL(selectionChanged()), App::wnd(), SLOT(updateGlobalMenu())); 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(); } } diff --git a/Telegram/SourceFiles/gui/flattextarea.h b/Telegram/SourceFiles/gui/flattextarea.h index 2a17b95af8..2b949ce2de 100644 --- a/Telegram/SourceFiles/gui/flattextarea.h +++ b/Telegram/SourceFiles/gui/flattextarea.h @@ -76,6 +76,8 @@ public: QMimeData *createMimeDataFromSelection() const; void setCtrlEnterSubmit(bool ctrlEnterSubmit); + void setTextFast(const QString &text); + public slots: void onTouchTimer(); diff --git a/Telegram/SourceFiles/gui/twidget.cpp b/Telegram/SourceFiles/gui/twidget.cpp index d58b3f8132..aaca90b7b7 100644 --- a/Telegram/SourceFiles/gui/twidget.cpp +++ b/Telegram/SourceFiles/gui/twidget.cpp @@ -43,12 +43,18 @@ void myEnsureResized(QWidget *target) { } } -QPixmap myGrab(QWidget *target, const QRect &rect) { +QPixmap myGrab(TWidget *target, QRect rect) { myEnsureResized(target); - qreal dpr = App::app()->devicePixelRatio(); + if (rect.isNull()) rect = target->rect(); + + qreal dpr = App::app()->devicePixelRatio(); QPixmap result(rect.size() * dpr); result.setDevicePixelRatio(dpr); result.fill(Qt::transparent); + + target->grabStart(); target->render(&result, QPoint(), QRegion(rect), QWidget::DrawChildren | QWidget::IgnoreMask); + target->grabFinish(); + return result; } diff --git a/Telegram/SourceFiles/gui/twidget.h b/Telegram/SourceFiles/gui/twidget.h index 4481112d4b..9cf324075c 100644 --- a/Telegram/SourceFiles/gui/twidget.h +++ b/Telegram/SourceFiles/gui/twidget.h @@ -202,13 +202,17 @@ public: bool event(QEvent *e) { return QWidget::event(e); } + virtual void grabStart() { + } + virtual void grabFinish() { + } private: }; void myEnsureResized(QWidget *target); -QPixmap myGrab(QWidget *target, const QRect &rect); +QPixmap myGrab(TWidget *target, QRect rect = QRect()); class PlainShadow : public TWidget { public: diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 587a2a89e5..895371ec3d 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -2381,12 +2381,13 @@ HistoryWidget::HistoryWidget(QWidget *parent) : TWidget(parent) , _confirmImageId(0) , _confirmWithText(false) , _titlePeerTextWidth(0) -, _showAnim(animFunc(this, &HistoryWidget::showStep)) +, _a_show(animFunc(this, &HistoryWidget::animStep_show)) , _scrollDelta(0) , _saveDraftStart(0) , _saveDraftText(false) , _sideShadow(this, st::shadowColor) -, _topShadow(this, st::shadowColor) { +, _topShadow(this, st::shadowColor) +, _inGrab(false) { _scroll.setFocusPolicy(Qt::NoFocus); setAcceptDrops(true); @@ -2844,7 +2845,7 @@ void HistoryWidget::setKbWasHidden() { if (_kbWasHidden || (!_keyboard.hasMarkup() && !_keyboard.forceReply())) return; _kbWasHidden = true; - if (!_showAnim.animating()) { + if (!_a_show.animating()) { _kbScroll.hide(); _attachEmoji.show(); _kbHide.hide(); @@ -3186,7 +3187,7 @@ void HistoryWidget::updateReportSpamStatus() { } void HistoryWidget::updateControlsVisibility() { - if (!_history || _showAnim.animating()) { + if (!_history || _a_show.animating()) { _reportSpamPanel.hide(); _scroll.hide(); _kbScroll.hide(); @@ -3595,7 +3596,7 @@ void HistoryWidget::windowShown() { bool HistoryWidget::isActive() const { if (!_history) return true; - if (_firstLoadRequest || _showAnim.animating()) return false; + if (_firstLoadRequest || _a_show.animating()) return false; if (_history->loadedAtBottom()) return true; if (_history->showFrom && !_history->showFrom->detached() && _history->unreadBar) return true; return false; @@ -3772,7 +3773,7 @@ void HistoryWidget::onHistoryToEnd() { void HistoryWidget::onCollapseComments() { 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 (HistoryItem *collapse = _history->asChannelHistory()->collapse()) { if (!collapse->detached()) { @@ -3993,12 +3994,13 @@ HistoryItem *HistoryWidget::atTopImportantMsg(int32 &bottomUnderScrollTop) const void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back) { if (App::app()) App::app()->mtpPause(); - _bgAnimCache = bgAnimCache; - _bgAnimTopBarCache = bgAnimTopBarCache; - _animCache = myGrab(this, rect()); + (back ? _cacheOver : _cacheUnder) = bgAnimCache; + (back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache; + (back ? _cacheUnder : _cacheOver) = myGrab(this); 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(); + _scroll.hide(); _kbScroll.hide(); _reportSpamPanel.hide(); @@ -4019,43 +4021,38 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo _botStart.hide(); _joinChannel.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(); - _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(); activate(); } -bool HistoryWidget::showStep(float64 ms) { - 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; +bool HistoryWidget::animStep_show(float64 ms) { + float64 dt = ms / st::slideDuration; bool res = true; - if (dt2 >= 1) { - _showAnim.stop(); - _sideShadow.show(); + if (dt >= 1) { + _a_show.stop(); + _sideShadow.setVisible(cWideMode()); _topShadow.show(); res = false; - a_bgCoord.finish(); - a_bgAlpha.finish(); - a_coord.finish(); - a_alpha.finish(); - _bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap(); + a_coordUnder.finish(); + a_coordOver.finish(); + a_shadow.finish(); + _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap(); App::main()->topBar()->stopAnim(); doneShow(); 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); + a_coordUnder.update(dt, st::slideFunction); + a_coordOver.update(dt, st::slideFunction); + a_shadow.update(dt, st::slideFunction); } update(); App::main()->topBar()->update(); @@ -4074,10 +4071,14 @@ void HistoryWidget::doneShow() { } } +void HistoryWidget::updateWideMode() { + _sideShadow.setVisible(cWideMode()); +} + void HistoryWidget::animStop() { - if (!_showAnim.animating()) return; - _showAnim.stop(); - _sideShadow.show(); + if (!_a_show.animating()) return; + _a_show.stop(); + _sideShadow.setVisible(cWideMode()); _topShadow.show(); } @@ -4616,11 +4617,11 @@ void HistoryWidget::selectMessage() { } void HistoryWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) { - if (_showAnim.animating()) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimTopBarCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animTopBarCache); + if (_a_show.animating()) { + p.drawPixmap(a_coordUnder.current(), 0, _cacheTopBarUnder); + p.drawPixmap(a_coordOver.current(), 0, _cacheTopBarOver); + p.setOpacity(a_shadow.current()); + p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), st::topBarHeight), App::sprite(), st::slideShadow); return; } @@ -4757,7 +4758,7 @@ void HistoryWidget::onFieldFocused() { } void HistoryWidget::checkMentionDropdown() { - if (!_history || _showAnim.animating()) return; + if (!_history || _a_show.animating()) return; QString start; _field.getMentionHashtagBotCommandStart(start); @@ -5275,8 +5276,8 @@ void HistoryWidget::resizeEvent(QResizeEvent *e) { break; } - _topShadow.resize(width() - (cWideMode() ? st::lineWidth : 0), st::lineWidth); - _topShadow.moveToLeft(cWideMode() ? st::lineWidth : 0, 0); + _topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth); + _topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0); _sideShadow.resize(st::lineWidth, height()); _sideShadow.moveToLeft(0, 0); } @@ -5481,7 +5482,7 @@ void HistoryWidget::updateBotKeyboard() { if (hasMarkup || forceReply) { if (_keyboard.singleUse() && _keyboard.hasMarkup() && _keyboard.forMsgId() == FullMsgId(_channel, _history->lastKeyboardId) && _history->lastKeyboardUsed) _kbWasHidden = true; if (!isBotStart() && !isBlocked() && (wasVisible || _replyTo || (!_field.hasSendText() && !_kbWasHidden))) { - if (!_showAnim.animating()) { + if (!_a_show.animating()) { if (hasMarkup) { _kbScroll.show(); _attachEmoji.hide(); @@ -5504,7 +5505,7 @@ void HistoryWidget::updateBotKeyboard() { _replyForwardPreviewCancel.show(); } } else { - if (!_showAnim.animating()) { + if (!_a_show.animating()) { _kbScroll.hide(); _attachEmoji.show(); _kbHide.hide(); @@ -5538,7 +5539,7 @@ void HistoryWidget::updateBotKeyboard() { } 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()) { _toHistoryEnd.show(); } else if (!toEndVisible && !_toHistoryEnd.isHidden()) { @@ -5548,7 +5549,7 @@ void HistoryWidget::updateToEndVisibility() { void HistoryWidget::updateCollapseCommentsVisibility() { 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 (HistoryItem *collapse = _history->asChannelHistory()->collapse()) { if (!collapse->detached()) { @@ -5706,7 +5707,7 @@ void HistoryWidget::onStickerSend(DocumentData *sticker) { void HistoryWidget::setFieldText(const QString &text) { _synthedTextUpdate = true; - _field.setPlainText(text); + _field.setTextFast(text); _synthedTextUpdate = false; _previewCancelled = false; @@ -5970,7 +5971,7 @@ void HistoryWidget::peerUpdated(PeerData *data) { App::api()->requestFullPeer(data); } } - if (!_showAnim.animating()) { + if (!_a_show.animating()) { bool resize = (_unblock.isHidden() == isBlocked() || (!isBlocked() && _joinChannel.isHidden() == isJoinChannel())); bool newCanSendMessages = canSendMessages(_peer); if (newCanSendMessages != _canSendMessages) { @@ -6281,11 +6282,16 @@ void HistoryWidget::paintEvent(QPaintEvent *e) { if (r != rect()) { p.setClipRect(r); } - if (_showAnim.animating()) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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; } diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 928bf42124..7a629936ff 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -463,8 +463,10 @@ public: HistoryItem *atTopImportantMsg(int32 &bottomUnderScrollTop) const; void animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false); - bool showStep(float64 ms); + bool animStep_show(float64 ms); void animStop(); + + void updateWideMode(); void doneShow(); QPoint clampMousePosition(QPoint point); @@ -536,6 +538,17 @@ public: bool contentOverlapped(const QRect &globalRect); + void grabStart() { + _sideShadow.hide(); + _inGrab = true; + resizeEvent(0); + } + void grabFinish() { + _sideShadow.setVisible(cWideMode()); + _inGrab = false; + resizeEvent(0); + } + ~HistoryWidget(); signals: @@ -772,10 +785,10 @@ private: QString _titlePeerText; int32 _titlePeerTextWidth; - Animation _showAnim; - QPixmap _animCache, _bgAnimCache, _animTopBarCache, _bgAnimTopBarCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; QTimer _scrollTimer; int32 _scrollDelta; @@ -791,6 +804,7 @@ private: QTimer _saveDraftTimer; PlainShadow _sideShadow, _topShadow; + bool _inGrab; }; diff --git a/Telegram/SourceFiles/intro/intro.cpp b/Telegram/SourceFiles/intro/intro.cpp index e42c186cd6..514631c730 100644 --- a/Telegram/SourceFiles/intro/intro.cpp +++ b/Telegram/SourceFiles/intro/intro.cpp @@ -52,10 +52,12 @@ namespace { } } -IntroWidget::IntroWidget(Window *window) : QWidget(window), +IntroWidget::IntroWidget(Window *window) : TWidget(window), _langChangeTo(0), -cacheForHideInd(0), -cacheForShowInd(0), +_a_stage(animFunc(this, &IntroWidget::animStep_stage)), +_cacheHideIndex(0), +_cacheShowIndex(0), +_a_show(animFunc(this, &IntroWidget::animStep_show)), wnd(window), steps(new IntroSteps(this)), phone(0), @@ -64,7 +66,6 @@ signup(0), pwdcheck(0), current(0), moving(0), -visibilityChanging(0), _callTimeout(60), _registered(false), _hasRecovery(false), @@ -85,7 +86,7 @@ _backFrom(0), _backTo(0) { memset(stages + 1, 0, sizeof(QWidget*) * 3); _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(); setFocus(); @@ -147,21 +148,21 @@ bool IntroWidget::createNext() { void IntroWidget::prepareMove() { if (App::app()) App::app()->mtpPause(); - if (cacheForHide.isNull() || cacheForHideInd != current) makeHideCache(); + if (_cacheHide.isNull() || _cacheHideIndex != current) makeHideCache(); stages[current + moving]->prepareShow(); - if (cacheForShow.isNull() || cacheForShowInd != current + moving) makeShowCache(); + if (_cacheShow.isNull() || _cacheShowIndex != current + moving) makeShowCache(); int32 m = (moving > 0) ? 1 : -1; - xCoordHide = anim::ivalue(0, -m * st::introSlideShift); - cAlphaHide = anim::fvalue(1, 0); - xCoordShow = anim::ivalue(m * st::introSlideShift, 0); - cAlphaShow = anim::fvalue(0, 1); - anim::start(this); + a_coordHide = anim::ivalue(0, -m * st::introSlideShift); + a_opacityHide = anim::fvalue(1, 0); + a_coordShow = anim::ivalue(m * st::introSlideShift, 0); + a_opacityShow = anim::fvalue(0, 1); + _a_stage.start(); _backTo = stages[current + moving]->hasBack() ? 1 : 0; _backFrom = stages[current]->hasBack() ? 1 : 0; - animStep(0); + animStep_stage(0); if (_backFrom > 0 || _backTo > 0) { _back.show(); } else { @@ -172,39 +173,39 @@ void IntroWidget::prepareMove() { } void IntroWidget::onDoneStateChanged(int oldState, ButtonStateChangeSource source) { - if (animating()) return; + if (_a_stage.animating()) return; if (source == ButtonByPress) { if (oldState & Button::StateDown) { - cacheForHide = QPixmap(); + _cacheHide = QPixmap(); } else { makeHideCache(); } } else if (source == ButtonByHover && current != 2) { if (!createNext()) return; - if (!cacheForShow) makeShowCache(current + 1); + if (!_cacheShow) makeShowCache(current + 1); } } void IntroWidget::makeHideCache(int stage) { if (stage < 0) stage = current; int w = st::introSize.width(), h = st::introSize.height(); - cacheForHide = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h)); - cacheForHideInd = stage; + _cacheHide = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h)); + _cacheHideIndex = stage; } void IntroWidget::makeShowCache(int stage) { if (stage < 0) stage = current + moving; int w = st::introSize.width(), h = st::introSize.height(); - cacheForShow = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h)); - cacheForShowInd = stage; + _cacheShow = myGrab(stages[stage], QRect(st::introSlideShift, 0, w, h)); + _cacheShowIndex = stage; } void IntroWidget::animShow(const QPixmap &bgAnimCache, bool back) { if (App::app()) App::app()->mtpPause(); - _bgAnimCache = bgAnimCache; + (back ? _cacheOver : _cacheUnder) = bgAnimCache; - anim::stop(this); + _a_show.stop(); stages[current]->show(); if (stages[current]->hasBack()) { _back.setOpacity(1); @@ -212,56 +213,65 @@ void IntroWidget::animShow(const QPixmap &bgAnimCache, bool back) { } else { _back.hide(); } - _animCache = myGrab(this, rect()); - - 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); + (back ? _cacheUnder : _cacheOver) = myGrab(this); stages[current]->deactivate(); stages[current]->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(); } -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 dt1 = (ms > st::introSlideDuration) ? 1 : (ms / st::introSlideDuration), dt2 = (ms > st::introSlideDelta) ? (ms - st::introSlideDelta) / (st::introSlideDuration) : 0; - bool res = true; - 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) { + if (dt >= 1) { res = false; - xCoordShow.finish(); - cAlphaShow.finish(); + a_coordShow.finish(); + a_opacityShow.finish(); - cacheForHide = cacheForShow = QPixmap(); + _cacheHide = _cacheShow = QPixmap(); current += moving; moving = 0; @@ -272,12 +282,12 @@ bool IntroWidget::animStep(float64 ms) { } if (App::app()) App::app()->mtpUnpause(); } else { - xCoordShow.update(dt2, st::introShowFunc); - cAlphaShow.update(dt2, st::introAlphaShowFunc); - xCoordHide.update(dt1, st::introHideFunc); - cAlphaHide.update(dt1, st::introAlphaHideFunc); + a_coordShow.update(dt2, st::introShowFunc); + a_opacityShow.update(dt2, st::introAlphaShowFunc); + a_coordHide.update(dt1, st::introHideFunc); + a_opacityHide.update(dt1, st::introAlphaHideFunc); if (_backFrom != _backTo) { - _back.setOpacity((_backFrom > _backTo) ? cAlphaHide.current() : cAlphaShow.current()); + _back.setOpacity((_backFrom > _backTo) ? a_opacityHide.current() : a_opacityShow.current()); } else { _back.setOpacity(1); } @@ -295,18 +305,21 @@ void IntroWidget::paintEvent(QPaintEvent *e) { p.setClipRect(e->rect()); } p.fillRect(e->rect(), st::white->b); - if (animating()) { - if (visibilityChanging) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); - } 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); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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 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) { - if (animating()) return; + if (_a_show.animating() || _a_stage.animating()) return; + if (e->key() == Qt::Key_Escape) { stages[current]->onBack(); } else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return || e->key() == Qt::Key_Space) { diff --git a/Telegram/SourceFiles/intro/intro.h b/Telegram/SourceFiles/intro/intro.h index 924e510f92..bc2b634f77 100644 --- a/Telegram/SourceFiles/intro/intro.h +++ b/Telegram/SourceFiles/intro/intro.h @@ -29,7 +29,7 @@ class IntroPwdCheck; class IntroStage; class Text; -class IntroWidget : public QWidget, public Animated { +class IntroWidget : public TWidget { Q_OBJECT public: @@ -44,7 +44,10 @@ public: void updateWideMode(); 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; QString currentCountry() const; @@ -94,14 +97,16 @@ private: int32 _langChangeTo; - QPixmap cacheForHide, cacheForShow; - int cacheForHideInd, cacheForShowInd; - anim::ivalue xCoordHide, xCoordShow; - anim::fvalue cAlphaHide, cAlphaShow; + Animation _a_stage; + QPixmap _cacheHide, _cacheShow; + int _cacheHideIndex, _cacheShowIndex; + anim::ivalue a_coordHide, a_coordShow; + anim::fvalue a_opacityHide, a_opacityShow; - QPixmap _animCache, _bgAnimCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; Window *wnd; IntroSteps *steps; @@ -110,7 +115,7 @@ private: IntroSignup *signup; IntroPwdCheck *pwdcheck; IntroStage *stages[5]; - int current, moving, visibilityChanging; + int current, moving; QString _phone, _phone_hash; int32 _callTimeout; @@ -129,10 +134,10 @@ private: }; -class IntroStage : public QWidget { +class IntroStage : public TWidget { public: - IntroStage(IntroWidget *parent) : QWidget(parent) { + IntroStage(IntroWidget *parent) : TWidget(parent) { } virtual void activate() = 0; // show and activate diff --git a/Telegram/SourceFiles/intro/introphone.cpp b/Telegram/SourceFiles/intro/introphone.cpp index cc98c7b73b..d1004a75a4 100644 --- a/Telegram/SourceFiles/intro/introphone.cpp +++ b/Telegram/SourceFiles/intro/introphone.cpp @@ -71,7 +71,7 @@ IntroPhone::IntroPhone(IntroWidget *parent) : IntroStage(parent), _signup.setLink(1, TextLinkPtr(new SignUpLink(this))); _signup.hide(); - _signupCache = myGrab(&_signup, _signup.rect()); + _signupCache = myGrab(&_signup); if (!country.onChooseCountry(intro()->currentCountry())) { country.onChooseCountry(qsl("US")); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 4384d2675e..e82e69aea7 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -277,12 +277,11 @@ void TopBarWidget::startAnim() { _mediaType.hide(); _animating = true; - _sideShadow.hide(); } void TopBarWidget::stopAnim() { _animating = false; - _sideShadow.show(); + _sideShadow.setVisible(cWideMode()); showAll(); } @@ -352,6 +351,7 @@ void TopBarWidget::showAll() { _info.hide(); } } + _sideShadow.setVisible(cWideMode()); resizeEvent(0); } @@ -366,6 +366,10 @@ void TopBarWidget::showSelected(uint32 selCount, bool canDelete) { showAll(); } +void TopBarWidget::updateWideMode() { + showAll(); +} + FlatButton *TopBarWidget::mediaTypeButton() { return &_mediaType; } @@ -374,21 +378,49 @@ MainWidget *TopBarWidget::main() { return static_cast(parentWidget()); } -MainWidget::MainWidget(Window *window) : TWidget(window), -_started(0), failedObjId(0), _toForwardNameVersion(0), _dialogsWidth(st::dlgMinWidth), -dialogs(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)) { +MainWidget::MainWidget(Window *window) : TWidget(window) +, _started(0) +, failedObjId(0) +, _toForwardNameVersion(0) +, _dialogsWidth(st::dlgMinWidth) +, _a_show(animFunc(this, &MainWidget::animStep_show)) +, dialogs(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)); MTP::setGlobalDoneHandler(rpcDone(&MainWidget::updateReceived)); _ptsWaiter.setRequesting(true); 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(&history, SIGNAL(cancelled()), &dialogs, SLOT(activate())); 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) { if (_hider == destroyed) { _hider = 0; @@ -659,8 +715,7 @@ void MainWidget::noHider(HistoryHider *destroyed) { } onHistoryShown(history.history(), history.msgId()); if (profile || overview || (history.peer() && history.peer()->id)) { - QPixmap animCache = myGrab(this, QRect(0, _playerHeight + st::topBarHeight, _dialogsWidth, height() - _playerHeight - st::topBarHeight)), - animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight)); + QPixmap animCache = grabInner(), animTopBarCache = grabTopBar(); dialogs.hide(); if (overview) { overview->show(); @@ -1837,7 +1892,7 @@ void MainWidget::documentPlayProgress(const SongMsgId &songId) { if (playing == songId) { _player.updateState(playing, playingState, playingPosition, playingDuration, playingFrequency); - if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing && !animating()) { + if (!(playingState & AudioPlayerStoppedMask) && playingState != AudioPlayerFinishing && !_a_show.animating()) { if (_player.isHidden()) { _player.clearSelection(); _player.show(); @@ -2328,20 +2383,16 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) } 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 (cWideMode()) { - 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)); - } + animCache = grabInner(); } else if (cWideMode()) { animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight)); } else { animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); } if (peerId || cWideMode()) { - animTopBarCache = myGrab(this, QRect(_topBar.x(), _topBar.y(), _topBar.width(), st::topBarHeight)); + animTopBarCache = grabTopBar(); } history.show(); } @@ -2373,7 +2424,7 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) if (onlyDialogs) { _topBar.hide(); history.hide(); - if (!animating()) { + if (!_a_show.animating()) { dialogs.show(); if (!animCache.isNull()) { dialogs.animShow(animCache); @@ -2390,7 +2441,7 @@ void MainWidget::showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool back) _viewsIncremented.remove(activePeer()); } if (!cWideMode() && !dialogs.isHidden()) dialogs.hide(); - if (!animating()) { + if (!_a_show.animating()) { if (history.isHidden()) history.show(); if (!animCache.isNull()) { 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 historyRect = QRect(history.x(), topBarRect.y() + topBarRect.height(), history.width(), history.y() + history.height() - topBarRect.y() - topBarRect.height()); QPixmap animCache, animTopBarCache; - if (!animating() && (!cWideMode() || profile || overview || history.peer())) { - animCache = myGrab(this, historyRect); - animTopBarCache = myGrab(this, topBarRect); + if (!_a_show.animating() && (!cWideMode() || profile || overview || history.peer())) { + animCache = grabInner(); + animTopBarCache = grabTopBar(); } if (!back) { if (overview) { @@ -2532,7 +2583,7 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop) App::wnd()->hideSettings(); 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 (overview) { _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) { if (App::app()) App::app()->mtpPause(); - _bgAnimCache = bgAnimCache; + (back ? _cacheOver : _cacheUnder) = bgAnimCache; + + _a_show.stop(); - anim::stop(this); showAll(); - _animCache = myGrab(this, rect()); - - 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); - + (back ? _cacheUnder : _cacheOver) = myGrab(this); 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(); } -bool MainWidget::animStep(float64 ms) { - 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; +bool MainWidget::animStep_show(float64 ms) { + float64 dt = ms / st::slideDuration; bool res = true; - if (dt2 >= 1) { + if (dt >= 1) { + _a_show.stop(); + res = false; - a_bgCoord.finish(); - a_bgAlpha.finish(); - a_coord.finish(); - a_alpha.finish(); + a_coordUnder.finish(); + a_coordOver.finish(); + a_shadow.finish(); - _animCache = _bgAnimCache = QPixmap(); + _cacheUnder = _cacheOver = QPixmap(); - anim::stop(this); showAll(); activate(); 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); + a_coordUnder.update(dt, st::slideFunction); + a_coordOver.update(dt, st::slideFunction); + a_shadow.update(dt, st::slideFunction); } update(); return res; } +void MainWidget::animStop_show() { + _a_show.stop(); +} + void MainWidget::paintEvent(QPaintEvent *e) { if (_background) checkChatBackground(); - QPainter p(this); - if (animating()) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); - } else { + Painter p(this); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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); } } @@ -2872,7 +2929,11 @@ void MainWidget::keyPressEvent(QKeyEvent *e) { void MainWidget::updateWideMode() { showAll(); - _topBar.showAll(); + _topBar.updateWideMode(); + history.updateWideMode(); + if (overview) overview->updateWideMode(); + if (profile) profile->updateWideMode(); + _player.updateWideMode(); } bool MainWidget::needBackButton() { @@ -2943,7 +3004,7 @@ void MainWidget::onHistoryShown(History *history, MsgId atMsgId) { _topBar.hide(); } resizeEvent(0); - if (animating()) { + if (_a_show.animating()) { _topBar.hide(); } dlgUpdated(history, atMsgId); @@ -3907,6 +3968,7 @@ void MainWidget::incrementSticker(DocumentData *sticker) { } void MainWidget::activate() { + if (_a_show.animating()) return; if (!profile && !overview) { if (_hider) { if (_hider->wasOffered()) { @@ -3943,7 +4005,7 @@ void MainWidget::addNewContact(int32 uid, bool show) { } bool MainWidget::isActive() const { - return !_isIdle && isVisible() && !animating(); + return !_isIdle && isVisible() && !_a_show.animating(); } bool MainWidget::historyIsActive() const { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 2b375e55c6..2993750ac1 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -55,8 +55,17 @@ public: void showAll(); void showSelected(uint32 selCount, bool canDelete = false); + void updateWideMode(); + FlatButton *mediaTypeButton(); + void grabStart() { + _sideShadow.hide(); + } + void grabFinish() { + _sideShadow.setVisible(cWideMode()); + } + public slots: void onForwardSelection(); @@ -177,7 +186,7 @@ enum ForwardWhatMessages { ForwardPressedLinkMessage }; -class MainWidget : public TWidget, public Animated, public RPCSender { +class MainWidget : public TWidget, public RPCSender { Q_OBJECT public: @@ -199,7 +208,8 @@ public: int32 contentScrollAddToY() const; 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); @@ -403,6 +413,9 @@ public: bool contentOverlapped(const QRect &globalRect); + QPixmap grabTopBar(); + QPixmap grabInner(); + ~MainWidget(); signals: @@ -539,9 +552,10 @@ private: void overviewPreloaded(PeerData *data, const MTPmessages_Messages &result, mtpRequestId req); bool overviewFailed(PeerData *data, const RPCError &error, mtpRequestId req); - QPixmap _animCache, _bgAnimCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; int32 _dialogsWidth; diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index c3ad16339b..8e0fed64c4 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -2544,17 +2544,20 @@ OverviewWidget::OverviewWidget(QWidget *parent, const PeerData *peer, MediaOverv , _scroll(this, st::historyScroll, false) , _inner(this, &_scroll, peer, type) , _noDropResizeIndex(false) -, _showing(false) +, _a_show(animFunc(this, &OverviewWidget::animStep_show)) , _scrollSetAfterShow(0) , _scrollDelta(0) , _selCount(0) , _sideShadow(this, st::shadowColor) -, _topShadow(this, st::shadowColor) { +, _topShadow(this, st::shadowColor) +, _inGrab(false) { _scroll.setFocusPolicy(Qt::NoFocus); _scroll.setWidget(&_inner); _scroll.move(0, 0); _inner.move(0, 0); + _sideShadow.setVisible(cWideMode()); + updateScrollColors(); _scroll.show(); @@ -2604,8 +2607,8 @@ void OverviewWidget::resizeEvent(QResizeEvent *e) { _noDropResizeIndex = false; } - _topShadow.resize(width() - (cWideMode() ? st::lineWidth : 0), st::lineWidth); - _topShadow.moveToLeft(cWideMode() ? st::lineWidth : 0, 0); + _topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth); + _topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0); _sideShadow.resize(st::lineWidth, height()); _sideShadow.moveToLeft(0, 0); } @@ -2614,11 +2617,16 @@ void OverviewWidget::paintEvent(QPaintEvent *e) { if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return; Painter p(this); - if (animating() && _showing) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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; } @@ -2675,18 +2683,18 @@ void OverviewWidget::scrollReset() { } void OverviewWidget::paintTopBar(QPainter &p, float64 over, int32 decreaseWidth) { - if (animating() && _showing) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimTopBarCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animTopBarCache); - } else { - 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); + if (_a_show.animating()) { + p.drawPixmap(a_coordUnder.current(), 0, _cacheTopBarUnder); + p.drawPixmap(a_coordOver.current(), 0, _cacheTopBarOver); + p.setOpacity(a_shadow.current()); + p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), st::topBarHeight), App::sprite(), st::slideShadow); + 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); } void OverviewWidget::topBarClick() { @@ -2784,60 +2792,63 @@ void OverviewWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimT if (App::app()) App::app()->mtpPause(); stopGif(); - _bgAnimCache = bgAnimCache; - _bgAnimTopBarCache = bgAnimTopBarCache; + + (back ? _cacheOver : _cacheUnder) = bgAnimCache; + (back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache; resizeEvent(0); _scroll.scrollToY(lastScrollTop < 0 ? countBestScroll() : lastScrollTop); - _animCache = myGrab(this, rect()); + (back ? _cacheUnder : _cacheOver) = myGrab(this); 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(); + _scrollSetAfterShow = _scroll.scrollTop(); _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(); - _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(); - _inner.activate(); + App::main()->topBar()->update(); + _inner.activate(); } -bool OverviewWidget::animStep(float64 ms) { - 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; +bool OverviewWidget::animStep_show(float64 ms) { + float64 dt = ms / st::slideDuration; bool res = true; - if (dt2 >= 1) { - res = _showing = false; - _sideShadow.show(); + if (dt >= 1) { + _a_show.stop(); + _sideShadow.setVisible(cWideMode()); _topShadow.show(); - a_bgCoord.finish(); - a_bgAlpha.finish(); - a_coord.finish(); - a_alpha.finish(); - _bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap(); + res = false; + a_coordUnder.finish(); + a_coordOver.finish(); + a_shadow.finish(); + _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap(); App::main()->topBar()->stopAnim(); + doneShow(); 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); + a_coordUnder.update(dt, st::slideFunction); + a_coordOver.update(dt, st::slideFunction); + a_shadow.update(dt, st::slideFunction); } update(); App::main()->topBar()->update(); return res; } +void OverviewWidget::updateWideMode() { + _sideShadow.setVisible(cWideMode()); +} + void OverviewWidget::doneShow() { _scroll.show(); _scroll.scrollToY(_scrollSetAfterShow); diff --git a/Telegram/SourceFiles/overviewwidget.h b/Telegram/SourceFiles/overviewwidget.h index af9ee4e1cd..449b3ea88a 100644 --- a/Telegram/SourceFiles/overviewwidget.h +++ b/Telegram/SourceFiles/overviewwidget.h @@ -263,7 +263,7 @@ private: ContextMenu *_menu; }; -class OverviewWidget : public TWidget, public RPCSender, public Animated { +class OverviewWidget : public TWidget, public RPCSender { Q_OBJECT public: @@ -293,8 +293,9 @@ public: void fastShow(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 mediaOverviewUpdated(PeerData *peer, MediaOverviewType type); @@ -316,6 +317,17 @@ public: void updateAfterDrag(); + void grabStart() { + _sideShadow.hide(); + _inGrab = true; + resizeEvent(0); + } + void grabFinish() { + _sideShadow.setVisible(cWideMode()); + _inGrab = false; + resizeEvent(0); + } + ~OverviewWidget(); public slots: @@ -340,10 +352,10 @@ private: QString _header; - bool _showing; - QPixmap _animCache, _bgAnimCache, _animTopBarCache, _bgAnimTopBarCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; int32 _scrollSetAfterShow; @@ -353,6 +365,7 @@ private: int32 _selCount; PlainShadow _sideShadow, _topShadow; + bool _inGrab; }; diff --git a/Telegram/SourceFiles/passcodewidget.cpp b/Telegram/SourceFiles/passcodewidget.cpp index 9faf759240..50cfe3f2a0 100644 --- a/Telegram/SourceFiles/passcodewidget.cpp +++ b/Telegram/SourceFiles/passcodewidget.cpp @@ -29,10 +29,11 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org #include "application.h" #include "gui/text.h" -PasscodeWidget::PasscodeWidget(QWidget *parent) : QWidget(parent), -_passcode(this, st::passcodeInput), -_submit(this, lang(lng_passcode_submit), st::passcodeSubmit), -_logout(this, lang(lng_passcode_logout)) { +PasscodeWidget::PasscodeWidget(QWidget *parent) : TWidget(parent) +, _a_show(animFunc(this, &PasscodeWidget::animStep_show)) +, _passcode(this, st::passcodeInput) +, _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)); 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) { if (App::app()) App::app()->mtpPause(); - _bgAnimCache = bgAnimCache; + (back ? _cacheOver : _cacheUnder) = bgAnimCache; + + _a_show.stop(); - anim::stop(this); showAll(); - _animCache = myGrab(this, rect()); - - 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); - + (back ? _cacheUnder : _cacheOver) = myGrab(this); 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(); } -bool PasscodeWidget::animStep(float64 ms) { - 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; +bool PasscodeWidget::animStep_show(float64 ms) { + float64 dt = ms / st::slideDuration; bool res = true; - if (dt2 >= 1) { - res = false; - a_bgCoord.finish(); - a_bgAlpha.finish(); - a_coord.finish(); - a_alpha.finish(); + if (dt >= 1) { + _a_show.stop(); - _animCache = _bgAnimCache = QPixmap(); + res = false; + a_coordUnder.finish(); + a_coordOver.finish(); + a_shadow.finish(); + + _cacheUnder = _cacheOver = QPixmap(); showAll(); if (App::wnd()) App::wnd()->setInnerFocus(); 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); + a_coordUnder.update(dt, st::slideFunction); + a_coordOver.update(dt, st::slideFunction); + a_shadow.update(dt, st::slideFunction); } update(); return res; } +void PasscodeWidget::animStop_show() { + _a_show.stop(); +} + void PasscodeWidget::showAll() { _passcode.show(); _submit.show(); @@ -178,11 +182,16 @@ void PasscodeWidget::paintEvent(QPaintEvent *e) { p.setClipRect(e->rect()); } - if (animating()) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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 { p.fillRect(rect(), st::setBG->b); diff --git a/Telegram/SourceFiles/passcodewidget.h b/Telegram/SourceFiles/passcodewidget.h index 1b195939d2..6d824bff44 100644 --- a/Telegram/SourceFiles/passcodewidget.h +++ b/Telegram/SourceFiles/passcodewidget.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org */ #pragma once -class PasscodeWidget : public QWidget, public Animated { +class PasscodeWidget : public TWidget { Q_OBJECT public: @@ -34,7 +34,8 @@ public: void setInnerFocus(); void animShow(const QPixmap &bgAnimCache, bool back = false); - bool animStep(float64 ms); + bool animStep_show(float64 ms); + void animStop_show(); ~PasscodeWidget(); @@ -45,16 +46,15 @@ public slots: void onChanged(); void onSubmit(); -signals: - private: void showAll(); void hideAll(); - QPixmap _animCache, _bgAnimCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; FlatInput _passcode; FlatButton _submit; diff --git a/Telegram/SourceFiles/playerwidget.cpp b/Telegram/SourceFiles/playerwidget.cpp index 2a102c65f0..623f0a6d59 100644 --- a/Telegram/SourceFiles/playerwidget.cpp +++ b/Telegram/SourceFiles/playerwidget.cpp @@ -57,6 +57,7 @@ PlayerWidget::PlayerWidget(QWidget *parent) : TWidget(parent) resize(st::wndMinWidth, st::playerHeight); setMouseTracking(true); memset(_stateHovers, 0, sizeof(_stateHovers)); + _sideShadow.setVisible(cWideMode()); } 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 { return (_down == OverPlayback) && (song == _song); } diff --git a/Telegram/SourceFiles/playerwidget.h b/Telegram/SourceFiles/playerwidget.h index 5796468e26..721b82fde1 100644 --- a/Telegram/SourceFiles/playerwidget.h +++ b/Telegram/SourceFiles/playerwidget.h @@ -51,6 +51,7 @@ public: void clearSelection(); void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type); + void updateWideMode(); bool seekingSong(const SongMsgId &song) const; diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index e24c9b8a40..f88d50641c 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -1526,13 +1526,17 @@ QString ProfileInner::overviewLinkText(int32 type, int32 count) { ProfileWidget::ProfileWidget(QWidget *parent, const PeerData *peer) : TWidget(parent) , _scroll(this, st::setScroll) , _inner(this, &_scroll, peer) -, _showing(false) +, _a_show(animFunc(this, &ProfileWidget::animStep_show)) , _sideShadow(this, st::shadowColor) -, _topShadow(this, st::shadowColor) { +, _topShadow(this, st::shadowColor) +, _inGrab(false) { _scroll.setWidget(&_inner); _scroll.move(0, 0); _inner.move(0, 0); _scroll.show(); + + _sideShadow.setVisible(cWideMode()); + connect(&_scroll, SIGNAL(scrolled()), &_inner, SLOT(updateSelected())); 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.moveToLeft(cWideMode() ? st::lineWidth : 0, 0); + _topShadow.resize(width() - ((cWideMode() && !_inGrab) ? st::lineWidth : 0), st::lineWidth); + _topShadow.moveToLeft((cWideMode() && !_inGrab) ? st::lineWidth : 0, 0); _sideShadow.resize(st::lineWidth, height()); _sideShadow.moveToLeft(0, 0); } @@ -1571,11 +1575,16 @@ void ProfileWidget::paintEvent(QPaintEvent *e) { if (App::wnd() && App::wnd()->contentOverlapped(this, e)) return; Painter p(this); - if (animating() && _showing) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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 { 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) { - if (animating() && _showing) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimTopBarCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animTopBarCache); - } else { - 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))); + if (_a_show.animating()) { + p.drawPixmap(a_coordUnder.current(), 0, _cacheTopBarUnder); + p.drawPixmap(a_coordOver.current(), 0, _cacheTopBarOver); + p.setOpacity(a_shadow.current()); + p.drawPixmap(QRect(a_coordOver.current() - st::slideShadow.pxWidth(), 0, st::slideShadow.pxWidth(), st::topBarHeight), App::sprite(), st::slideShadow); + 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))); } void ProfileWidget::topBarClick() { @@ -1618,54 +1628,53 @@ void ProfileWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo if (App::app()) App::app()->mtpPause(); 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); - _sideShadow.hide(); + (back ? _cacheOver : _cacheUnder) = bgAnimCache; + (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(); - _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(); - _inner.setFocus(); + App::main()->topBar()->update(); + _inner.setFocus(); } -bool ProfileWidget::animStep(float64 ms) { - 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; +bool ProfileWidget::animStep_show(float64 ms) { + float64 dt = ms / st::slideDuration; bool res = true; - if (dt2 >= 1) { - res = _showing = false; - _sideShadow.show(); + if (dt >= 1) { + _a_show.stop(); + _sideShadow.setVisible(cWideMode()); _topShadow.show(); - a_bgCoord.finish(); - a_bgAlpha.finish(); - a_coord.finish(); - a_alpha.finish(); - _bgAnimCache = _animCache = _animTopBarCache = _bgAnimTopBarCache = QPixmap(); + res = false; + a_coordUnder.finish(); + a_coordOver.finish(); + a_shadow.finish(); + _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap(); App::main()->topBar()->stopAnim(); + _scroll.show(); _inner.start(); activate(); 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); + a_coordUnder.update(dt, st::slideFunction); + a_coordOver.update(dt, st::slideFunction); + a_shadow.update(dt, st::slideFunction); } 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() { if (_inner.peer() && _inner.peer()->isUser() && _inner.peer()->asUser()->botInfo) { _inner.peer()->asUser()->botInfo->startGroupToken = QString(); diff --git a/Telegram/SourceFiles/profilewidget.h b/Telegram/SourceFiles/profilewidget.h index 22248cca67..d98c17250c 100644 --- a/Telegram/SourceFiles/profilewidget.h +++ b/Telegram/SourceFiles/profilewidget.h @@ -201,7 +201,7 @@ private: }; -class ProfileWidget : public TWidget, public RPCSender, public Animated { +class ProfileWidget : public TWidget, public RPCSender { Q_OBJECT public: @@ -221,7 +221,7 @@ public: int32 lastScrollTop() const; 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 updateOnlineDisplayTimer(); @@ -230,6 +230,18 @@ public: void updateNotifySettings(); 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(); ~ProfileWidget(); @@ -244,12 +256,13 @@ private: ScrollArea _scroll; ProfileInner _inner; - bool _showing; - QPixmap _animCache, _bgAnimCache, _animTopBarCache, _bgAnimTopBarCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; PlainShadow _sideShadow, _topShadow; + bool _inGrab; }; diff --git a/Telegram/SourceFiles/settingswidget.cpp b/Telegram/SourceFiles/settingswidget.cpp index 2ed47f5120..aab9f85257 100644 --- a/Telegram/SourceFiles/settingswidget.cpp +++ b/Telegram/SourceFiles/settingswidget.cpp @@ -1751,11 +1751,14 @@ void SettingsInner::onPhotoUpdateDone(PeerId peer) { update(); } -SettingsWidget::SettingsWidget(Window *parent) : QWidget(parent), - _scroll(this, st::setScroll), _inner(this), _close(this, st::setClose) { +SettingsWidget::SettingsWidget(Window *parent) : TWidget(parent) +, _a_show(animFunc(this, &SettingsWidget::animStep_show)) +, _scroll(this, st::setScroll) +, _inner(this) +, _close(this, st::setClose) { _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())); 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) { if (App::app()) App::app()->mtpPause(); - _bgAnimCache = bgAnimCache; + (back ? _cacheOver : _cacheUnder) = bgAnimCache; + + _a_show.stop(); - anim::stop(this); showAll(); - _animCache = myGrab(this, rect()); - - 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); - + (back ? _cacheUnder : _cacheOver) = myGrab(this); 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(); } -bool SettingsWidget::animStep(float64 ms) { - 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; +bool SettingsWidget::animStep_show(float64 ms) { + float64 dt = ms / st::slideDuration; bool res = true; - if (dt2 >= 1) { - res = false; - a_bgCoord.finish(); - a_bgAlpha.finish(); - a_coord.finish(); - a_alpha.finish(); + if (dt >= 1) { + _a_show.stop(); - _animCache = _bgAnimCache = QPixmap(); + res = false; + a_coordUnder.finish(); + a_coordOver.finish(); + a_shadow.finish(); + + _cacheUnder = _cacheOver = QPixmap(); showAll(); _inner.setFocus(); 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); + a_coordUnder.update(dt, st::slideFunction); + a_coordOver.update(dt, st::slideFunction); + a_shadow.update(dt, st::slideFunction); } update(); return res; } +void SettingsWidget::animStop_show() { + _a_show.stop(); +} + void SettingsWidget::paintEvent(QPaintEvent *e) { QRect r(e->rect()); bool trivial = (rect() == r); - QPainter p(this); + Painter p(this); if (!trivial) { p.setClipRect(r); } - if (animating()) { - p.setOpacity(a_bgAlpha.current()); - p.drawPixmap(a_bgCoord.current(), 0, _bgAnimCache); - p.setOpacity(a_alpha.current()); - p.drawPixmap(a_coord.current(), 0, _animCache); + if (_a_show.animating()) { + if (a_coordOver.current() > 0) { + p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current(), 0, a_coordOver.current(), height())); + p.setOpacity(a_shadow.current() * st::slideFadeOut); + 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 { p.fillRect(rect(), st::setBG->b); } diff --git a/Telegram/SourceFiles/settingswidget.h b/Telegram/SourceFiles/settingswidget.h index e0fc5dbb97..234d1563d0 100644 --- a/Telegram/SourceFiles/settingswidget.h +++ b/Telegram/SourceFiles/settingswidget.h @@ -299,7 +299,7 @@ private: }; -class SettingsWidget : public QWidget, public Animated { +class SettingsWidget : public TWidget { Q_OBJECT public: @@ -314,7 +314,8 @@ public: void updateWideMode(); void animShow(const QPixmap &bgAnimCache, bool back = false); - bool animStep(float64 ms); + bool animStep_show(float64 ms); + void animStop_show(); void updateOnlineDisplay(); void updateConnectionType(); @@ -338,9 +339,10 @@ private: void showAll(); void hideAll(); - QPixmap _animCache, _bgAnimCache; - anim::ivalue a_coord, a_bgCoord; - anim::fvalue a_alpha, a_bgAlpha; + Animation _a_show; + QPixmap _cacheUnder, _cacheOver; + anim::ivalue a_coordUnder, a_coordOver; + anim::fvalue a_shadow; ScrollArea _scroll; SettingsInner _inner; diff --git a/Telegram/SourceFiles/window.cpp b/Telegram/SourceFiles/window.cpp index 1fe562c6f1..9bb6ceddb2 100644 --- a/Telegram/SourceFiles/window.cpp +++ b/Telegram/SourceFiles/window.cpp @@ -480,21 +480,21 @@ void Window::clearWidgets() { _passcode = 0; } if (settings) { - anim::stop(settings); + settings->animStop_show(); settings->hide(); settings->deleteLater(); settings->rpcInvalidate(); settings = 0; } if (main) { - anim::stop(main); + main->animStop_show(); main->hide(); main->deleteLater(); main->rpcInvalidate(); main = 0; } if (intro) { - anim::stop(intro); + intro->animStop_show(); intro->hide(); intro->deleteLater(); intro->rpcInvalidate(); @@ -504,12 +504,26 @@ void Window::clearWidgets() { 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() { 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->deleteLater(); _passcode = 0; @@ -526,9 +540,10 @@ void Window::clearPasscode() { } void Window::setupPasscode(bool anim) { - QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); + QPixmap bg = grabInner(); + if (_passcode) { - anim::stop(_passcode); + _passcode->animStop_show(); _passcode->hide(); _passcode->deleteLater(); } @@ -572,9 +587,9 @@ void Window::checkAutoLock() { void Window::setupIntro(bool anim) { cSetContactsReceived(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(); intro = new IntroWidget(this); @@ -630,7 +645,7 @@ void Window::sendServiceHistoryRequest() { void Window::setupMain(bool anim, const MTPUser *self) { Local::readStickers(); - QPixmap bg = anim ? myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)) : QPixmap(); + QPixmap bg = anim ? grabInner() : QPixmap(); clearWidgets(); main = new MainWidget(this); main->move(0, st::titleHeight); @@ -667,13 +682,13 @@ void Window::showSettings() { if (settings) { return hideSettings(); } - QPixmap bg = myGrab(this, QRect(0, st::titleHeight, width(), height() - st::titleHeight)); + QPixmap bg = grabInner(); if (intro) { - anim::stop(intro); + intro->animStop_show(); intro->hide(); } else if (main) { - anim::stop(main); + main->animStop_show(); main->hide(); } settings = new SettingsWidget(this); @@ -687,7 +702,7 @@ void Window::hideSettings(bool fast) { if (!settings || _passcode) return; if (fast) { - anim::stop(settings); + settings->animStop_show(); settings->hide(); settings->deleteLater(); settings->rpcInvalidate(); @@ -698,9 +713,9 @@ void Window::hideSettings(bool fast) { main->show(); } } 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->deleteLater(); settings->rpcInvalidate(); @@ -1750,7 +1765,7 @@ void Window::sendPaths() { if (layerShown()) { hideLayer(); } - if (main && !main->animating()) { + if (main) { main->activate(); } } diff --git a/Telegram/SourceFiles/window.h b/Telegram/SourceFiles/window.h index 5db77d1119..da1f032f69 100644 --- a/Telegram/SourceFiles/window.h +++ b/Telegram/SourceFiles/window.h @@ -293,6 +293,8 @@ signals: private: + QPixmap grabInner(); + void placeSmallCounter(QImage &img, int size, int count, style::color bg, const QPoint &shift, style::color color); QImage icon16, icon32, icon64, iconbig16, iconbig32, iconbig64; diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj index 9a2473c0c7..c473287b22 100644 --- a/Telegram/Telegram.vcxproj +++ b/Telegram/Telegram.vcxproj @@ -106,6 +106,7 @@ AnySuitable true Speed + /Zm110 %(AdditionalOptions) Windows