diff --git a/Telegram/SourceFiles/info/info_layer_wrap.cpp b/Telegram/SourceFiles/info/info_layer_wrap.cpp index 5038a8b4f7..52f16bf3fe 100644 --- a/Telegram/SourceFiles/info/info_layer_wrap.cpp +++ b/Telegram/SourceFiles/info/info_layer_wrap.cpp @@ -27,12 +27,18 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org #include "window/section_widget.h" #include "window/window_controller.h" #include "window/main_window.h" +#include "auth_session.h" #include "styles/style_info.h" #include "styles/style_settings.h" #include "styles/style_window.h" #include "styles/style_boxes.h" namespace Info { +namespace { + +constexpr auto kThirdSectionInfoTimeoutMs = 1000; + +} // namespace LayerWrap::LayerWrap( not_null controller, @@ -98,29 +104,40 @@ void LayerWrap::showFinished() { void LayerWrap::parentResized() { auto parentSize = parentWidget()->size(); - auto windowWidth = parentSize.width(); - if (windowWidth < MinimalSupportedWidth()) { - hide(); - setParent(nullptr); + auto parentWidth = parentSize.width(); + if (parentWidth < MinimalSupportedWidth()) { auto localCopy = _controller; - localCopy->showSection( - MoveMemento(std::move(_content), Wrap::Narrow)); + auto memento = MoveMemento(std::move(_content), Wrap::Narrow); localCopy->hideSpecialLayer(LayerOption::ForceFast); + localCopy->showSection(std::move(memento)); + } else if (_controller->canShowThirdSectionWithoutResize()) { + takeToThirdSection(); } else { auto newWidth = qMin( - windowWidth - 2 * st::infoMinimalLayerMargin, + parentWidth - 2 * st::infoMinimalLayerMargin, st::infoDesiredWidth); resizeToWidth(newWidth); } } +bool LayerWrap::takeToThirdSection() { + auto localCopy = _controller; + auto memento = MoveMemento(std::move(_content), Wrap::Side); + localCopy->hideSpecialLayer(LayerOption::ForceFast); + + Auth().data().setThirdSectionInfoEnabled(true); + Auth().saveDataDelayed(kThirdSectionInfoTimeoutMs); + localCopy->showSection(std::move(memento)); + return true; +} + int LayerWrap::MinimalSupportedWidth() { auto minimalMargins = 2 * st::infoMinimalLayerMargin; return st::infoMinimalWidth + minimalMargins; } int LayerWrap::resizeGetHeight(int newWidth) { - if (!parentWidget()) { + if (!parentWidget() || !_content) { return 0; } diff --git a/Telegram/SourceFiles/info/info_layer_wrap.h b/Telegram/SourceFiles/info/info_layer_wrap.h index 88bd86e38f..e89c746835 100644 --- a/Telegram/SourceFiles/info/info_layer_wrap.h +++ b/Telegram/SourceFiles/info/info_layer_wrap.h @@ -45,6 +45,8 @@ public: void showFinished() override; void parentResized() override; + bool takeToThirdSection() override; + static int MinimalSupportedWidth(); protected: diff --git a/Telegram/SourceFiles/info/info_side_wrap.cpp b/Telegram/SourceFiles/info/info_side_wrap.cpp index 29494ce7ee..cfc308662c 100644 --- a/Telegram/SourceFiles/info/info_side_wrap.cpp +++ b/Telegram/SourceFiles/info/info_side_wrap.cpp @@ -236,6 +236,11 @@ void SideWrap::setCurrentTab(Tab tab) { void SideWrap::resizeEvent(QResizeEvent *e) { if (_tabs) { _tabs->resizeToWidth(width()); + _tabsShadow->setGeometry( + 0, + _tabs->height() - st::lineWidth, + width(), + st::lineWidth); } if (_content) { _content->setGeometry(contentGeometry()); diff --git a/Telegram/SourceFiles/layerwidget.cpp b/Telegram/SourceFiles/layerwidget.cpp index 93ed128a27..d611dab923 100644 --- a/Telegram/SourceFiles/layerwidget.cpp +++ b/Telegram/SourceFiles/layerwidget.cpp @@ -54,6 +54,7 @@ public: void setLayerBoxes(const QRect &specialLayerBox, const QRect &layerBox); void setCacheImages(QPixmap &&bodyCache, QPixmap &&mainMenuCache, QPixmap &&specialLayerCache, QPixmap &&layerCache); void startAnimation(Action action); + void skipAnimation(Action action); void finishAnimation(); bool animating() const { @@ -129,6 +130,11 @@ void LayerStackWidget::BackgroundWidget::startAnimation(Action action) { checkIfDone(); } +void LayerStackWidget::BackgroundWidget::skipAnimation(Action action) { + startAnimation(action); + finishAnimation(); +} + void LayerStackWidget::BackgroundWidget::checkIfDone() { if (!_wasAnimating || _inPaintEvent || animating()) { return; @@ -346,37 +352,37 @@ bool LayerWidget::overlaps(const QRect &globalRect) { void LayerStackWidget::keyPressEvent(QKeyEvent *e) { if (e->key() == Qt::Key_Escape) { - hideCurrent(); + hideCurrent(LayerOption::Animated); } } void LayerStackWidget::mousePressEvent(QMouseEvent *e) { - hideCurrent(); + hideCurrent(LayerOption::Animated); } -void LayerStackWidget::hideCurrent() { - return currentLayer() ? hideLayers() : hideAll(); +void LayerStackWidget::hideCurrent(LayerOptions options) { + return currentLayer() ? hideLayers(options) : hideAll(options); } -void LayerStackWidget::hideLayers() { +void LayerStackWidget::hideLayers(LayerOptions options) { startAnimation([] {}, [this] { clearLayers(); - }, Action::HideLayer); + }, Action::HideLayer, options); } -void LayerStackWidget::hideAll() { +void LayerStackWidget::hideAll(LayerOptions options) { startAnimation([] {}, [this] { clearLayers(); clearSpecialLayer(); _mainMenu.destroyDelayed(); - }, Action::HideAll); + }, Action::HideAll, options); } -void LayerStackWidget::hideTopLayer() { +void LayerStackWidget::hideTopLayer(LayerOptions options) { if (_specialLayer) { - hideLayers(); + hideLayers(options); } else { - hideAll(); + hideAll(options); } } @@ -424,10 +430,10 @@ void LayerStackWidget::onLayerClosed(LayerWidget *layer) { } layer->deleteLater(); if (layer == _specialLayer) { - hideAll(); + hideAll(LayerOption::Animated); } else if (layer == currentLayer()) { if (_layers.size() == 1) { - hideCurrent(); + hideCurrent(LayerOption::Animated); } else { if (layer->inFocusChain()) setFocus(); layer->hide(); @@ -501,14 +507,25 @@ bool LayerStackWidget::contentOverlapped(const QRect &globalRect) { } template -void LayerStackWidget::startAnimation(SetupNew setupNewWidgets, ClearOld clearOldWidgets, Action action) { +void LayerStackWidget::startAnimation( + SetupNew setupNewWidgets, + ClearOld clearOldWidgets, + Action action, + LayerOptions options) { if (App::quitting()) return; - setupNewWidgets(); - setCacheImages(); - clearOldWidgets(); - prepareForAnimation(); - _background->startAnimation(action); + if (options & LayerOption::ForceFast) { + setupNewWidgets(); + clearOldWidgets(); + prepareForAnimation(); + _background->skipAnimation(action); + } else { + setupNewWidgets(); + setCacheImages(); + clearOldWidgets(); + prepareForAnimation(); + _background->startAnimation(action); + } } void LayerStackWidget::resizeEvent(QResizeEvent *e) { @@ -601,7 +618,7 @@ void LayerStackWidget::showSpecialLayer(object_ptr layer) { }, [this] { clearLayers(); _mainMenu.destroyDelayed(); - }, Action::ShowSpecialLayer); + }, Action::ShowSpecialLayer, LayerOption::Animated); } void LayerStackWidget::showMainMenu() { @@ -612,7 +629,7 @@ void LayerStackWidget::showMainMenu() { }, [this] { clearLayers(); _specialLayer.destroyDelayed(); - }, Action::ShowMainMenu); + }, Action::ShowMainMenu, LayerOption::Animated); } void LayerStackWidget::appendBox(object_ptr box) { @@ -637,7 +654,7 @@ LayerWidget *LayerStackWidget::pushBox(object_ptr box) { } else { startAnimation([] {}, [this] { _mainMenu.destroyDelayed(); - }, Action::ShowLayer); + }, Action::ShowLayer, LayerOption::Animated); } return layer.data(); @@ -653,6 +670,12 @@ void LayerStackWidget::prependBox(object_ptr box) { initChildLayer(layer); } +bool LayerStackWidget::takeToThirdSection() { + return _specialLayer + ? _specialLayer->takeToThirdSection() + : false; +} + void LayerStackWidget::clearLayers() { for (auto layer : base::take(_layers)) { layer->setClosing(); @@ -697,7 +720,7 @@ void LayerStackWidget::sendFakeMouseEvent() { void LayerStackWidget::onLayerDestroyed(QObject *obj) { if (obj == _specialLayer) { _specialLayer = nullptr; - hideAll(); + hideAll(LayerOption::Animated); } else if (obj == currentLayer()) { _layers.pop_back(); if (auto newLayer = currentLayer()) { @@ -707,7 +730,7 @@ void LayerStackWidget::onLayerDestroyed(QObject *obj) { showFinished(); } } else if (!_specialLayer) { - hideAll(); + hideAll(LayerOption::Animated); } } else { for (auto i = _layers.begin(), e = _layers.end(); i != e; ++i) { diff --git a/Telegram/SourceFiles/layerwidget.h b/Telegram/SourceFiles/layerwidget.h index 0e8375e95f..6537314390 100644 --- a/Telegram/SourceFiles/layerwidget.h +++ b/Telegram/SourceFiles/layerwidget.h @@ -52,6 +52,9 @@ public: void setResizedCallback(base::lambda callback) { _resizedCallback = std::move(callback); } + virtual bool takeToThirdSection() { + return false; + } protected: void closeLayer() { @@ -96,15 +99,16 @@ public: void showMainMenu(); void appendBox(object_ptr box); void prependBox(object_ptr box); + bool takeToThirdSection(); bool canSetFocus() const; void setInnerFocus(); bool contentOverlapped(const QRect &globalRect); - void hideLayers(); - void hideAll(); - void hideTopLayer(); + void hideLayers(LayerOptions options); + void hideAll(LayerOptions options); + void hideTopLayer(LayerOptions options); bool layerShown() const; @@ -123,7 +127,7 @@ private slots: private: LayerWidget *pushBox(object_ptr box); void showFinished(); - void hideCurrent(); + void hideCurrent(LayerOptions options); enum class Action { ShowMainMenu, @@ -133,7 +137,11 @@ private: HideAll, }; template - void startAnimation(SetupNew setupNewWidgets, ClearOld clearOldWidgets, Action action); + void startAnimation( + SetupNew setupNewWidgets, + ClearOld clearOldWidgets, + Action action, + LayerOptions options); void prepareForAnimation(); void animationDone(); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 62d876403c..76c7ff77fc 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -3417,7 +3417,8 @@ void MainWidget::updateControlsGeometry() { _dialogs->stopWidthAnimation(); } if (Adaptive::ThreeColumn()) { - if (!_thirdSection) { + if (!_thirdSection + && !_controller->takeThirdSectionFromLayer()) { if (Auth().data().tabbedSelectorSectionEnabled()) { _history->pushTabbedSelectorToThirdSection(); } else if (Auth().data().thirdSectionInfoEnabled()) { diff --git a/Telegram/SourceFiles/mainwindow.cpp b/Telegram/SourceFiles/mainwindow.cpp index d0dd228503..f358007b26 100644 --- a/Telegram/SourceFiles/mainwindow.cpp +++ b/Telegram/SourceFiles/mainwindow.cpp @@ -364,7 +364,7 @@ void MainWindow::destroyLayerDelayed() { void MainWindow::ui_hideSettingsAndLayer(LayerOptions options) { if (_layerBg) { - _layerBg->hideAll(); + _layerBg->hideAll(options); if (options & LayerOption::ForceFast) { destroyLayerDelayed(); } @@ -420,7 +420,7 @@ void MainWindow::ui_showBox( } } else { if (_layerBg) { - _layerBg->hideTopLayer(); + _layerBg->hideTopLayer(options); if ((options & LayerOption::ForceFast) && !_layerBg->layerShown()) { destroyLayerDelayed(); } @@ -721,6 +721,10 @@ void MainWindow::layerFinishedHide(LayerStackWidget *was) { } } +bool MainWindow::takeThirdSectionFromLayer() { + return _layerBg ? _layerBg->takeToThirdSection() : false; +} + void MainWindow::fixOrder() { if (_layerBg) _layerBg->raise(); if (_mediaPreview) _mediaPreview->raise(); diff --git a/Telegram/SourceFiles/mainwindow.h b/Telegram/SourceFiles/mainwindow.h index 4356b8bf40..c598f1a03a 100644 --- a/Telegram/SourceFiles/mainwindow.h +++ b/Telegram/SourceFiles/mainwindow.h @@ -104,6 +104,7 @@ public: void noIntro(Intro::Widget *was); void noLayerStack(LayerStackWidget *was); void layerFinishedHide(LayerStackWidget *was); + bool takeThirdSectionFromLayer(); void checkHistoryActivation(); diff --git a/Telegram/SourceFiles/window/top_bar_widget.cpp b/Telegram/SourceFiles/window/top_bar_widget.cpp index a83719dce7..c34a928a22 100644 --- a/Telegram/SourceFiles/window/top_bar_widget.cpp +++ b/Telegram/SourceFiles/window/top_bar_widget.cpp @@ -44,7 +44,10 @@ constexpr auto kThirdSectionInfoTimeoutMs = 1000; } // namespace -TopBarWidget::TopBarWidget(QWidget *parent, not_null controller) : RpWidget(parent) +TopBarWidget::TopBarWidget( + QWidget *parent, + not_null controller) +: RpWidget(parent) , _controller(controller) , _clearSelection(this, langFactory(lng_selected_clear), st::topBarClearButton) , _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton) diff --git a/Telegram/SourceFiles/window/window_controller.cpp b/Telegram/SourceFiles/window/window_controller.cpp index f4a0b0b315..6bace5dda2 100644 --- a/Telegram/SourceFiles/window/window_controller.cpp +++ b/Telegram/SourceFiles/window/window_controller.cpp @@ -159,6 +159,15 @@ bool Controller::canShowThirdSection() const { return window()->canExtendWidthBy(extendBy); } +bool Controller::canShowThirdSectionWithoutResize() const { + auto currentWidth = computeColumnLayout().bodyWidth; + return currentWidth >= minimalThreeColumnWidth(); +} + +bool Controller::takeThirdSectionFromLayer() { + return App::wnd()->takeThirdSectionFromLayer(); +} + void Controller::resizeForThirdSection() { auto layout = computeColumnLayout(); if (layout.windowLayout == Adaptive::WindowLayout::ThreeColumn) { diff --git a/Telegram/SourceFiles/window/window_controller.h b/Telegram/SourceFiles/window/window_controller.h index 05053a3dd8..cb920bebbf 100644 --- a/Telegram/SourceFiles/window/window_controller.h +++ b/Telegram/SourceFiles/window/window_controller.h @@ -85,6 +85,8 @@ public: int dialogsSmallColumnWidth() const; void updateColumnLayout(); bool canShowThirdSection() const; + bool canShowThirdSectionWithoutResize() const; + bool takeThirdSectionFromLayer(); void resizeForThirdSection(); void closeThirdSection(); void showSection(