confirm_box.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "ui/boxes/confirm_box.h"
  8. #include "lang/lang_keys.h"
  9. #include "ui/rect.h"
  10. #include "ui/widgets/buttons.h"
  11. #include "styles/style_layers.h"
  12. namespace Ui {
  13. void ConfirmBox(not_null<Ui::GenericBox*> box, ConfirmBoxArgs &&args) {
  14. const auto weak = Ui::MakeWeak(box);
  15. const auto lifetime = box->lifetime().make_state<rpl::lifetime>();
  16. const auto withTitle = !v::is_null(args.title);
  17. if (withTitle) {
  18. box->setTitle(v::text::take_marked(std::move(args.title)));
  19. }
  20. if (!v::is_null(args.text)) {
  21. const auto padding = st::boxPadding;
  22. const auto use = args.labelPadding
  23. ? *args.labelPadding
  24. : withTitle
  25. ? QMargins(padding.left(), 0, padding.right(), padding.bottom())
  26. : padding;
  27. const auto label = box->addRow(
  28. object_ptr<Ui::FlatLabel>(
  29. box.get(),
  30. v::text::take_marked(std::move(args.text)),
  31. args.labelStyle ? *args.labelStyle : st::boxLabel),
  32. use);
  33. if (args.labelFilter) {
  34. label->setClickHandlerFilter(std::move(args.labelFilter));
  35. }
  36. }
  37. const auto prepareCallback = [&](ConfirmBoxArgs::Callback &callback) {
  38. return [=, confirmed = std::move(callback)]() {
  39. if (const auto callbackPtr = std::get_if<1>(&confirmed)) {
  40. if (auto callback = (*callbackPtr)) {
  41. callback();
  42. }
  43. } else if (const auto callbackPtr = std::get_if<2>(&confirmed)) {
  44. if (auto callback = (*callbackPtr)) {
  45. callback(crl::guard(weak, [=] { weak->closeBox(); }));
  46. }
  47. } else if (weak) {
  48. weak->closeBox();
  49. }
  50. };
  51. };
  52. const auto &defaultButtonStyle = box->getDelegate()->style().button;
  53. const auto confirmButton = box->addButton(
  54. v::text::take_plain(std::move(args.confirmText), tr::lng_box_ok()),
  55. [=, c = prepareCallback(args.confirmed)]() {
  56. lifetime->destroy();
  57. c();
  58. },
  59. args.confirmStyle ? *args.confirmStyle : defaultButtonStyle);
  60. box->events(
  61. ) | rpl::start_with_next([=](not_null<QEvent*> e) {
  62. if ((e->type() != QEvent::KeyPress) || !confirmButton) {
  63. return;
  64. }
  65. const auto k = static_cast<QKeyEvent*>(e.get());
  66. if (k->key() == Qt::Key_Enter || k->key() == Qt::Key_Return) {
  67. confirmButton->clicked(Qt::KeyboardModifiers(), Qt::LeftButton);
  68. }
  69. }, box->lifetime());
  70. if (!args.inform) {
  71. const auto cancelButton = box->addButton(
  72. v::text::take_plain(std::move(args.cancelText), tr::lng_cancel()),
  73. crl::guard(weak, [=, c = prepareCallback(args.cancelled)]() {
  74. lifetime->destroy();
  75. c();
  76. }),
  77. args.cancelStyle ? *args.cancelStyle : defaultButtonStyle);
  78. box->boxClosing(
  79. ) | rpl::start_with_next(crl::guard(cancelButton, [=] {
  80. cancelButton->clicked(Qt::KeyboardModifiers(), Qt::LeftButton);
  81. }), *lifetime);
  82. }
  83. if (args.strictCancel) {
  84. lifetime->destroy();
  85. }
  86. }
  87. object_ptr<Ui::GenericBox> MakeConfirmBox(ConfirmBoxArgs &&args) {
  88. return Box(ConfirmBox, std::move(args));
  89. }
  90. void IconWithTitle(
  91. not_null<VerticalLayout*> container,
  92. not_null<RpWidget*> icon,
  93. not_null<RpWidget*> title,
  94. RpWidget *subtitle) {
  95. const auto line = container->add(
  96. object_ptr<RpWidget>(container),
  97. st::boxRowPadding);
  98. icon->setParent(line);
  99. title->setParent(line);
  100. if (subtitle) {
  101. subtitle->setParent(line);
  102. }
  103. icon->heightValue(
  104. ) | rpl::start_with_next([=](int height) {
  105. line->resize(line->width(), height);
  106. }, icon->lifetime());
  107. line->widthValue(
  108. ) | rpl::start_with_next([=](int width) {
  109. icon->moveToLeft(0, 0);
  110. const auto skip = st::defaultBoxCheckbox.textPosition.x();
  111. title->resizeToWidth(width - rect::right(icon) - skip);
  112. if (subtitle) {
  113. subtitle->resizeToWidth(title->width());
  114. title->moveToLeft(rect::right(icon) + skip, icon->y());
  115. subtitle->moveToLeft(
  116. title->x(),
  117. icon->y() + icon->height() - subtitle->height());
  118. } else {
  119. title->moveToLeft(
  120. rect::right(icon) + skip,
  121. ((icon->height() - title->height()) / 2));
  122. }
  123. }, title->lifetime());
  124. icon->setAttribute(Qt::WA_TransparentForMouseEvents);
  125. title->setAttribute(Qt::WA_TransparentForMouseEvents);
  126. }
  127. } // namespace Ui