window_theme_warning.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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 "window/themes/window_theme_warning.h"
  8. #include "ui/widgets/buttons.h"
  9. #include "ui/widgets/shadow.h"
  10. #include "ui/painter.h"
  11. #include "ui/ui_utility.h"
  12. #include "ui/cached_round_corners.h"
  13. #include "window/themes/window_theme.h"
  14. #include "lang/lang_keys.h"
  15. #include "styles/style_layers.h"
  16. #include "styles/style_boxes.h"
  17. namespace Window {
  18. namespace Theme {
  19. namespace {
  20. constexpr int kWaitBeforeRevertMs = 15999;
  21. } // namespace
  22. WarningWidget::WarningWidget(QWidget *parent)
  23. : TWidget(parent)
  24. , _timer([=] { handleTimer(); })
  25. , _secondsLeft(kWaitBeforeRevertMs / 1000)
  26. , _keepChanges(this, tr::lng_theme_keep_changes(), st::defaultBoxButton)
  27. , _revert(this, tr::lng_theme_revert(), st::defaultBoxButton) {
  28. using TextTransform = Ui::RoundButton::TextTransform;
  29. _keepChanges->setTextTransform(TextTransform::NoTransform);
  30. _keepChanges->setClickedCallback([] { KeepApplied(); });
  31. _revert->setTextTransform(TextTransform::NoTransform);
  32. _revert->setClickedCallback([] { Revert(); });
  33. updateText();
  34. }
  35. void WarningWidget::keyPressEvent(QKeyEvent *e) {
  36. if (e->key() == Qt::Key_Escape) {
  37. Window::Theme::Revert();
  38. }
  39. }
  40. void WarningWidget::paintEvent(QPaintEvent *e) {
  41. Painter p(this);
  42. if (!_cache.isNull()) {
  43. if (!_animation.animating()) {
  44. if (isHidden()) {
  45. return;
  46. }
  47. }
  48. p.setOpacity(_animation.value(_hiding ? 0. : 1.));
  49. p.drawPixmap(_outer.topLeft(), _cache);
  50. if (!_animation.animating()) {
  51. _cache = QPixmap();
  52. showChildren();
  53. _started = crl::now();
  54. _timer.callOnce(100);
  55. }
  56. return;
  57. }
  58. Ui::Shadow::paint(p, _inner, width(), st::boxRoundShadow);
  59. Ui::FillRoundRect(p, _inner, st::boxBg, Ui::BoxCorners);
  60. p.setFont(st::boxTitleFont);
  61. p.setPen(st::boxTitleFg);
  62. p.drawTextLeft(_inner.x() + st::boxTitlePosition.x(), _inner.y() + st::boxTitlePosition.y(), width(), tr::lng_theme_sure_keep(tr::now));
  63. p.setFont(st::boxTextFont);
  64. p.setPen(st::boxTextFg);
  65. p.drawTextLeft(_inner.x() + st::boxTitlePosition.x(), _inner.y() + st::themeWarningTextTop, width(), _text);
  66. }
  67. void WarningWidget::resizeEvent(QResizeEvent *e) {
  68. _inner = QRect((width() - st::themeWarningWidth) / 2, (height() - st::themeWarningHeight) / 2, st::themeWarningWidth, st::themeWarningHeight);
  69. _outer = _inner.marginsAdded(st::boxRoundShadow.extend);
  70. updateControlsGeometry();
  71. update();
  72. }
  73. void WarningWidget::updateControlsGeometry() {
  74. auto left = _inner.x() + _inner.width() - st::defaultBox.buttonPadding.right() - _keepChanges->width();
  75. _keepChanges->moveToLeft(left, _inner.y() + _inner.height() - st::defaultBox.buttonPadding.bottom() - _keepChanges->height());
  76. _revert->moveToLeft(left - st::defaultBox.buttonPadding.left() - _revert->width(), _keepChanges->y());
  77. }
  78. void WarningWidget::refreshLang() {
  79. InvokeQueued(this, [this] { updateControlsGeometry(); });
  80. }
  81. void WarningWidget::handleTimer() {
  82. auto msPassed = crl::now() - _started;
  83. setSecondsLeft((kWaitBeforeRevertMs - msPassed) / 1000);
  84. }
  85. void WarningWidget::setSecondsLeft(int secondsLeft) {
  86. if (secondsLeft <= 0) {
  87. Window::Theme::Revert();
  88. } else {
  89. if (_secondsLeft != secondsLeft) {
  90. _secondsLeft = secondsLeft;
  91. updateText();
  92. update();
  93. }
  94. _timer.callOnce(100);
  95. }
  96. }
  97. void WarningWidget::updateText() {
  98. _text = tr::lng_theme_reverting(tr::now, lt_count, _secondsLeft);
  99. }
  100. void WarningWidget::showAnimated() {
  101. startAnimation(false);
  102. show();
  103. setFocus();
  104. }
  105. void WarningWidget::hideAnimated() {
  106. startAnimation(true);
  107. }
  108. void WarningWidget::startAnimation(bool hiding) {
  109. _timer.cancel();
  110. _hiding = hiding;
  111. if (_cache.isNull()) {
  112. showChildren();
  113. Ui::SendPendingMoveResizeEvents(this);
  114. _cache = Ui::GrabWidget(this, _outer);
  115. }
  116. hideChildren();
  117. _animation.start([this] {
  118. update();
  119. if (_hiding) {
  120. hide();
  121. if (_hiddenCallback) {
  122. _hiddenCallback();
  123. }
  124. }
  125. }, _hiding ? 1. : 0., _hiding ? 0. : 1., st::boxDuration);
  126. }
  127. } // namespace Theme
  128. } // namespace Window