info_userpic_bubble_wrap.cpp 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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 "info/userpic/info_userpic_bubble_wrap.h"
  8. #include "ui/painter.h"
  9. #include "ui/rect.h"
  10. #include "ui/wrap/padding_wrap.h"
  11. #include "ui/wrap/vertical_layout.h"
  12. #include "styles/style_chat.h"
  13. #include "styles/style_info_userpic_builder.h"
  14. namespace Ui {
  15. namespace {
  16. void PaintExcludeTopShadow(QPainter &p, int radius, const QRect &r) {
  17. constexpr auto kHorizontalOffset = 1.;
  18. constexpr auto kVerticalOffset = 2.;
  19. constexpr auto kOpacityStep1 = 0.2;
  20. constexpr auto kOpacityStep2 = 0.4;
  21. const auto opacity = p.opacity();
  22. const auto hOffset = style::ConvertScale(kHorizontalOffset);
  23. const auto vOffset = style::ConvertScale(kVerticalOffset);
  24. p.setOpacity(opacity * kOpacityStep1);
  25. p.drawRoundedRect(
  26. r + QMarginsF(hOffset, -radius, hOffset, 0),
  27. radius,
  28. radius);
  29. p.setOpacity(opacity * kOpacityStep1);
  30. p.drawRoundedRect(
  31. r + QMarginsF(0, 0, 0, vOffset),
  32. radius,
  33. radius);
  34. p.setOpacity(opacity * kOpacityStep2);
  35. p.drawRoundedRect(
  36. r + QMarginsF(0, 0, 0, vOffset / 2.),
  37. radius,
  38. radius);
  39. p.setOpacity(opacity);
  40. }
  41. } // namespace
  42. QRect BubbleWrapInnerRect(const QRect &r) {
  43. return r - st::userpicBuilderEmojiBubblePadding;
  44. }
  45. not_null<Ui::RpWidget*> AddBubbleWrap(
  46. not_null<Ui::VerticalLayout*> container,
  47. const QSize &size) {
  48. const auto bubble = container->add(object_ptr<Ui::CenterWrap<RpWidget>>(
  49. container,
  50. object_ptr<Ui::RpWidget>(container)))->entity();
  51. bubble->resize(size);
  52. auto cached = QImage(
  53. size * style::DevicePixelRatio(),
  54. QImage::Format_ARGB32_Premultiplied);
  55. cached.setDevicePixelRatio(style::DevicePixelRatio());
  56. cached.fill(Qt::transparent);
  57. {
  58. auto p = QPainter(&cached);
  59. const auto innerRect = BubbleWrapInnerRect(bubble->rect());
  60. auto hq = PainterHighQualityEnabler(p);
  61. const auto radius = st::bubbleRadiusSmall;
  62. p.setPen(Qt::NoPen);
  63. p.setBrush(st::shadowFg);
  64. PaintExcludeTopShadow(p, radius, innerRect);
  65. p.setBrush(st::boxBg);
  66. p.drawRoundedRect(innerRect, radius, radius);
  67. }
  68. bubble->paintRequest(
  69. ) | rpl::start_with_next([bubble, cached = std::move(cached)] {
  70. auto p = QPainter(bubble);
  71. p.drawImage(0, 0, cached);
  72. }, bubble->lifetime());
  73. return bubble;
  74. }
  75. } // namespace Ui