Switch Info between columns and layer.

This commit is contained in:
John Preston 2017-09-19 13:32:34 +03:00
parent 3fbb643d51
commit 5586d231de
11 changed files with 116 additions and 41 deletions

View File

@ -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<Window::Controller*> 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;
}

View File

@ -45,6 +45,8 @@ public:
void showFinished() override;
void parentResized() override;
bool takeToThirdSection() override;
static int MinimalSupportedWidth();
protected:

View File

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

View File

@ -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 <typename SetupNew, typename ClearOld>
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<LayerWidget> 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<BoxContent> box) {
@ -637,7 +654,7 @@ LayerWidget *LayerStackWidget::pushBox(object_ptr<BoxContent> box) {
} else {
startAnimation([] {}, [this] {
_mainMenu.destroyDelayed();
}, Action::ShowLayer);
}, Action::ShowLayer, LayerOption::Animated);
}
return layer.data();
@ -653,6 +670,12 @@ void LayerStackWidget::prependBox(object_ptr<BoxContent> 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) {

View File

@ -52,6 +52,9 @@ public:
void setResizedCallback(base::lambda<void()> callback) {
_resizedCallback = std::move(callback);
}
virtual bool takeToThirdSection() {
return false;
}
protected:
void closeLayer() {
@ -96,15 +99,16 @@ public:
void showMainMenu();
void appendBox(object_ptr<BoxContent> box);
void prependBox(object_ptr<BoxContent> 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<BoxContent> box);
void showFinished();
void hideCurrent();
void hideCurrent(LayerOptions options);
enum class Action {
ShowMainMenu,
@ -133,7 +137,11 @@ private:
HideAll,
};
template <typename SetupNew, typename ClearOld>
void startAnimation(SetupNew setupNewWidgets, ClearOld clearOldWidgets, Action action);
void startAnimation(
SetupNew setupNewWidgets,
ClearOld clearOldWidgets,
Action action,
LayerOptions options);
void prepareForAnimation();
void animationDone();

View File

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

View File

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

View File

@ -104,6 +104,7 @@ public:
void noIntro(Intro::Widget *was);
void noLayerStack(LayerStackWidget *was);
void layerFinishedHide(LayerStackWidget *was);
bool takeThirdSectionFromLayer();
void checkHistoryActivation();

View File

@ -44,7 +44,10 @@ constexpr auto kThirdSectionInfoTimeoutMs = 1000;
} // namespace
TopBarWidget::TopBarWidget(QWidget *parent, not_null<Window::Controller*> controller) : RpWidget(parent)
TopBarWidget::TopBarWidget(
QWidget *parent,
not_null<Window::Controller*> controller)
: RpWidget(parent)
, _controller(controller)
, _clearSelection(this, langFactory(lng_selected_clear), st::topBarClearButton)
, _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton)

View File

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

View File

@ -85,6 +85,8 @@ public:
int dialogsSmallColumnWidth() const;
void updateColumnLayout();
bool canShowThirdSection() const;
bool canShowThirdSectionWithoutResize() const;
bool takeThirdSectionFromLayer();
void resizeForThirdSection();
void closeThirdSection();
void showSection(