profile_cover_drop_area.cpp 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  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 "profile/profile_cover_drop_area.h"
  8. #include "ui/ui_utility.h"
  9. #include "styles/style_profile.h"
  10. namespace Profile {
  11. CoverDropArea::CoverDropArea(QWidget *parent, const QString &title, const QString &subtitle) : TWidget(parent)
  12. , _title(title)
  13. , _subtitle(subtitle)
  14. , _titleWidth(st::profileDropAreaTitleFont->width(_title))
  15. , _subtitleWidth(st::profileDropAreaSubtitleFont->width(_subtitle)) {
  16. }
  17. void CoverDropArea::showAnimated() {
  18. show();
  19. _hiding = false;
  20. setupAnimation();
  21. }
  22. void CoverDropArea::hideAnimated(HideFinishCallback &&callback) {
  23. _hideFinishCallback = std::move(callback);
  24. _hiding = true;
  25. setupAnimation();
  26. }
  27. void CoverDropArea::paintEvent(QPaintEvent *e) {
  28. auto p = QPainter(this);
  29. if (_a_appearance.animating()) {
  30. p.setOpacity(_a_appearance.value(_hiding ? 0. : 1.));
  31. p.drawPixmap(0, 0, _cache);
  32. return;
  33. }
  34. if (!_cache.isNull()) {
  35. _cache = QPixmap();
  36. if (_hiding) {
  37. hide();
  38. if (_hideFinishCallback) {
  39. _hideFinishCallback(this);
  40. }
  41. return;
  42. }
  43. }
  44. p.fillRect(e->rect(), st::profileDropAreaBg);
  45. if (width() < st::profileDropAreaPadding.left() + st::profileDropAreaPadding.right()) return;
  46. if (height() < st::profileDropAreaPadding.top() + st::profileDropAreaPadding.bottom()) return;
  47. auto border = st::profileDropAreaBorderWidth;
  48. auto &borderFg = st::profileDropAreaBorderFg;
  49. auto inner = rect().marginsRemoved(st::profileDropAreaPadding);
  50. p.fillRect(inner.x(), inner.y(), inner.width(), border, borderFg);
  51. p.fillRect(inner.x(), inner.y() + inner.height() - border, inner.width(), border, borderFg);
  52. p.fillRect(inner.x(), inner.y() + border, border, inner.height() - 2 * border, borderFg);
  53. p.fillRect(inner.x() + inner.width() - border, inner.y() + border, border, inner.height() - 2 * border, borderFg);
  54. int titleLeft = inner.x() + (inner.width() - _titleWidth) / 2;
  55. int titleTop = inner.y() + st::profileDropAreaTitleTop + st::profileDropAreaTitleFont->ascent;
  56. p.setFont(st::profileDropAreaTitleFont);
  57. p.setPen(st::profileDropAreaFg);
  58. p.drawText(titleLeft, titleTop, _title);
  59. int subtitleLeft = inner.x() + (inner.width() - _subtitleWidth) / 2;
  60. int subtitleTop = inner.y() + st::profileDropAreaSubtitleTop + st::profileDropAreaSubtitleFont->ascent;
  61. p.setFont(st::profileDropAreaSubtitleFont);
  62. p.setPen(st::profileDropAreaFg);
  63. p.drawText(subtitleLeft, subtitleTop, _subtitle);
  64. }
  65. void CoverDropArea::setupAnimation() {
  66. if (_cache.isNull()) {
  67. _cache = Ui::GrabWidget(this);
  68. }
  69. auto from = _hiding ? 1. : 0., to = _hiding ? 0. : 1.;
  70. _a_appearance.start(
  71. [=] { update(); },
  72. from,
  73. to,
  74. st::profileDropAreaDuration);
  75. }
  76. } // namespace Profile