diff --git a/README.md b/README.md index eb79d16a7..c56329b1f 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is * Windows XP - Windows 10 (**not** RT) * Mac OS X 10.8 - Mac OS X 10.11 * Mac OS X 10.6 - Mac OS X 10.7 (separate build) -* Ubuntu 12.04 - Ubuntu 15.04 +* Ubuntu 12.04 - Ubuntu 16.04 * Fedora 22 ## Third-party libraries diff --git a/Telegram/Resources/basic.style b/Telegram/Resources/basic.style index f3fba09aa..72b2a6289 100644 --- a/Telegram/Resources/basic.style +++ b/Telegram/Resources/basic.style @@ -373,12 +373,13 @@ statusFont: font(fsize); versionColor: #777; shadowColor: rgba(0, 0, 0, 24); +shadowToggleDuration: 200; slideDuration: 240; slideShift: 100px; slideFadeOut: 0.3; slideShadow: sprite(348px, 71px, 48px, 1px); -slideFunction: transition(easeOutCirc); +slideFunction: transition(linear); btnDefIconed: iconedButton { color: white; diff --git a/Telegram/SourceFiles/boxes/contactsbox.cpp b/Telegram/SourceFiles/boxes/contactsbox.cpp index 92540758a..b79f89819 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.cpp +++ b/Telegram/SourceFiles/boxes/contactsbox.cpp @@ -1976,7 +1976,7 @@ void MembersInner::chooseParticipant() { if (_sel < 0 || _sel >= _rows.size()) return; if (PeerData *peer = _rows[_sel]) { Ui::hideLayer(); - App::main()->showPeerProfile(peer, ShowAtUnreadMsgId); + Ui::showPeerProfile(peer); } } diff --git a/Telegram/SourceFiles/codegen/style/processor.cpp b/Telegram/SourceFiles/codegen/style/processor.cpp index 5c385f25f..39f02c41e 100644 --- a/Telegram/SourceFiles/codegen/style/processor.cpp +++ b/Telegram/SourceFiles/codegen/style/processor.cpp @@ -74,14 +74,15 @@ bool Processor::write(const structure::Module &module) const { QFileInfo srcFile(module.filepath()); QString dstFilePath = dir.absolutePath() + '/' + destFileBaseName(module); + bool forceReGenerate = false;// !options_.rebuildDependencies; common::ProjectInfo project = { "codegen_style", srcFile.fileName(), "stdafx.h", - !options_.rebuildDependencies, // forceReGenerate + forceReGenerate }; - SpriteGenerator spriteGenerator(module); + SpriteGenerator spriteGenerator(module, forceReGenerate); if (!spriteGenerator.writeSprites()) { return false; } diff --git a/Telegram/SourceFiles/codegen/style/sprite_generator.cpp b/Telegram/SourceFiles/codegen/style/sprite_generator.cpp index cc3c2c1bc..2113fa833 100644 --- a/Telegram/SourceFiles/codegen/style/sprite_generator.cpp +++ b/Telegram/SourceFiles/codegen/style/sprite_generator.cpp @@ -48,8 +48,9 @@ constexpr int kErrorCouldNotWrite = 845; } // namespace -SpriteGenerator::SpriteGenerator(const structure::Module &module) -: module_(module) +SpriteGenerator::SpriteGenerator(const structure::Module &module, bool forceReGenerate) +: forceReGenerate_(forceReGenerate) +, module_(module) , basePath_(QFileInfo(module.filepath()).dir().absolutePath()) { } @@ -84,7 +85,7 @@ bool SpriteGenerator::writeSprites() { } } QFile file(filepath); - if (file.open(QIODevice::ReadOnly)) { + if (!forceReGenerate_ && file.open(QIODevice::ReadOnly)) { if (file.readAll() == spriteData) { continue; } diff --git a/Telegram/SourceFiles/codegen/style/sprite_generator.h b/Telegram/SourceFiles/codegen/style/sprite_generator.h index 832a71984..fc1458db3 100644 --- a/Telegram/SourceFiles/codegen/style/sprite_generator.h +++ b/Telegram/SourceFiles/codegen/style/sprite_generator.h @@ -34,7 +34,7 @@ class Module; class SpriteGenerator { public: - SpriteGenerator(const structure::Module &module); + SpriteGenerator(const structure::Module &module, bool forceReGenerate); SpriteGenerator(const SpriteGenerator &other) = delete; SpriteGenerator &operator=(const SpriteGenerator &other) = delete; @@ -46,6 +46,7 @@ private: QImage generateSprite(int scale); // scale = 5 for 125% and 6 for 150%. const structure::Module &module_; + bool forceReGenerate_; QString basePath_; QImage sprite2x_; QList sprites_; diff --git a/Telegram/SourceFiles/dialogswidget.cpp b/Telegram/SourceFiles/dialogswidget.cpp index 948ec9619..348bc8907 100644 --- a/Telegram/SourceFiles/dialogswidget.cpp +++ b/Telegram/SourceFiles/dialogswidget.cpp @@ -661,7 +661,7 @@ bool DialogsInner::menuPeerMuted() { void DialogsInner::onContextProfile() { if (!_menuPeer) return; - App::main()->showPeerProfile(_menuPeer); + Ui::showPeerProfile(_menuPeer); } void DialogsInner::onContextToggleNotifications() { @@ -1849,27 +1849,30 @@ void DialogsWidget::dialogsToUp() { } } -void DialogsWidget::animShow(const QPixmap &bgAnimCache) { +void DialogsWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) { if (App::app()) App::app()->mtpPause(); - bool back = true; - (back ? _cacheOver : _cacheUnder) = bgAnimCache; + _cacheUnder = params.oldContentCache; + show(); + _cacheOver = App::main()->grabForShowAnimation(params); _a_show.stop(); - (back ? _cacheUnder : _cacheOver) = myGrab(this); - _scroll.hide(); _filter.hide(); _cancelSearch.hide(); _newGroup.hide(); - a_coordUnder = back ? anim::ivalue(-st::slideShift, 0) : anim::ivalue(0, -st::slideShift); - a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0); - a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1); + int delta = st::slideShift; + a_progress = anim::fvalue(0, 1); + if (direction == Window::SlideDirection::FromLeft) { + a_coordUnder = anim::ivalue(0, delta); + a_coordOver = anim::ivalue(-delta, 0); + } else { + a_coordUnder = anim::ivalue(0, -delta); + a_coordOver = anim::ivalue(delta, 0); + } _a_show.start(); - - show(); } void DialogsWidget::step_show(float64 ms, bool timer) { @@ -1879,7 +1882,7 @@ void DialogsWidget::step_show(float64 ms, bool timer) { a_coordUnder.finish(); a_coordOver.finish(); - a_shadow.finish(); + a_progress.finish(); _cacheUnder = _cacheOver = QPixmap(); @@ -1894,7 +1897,7 @@ void DialogsWidget::step_show(float64 ms, bool timer) { } else { a_coordUnder.update(dt, st::slideFunction); a_coordOver.update(dt, st::slideFunction); - a_shadow.update(dt, st::slideFunction); + a_progress.update(dt, st::slideFunction); } if (timer) update(); } @@ -2535,15 +2538,24 @@ void DialogsWidget::paintEvent(QPaintEvent *e) { p.setClipRect(r); } if (_a_show.animating()) { - if (a_coordOver.current() > 0) { - p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * cRetinaFactor(), 0, a_coordOver.current() * cRetinaFactor(), height() * cRetinaFactor())); - p.setOpacity(a_shadow.current() * st::slideFadeOut); - p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b); - p.setOpacity(1); + int retina = cIntRetinaFactor(); + if (a_progress.current() < 1) { + int underLeft = a_coordUnder.current(); + int underWidth = _cacheUnder.width() / retina; + int underHeight = _cacheUnder.height() / retina; + p.fillRect(r, st::white); + QRect underDst(0, 0, underWidth + underLeft, underHeight); + QRect underSrc(-underLeft * retina, 0, (underWidth + underLeft) * retina, underHeight * retina); + p.setOpacity(1. - a_progress.current()); + p.drawPixmap(underDst, _cacheUnder, underSrc); + p.setOpacity(a_progress.current()); } - 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.rect()); + int overLeft = a_coordOver.current(); + int overWidth = _cacheOver.width() / retina; + int overHeight = _cacheOver.height() / retina; + QRect overDst(overLeft, 0, overWidth - overLeft, overHeight); + QRect overSrc(0, 0, (overWidth - overLeft) * retina, overHeight * retina); + p.drawPixmap(overDst, _cacheOver, overSrc); return; } QRect above(0, 0, width(), _scroll.y()); diff --git a/Telegram/SourceFiles/dialogswidget.h b/Telegram/SourceFiles/dialogswidget.h index fe5b33e62..b12e613c0 100644 --- a/Telegram/SourceFiles/dialogswidget.h +++ b/Telegram/SourceFiles/dialogswidget.h @@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "window/section_widget.h" + class MainWidget; namespace Dialogs { class Row; @@ -260,7 +262,10 @@ public: void dialogsToUp(); - void animShow(const QPixmap &bgAnimCache); + bool hasTopBarShadow() const { + return true; + } + void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms); void step_show(float64 ms, bool timer); void destroyData(); @@ -338,7 +343,7 @@ private: Animation _a_show; QPixmap _cacheUnder, _cacheOver; anim::ivalue a_coordUnder, a_coordOver; - anim::fvalue a_shadow; + anim::fvalue a_progress; PeerData *_searchInPeer, *_searchInMigrated; diff --git a/Telegram/SourceFiles/facades.cpp b/Telegram/SourceFiles/facades.cpp index 6cc869d32..defd46993 100644 --- a/Telegram/SourceFiles/facades.cpp +++ b/Telegram/SourceFiles/facades.cpp @@ -20,6 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #include "stdafx.h" +#include "profile/profile_section_memento.h" #include "mainwindow.h" #include "mainwidget.h" #include "application.h" @@ -237,7 +238,15 @@ void autoplayMediaInlineAsync(const FullMsgId &msgId) { } void showPeerProfile(const PeerId &peer) { - if (MainWidget *m = App::main()) m->showPeerProfile(App::peer(peer)); + if (auto m = App::main()) { + m->showWideSection(Profile::SectionMemento(App::peer(peer))); + } +} + +void showPeerOverview(const PeerId &peer, MediaOverviewType type) { + if (auto m = App::main()) { + m->showMediaOverview(App::peer(peer), type); + } } void showPeerHistory(const PeerId &peer, MsgId msgId, bool back) { diff --git a/Telegram/SourceFiles/facades.h b/Telegram/SourceFiles/facades.h index 4ee4a8998..0966f9d9b 100644 --- a/Telegram/SourceFiles/facades.h +++ b/Telegram/SourceFiles/facades.h @@ -75,6 +75,14 @@ inline void showPeerProfile(const History *history) { showPeerProfile(history->peer->id); } +void showPeerOverview(const PeerId &peer, MediaOverviewType type); +inline void showPeerOverview(const PeerData *peer, MediaOverviewType type) { + showPeerOverview(peer->id, type); +} +inline void showPeerOverview(const History *history, MediaOverviewType type) { + showPeerOverview(history->peer->id, type); +} + void showPeerHistory(const PeerId &peer, MsgId msgId, bool back = false); inline void showPeerHistory(const PeerData *peer, MsgId msgId, bool back = false) { showPeerHistory(peer->id, msgId, back); diff --git a/Telegram/SourceFiles/historywidget.cpp b/Telegram/SourceFiles/historywidget.cpp index 0544ead19..fe17b8cdd 100644 --- a/Telegram/SourceFiles/historywidget.cpp +++ b/Telegram/SourceFiles/historywidget.cpp @@ -4089,7 +4089,9 @@ bool HistoryWidget::reportSpamSettingFail(const RPCError &error, mtpRequestId re } void HistoryWidget::updateControlsVisibility() { - _topShadow.setVisible(_peer ? true : false); + if (!_a_show.animating()) { + _topShadow.setVisible(_peer ? true : false); + } if (!_history || _a_show.animating()) { _reportSpamPanel.hide(); _scroll.hide(); @@ -5123,15 +5125,15 @@ HistoryItem *HistoryWidget::atTopImportantMsg(int32 &bottomUnderScrollTop) const return _list->atTopImportantMsg(_scroll.scrollTop(), _scroll.height(), bottomUnderScrollTop); } -void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back) { +void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) { if (App::app()) App::app()->mtpPause(); - (back ? _cacheOver : _cacheUnder) = bgAnimCache; - (back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache; - (back ? _cacheUnder : _cacheOver) = myGrab(this); - App::main()->topBar()->stopAnim(); - (back ? _cacheTopBarUnder : _cacheTopBarOver) = myGrab(App::main()->topBar()); + _cacheUnder = params.oldContentCache; + show(); + _topShadow.setVisible(params.withTopBarShadow ? false : true); + _cacheOver = App::main()->grabForShowAnimation(params); App::main()->topBar()->startAnim(); + _topShadow.setVisible(params.withTopBarShadow ? true : false); _scroll.hide(); _kbScroll.hide(); @@ -5155,31 +5157,37 @@ void HistoryWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTo _botStart.hide(); _joinChannel.hide(); _muteUnmute.hide(); - _topShadow.hide(); if (_pinnedBar) { _pinnedBar->shadow.hide(); _pinnedBar->cancel.hide(); } - a_coordUnder = back ? anim::ivalue(-st::slideShift, 0) : anim::ivalue(0, -st::slideShift); - a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0); - a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1); + int delta = st::slideShift; + a_progress = anim::fvalue(0, 1); + if (direction == Window::SlideDirection::FromLeft) { + a_coordUnder = anim::ivalue(0, delta); + a_coordOver = anim::ivalue(-delta, 0); + } else { + a_coordUnder = anim::ivalue(0, -delta); + a_coordOver = anim::ivalue(delta, 0); + } _a_show.start(); App::main()->topBar()->update(); + activate(); } void HistoryWidget::step_show(float64 ms, bool timer) { - float64 dt = ms / 3000;// st::slideDuration; + float64 dt = ms / st::slideDuration; if (dt >= 1) { _a_show.stop(); _topShadow.setVisible(_peer ? true : false); a_coordUnder.finish(); a_coordOver.finish(); - a_shadow.finish(); - _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap(); + a_progress.finish(); + _cacheUnder = _cacheOver = QPixmap(); App::main()->topBar()->stopAnim(); doneShow(); @@ -5187,7 +5195,7 @@ void HistoryWidget::step_show(float64 ms, bool timer) { } else { a_coordUnder.update(dt, st::slideFunction); a_coordOver.update(dt, st::slideFunction); - a_shadow.update(dt, st::slideFunction); + a_progress.update(dt, st::slideFunction); } if (timer) { update(); @@ -5903,10 +5911,24 @@ void HistoryWidget::onForwardHere() { void HistoryWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) { 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.rect()); + int retina = cIntRetinaFactor(); + if (a_progress.current() < 1) { + int underLeft = a_coordUnder.current(); + int underWidth = _cacheUnder.width() / retina; + int underHeight = st::topBarHeight; + p.fillRect(0, 0, underWidth, underHeight, st::white); + QRect underDst(0, 0, underWidth + underLeft, underHeight); + QRect underSrc(-underLeft * retina, 0, (underWidth + underLeft) * retina, underHeight * retina); + p.setOpacity(1. - a_progress.current()); + p.drawPixmap(underDst, _cacheUnder, underSrc); + p.setOpacity(a_progress.current()); + } + int overLeft = a_coordOver.current(); + int overWidth = _cacheOver.width() / retina; + int overHeight = st::topBarHeight; + QRect overDst(overLeft, 0, overWidth - overLeft, overHeight); + QRect overSrc(0, 0, (overWidth - overLeft) * retina, overHeight * retina); + p.drawPixmap(overDst, _cacheOver, overSrc); return; } @@ -5940,7 +5962,7 @@ void HistoryWidget::topBarClick() { if (Adaptive::OneColumn()) { Ui::showChatsList(); } else { - if (_history) App::main()->showPeerProfile(_peer); + if (_history) Ui::showPeerProfile(_peer); } } @@ -8310,20 +8332,31 @@ void HistoryWidget::paintEvent(QPaintEvent *e) { if (r != rect()) { p.setClipRect(r); } + bool hasTopBar = !App::main()->topBar()->isHidden(), hasPlayer = !App::main()->player()->isHidden(); + if (_a_show.animating()) { - if (a_coordOver.current() > 0) { - p.drawPixmap(QRect(0, 0, a_coordOver.current(), height()), _cacheUnder, QRect(-a_coordUnder.current() * cRetinaFactor(), 0, a_coordOver.current() * cRetinaFactor(), height() * cRetinaFactor())); - p.setOpacity(a_shadow.current() * st::slideFadeOut); - p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b); - p.setOpacity(1); + int retina = cIntRetinaFactor(); + int inCacheTop = hasTopBar ? st::topBarHeight : 0; + if (a_progress.current() < 1) { + int underLeft = a_coordUnder.current(); + int underWidth = _cacheUnder.width() / retina; + int underHeight = height(); + p.fillRect(r, st::white); + QRect underDst(0, 0, underWidth + underLeft, underHeight); + QRect underSrc(-underLeft * retina, inCacheTop * retina, (underWidth + underLeft) * retina, underHeight * retina); + p.setOpacity(1. - a_progress.current()); + p.drawPixmap(underDst, _cacheUnder, underSrc); + p.setOpacity(a_progress.current()); } - 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.rect()); + int overLeft = a_coordOver.current(); + int overWidth = _cacheOver.width() / retina; + int overHeight = height(); + QRect overDst(overLeft, 0, overWidth - overLeft, overHeight); + QRect overSrc(0, inCacheTop * retina, (overWidth - overLeft) * retina, overHeight * retina); + p.drawPixmap(overDst, _cacheOver, overSrc); return; } - bool hasTopBar = !App::main()->topBar()->isHidden(), hasPlayer = !App::main()->player()->isHidden(); QRect fill(0, 0, width(), App::main()->height()); int fromy = (hasTopBar ? (-st::topBarHeight) : 0) + (hasPlayer ? (-st::playerHeight) : 0), x = 0, y = 0; QPixmap cached = App::main()->cachedBackground(fill, x, y); diff --git a/Telegram/SourceFiles/historywidget.h b/Telegram/SourceFiles/historywidget.h index 082d97e9f..f9e82b830 100644 --- a/Telegram/SourceFiles/historywidget.h +++ b/Telegram/SourceFiles/historywidget.h @@ -25,6 +25,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "dropdown.h" #include "history/history_common.h" #include "history/field_autocomplete.h" +#include "window/section_widget.h" namespace InlineBots { namespace Layout { @@ -576,7 +577,10 @@ public: MsgId msgId() const; HistoryItem *atTopImportantMsg(int32 &bottomUnderScrollTop) const; - void animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false); + bool hasTopBarShadow() const { + return peer() != nullptr; + } + void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms); void step_show(float64 ms, bool timer); void animStop(); @@ -659,9 +663,14 @@ public: _inGrab = true; resizeEvent(0); } + void grapWithoutTopBarShadow() { + grabStart(); + _topShadow.hide(); + } void grabFinish() override { _inGrab = false; resizeEvent(0); + _topShadow.show(); } bool isItemVisible(HistoryItem *item); @@ -1084,9 +1093,9 @@ private: int32 _titlePeerTextWidth = 0; Animation _a_show; - QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver; + QPixmap _cacheUnder, _cacheOver; anim::ivalue a_coordUnder, a_coordOver; - anim::fvalue a_shadow; + anim::fvalue a_progress; QTimer _scrollTimer; int32 _scrollDelta = 0; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index b64e60a50..ae9599980 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -22,7 +22,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "mainwidget.h" #include "ui/buttons/peer_avatar_button.h" -#include "profile/profile_widget.h" +#include "window/section_memento.h" +#include "window/section_widget.h" #include "window/top_bar_widget.h" #include "apiwrap.h" #include "dialogswidget.h" @@ -45,6 +46,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "shortcuts.h" #include "audio.h" +StackItemSection::StackItemSection(std_::unique_ptr &&memento) : StackItem(nullptr) +, _memento(std_::move(memento)) { +} + +StackItemSection::~StackItemSection() { +} + MainWidget::MainWidget(MainWindow *window) : TWidget(window) , _a_show(animation(this, &MainWidget::step_show)) , _sideShadow(this, st::shadowColor) @@ -390,8 +398,8 @@ void MainWidget::rpcClear() { QPixmap MainWidget::grabInner() { if (_overview && !_overview->isHidden()) { return myGrab(_overview); - } else if (_profile && !_profile->isHidden()) { - return myGrab(_profile, QRect(0, st::topBarHeight, _history->width(), _history->height() - st::topBarHeight)); + } else if (_wideSection && !_wideSection->isHidden()) { + return myGrab(_wideSection, QRect(0, st::topBarHeight, _history->width(), _history->height() - st::topBarHeight)); } else if (Adaptive::OneColumn() && _history->isHidden()) { return myGrab(_dialogs, QRect(0, st::topBarHeight, _dialogs->width(), _dialogs->height() - st::topBarHeight)); } else if (_history->peer()) { @@ -411,8 +419,8 @@ bool MainWidget::isItemVisible(HistoryItem *item) { QPixmap MainWidget::grabTopBar() { if (!_topBar->isHidden()) { return myGrab(_topBar); - } else if (_profile) { - return myGrab(_profile, QRect(0, 0, _profile->width(), st::topBarHeight)); + } else if (_wideSection) { + return myGrab(_wideSection, QRect(0, 0, _wideSection->width(), st::topBarHeight)); } else if (Adaptive::OneColumn() && _history->isHidden()) { return myGrab(_dialogs, QRect(0, 0, _dialogs->width(), st::topBarHeight)); } else { @@ -528,29 +536,22 @@ void MainWidget::noHider(HistoryHider *destroyed) { _forwardConfirm = 0; } onHistoryShown(_history->history(), _history->msgId()); - if (_profile || _overview || (_history->peer() && _history->peer()->id)) { - QPixmap animCache, animTopBarCache; - if (_profile) { - if (Adaptive::OneColumn()) { - animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); - } else { - _sideShadow.hide(); - animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight)); - _sideShadow.show(); - } + if (_wideSection || _overview || (_history->peer() && _history->peer()->id)) { + Window::SectionSlideParams animationParams; + if (_overview) { + animationParams = prepareOverviewAnimation(); + } else if (_wideSection) { + animationParams = prepareWideSectionAnimation(_wideSection); } else { - animCache = grabInner(); - animTopBarCache = grabTopBar(); + animationParams = prepareHistoryAnimation(_history->peer() ? _history->peer()->id : 0); } _dialogs->hide(); if (_overview) { - _overview->show(); - _overview->animShow(animCache, animTopBarCache); - } else if (_profile) { - _profile->showAnimated(SlideDirection::FromRight, animCache); + _overview->showAnimated(Window::SlideDirection::FromRight, animationParams); + } else if (_wideSection) { + _wideSection->showAnimated(Window::SlideDirection::FromRight, animationParams); } else { - _history->show(); - _history->animShow(animCache, animTopBarCache); + _history->showAnimated(Window::SlideDirection::FromRight, animationParams); } } App::wnd()->getTitle()->updateBackButton(); @@ -575,19 +576,19 @@ void MainWidget::hiderLayer(HistoryHider *h) { dialogsToUp(); _hider->hide(); - QPixmap animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); + auto animationParams = prepareDialogsAnimation(); onHistoryShown(0, 0); if (_overview) { _overview->hide(); - } else if (_profile) { - _profile->hide(); + } else if (_wideSection) { + _wideSection->hide(); } else { _history->hide(); } _dialogs->show(); resizeEvent(0); - _dialogs->animShow(animCache); + _dialogs->showAnimated(Window::SlideDirection::FromLeft, animationParams); App::wnd()->getTitle()->updateBackButton(); } else { _hider->show(); @@ -1878,15 +1879,15 @@ void MainWidget::setInnerFocus() { _hider->setFocus(); } else if (_overview) { _overview->activate(); - } else if (_profile) { - _profile->setInnerFocus(); + } else if (_wideSection) { + _wideSection->setInnerFocus(); } else { dialogsActivate(); } } else if (_overview) { _overview->activate(); - } else if (_profile) { - _profile->setInnerFocus(); + } else if (_wideSection) { + _wideSection->setInnerFocus(); } else { _history->setInnerFocus(); } @@ -2030,31 +2031,19 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac _hider = nullptr; } - QPixmap animCache, animTopBarCache; - if (!_a_show.animating() && ((_history->isHidden() && (_profile || _overview)) || (Adaptive::OneColumn() && (_history->isHidden() || !peerId)))) { - if (peerId) { - animCache = grabInner(); - } else if (Adaptive::OneColumn()) { - animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); - } else { - _sideShadow.hide(); - animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight)); - _sideShadow.show(); - } - if (peerId || !Adaptive::OneColumn()) { - animTopBarCache = grabTopBar(); - } - _history->show(); + Window::SectionSlideParams animationParams; + if (!_a_show.animating() && ((_history->isHidden() && (_wideSection || _overview)) || (Adaptive::OneColumn() && (_history->isHidden() || !peerId)))) { + animationParams = prepareHistoryAnimation(peerId); } if (_history->peer() && _history->peer()->id != peerId) clearBotStartToken(_history->peer()); _history->showHistory(peerId, showAtMsgId); bool noPeer = (!_history->peer() || !_history->peer()->id), onlyDialogs = noPeer && Adaptive::OneColumn(); - if (_profile || _overview) { - if (_profile) { - _profile->hide(); - _profile->deleteLater(); - _profile = nullptr; + if (_wideSection || _overview) { + if (_wideSection) { + _wideSection->hide(); + _wideSection->deleteLater(); + _wideSection = nullptr; } if (_overview) { _overview->hide(); @@ -2073,9 +2062,10 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac _topBar->hide(); _history->hide(); if (!_a_show.animating()) { - _dialogs->show(); - if (!animCache.isNull()) { - _dialogs->animShow(animCache); + if (!animationParams.oldContentCache.isNull()) { + _dialogs->showAnimated(back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight, animationParams); + } else { + _dialogs->show(); } } } else { @@ -2090,11 +2080,13 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac } if (Adaptive::OneColumn() && !_dialogs->isHidden()) _dialogs->hide(); if (!_a_show.animating()) { - if (_history->isHidden()) _history->show(); - if (!animCache.isNull()) { - _history->animShow(animCache, animTopBarCache, back); - } else if (App::wnd()) { - QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus())); + if (!animationParams.oldContentCache.isNull()) { + _history->showAnimated(back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight, animationParams); + } else { + _history->show(); + if (App::wnd()) { + QTimer::singleShot(0, App::wnd(), SLOT(setInnerFocus())); + } } } } @@ -2112,8 +2104,8 @@ void MainWidget::ui_showPeerHistory(quint64 peerId, qint32 showAtMsgId, bool bac } PeerData *MainWidget::ui_getPeerForMouseAction() { - if (_profile) { - //return _profile->ui_getPeerForMouseAction(); TODO + if (_wideSection) { + //return _wideSection->ui_getPeerForMouseAction(); TODO } return _history->ui_getPeerForMouseAction(); } @@ -2152,10 +2144,6 @@ MsgId MainWidget::activeMsgId() { return _history->peer() ? _history->msgId() : _msgIdInStack; } -PeerData *MainWidget::profilePeer() { - return _profile ? _profile->peer() : 0; -} - PeerData *MainWidget::overviewPeer() { return _overview ? _overview->peer() : 0; } @@ -2186,18 +2174,15 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool return; } - 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 (!_a_show.animating() && (Adaptive::OneColumn() || _profile || _overview || _history->peer())) { - animCache = grabInner(); - animTopBarCache = grabTopBar(); + Window::SectionSlideParams animationParams; + if (!_a_show.animating() && (Adaptive::OneColumn() || _wideSection || _overview || _history->peer())) { + animationParams = prepareOverviewAnimation(); } if (!back) { if (_overview) { _stack.push_back(new StackItemOverview(_overview->peer(), _overview->type(), _overview->lastWidth(), _overview->lastScrollTop())); - } else if (_profile) { -// _stack.push_back(new StackItemProfile(_profile->peer(), _profile->lastScrollTop())); TODO + } else if (_wideSection) { + _stack.push_back(new StackItemSection(_wideSection->createMemento())); } else if (_history->peer()) { dlgUpdated(); _peerInStack = _history->peer(); @@ -2212,18 +2197,19 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool _overview->deleteLater(); _overview->rpcClear(); } - if (_profile) { - _profile->hide(); - _profile->deleteLater(); - _profile = nullptr; + if (_wideSection) { + _wideSection->hide(); + _wideSection->deleteLater(); + _wideSection = nullptr; } _overview = new OverviewWidget(this, peer, type); _mediaTypeMask = 0; _topBar->show(); resizeEvent(nullptr); mediaOverviewUpdated(peer, type); - if (!animCache.isNull()) { - _overview->animShow(animCache, animTopBarCache, back, lastScrollTop); + _overview->setLastScrollTop(lastScrollTop); + if (!animationParams.oldContentCache.isNull()) { + _overview->showAnimated(back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight, animationParams); } else { _overview->fastShow(); } @@ -2238,36 +2224,88 @@ void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool App::wnd()->getTitle()->updateBackButton(); } -void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop) { - if (peer->migrateTo()) { - peer = peer->migrateTo(); - } - +void MainWidget::showWideSection(Window::SectionMemento &memento) { App::wnd()->hideSettings(); - if (_profile && _profile->peer() == peer) return; + if (_wideSection && _wideSection->showInternal(&memento)) { + return; + } - QPixmap animCache; - if (Adaptive::OneColumn()) { - animCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); - } else { - _sideShadow.hide(); - animCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight)); - _sideShadow.show(); + if (_overview) { + _stack.push_back(new StackItemOverview(_overview->peer(), _overview->type(), _overview->lastWidth(), _overview->lastScrollTop())); + } else if (_wideSection) { + _stack.push_back(new StackItemSection(_wideSection->createMemento())); + } else if (_history->peer()) { + dlgUpdated(); + _peerInStack = _history->peer(); + _msgIdInStack = _history->msgId(); + dlgUpdated(); + _stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, _history->replyReturns())); } -// QPixmap animCache = grabInner(), animTopBarCache = grabTopBar(); - if (!back) { - if (_overview) { - _stack.push_back(new StackItemOverview(_overview->peer(), _overview->type(), _overview->lastWidth(), _overview->lastScrollTop())); - } else if (_profile) { -// _stack.push_back(new StackItemProfile(_profile->peer(), _profile->lastScrollTop())); TODO - } else if (_history->peer()) { - dlgUpdated(); - _peerInStack = _history->peer(); - _msgIdInStack = _history->msgId(); - dlgUpdated(); - _stack.push_back(new StackItemHistory(_peerInStack, _msgIdInStack, _history->replyReturns())); + showWideSectionAnimated(&memento, false); +} + +Window::SectionSlideParams MainWidget::prepareShowAnimation(bool willHaveTopBarShadow) { + Window::SectionSlideParams result; + result.withTopBarShadow = willHaveTopBarShadow; + if (selectingPeer() && Adaptive::OneColumn()) { + result.withTopBarShadow = false; + } else if (_wideSection) { + if (!_wideSection->hasTopBarShadow()) { + result.withTopBarShadow = false; } + } else if (!_overview && !_history->peer()) { + result.withTopBarShadow = false; } + + if (selectingPeer() && Adaptive::OneColumn()) { + result.oldContentCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); + } else if (_wideSection) { + result.oldContentCache = _wideSection->grabForShowAnimation(result); + } else { + if (result.withTopBarShadow) { + if (_overview) _overview->grapWithoutTopBarShadow(); + _history->grapWithoutTopBarShadow(); + } else { + if (_overview) _overview->grabStart(); + _history->grabStart(); + } + if (Adaptive::OneColumn()) { + result.oldContentCache = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); + } else { + _sideShadow.hide(); + result.oldContentCache = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight)); + _sideShadow.show(); + } + if (_overview) _overview->grabFinish(); + _history->grabFinish(); + } + + return result; +} + +Window::SectionSlideParams MainWidget::prepareWideSectionAnimation(Window::SectionWidget *section) { + return prepareShowAnimation(section->hasTopBarShadow()); +} + +Window::SectionSlideParams MainWidget::prepareHistoryAnimation(PeerId historyPeerId) { + return prepareShowAnimation(historyPeerId != 0); +} + +Window::SectionSlideParams MainWidget::prepareOverviewAnimation() { + return prepareShowAnimation(true); +} + +Window::SectionSlideParams MainWidget::prepareDialogsAnimation() { + return prepareShowAnimation(false); +} + +void MainWidget::showWideSectionAnimated(Window::SectionMemento *memento, bool back) { + QPixmap animCache; + + auto newWideGeometry = QRect(_history->x(), _playerHeight, _history->width(), height() - _playerHeight); + auto newWideSection = memento->createWidget(this, newWideGeometry); + Window::SectionSlideParams animationParams = prepareWideSectionAnimation(newWideSection); + if (_overview) { _overview->hide(); _overview->clear(); @@ -2275,17 +2313,17 @@ void MainWidget::showPeerProfile(PeerData *peer, bool back, int32 lastScrollTop) _overview->rpcClear(); _overview = nullptr; } - if (_profile) { - _profile->hide(); - _profile->deleteLater(); - _profile = nullptr; + if (_wideSection) { + _wideSection->hide(); + _wideSection->deleteLater(); + _wideSection = nullptr; } - _profile = new Profile::Widget(this, peer); + _wideSection = newWideSection; _topBar->hide(); resizeEvent(0); - _profile->showAnimated(SlideDirection::FromRight, animCache); + auto direction = back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight; + _wideSection->showAnimated(direction, animationParams); _history->animStop(); - if (back) clearBotStartToken(_history->peer()); _history->showHistory(0, 0); _history->hide(); if (Adaptive::OneColumn()) _dialogs->hide(); @@ -2304,6 +2342,9 @@ void MainWidget::showBackFromStack() { } StackItem *item = _stack.back(); _stack.pop_back(); + if (auto currentHistoryPeer = _history->peer()) { + clearBotStartToken(currentHistoryPeer); + } if (item->type() == HistoryStackItem) { dlgUpdated(); _peerInStack = 0; @@ -2319,9 +2360,9 @@ void MainWidget::showBackFromStack() { StackItemHistory *histItem = static_cast(item); Ui::showPeerHistory(histItem->peer->id, App::main()->activeMsgId(), true); _history->setReplyReturns(histItem->peer->id, histItem->replyReturns); - } else if (item->type() == ProfileStackItem) { - StackItemProfile *profItem = static_cast(item); - showPeerProfile(profItem->peer, true, profItem->lastScrollTop); + } else if (item->type() == SectionStackItem) { + StackItemSection *sectionItem = static_cast(item); + showWideSectionAnimated(sectionItem->memento(), true); } else if (item->type() == OverviewStackItem) { StackItemOverview *overItem = static_cast(item); showMediaOverview(overItem->peer, overItem->mediaType, true, overItem->lastScrollTop); @@ -2345,6 +2386,19 @@ QRect MainWidget::historyRect() const { return r; } +QPixmap MainWidget::grabForShowAnimation(const Window::SectionSlideParams ¶ms) { + _topBar->stopAnim(); + QPixmap result; + if (Adaptive::OneColumn()) { + result = myGrab(this, QRect(0, _playerHeight, _dialogsWidth, height() - _playerHeight)); + } else { + _sideShadow.hide(); + result = myGrab(this, QRect(_dialogsWidth, _playerHeight, width() - _dialogsWidth, height() - _playerHeight)); + _sideShadow.show(); + } + return result; +} + void MainWidget::dlgUpdated() { if (_peerInStack) { _dialogs->dlgUpdated(App::history(_peerInStack->id), _msgIdInStack); @@ -2482,12 +2536,13 @@ void MainWidget::paintEvent(QPaintEvent *e) { void MainWidget::hideAll() { _dialogs->hide(); _history->hide(); - if (_profile) { - _profile->hide(); + if (_wideSection) { + _wideSection->hide(); } if (_overview) { _overview->hide(); } + _sideShadow.hide(); _topBar->hide(); _mediaType->hide(); if (_player->isOpened() && !_player->isHidden()) { @@ -2501,6 +2556,7 @@ void MainWidget::showAll() { cSetPasswordRecovered(false); Ui::showLayer(new InformBox(lang(lng_signin_password_removed))); } + _sideShadow.show(); if (Adaptive::OneColumn()) { if (_hider) { _hider->hide(); @@ -2515,12 +2571,12 @@ void MainWidget::showAll() { _dialogs->show(); _history->hide(); if (_overview) _overview->hide(); - if (_profile) _profile->hide(); + if (_wideSection) _wideSection->hide(); _topBar->hide(); } else if (_overview) { _overview->show(); - } else if (_profile) { - _profile->show(); + } else if (_wideSection) { + _wideSection->show(); } else if (_history->peer()) { _history->show(); _history->resizeEvent(0); @@ -2528,7 +2584,7 @@ void MainWidget::showAll() { _dialogs->show(); _history->hide(); } - if (_profile) { + if (_wideSection) { _topBar->hide(); } else if (!selectingPeer() && (_overview || _history->peer())) { _topBar->show(); @@ -2545,13 +2601,13 @@ void MainWidget::showAll() { _dialogs->show(); if (_overview) { _overview->show(); - } else if (_profile) { - _profile->show(); + } else if (_wideSection) { + _wideSection->show(); } else { _history->show(); _history->resizeEvent(0); } - if (_profile) { + if (_wideSection) { _topBar->hide(); } else if (_overview || _history->peer()) { _topBar->show(); @@ -2593,9 +2649,9 @@ void MainWidget::resizeEvent(QResizeEvent *e) { } } _mediaType->moveToLeft(width() - _mediaType->width(), _playerHeight + st::topBarHeight); - if (_profile) { - QRect profileGeometry(_history->x(), _playerHeight, _history->width(), height() - _playerHeight); - _profile->setGeometryWithTopMoved(profileGeometry, _contentScrollAddToY); + if (_wideSection) { + QRect wideSectionGeometry(_history->x(), _playerHeight, _history->width(), height() - _playerHeight); + _wideSection->setGeometryWithTopMoved(wideSectionGeometry, _contentScrollAddToY); } if (_overview) _overview->setGeometry(_history->geometry()); _contentScrollAddToY = 0; @@ -2611,20 +2667,21 @@ void MainWidget::keyPressEvent(QKeyEvent *e) { void MainWidget::updateAdaptiveLayout() { showAll(); _sideShadow.setVisible(!Adaptive::OneColumn()); + if (_wideSection) { + _wideSection->updateAdaptiveLayout(); + } _topBar->updateAdaptiveLayout(); _history->updateAdaptiveLayout(); } bool MainWidget::needBackButton() { - return _overview || _profile || (_history->peer() && _history->peer()->id); + return _overview || _wideSection || _history->peer(); } void MainWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) { - if (_profile) { -// _profile->paintTopBar(p, over, decreaseWidth); - } else if (_overview) { + if (_overview) { _overview->paintTopBar(p, over, decreaseWidth); - } else { + } else if (!_wideSection) { _history->paintTopBar(p, over, decreaseWidth); } } @@ -2668,11 +2725,9 @@ PlayerWidget *MainWidget::player() { } void MainWidget::onTopBarClick() { - if (_profile) { -// _profile->topBarClick(); - } else if (_overview) { + if (_overview) { _overview->topBarClick(); - } else { + } else if (!_wideSection) { _history->topBarClick(); } } @@ -3308,7 +3363,7 @@ void MainWidget::openPeerByName(const QString &username, MsgId msgId, const QStr // Always open bot chats, even from mention links. Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId); } else { - showPeerProfile(peer); + Ui::showPeerProfile(peer); } } else { if (msgId == ShowAtProfileMsgId || !peer->isChannel()) { // show specific posts only in channels / supergroups @@ -3391,7 +3446,7 @@ void MainWidget::usernameResolveDone(QPair msgIdAndStartToken, c // Always open bot chats, even from mention links. Ui::showPeerHistoryAsync(peer->id, ShowAtUnreadMsgId); } else { - showPeerProfile(peer); + Ui::showPeerProfile(peer); } } else { if (msgId == ShowAtProfileMsgId || !peer->isChannel()) { // show specific posts only in channels / supergroups @@ -3690,7 +3745,7 @@ void MainWidget::incrementSticker(DocumentData *sticker) { void MainWidget::activate() { if (_a_show.animating()) return; - if (!_profile && !_overview) { + if (!_wideSection && !_overview) { if (_hider) { if (_hider->wasOffered()) { _hider->setFocus(); @@ -3724,7 +3779,7 @@ bool MainWidget::isActive() const { } bool MainWidget::historyIsActive() const { - return isActive() && !_profile && !_overview && _history->isActive(); + return isActive() && !_wideSection && !_overview && _history->isActive(); } bool MainWidget::lastWasOnline() const { diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index a95614bda..b395d2949 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -33,18 +33,16 @@ class PeerAvatarButton; namespace Window { class TopBarWidget; +class SectionMemento; +class SectionWidget; +struct SectionSlideParams; } // namespace Window -namespace Profile { -class Widget; -} // namespace Profile - class MainWindow; class ApiWrap; class ConfirmBox; class DialogsWidget; class HistoryWidget; -class ProfileWidget; class OverviewWidget; class PlayerWidget; class HistoryHider; @@ -52,7 +50,7 @@ class Dropdown; enum StackItemType { HistoryStackItem, - ProfileStackItem, + SectionStackItem, OverviewStackItem, }; @@ -68,8 +66,9 @@ public: class StackItemHistory : public StackItem { public: - StackItemHistory(PeerData *peer, MsgId msgId, QList replyReturns) : StackItem(peer), -msgId(msgId), replyReturns(replyReturns) { + StackItemHistory(PeerData *peer, MsgId msgId, QList replyReturns) : StackItem(peer) + , msgId(msgId) + , replyReturns(replyReturns) { } StackItemType type() const { return HistoryStackItem; @@ -78,19 +77,29 @@ msgId(msgId), replyReturns(replyReturns) { QList replyReturns; }; -class StackItemProfile : public StackItem { +class StackItemSection : public StackItem { public: - StackItemProfile(PeerData *peer, int32 lastScrollTop) : StackItem(peer), lastScrollTop(lastScrollTop) { - } + StackItemSection(std_::unique_ptr &&memento); + ~StackItemSection(); + StackItemType type() const { - return ProfileStackItem; + return SectionStackItem; } - int32 lastScrollTop; + Window::SectionMemento *memento() const { + return _memento.get(); + } + +private: + std_::unique_ptr _memento; + }; class StackItemOverview : public StackItem { public: - StackItemOverview(PeerData *peer, MediaOverviewType mediaType, int32 lastWidth, int32 lastScrollTop) : StackItem(peer), mediaType(mediaType), lastWidth(lastWidth), lastScrollTop(lastScrollTop) { + StackItemOverview(PeerData *peer, MediaOverviewType mediaType, int32 lastWidth, int32 lastScrollTop) : StackItem(peer) + , mediaType(mediaType) + , lastWidth(lastWidth) + , lastScrollTop(lastScrollTop) { } StackItemType type() const { return OverviewStackItem; @@ -214,14 +223,14 @@ public: PeerData *activePeer(); MsgId activeMsgId(); - PeerData *profilePeer(); PeerData *overviewPeer(); bool mediaTypeSwitch(); - void showPeerProfile(PeerData *peer, bool back = false, int32 lastScrollTop = -1); + void showWideSection(Window::SectionMemento &memento); void showMediaOverview(PeerData *peer, MediaOverviewType type, bool back = false, int32 lastScrollTop = -1); void showBackFromStack(); void orderWidgets(); QRect historyRect() const; + QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms); void onSendFileConfirm(const FileLoadResultPtr &file, bool ctrlShiftEnter); void onSendFileCancel(const FileLoadResultPtr &file); @@ -485,7 +494,6 @@ public slots: void ui_autoplayMediaInlineAsync(qint32 channelId, qint32 msgId); private: - void sendReadRequest(PeerData *peer, MsgId upTo); void channelWasRead(PeerData *peer, const MTPBool &result); void historyWasRead(PeerData *peer, const MTPmessages_AffectedMessages &result); @@ -495,6 +503,15 @@ private: void messagesAffected(PeerData *peer, const MTPmessages_AffectedMessages &result); void overviewLoaded(History *history, const MTPmessages_Messages &result, mtpRequestId req); + Window::SectionSlideParams prepareShowAnimation(bool willHaveTopBarShadow); + void showWideSectionAnimated(Window::SectionMemento *memento, bool back); + + // All this methods use the prepareShowAnimation(). + Window::SectionSlideParams prepareWideSectionAnimation(Window::SectionWidget *section); + Window::SectionSlideParams prepareHistoryAnimation(PeerId historyPeerId); + Window::SectionSlideParams prepareOverviewAnimation(); + Window::SectionSlideParams prepareDialogsAnimation(); + bool _started = false; uint64 failedObjId = 0; @@ -564,7 +581,7 @@ private: ChildWidget _dialogs; ChildWidget _history; - ChildWidget _profile = { nullptr }; + ChildWidget _wideSection = { nullptr }; ChildWidget _overview = { nullptr }; ChildWidget _player; ChildWidget _topBar; diff --git a/Telegram/SourceFiles/mediaview.cpp b/Telegram/SourceFiles/mediaview.cpp index 0c8c0b804..ce5c1ad81 100644 --- a/Telegram/SourceFiles/mediaview.cpp +++ b/Telegram/SourceFiles/mediaview.cpp @@ -1838,7 +1838,7 @@ void MediaView::mouseReleaseEvent(QMouseEvent *e) { if (_over == OverName && _down == OverName) { if (App::wnd() && _from) { close(); - if (App::main()) App::main()->showPeerProfile(_from); + Ui::showPeerProfile(_from); } } else if (_over == OverDate && _down == OverDate) { onToMessage(); diff --git a/Telegram/SourceFiles/overviewwidget.cpp b/Telegram/SourceFiles/overviewwidget.cpp index b011cba2f..85b682f05 100644 --- a/Telegram/SourceFiles/overviewwidget.cpp +++ b/Telegram/SourceFiles/overviewwidget.cpp @@ -1987,15 +1987,25 @@ void OverviewWidget::paintEvent(QPaintEvent *e) { 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() * cRetinaFactor(), 0, a_coordOver.current() * cRetinaFactor(), height() * cRetinaFactor())); - p.setOpacity(a_shadow.current() * st::slideFadeOut); - p.fillRect(0, 0, a_coordOver.current(), height(), st::black->b); - p.setOpacity(1); + int retina = cIntRetinaFactor(); + int inCacheTop = st::topBarHeight; + if (a_progress.current() < 1) { + int underLeft = a_coordUnder.current(); + int underWidth = _cacheUnder.width() / retina; + int underHeight = height(); + p.fillRect(e->rect(), st::white); + QRect underDst(0, 0, underWidth + underLeft, underHeight); + QRect underSrc(-underLeft * retina, inCacheTop * retina, (underWidth + underLeft) * retina, underHeight * retina); + p.setOpacity(1. - a_progress.current()); + p.drawPixmap(underDst, _cacheUnder, underSrc); + p.setOpacity(a_progress.current()); } - 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.rect()); + int overLeft = a_coordOver.current(); + int overWidth = _cacheOver.width() / retina; + int overHeight = height(); + QRect overDst(overLeft, 0, overWidth - overLeft, overHeight); + QRect overSrc(0, inCacheTop * retina, (overWidth - overLeft) * retina, overHeight * retina); + p.drawPixmap(overDst, _cacheOver, overSrc); return; } @@ -2020,10 +2030,24 @@ void OverviewWidget::scrollReset() { void OverviewWidget::paintTopBar(Painter &p, float64 over, int32 decreaseWidth) { 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.rect()); + int retina = cIntRetinaFactor(); + if (a_progress.current() < 1) { + int underLeft = a_coordUnder.current(); + int underWidth = _cacheUnder.width() / retina; + int underHeight = st::topBarHeight; + p.fillRect(0, 0, underWidth, underHeight, st::white); + QRect underDst(0, 0, underWidth + underLeft, underHeight); + QRect underSrc(-underLeft * retina, 0, (underWidth + underLeft) * retina, underHeight * retina); + p.setOpacity(1. - a_progress.current()); + p.drawPixmap(underDst, _cacheUnder, underSrc); + p.setOpacity(a_progress.current()); + } + int overLeft = a_coordOver.current(); + int overWidth = _cacheOver.width() / retina; + int overHeight = st::topBarHeight; + QRect overDst(overLeft, 0, overWidth - overLeft, overHeight); + QRect overSrc(0, 0, (overWidth - overLeft) * retina, overHeight * retina); + p.drawPixmap(overDst, _cacheOver, overSrc); return; } p.setOpacity(st::topBarBackAlpha + (1 - st::topBarBackAlpha) * over); @@ -2127,31 +2151,40 @@ void OverviewWidget::fastShow(bool back, int32 lastScrollTop) { if (App::app()) App::app()->mtpUnpause(); } -void OverviewWidget::animShow(const QPixmap &bgAnimCache, const QPixmap &bgAnimTopBarCache, bool back, int32 lastScrollTop) { - if (App::app()) App::app()->mtpPause(); - - (back ? _cacheOver : _cacheUnder) = bgAnimCache; - (back ? _cacheTopBarOver : _cacheTopBarUnder) = bgAnimTopBarCache; +void OverviewWidget::setLastScrollTop(int lastScrollTop) { resizeEvent(0); _scroll.scrollToY(lastScrollTop < 0 ? countBestScroll() : lastScrollTop); - (back ? _cacheUnder : _cacheOver) = myGrab(this); - App::main()->topBar()->stopAnim(); - (back ? _cacheTopBarUnder : _cacheTopBarOver) = myGrab(App::main()->topBar()); +} + +void OverviewWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) { + if (App::app()) App::app()->mtpPause(); + + resizeEvent(0); + + _cacheUnder = params.oldContentCache; + show(); + _topShadow.setVisible(params.withTopBarShadow ? false : true); + _cacheOver = App::main()->grabForShowAnimation(params); + _topShadow.setVisible(params.withTopBarShadow ? true : false); App::main()->topBar()->startAnim(); _scrollSetAfterShow = _scroll.scrollTop(); _scroll.hide(); - _topShadow.hide(); - a_coordUnder = back ? anim::ivalue(-st::slideShift, 0) : anim::ivalue(0, -st::slideShift); - a_coordOver = back ? anim::ivalue(0, width()) : anim::ivalue(width(), 0); - a_shadow = back ? anim::fvalue(1, 0) : anim::fvalue(0, 1); + int delta = st::slideShift; + a_progress = anim::fvalue(0, 1); + if (direction == Window::SlideDirection::FromLeft) { + a_coordUnder = anim::ivalue(0, delta); + a_coordOver = anim::ivalue(-delta, 0); + } else { + a_coordUnder = anim::ivalue(0, -delta); + a_coordOver = anim::ivalue(delta, 0); + } _a_show.start(); - show(); - App::main()->topBar()->update(); - _inner.activate(); + + activate(); } void OverviewWidget::step_show(float64 ms, bool timer) { @@ -2162,8 +2195,8 @@ void OverviewWidget::step_show(float64 ms, bool timer) { a_coordUnder.finish(); a_coordOver.finish(); - a_shadow.finish(); - _cacheUnder = _cacheOver = _cacheTopBarUnder = _cacheTopBarOver = QPixmap(); + a_progress.finish(); + _cacheUnder = _cacheOver = QPixmap(); App::main()->topBar()->stopAnim(); doneShow(); @@ -2172,7 +2205,7 @@ void OverviewWidget::step_show(float64 ms, bool timer) { } else { a_coordUnder.update(dt, st::slideFunction); a_coordOver.update(dt, st::slideFunction); - a_shadow.update(dt, st::slideFunction); + a_progress.update(dt, st::slideFunction); } if (timer) { update(); diff --git a/Telegram/SourceFiles/overviewwidget.h b/Telegram/SourceFiles/overviewwidget.h index 75639b066..c053cb57f 100644 --- a/Telegram/SourceFiles/overviewwidget.h +++ b/Telegram/SourceFiles/overviewwidget.h @@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +#include "window/section_widget.h" + namespace Overview { namespace Layout { @@ -276,7 +278,11 @@ public: int32 countBestScroll() const; void fastShow(bool back = false, int32 lastScrollTop = -1); - void animShow(const QPixmap &oldAnimCache, const QPixmap &bgAnimTopBarCache, bool back = false, int32 lastScrollTop = -1); + bool hasTopBarShadow() const { + return true; + } + void setLastScrollTop(int lastScrollTop); + void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms); void step_show(float64 ms, bool timer); void doneShow(); @@ -302,9 +308,14 @@ public: _inGrab = true; resizeEvent(0); } + void grapWithoutTopBarShadow() { + grabStart(); + _topShadow.hide(); + } void grabFinish() override { _inGrab = false; resizeEvent(0); + _topShadow.show(); } void rpcClear() override { _inner.rpcClear(); @@ -340,9 +351,9 @@ private: QString _header; Animation _a_show; - QPixmap _cacheUnder, _cacheOver, _cacheTopBarUnder, _cacheTopBarOver; + QPixmap _cacheUnder, _cacheOver; anim::ivalue a_coordUnder, a_coordOver; - anim::fvalue a_shadow; + anim::fvalue a_progress; int32 _scrollSetAfterShow; diff --git a/Telegram/SourceFiles/profile/profile_inner_widget.cpp b/Telegram/SourceFiles/profile/profile_inner_widget.cpp index 8a6cf4fc4..49580822b 100644 --- a/Telegram/SourceFiles/profile/profile_inner_widget.cpp +++ b/Telegram/SourceFiles/profile/profile_inner_widget.cpp @@ -44,7 +44,7 @@ void InnerWidget::setVisibleTopBottom(int visibleTop, int visibleBottom) { int notDisplayedAtBottom = height() - _visibleBottom; if (notDisplayedAtBottom > 0) { - decreaseAdditionalHeight(notDisplayedAtBottom); +// decreaseAdditionalHeight(notDisplayedAtBottom); } //loadProfilePhotos(_visibleTop); @@ -65,6 +65,10 @@ void InnerWidget::paintEvent(QPaintEvent *e) { p.fillRect(e->rect(), st::white); } +void InnerWidget::mousePressEvent(QMouseEvent *e) { // TEMP for testing + Ui::showPeerOverview(_peer, OverviewPhotos); +} + int InnerWidget::resizeGetHeight(int newWidth) { _cover->resizeToWidth(newWidth); int newHeight = _cover->height(); diff --git a/Telegram/SourceFiles/profile/profile_inner_widget.h b/Telegram/SourceFiles/profile/profile_inner_widget.h index e91c018ea..66540915f 100644 --- a/Telegram/SourceFiles/profile/profile_inner_widget.h +++ b/Telegram/SourceFiles/profile/profile_inner_widget.h @@ -43,6 +43,7 @@ public: protected: void paintEvent(QPaintEvent *e) override; + void mousePressEvent(QMouseEvent *e) override; // TEMP for testing private: // Resizes content and counts natural widget height for the desired width. diff --git a/Telegram/SourceFiles/profile/profile_section_memento.cpp b/Telegram/SourceFiles/profile/profile_section_memento.cpp new file mode 100644 index 000000000..34f8ab410 --- /dev/null +++ b/Telegram/SourceFiles/profile/profile_section_memento.cpp @@ -0,0 +1,35 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "profile/profile_section_memento.h" + +#include "profile/profile_widget.h" + +namespace Profile { + +Window::SectionWidget *SectionMemento::createWidget(QWidget *parent, const QRect &geometry) const { + auto result = new Widget(parent, _peer); + result->setGeometry(geometry); + result->setInternalState(this); + return result; +} + +} // namespace Profile diff --git a/Telegram/SourceFiles/profile/profile_section_memento.h b/Telegram/SourceFiles/profile/profile_section_memento.h new file mode 100644 index 000000000..b73a1a845 --- /dev/null +++ b/Telegram/SourceFiles/profile/profile_section_memento.h @@ -0,0 +1,44 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "window/section_memento.h" + +namespace Profile { + +class Widget; + +class SectionMemento : public Window::SectionMemento { +public: + SectionMemento(PeerData *peer) : _peer(peer) { + } + + Window::SectionWidget *createWidget(QWidget *parent, const QRect &geometry) const override; + +private: + friend class Widget; + + PeerData *_peer; + int _scrollTop = 0; + +}; + +} // namespace Window diff --git a/Telegram/SourceFiles/profile/profile_widget.cpp b/Telegram/SourceFiles/profile/profile_widget.cpp index 05458068d..af7d1717e 100644 --- a/Telegram/SourceFiles/profile/profile_widget.cpp +++ b/Telegram/SourceFiles/profile/profile_widget.cpp @@ -23,19 +23,25 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "profile/profile_fixed_bar.h" #include "profile/profile_inner_widget.h" +#include "profile/profile_section_memento.h" #include "mainwindow.h" #include "application.h" namespace Profile { -Widget::Widget(QWidget *parent, PeerData *peer) : TWidget(parent) +Widget::Widget(QWidget *parent, PeerData *peer) : Window::SectionWidget(parent) , _fixedBar(this, peer) +, _fixedBarShadow(this, st::shadowColor) , _scroll(this, st::setScroll) , _inner(this, peer) { _fixedBar->move(0, 0); _fixedBar->resizeToWidth(width()); _fixedBar->show(); + _fixedBarShadow->setMode(ToggleableShadow::Mode::HiddenFast); + _fixedBarShadow->raise(); + updateAdaptiveLayout(); + _scroll->setWidget(_inner); _scroll->move(0, _fixedBar->height()); _scroll->show(); @@ -44,86 +50,85 @@ Widget::Widget(QWidget *parent, PeerData *peer) : TWidget(parent) connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll())); } +void Widget::updateAdaptiveLayout() { + _fixedBarShadow->moveToLeft(Adaptive::OneColumn() ? 0 : st::lineWidth, _fixedBar->height()); +} + PeerData *Widget::peer() const { return _inner->peer(); } -void Widget::setGeometryWithTopMoved(const QRect &newGeometry, int topDelta) { - _topDelta = topDelta; - bool willBeResized = (size() != newGeometry.size()); - if (geometry() != newGeometry) { - setGeometry(newGeometry); - } - if (!willBeResized) { - resizeEvent(nullptr); - } - _topDelta = 0; -} - -void Widget::showAnimated(SlideDirection direction, const QPixmap &oldContentCache) { - _showAnimation = nullptr; - - showChildren(); - _fixedBar->setAnimatingMode(false); - auto myContentCache = myGrab(this); - hideChildren(); - _fixedBar->setAnimatingMode(true); - - _showAnimation = std_::make_unique(); - _showAnimation->setDirection(direction); - _showAnimation->setRepaintCallback(func(this, &Widget::repaintCallback)); - _showAnimation->setFinishedCallback(func(this, &Widget::showFinished)); - _showAnimation->setPixmaps(oldContentCache, myContentCache); - _showAnimation->start(); - - show(); +QPixmap Widget::grabForShowAnimation(const Window::SectionSlideParams ¶ms) { + if (params.withTopBarShadow) _fixedBarShadow->hide(); + auto result = myGrab(this); + if (params.withTopBarShadow) _fixedBarShadow->show(); + return result; } void Widget::setInnerFocus() { _inner->setFocus(); } +bool Widget::showInternal(Window::SectionMemento *memento) { + if (auto profileMemento = dynamic_cast(memento)) { + if (profileMemento->_peer == peer()) { + // Perhaps no need to do that?.. + _scroll->scrollToY(profileMemento->_scrollTop); + + return true; + } + } + return false; +} + +void Widget::setInternalState(const SectionMemento *memento) { + myEnsureResized(this); + _scroll->scrollToY(memento->_scrollTop); + _fixedBarShadow->setMode(memento->_scrollTop > 0 ? ToggleableShadow::Mode::ShownFast : ToggleableShadow::Mode::HiddenFast); +} + +std_::unique_ptr Widget::createMemento() const { + auto result = std_::make_unique(peer()); + result->_scrollTop = _scroll->scrollTop(); + return std_::move(result); +} + void Widget::resizeEvent(QResizeEvent *e) { - int newScrollTop = _scroll->scrollTop() + _topDelta; + if (!width() || !height()) { + return; + } + + int newScrollTop = _scroll->scrollTop() + topDelta(); _fixedBar->resizeToWidth(width()); + _fixedBarShadow->resize(width(), st::lineWidth); QSize scrollSize(width(), height() - _fixedBar->height()); if (_scroll->size() != scrollSize) { _scroll->resize(scrollSize); - _inner->resizeToWidth(scrollSize.width(), _scroll->height()); + _inner->resizeToWidth(scrollSize.width(), _scroll->height() * 2); } if (!_scroll->isHidden()) { - if (_topDelta) { + if (topDelta()) { _scroll->scrollToY(newScrollTop); } int scrollTop = _scroll->scrollTop(); _inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height()); - } -} - -void Widget::paintEvent(QPaintEvent *e) { - if (Ui::skipPaintEvent(this, e)) return; - - if (_showAnimation) { - Painter p(this); - _showAnimation->paintContents(p, e->rect()); + _fixedBarShadow->setMode((scrollTop > 0) ? ToggleableShadow::Mode::Shown : ToggleableShadow::Mode::Hidden); } } void Widget::onScroll() { int scrollTop = _scroll->scrollTop(); _inner->setVisibleTopBottom(scrollTop, scrollTop + _scroll->height()); + _fixedBarShadow->setMode((scrollTop > 0) ? ToggleableShadow::Mode::Shown : ToggleableShadow::Mode::Hidden); } -void Widget::showFinished() { - if (isHidden()) return; +void Widget::showAnimatedHook() { + _fixedBar->setAnimatingMode(true); +} - App::app()->mtpUnpause(); - - showChildren(); +void Widget::showFinishedHook() { _fixedBar->setAnimatingMode(false); - - setInnerFocus(); } } // namespace Profile diff --git a/Telegram/SourceFiles/profile/profile_widget.h b/Telegram/SourceFiles/profile/profile_widget.h index cb27e3fcf..c509f7f4d 100644 --- a/Telegram/SourceFiles/profile/profile_widget.h +++ b/Telegram/SourceFiles/profile/profile_widget.h @@ -20,53 +20,57 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "ui/slide_animation.h" +#include "window/section_widget.h" class ScrollArea; namespace Profile { +class SectionMemento; class InnerWidget; class FixedBar; -class Widget final : public TWidget { +class Widget final : public Window::SectionWidget { Q_OBJECT public: Widget(QWidget *parent, PeerData *peer); PeerData *peer() const; + PeerData *peerForDialogs() const override { + return peer(); + } - // When resizing the widget with top edge moved up or down and we - // want to add this top movement to the scroll position, so inner - // content will not move. - void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta); + bool hasTopBarShadow() const override { + return _fixedBarShadow->isFullyShown(); + } - void showAnimated(SlideDirection direction, const QPixmap &oldContentCache); + QPixmap grabForShowAnimation(const Window::SectionSlideParams ¶ms) override; - void setInnerFocus(); + void setInnerFocus() override; + + void updateAdaptiveLayout() override; + + bool showInternal(Window::SectionMemento *memento) override; + std_::unique_ptr createMemento() const override; + + void setInternalState(const SectionMemento *memento); protected: void resizeEvent(QResizeEvent *e) override; - void paintEvent(QPaintEvent *e) override; + + void showAnimatedHook() override; + void showFinishedHook() override; private slots: void onScroll(); private: - // QWidget::update() method is overloaded and we need template deduction. - void repaintCallback() { - update(); - } - void showFinished(); + friend class SectionMemento; - ChildWidget _fixedBar; ChildWidget _scroll; ChildWidget _inner; - - std_::unique_ptr _showAnimation; - - // Saving here topDelta in resizeWithTopMoved() to get it passed to resizeEvent(). - int _topDelta = 0; + ChildWidget _fixedBar; + ChildWidget _fixedBarShadow; }; diff --git a/Telegram/SourceFiles/profilewidget.cpp b/Telegram/SourceFiles/profilewidget.cpp index 6cd270599..986fe86c5 100644 --- a/Telegram/SourceFiles/profilewidget.cpp +++ b/Telegram/SourceFiles/profilewidget.cpp @@ -1170,7 +1170,7 @@ void ProfileInner::mousePressEvent(QMouseEvent *e) { _kickDown = _kickOver; update(); } else if (_selectedRow >= 0 && _selectedRow < _participants.size()) { - App::main()->showPeerProfile(_participants[_selectedRow]); + Ui::showPeerProfile(_participants[_selectedRow]); } else if (QRect(_left, st::profilePadding.top(), st::setPhotoSize, st::setPhotoSize).contains(e->pos())) { if (_photoLink) { _photoLink->onClick(e->button()); diff --git a/Telegram/SourceFiles/structs.cpp b/Telegram/SourceFiles/structs.cpp index b42abb395..d1355380e 100644 --- a/Telegram/SourceFiles/structs.cpp +++ b/Telegram/SourceFiles/structs.cpp @@ -1502,7 +1502,7 @@ void PeerOpenClickHandler::onClickImpl() const { Ui::showPeerHistory(peer(), ShowAtUnreadMsgId); } } else { - App::main()->showPeerProfile(peer()); + Ui::showPeerProfile(peer()); } } } diff --git a/Telegram/SourceFiles/ui/animation.h b/Telegram/SourceFiles/ui/animation.h index d7c3e4a14..71796e7b3 100644 --- a/Telegram/SourceFiles/ui/animation.h +++ b/Telegram/SourceFiles/ui/animation.h @@ -365,7 +365,7 @@ public: using Callback = Function; - SimpleAnimation() : _data(0) { + SimpleAnimation() { } bool animating(uint64 ms) { @@ -376,7 +376,7 @@ public: return false; } - bool isNull() { + bool isNull() const { return !_data; } @@ -384,6 +384,10 @@ public: return _data ? _data->a.current() : typename AnimType::Type(); } + typename AnimType::Type current(const typename AnimType::Type &def) { + return _data ? _data->a.current() : def; + } + typename AnimType::Type current(uint64 ms, const typename AnimType::Type &def) { return animating(ms) ? current() : def; } @@ -405,6 +409,17 @@ public: } } + void finish() { + if (isNull()) { + return; + } + + _data->a.finish(); + _data->_a.stop(); + delete _data; + _data = nullptr; + } + ~SimpleAnimation() { deleteAndMark(_data); } @@ -424,7 +439,7 @@ private: float64 duration; anim::transition transition; }; - Data *_data; + Data *_data = nullptr; void step(float64 ms, bool timer) { float64 dt = (ms >= _data->duration) ? 1 : (ms / _data->duration); @@ -439,15 +454,15 @@ private: } if (!_data->_a.animating()) { delete _data; - _data = 0; + _data = nullptr; } } }; -typedef SimpleAnimation FloatAnimation; -typedef SimpleAnimation IntAnimation; -typedef SimpleAnimation ColorAnimation; +using FloatAnimation = SimpleAnimation; +using IntAnimation = SimpleAnimation; +using ColorAnimation = SimpleAnimation; #define EnsureAnimation(animation, from, callback) if ((animation).isNull()) { (animation).setup((from), (callback)); } diff --git a/Telegram/SourceFiles/ui/twidget.cpp b/Telegram/SourceFiles/ui/twidget.cpp index cb3ea81b7..fcccb15a6 100644 --- a/Telegram/SourceFiles/ui/twidget.cpp +++ b/Telegram/SourceFiles/ui/twidget.cpp @@ -77,3 +77,45 @@ QPixmap myGrab(TWidget *target, QRect rect) { return result; } + +enum class Mode { + Shown, + ShownFast, + Hidden, + HiddenFast +}; +void ToggleableShadow::setMode(Mode mode) { + if (mode == Mode::ShownFast || mode == Mode::HiddenFast) { + if (!_a_opacity.isNull()) { + _a_opacity.finish(); + update(); + } + } + if (_shown && (mode == Mode::Hidden || mode == Mode::HiddenFast)) { + _shown = false; + if (mode == Mode::Hidden) { + if (_a_opacity.isNull()) { + _a_opacity.setup(1., func(this, &ToggleableShadow::repaintCallback)); + } + _a_opacity.start(0., st::shadowToggleDuration); + } + } else if (!_shown && (mode == Mode::Shown || mode == Mode::ShownFast)) { + _shown = true; + if (mode == Mode::Shown) { + if (_a_opacity.isNull()) { + _a_opacity.setup(0., func(this, &ToggleableShadow::repaintCallback)); + } + _a_opacity.start(1., st::shadowToggleDuration); + } + } +} + +void ToggleableShadow::paintEvent(QPaintEvent *e) { + Painter p(this); + if (_a_opacity.animating(getms())) { + p.setOpacity(_a_opacity.current()); + } else if (!_shown) { + return; + } + p.fillRect(e->rect(), _color); +} diff --git a/Telegram/SourceFiles/ui/twidget.h b/Telegram/SourceFiles/ui/twidget.h index 3af3f6ec9..7b6935568 100644 --- a/Telegram/SourceFiles/ui/twidget.h +++ b/Telegram/SourceFiles/ui/twidget.h @@ -208,7 +208,9 @@ class PlainShadow : public TWidget { public: PlainShadow(QWidget *parent, const style::color &color) : TWidget(parent), _color(color) { } - void paintEvent(QPaintEvent *e) { + +protected: + void paintEvent(QPaintEvent *e) override { Painter(this).fillRect(e->rect(), _color->b); } @@ -217,6 +219,37 @@ private: }; +class ToggleableShadow : public TWidget { +public: + ToggleableShadow(QWidget *parent, const style::color &color) : TWidget(parent), _color(color) { + } + + enum class Mode { + Shown, + ShownFast, + Hidden, + HiddenFast + }; + void setMode(Mode mode); + + bool isFullyShown() const { + return _shown && _a_opacity.isNull(); + } + +protected: + void paintEvent(QPaintEvent *e) override; + +private: + void repaintCallback() { + update(); + } + + const style::color &_color; + FloatAnimation _a_opacity; + bool _shown = true; + +}; + class SingleDelayedCall : public QObject { Q_OBJECT diff --git a/Telegram/SourceFiles/window/section_memento.h b/Telegram/SourceFiles/window/section_memento.h new file mode 100644 index 000000000..2d2e6ae09 --- /dev/null +++ b/Telegram/SourceFiles/window/section_memento.h @@ -0,0 +1,33 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +namespace Window { + +class SectionWidget; + +class SectionMemento { +public: + virtual SectionWidget *createWidget(QWidget *parent, const QRect &geometry) const = 0; + +}; + +} // namespace Window diff --git a/Telegram/SourceFiles/window/section_widget.cpp b/Telegram/SourceFiles/window/section_widget.cpp new file mode 100644 index 000000000..f9c3a1454 --- /dev/null +++ b/Telegram/SourceFiles/window/section_widget.cpp @@ -0,0 +1,82 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#include "stdafx.h" +#include "window/section_widget.h" + +#include "application.h" + +namespace Window { + +SectionWidget::SectionWidget(QWidget *parent) : TWidget(parent) { +} + +void SectionWidget::setGeometryWithTopMoved(const QRect &newGeometry, int topDelta) { + _topDelta = topDelta; + bool willBeResized = (size() != newGeometry.size()); + if (geometry() != newGeometry) { + setGeometry(newGeometry); + } + if (!willBeResized) { + resizeEvent(nullptr); + } + _topDelta = 0; +} + +void SectionWidget::showAnimated(SlideDirection direction, const SectionSlideParams ¶ms) { + t_assert(_showAnimation == nullptr); + + showChildren(); + auto myContentCache = grabForShowAnimation(params); + hideChildren(); + showAnimatedHook(); + + _showAnimation = std_::make_unique(); + _showAnimation->setDirection(direction); + _showAnimation->setRepaintCallback(func(this, &SectionWidget::repaintCallback)); + _showAnimation->setFinishedCallback(func(this, &SectionWidget::showFinished)); + _showAnimation->setPixmaps(params.oldContentCache, myContentCache); + _showAnimation->setTopBarShadow(params.withTopBarShadow); + _showAnimation->start(); + + show(); +} + +void SectionWidget::paintEvent(QPaintEvent *e) { + if (Ui::skipPaintEvent(this, e)) return; + + if (_showAnimation) { + Painter p(this); + _showAnimation->paintContents(p, e->rect()); + } +} + +void SectionWidget::showFinished() { + if (isHidden()) return; + + App::app()->mtpUnpause(); + + showChildren(); + showFinishedHook(); + + setInnerFocus(); +} + +} // namespace Window diff --git a/Telegram/SourceFiles/window/section_widget.h b/Telegram/SourceFiles/window/section_widget.h new file mode 100644 index 000000000..be34fd924 --- /dev/null +++ b/Telegram/SourceFiles/window/section_widget.h @@ -0,0 +1,108 @@ +/* +This file is part of Telegram Desktop, +the official desktop version of Telegram messaging app, see https://telegram.org + +Telegram Desktop is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +It is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +In addition, as a special exception, the copyright holders give permission +to link the code of portions of this program with the OpenSSL library. + +Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE +Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org +*/ +#pragma once + +#include "ui/twidget.h" +#include "window/slide_animation.h" + +namespace Window { + +class SectionMemento; + +struct SectionSlideParams { + QPixmap oldContentCache; + bool withTopBarShadow = false; +}; + +class SectionWidget : public TWidget { + Q_OBJECT + +public: + + SectionWidget(QWidget *parent); + + virtual PeerData *peerForDialogs() const { + return nullptr; + } + + // When resizing the widget with top edge moved up or down and we + // want to add this top movement to the scroll position, so inner + // content will not move. + void setGeometryWithTopMoved(const QRect &newGeometry, int topDelta); + + virtual bool hasTopBarShadow() const { + return false; + } + void showAnimated(SlideDirection direction, const SectionSlideParams ¶ms); + + // This can be used to grab with or without top bar shadow. + // This will be protected when animation preparation will be done inside. + virtual QPixmap grabForShowAnimation(const SectionSlideParams ¶ms) { + return myGrab(this); + } + + // Attempt to show the required section inside the existing one. + // For example if this section already shows exactly the required + // memento it can simply return true - it is shown already. + virtual bool showInternal(SectionMemento *memento) = 0; + + // Create a memento of that section to store it in the history stack. + virtual std_::unique_ptr createMemento() const = 0; + + virtual void setInnerFocus() { + setFocus(); + } + + virtual void updateAdaptiveLayout() { + } + +protected: + void paintEvent(QPaintEvent *e) override; + + // Temp variable used in resizeEvent() implementation, that is passed + // to setGeometryWithTopMoved() to adjust the scroll position with the resize. + int topDelta() const { + return _topDelta; + } + + // Called after the hideChildren() call in showAnimated(). + virtual void showAnimatedHook() { + } + + // Called after the showChildren() call in showFinished(). + virtual void showFinishedHook() { + } + +private: + // QWidget::update() method is overloaded and we need template deduction. + void repaintCallback() { + update(); + } + void showFinished(); + + std_::unique_ptr _showAnimation; + + // Saving here topDelta in resizeWithTopMoved() to get it passed to resizeEvent(). + int _topDelta = 0; + +}; + +} // namespace Window diff --git a/Telegram/SourceFiles/ui/slide_animation.cpp b/Telegram/SourceFiles/window/slide_animation.cpp similarity index 83% rename from Telegram/SourceFiles/ui/slide_animation.cpp rename to Telegram/SourceFiles/window/slide_animation.cpp index 266a1ad16..4aec4bf78 100644 --- a/Telegram/SourceFiles/ui/slide_animation.cpp +++ b/Telegram/SourceFiles/window/slide_animation.cpp @@ -19,17 +19,20 @@ Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #include "stdafx.h" -#include "ui/slide_animation.h" +#include "window/slide_animation.h" + +namespace Window { SlideAnimation::SlideAnimation() -: _animation(animation(this, &SlideAnimation::step)) { + : _animation(animation(this, &SlideAnimation::step)) { } void SlideAnimation::paintContents(Painter &p, const QRect &update) const { + int retina = cIntRetinaFactor(); + _animation.step(getms()); if (a_progress.current() < 1) { p.fillRect(update, st::white); - int retina = cIntRetinaFactor(); int underLeft = a_coordUnder.current(); int underWidth = _cacheUnder.width() / retina; int underHeight = _cacheUnder.height() / retina; @@ -40,6 +43,11 @@ void SlideAnimation::paintContents(Painter &p, const QRect &update) const { p.setOpacity(a_progress.current()); } p.drawPixmap(a_coordOver.current(), 0, _cacheOver); + + if (_topBarShadowEnabled) { + p.setOpacity(1); + p.fillRect(0, st::topBarHeight, _cacheOver.width() / retina, st::lineWidth, st::shadowColor); + } } void SlideAnimation::setDirection(SlideDirection direction) { @@ -51,6 +59,10 @@ void SlideAnimation::setPixmaps(const QPixmap &oldContentCache, const QPixmap &n _cacheOver = newContentCache; } +void SlideAnimation::setTopBarShadow(bool enabled) { + _topBarShadowEnabled = enabled; +} + void SlideAnimation::setRepaintCallback(RepaintCallback &&callback) { _repaintCallback = std_::move(callback); } @@ -60,13 +72,11 @@ void SlideAnimation::setFinishedCallback(FinishedCallback &&callback) { } void SlideAnimation::start() { - int width = _cacheUnder.width() / cIntRetinaFactor(); int delta = st::slideShift; a_progress = anim::fvalue(0, 1); if (_direction == SlideDirection::FromLeft) { - std::swap(_cacheUnder, _cacheOver); - a_coordUnder = anim::ivalue(-delta, 0); - a_coordOver = anim::ivalue(0, delta); + a_coordUnder = anim::ivalue(0, delta); + a_coordOver = anim::ivalue(-delta, 0); } else { a_coordUnder = anim::ivalue(0, -delta); a_coordOver = anim::ivalue(delta, 0); @@ -75,7 +85,7 @@ void SlideAnimation::start() { } void SlideAnimation::step(float64 ms, bool timer) { - float64 dt = ms / 3000;// st::slideDuration; + float64 dt = ms / st::slideDuration; if (dt >= 1) { dt = 1; if (timer) { @@ -95,3 +105,5 @@ void SlideAnimation::step(float64 ms, bool timer) { _repaintCallback.call(); } } + +} // namespace Window diff --git a/Telegram/SourceFiles/ui/slide_animation.h b/Telegram/SourceFiles/window/slide_animation.h similarity index 93% rename from Telegram/SourceFiles/ui/slide_animation.h rename to Telegram/SourceFiles/window/slide_animation.h index 0739cb081..5ce4068ae 100644 --- a/Telegram/SourceFiles/ui/slide_animation.h +++ b/Telegram/SourceFiles/window/slide_animation.h @@ -20,6 +20,8 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once +namespace Window { + enum class SlideDirection { FromRight, FromLeft, @@ -33,6 +35,7 @@ public: void setDirection(SlideDirection direction); void setPixmaps(const QPixmap &oldContentCache, const QPixmap &newContentCache); + void setTopBarShadow(bool enabled); using RepaintCallback = Function; void setRepaintCallback(RepaintCallback &&callback); @@ -46,6 +49,7 @@ private: void step(float64 ms, bool timer); SlideDirection _direction = SlideDirection::FromRight; + bool _topBarShadowEnabled = false; mutable Animation _animation; QPixmap _cacheUnder, _cacheOver; @@ -56,3 +60,5 @@ private: FinishedCallback _finishedCallback; }; + +} // namespace Window diff --git a/Telegram/SourceFiles/window/top_bar_widget.cpp b/Telegram/SourceFiles/window/top_bar_widget.cpp index 0b1fe6e49..c175611f0 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.cpp +++ b/Telegram/SourceFiles/window/top_bar_widget.cpp @@ -81,17 +81,17 @@ void TopBarWidget::onClearSelection() { void TopBarWidget::onInfoClicked() { PeerData *p = App::main() ? App::main()->historyPeer() : 0; - if (p) App::main()->showPeerProfile(p); + if (p) Ui::showPeerProfile(p); } void TopBarWidget::onAddContact() { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; UserData *u = p ? p->asUser() : 0; if (u) Ui::showLayer(new AddContactBox(u->firstName, u->lastName, u->phone.isEmpty() ? App::phoneFromSharedContact(peerToUser(u->id)) : u->phone)); } void TopBarWidget::onEdit() { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; if (p) { if (p->isChannel()) { Ui::showLayer(new EditChannelBox(p->asChannel())); @@ -104,7 +104,7 @@ void TopBarWidget::onEdit() { } void TopBarWidget::onDeleteContact() { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; UserData *u = p ? p->asUser() : 0; if (u) { ConfirmBox *box = new ConfirmBox(lng_sure_delete_contact(lt_contact, p->name), lang(lng_box_delete)); @@ -114,7 +114,7 @@ void TopBarWidget::onDeleteContact() { } void TopBarWidget::onDeleteContactSure() { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; UserData *u = p ? p->asUser() : 0; if (u) { Ui::showChatsList(); @@ -124,7 +124,7 @@ void TopBarWidget::onDeleteContactSure() { } void TopBarWidget::onDeleteAndExit() { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; ChatData *c = p ? p->asChat() : 0; if (c) { ConfirmBox *box = new ConfirmBox(lng_sure_delete_and_exit(lt_group, p->name), lang(lng_box_leave), st::attentionBoxButton); @@ -134,7 +134,7 @@ void TopBarWidget::onDeleteAndExit() { } void TopBarWidget::onDeleteAndExitSure() { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; ChatData *c = p ? p->asChat() : 0; if (c) { Ui::showChatsList(); @@ -181,22 +181,28 @@ void TopBarWidget::step_appearance(float64 ms, bool timer) { void TopBarWidget::paintEvent(QPaintEvent *e) { Painter p(this); - if (e->rect().top() < st::topBarHeight) { // optimize shadow-only drawing - p.fillRect(QRect(0, 0, width(), st::topBarHeight), st::topBarBG->b); - if (_clearSelection->isHidden()) { - p.save(); - main()->paintTopBar(p, a_over.current(), _info->isHidden() ? 0 : _info->width()); - p.restore(); - } else { - p.setFont(st::linkFont->f); - p.setPen(st::btnDefLink.color->p); - p.drawText(_selStrLeft, st::topBarButton.textTop + st::linkFont->ascent, _selStr); + p.fillRect(QRect(0, 0, width(), st::topBarHeight), st::topBarBG->b); + if (_clearSelection->isHidden()) { + p.save(); + int decreaseWidth = 0; + if (!_info->isHidden()) { + decreaseWidth += _info->width(); + decreaseWidth -= st::topBarForwardPadding.right(); } + if (!_search->isHidden()) { + decreaseWidth += _search->width(); + } + main()->paintTopBar(p, a_over.current(), decreaseWidth); + p.restore(); + } else { + p.setFont(st::linkFont); + p.setPen(st::btnDefLink.color); + p.drawText(_selStrLeft, st::topBarButton.textTop + st::linkFont->ascent, _selStr); } } void TopBarWidget::mousePressEvent(QMouseEvent *e) { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; if (e->button() == Qt::LeftButton && e->pos().y() < st::topBarHeight && (p || !_selCount)) { emit clicked(); } @@ -289,7 +295,7 @@ void TopBarWidget::showAll() { resizeEvent(0); return; } - PeerData *p = App::main() ? App::main()->profilePeer() : 0, *h = App::main() ? App::main()->historyPeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0; + PeerData *p = nullptr/*App::main() ? App::main()->profilePeer() : 0*/, *h = App::main() ? App::main()->historyPeer() : 0, *o = App::main() ? App::main()->overviewPeer() : 0; if (p && (p->isChat() || (p->isUser() && (p->asUser()->contact >= 0 || !App::phoneFromSharedContact(peerToUser(p->id)).isEmpty())))) { if (p->isChat()) { if (p->asChat()->canEdit()) { @@ -362,7 +368,7 @@ void TopBarWidget::showAll() { } void TopBarWidget::showSelected(uint32 selCount, bool canDelete) { - PeerData *p = App::main() ? App::main()->profilePeer() : 0; + PeerData *p = nullptr;// App::main() ? App::main()->profilePeer() : 0; _selPeer = App::main()->overviewPeer() ? App::main()->overviewPeer() : App::main()->peer(); _selCount = selCount; _canDelete = canDelete; diff --git a/Telegram/SourceFiles/window/top_bar_widget.h b/Telegram/SourceFiles/window/top_bar_widget.h index 69c416e50..ae428cf0d 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.h +++ b/Telegram/SourceFiles/window/top_bar_widget.h @@ -27,7 +27,6 @@ class PeerAvatarButton; } // namespace Ui class FlatButton; class IconedButton; -class PlainShadow; namespace Window { diff --git a/Telegram/Telegram.vcxproj b/Telegram/Telegram.vcxproj index 3e80efccd..b96571968 100644 --- a/Telegram/Telegram.vcxproj +++ b/Telegram/Telegram.vcxproj @@ -429,6 +429,10 @@ true true + + true + true + true true @@ -736,6 +740,10 @@ true true + + true + true + true true @@ -1069,6 +1077,10 @@ true true + + true + true + true true @@ -1190,6 +1202,7 @@ + true @@ -1239,7 +1252,6 @@ - @@ -1253,6 +1265,8 @@ + + NotUsing @@ -1513,6 +1527,7 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/profile/profile_fixed_bar.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + @@ -1675,7 +1690,6 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" "-fstdafx.h" "-f../../SourceFiles/ui/twidget.h" - @@ -1714,6 +1728,22 @@ .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" "-fstdafx.h" "-f../../SourceFiles/window/top_bar_widget.h" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing section_widget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/window/section_widget.h" -DAL_LIBTYPE_STATIC -DCUSTOM_API_ID -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing section_widget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/window/section_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl_debug\Debug\include" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing section_widget.h... + .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" "-fstdafx.h" "-f../../SourceFiles/window/section_widget.h" -DAL_LIBTYPE_STATIC -DUNICODE -DWIN32 -DWIN64 -DHAVE_STDINT_H -DZLIB_WINAPI -DQT_NO_DEBUG -DNDEBUG -D_SCL_SECURE_NO_WARNINGS "-I.\SourceFiles" "-I.\GeneratedFiles" "-I.\GeneratedFiles\$(ConfigurationName)\." "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtCore\5.6.0\QtCore" "-I$(QTDIR)\include\QtGui\5.6.0\QtGui" "-I.\..\..\Libraries\breakpad\src" "-I.\..\..\Libraries\lzma\C" "-I.\..\..\Libraries\libexif-0.6.20" "-I.\..\..\Libraries\zlib-1.2.8" "-I.\..\..\Libraries\ffmpeg" "-I.\..\..\Libraries\openal-soft\include" "-I.\ThirdParty\minizip" "-I.\..\..\Libraries\openssl\Release\include" + + + diff --git a/Telegram/Telegram.vcxproj.filters b/Telegram/Telegram.vcxproj.filters index 807393a2c..0fec8a251 100644 --- a/Telegram/Telegram.vcxproj.filters +++ b/Telegram/Telegram.vcxproj.filters @@ -1119,9 +1119,6 @@ GeneratedFiles\Release - - SourceFiles\ui - GeneratedFiles\Deploy @@ -1173,6 +1170,24 @@ GeneratedFiles\Release + + SourceFiles\window + + + GeneratedFiles\Deploy + + + GeneratedFiles\Debug + + + GeneratedFiles\Release + + + SourceFiles\window + + + SourceFiles\profile + @@ -1346,12 +1361,18 @@ Resources\winrc - - SourceFiles\ui - GeneratedFiles\styles + + SourceFiles\window + + + SourceFiles\window + + + SourceFiles\profile + @@ -1609,6 +1630,9 @@ Resources + + SourceFiles\window +