layer_manager.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #include "ui/layers/layer_manager.h"
  8. #include "ui/layers/show.h"
  9. #include "ui/ui_utility.h"
  10. namespace Ui {
  11. class LayerManager::ManagerShow final : public Show {
  12. public:
  13. explicit ManagerShow(not_null<LayerManager*> manager);
  14. ~ManagerShow();
  15. void showOrHideBoxOrLayer(
  16. std::variant<
  17. v::null_t,
  18. object_ptr<BoxContent>,
  19. std::unique_ptr<LayerWidget>> &&layer,
  20. LayerOptions options,
  21. anim::type animated) const override;
  22. [[nodiscard]] not_null<QWidget*> toastParent() const override;
  23. [[nodiscard]] bool valid() const override;
  24. operator bool() const override;
  25. private:
  26. const base::weak_ptr<LayerManager> _manager;
  27. };
  28. LayerManager::ManagerShow::ManagerShow(not_null<LayerManager*> manager)
  29. : _manager(manager.get()) {
  30. }
  31. LayerManager::ManagerShow::~ManagerShow() = default;
  32. void LayerManager::ManagerShow::showOrHideBoxOrLayer(
  33. std::variant<
  34. v::null_t,
  35. object_ptr<BoxContent>,
  36. std::unique_ptr<LayerWidget>> &&layer,
  37. LayerOptions options,
  38. anim::type animated) const {
  39. using UniqueLayer = std::unique_ptr<Ui::LayerWidget>;
  40. using ObjectBox = object_ptr<Ui::BoxContent>;
  41. if (auto layerWidget = std::get_if<UniqueLayer>(&layer)) {
  42. if (const auto manager = _manager.get()) {
  43. manager->showLayer(std::move(*layerWidget), options, animated);
  44. }
  45. } else if (auto box = std::get_if<ObjectBox>(&layer)) {
  46. if (const auto manager = _manager.get()) {
  47. manager->showBox(std::move(*box), options, animated);
  48. }
  49. } else if (const auto manager = _manager.get()) {
  50. manager->hideAll(animated);
  51. }
  52. }
  53. not_null<QWidget*> LayerManager::ManagerShow::toastParent() const {
  54. const auto manager = _manager.get();
  55. Ensures(manager != nullptr);
  56. return manager->toastParent();
  57. }
  58. bool LayerManager::ManagerShow::valid() const {
  59. return (_manager.get() != nullptr);
  60. }
  61. LayerManager::ManagerShow::operator bool() const {
  62. return valid();
  63. }
  64. LayerManager::LayerManager(not_null<RpWidget*> widget)
  65. : _widget(widget) {
  66. }
  67. void LayerManager::setStyleOverrides(
  68. const style::Box *boxSt,
  69. const style::Box *layerSt) {
  70. _boxSt = boxSt;
  71. _layerSt = layerSt;
  72. if (_layer) {
  73. _layer->setStyleOverrides(_boxSt, _layerSt);
  74. }
  75. }
  76. void LayerManager::setHideByBackgroundClick(bool hide) {
  77. _hideByBackgroundClick = hide;
  78. if (_layer) {
  79. _layer->setHideByBackgroundClick(hide);
  80. }
  81. }
  82. void LayerManager::showBox(
  83. object_ptr<BoxContent> box,
  84. LayerOptions options,
  85. anim::type animated) {
  86. ensureLayerCreated();
  87. _layer->showBox(std::move(box), options, animated);
  88. setFocus();
  89. }
  90. void LayerManager::showLayer(
  91. std::unique_ptr<LayerWidget> layer,
  92. LayerOptions options,
  93. anim::type animated) {
  94. ensureLayerCreated();
  95. _layer->showLayer(std::move(layer), options, animated);
  96. setFocus();
  97. }
  98. void LayerManager::hideAll(anim::type animated) {
  99. if (animated == anim::type::instant) {
  100. destroyLayer();
  101. } else if (_layer) {
  102. _layer->hideAll(animated);
  103. }
  104. }
  105. void LayerManager::raise() {
  106. if (_layer) {
  107. _layer->raise();
  108. }
  109. }
  110. bool LayerManager::setFocus() {
  111. if (!_layer) {
  112. return false;
  113. }
  114. _layer->setInnerFocus();
  115. return true;
  116. }
  117. std::shared_ptr<Show> LayerManager::uiShow() {
  118. if (!_cachedShow) {
  119. _cachedShow = std::make_shared<ManagerShow>(this);
  120. }
  121. return _cachedShow;
  122. }
  123. const LayerWidget *LayerManager::topShownLayer() const {
  124. return _layer ? _layer->topShownLayer() : nullptr;
  125. }
  126. void LayerManager::ensureLayerCreated() {
  127. if (_layer) {
  128. return;
  129. }
  130. _layer.emplace(_widget, crl::guard(this, [=] {
  131. return uiShow();
  132. }));
  133. _layer->setHideByBackgroundClick(_hideByBackgroundClick);
  134. _layer->setStyleOverrides(_boxSt, _layerSt);
  135. _layer->hideFinishEvents(
  136. ) | rpl::filter([=] {
  137. return _layer != nullptr; // Last hide finish is sent from destructor.
  138. }) | rpl::start_with_next([=] {
  139. destroyLayer();
  140. }, _layer->lifetime());
  141. _layer->move(0, 0);
  142. _widget->sizeValue(
  143. ) | rpl::start_with_next([=](QSize size) {
  144. _layer->resize(size);
  145. }, _layer->lifetime());
  146. _layerShown = true;
  147. }
  148. void LayerManager::destroyLayer() {
  149. if (!_layer) {
  150. return;
  151. }
  152. auto layer = base::take(_layer);
  153. _layerShown = false;
  154. const auto resetFocus = Ui::InFocusChain(layer);
  155. if (resetFocus) {
  156. _widget->setFocus();
  157. }
  158. layer = nullptr;
  159. }
  160. } // namespace Ui