From d3e8eb429201b2966b384a95bae6bc7f42f55cf7 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 20 Sep 2019 10:35:47 +0300 Subject: [PATCH] Add LayerManager for any RpWidget. --- gyp/sources.txt | 2 + ui/layers/layer_manager.cpp | 85 +++++++++++++++++++++++++++++++++++++ ui/layers/layer_manager.h | 41 ++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 ui/layers/layer_manager.cpp create mode 100644 ui/layers/layer_manager.h diff --git a/gyp/sources.txt b/gyp/sources.txt index 9183f28..eeaedcc 100644 --- a/gyp/sources.txt +++ b/gyp/sources.txt @@ -22,6 +22,8 @@ <(src_loc)/ui/layers/box_layer_widget.h <(src_loc)/ui/layers/generic_box.cpp <(src_loc)/ui/layers/generic_box.h +<(src_loc)/ui/layers/layer_manager.cpp +<(src_loc)/ui/layers/layer_manager.h <(src_loc)/ui/layers/layer_widget.cpp <(src_loc)/ui/layers/layer_widget.h <(src_loc)/ui/platform/ui_platform_utility.h diff --git a/ui/layers/layer_manager.cpp b/ui/layers/layer_manager.cpp new file mode 100644 index 0000000..d44e89e --- /dev/null +++ b/ui/layers/layer_manager.cpp @@ -0,0 +1,85 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#include "ui/layers/layer_manager.h" + +namespace Ui { + +LayerManager::LayerManager(not_null widget) : _widget(widget) { +} + +void LayerManager::setHideByBackgroundClick(bool hide) { + _hideByBackgroundClick = hide; + if (_layer) { + _layer->setHideByBackgroundClick(hide); + } +} + +void LayerManager::showBox( + object_ptr box, + LayerOptions options, + anim::type animated) { + ensureLayerCreated(); + _layer->showBox(std::move(box), options, animated); +} + +void LayerManager::hideAll(anim::type animated) { + if (animated == anim::type::instant) { + destroyLayer(); + } else if (_layer) { + _layer->hideAll(animated); + } +} + +void LayerManager::raise() { + if (_layer) { + _layer->raise(); + } +} + +bool LayerManager::setFocus() { + if (!_layer) { + return false; + } + _layer->setInnerFocus(); + return true; +} + +void LayerManager::ensureLayerCreated() { + if (_layer) { + return; + } + _layer.emplace(_widget); + _layer->setHideByBackgroundClick(_hideByBackgroundClick); + + _layer->hideFinishEvents( + ) | rpl::filter([=] { + return _layer != nullptr; // Last hide finish is sent from destructor. + }) | rpl::start_with_next([=] { + destroyLayer(); + }, _layer->lifetime()); + + _layer->move(0, 0); + _widget->sizeValue( + ) | rpl::start_with_next([=](QSize size) { + _layer->resize(size); + }, _layer->lifetime()); +} + +void LayerManager::destroyLayer() { + if (!_layer) { + return; + } + + auto layer = base::take(_layer); + const auto resetFocus = Ui::InFocusChain(layer); + if (resetFocus) { + _widget->setFocus(); + } + layer = nullptr; +} + +} // namespace Ui diff --git a/ui/layers/layer_manager.h b/ui/layers/layer_manager.h new file mode 100644 index 0000000..1f0d31e --- /dev/null +++ b/ui/layers/layer_manager.h @@ -0,0 +1,41 @@ +// This file is part of Desktop App Toolkit, +// a set of libraries for developing nice desktop applications. +// +// For license and copyright information please follow this link: +// https://github.com/desktop-app/legal/blob/master/LEGAL +// +#pragma once + +#include "ui/layers/layer_widget.h" + +#include + +namespace Ui { + +class BoxContent; +class RpWidget; + +class LayerManager final { +public: + explicit LayerManager(not_null widget); + + void setHideByBackgroundClick(bool hide); + void showBox( + object_ptr box, + LayerOptions options = LayerOption::KeepOther, + anim::type animated = anim::type::normal); + void hideAll(anim::type animated = anim::type::normal); + void raise(); + bool setFocus(); + +private: + void ensureLayerCreated(); + void destroyLayer(); + + const not_null _widget; + base::unique_qptr _layer; + bool _hideByBackgroundClick = false; + +}; + +} // namespace Ui