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);
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);

View File

@ -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() {

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() {
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);

View File

@ -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());

View File

@ -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;

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) {
_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;

View File

@ -629,7 +629,7 @@ private:
bool _overDelete;
};
class MentionsDropdown : public QWidget, public Animated {
class MentionsDropdown : public TWidget, public Animated {
Q_OBJECT
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 (!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;
void setCtrlEnterSubmit(bool ctrlEnterSubmit);
void setTextFast(const QString &text);
public slots:
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);
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;
}

View File

@ -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:

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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) {

View File

@ -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

View File

@ -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"));

View File

@ -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<MainWidget*>(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 {

View File

@ -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;

View File

@ -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);

View File

@ -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;
};

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -51,6 +51,7 @@ public:
void clearSelection();
void mediaOverviewUpdated(PeerData *peer, MediaOverviewType type);
void updateWideMode();
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)
, _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();

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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;

View File

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