Leave only one style of the reaction button.

This commit is contained in:
John Preston 2022-01-03 14:47:27 +03:00
parent c313cfb4ec
commit a1c342c822
3 changed files with 26 additions and 152 deletions

View file

@ -1845,11 +1845,7 @@ Reactions::ButtonParameters Message::reactionButtonParameters(
using namespace Reactions; using namespace Reactions;
auto result = ButtonParameters{ .context = data()->fullId() }; auto result = ButtonParameters{ .context = data()->fullId() };
const auto outbg = hasOutLayout(); const auto outbg = hasOutLayout();
result.style = (!_comments && !embedReactionsInBubble()) const auto outsideBubble = (!_comments && !embedReactionsInBubble());
? ButtonStyle::Service
: outbg
? ButtonStyle::Outgoing
: ButtonStyle::Incoming;
const auto geometry = countGeometry(); const auto geometry = countGeometry();
result.pointer = position; result.pointer = position;
const auto onTheLeft = (outbg && !delegate()->elementIsChatWide()); const auto onTheLeft = (outbg && !delegate()->elementIsChatWide());
@ -1864,7 +1860,7 @@ Reactions::ButtonParameters Message::reactionButtonParameters(
const auto innerHeight = geometry.height() const auto innerHeight = geometry.height()
- keyboardHeight - keyboardHeight
- reactionsHeight; - reactionsHeight;
const auto maybeRelativeCenter = (result.style == ButtonStyle::Service) const auto maybeRelativeCenter = outsideBubble
? media()->reactionButtonCenterOverride() ? media()->reactionButtonCenterOverride()
: std::nullopt; : std::nullopt;
const auto addOnTheRight = [&] { const auto addOnTheRight = [&] {

View file

@ -23,9 +23,7 @@ namespace {
constexpr auto kToggleDuration = crl::time(80); constexpr auto kToggleDuration = crl::time(80);
constexpr auto kActivateDuration = crl::time(150); constexpr auto kActivateDuration = crl::time(150);
constexpr auto kExpandDuration = crl::time(150); constexpr auto kExpandDuration = crl::time(150);
constexpr auto kInCacheIndex = 0; constexpr auto kBgCacheIndex = 0;
constexpr auto kOutCacheIndex = 1;
constexpr auto kServiceCacheIndex = 2;
constexpr auto kShadowCacheIndex = 0; constexpr auto kShadowCacheIndex = 0;
constexpr auto kEmojiCacheIndex = 1; constexpr auto kEmojiCacheIndex = 1;
constexpr auto kMaskCacheIndex = 2; constexpr auto kMaskCacheIndex = 2;
@ -84,10 +82,6 @@ Button::Button(
Button::~Button() = default; Button::~Button() = default;
ButtonStyle Button::style() const {
return _style;
}
bool Button::isHidden() const { bool Button::isHidden() const {
return (_state == State::Hidden) && !_scaleAnimation.animating(); return (_state == State::Hidden) && !_scaleAnimation.animating();
} }
@ -160,12 +154,6 @@ void Button::applyParameters(
? State::Active ? State::Active
: State::Shown; : State::Shown;
applyState(state, update); applyState(state, update);
if (_style != parameters.style) {
_style = parameters.style;
if (update) {
update(_geometry);
}
}
if (parameters.outside && _state == State::Shown) { if (parameters.outside && _state == State::Shown) {
_hideTimer.callOnce(kButtonHideDelay); _hideTimer.callOnce(kButtonHideDelay);
} else { } else {
@ -281,24 +269,18 @@ Manager::Manager(
_inner.translate(QRect({}, _outer).center() - _inner.center()); _inner.translate(QRect({}, _outer).center() - _inner.center());
const auto ratio = style::DevicePixelRatio(); const auto ratio = style::DevicePixelRatio();
_cacheInOutService = QImage( _cacheBg = QImage(
_outer.width() * 3 * ratio, _outer.width() * ratio,
_outer.height() * kFramesCount * ratio, _outer.height() * kFramesCount * ratio,
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
_cacheInOutService.setDevicePixelRatio(ratio); _cacheBg.setDevicePixelRatio(ratio);
_cacheInOutService.fill(Qt::transparent); _cacheBg.fill(Qt::transparent);
_cacheParts = QImage( _cacheParts = QImage(
_outer.width() * kCacheColumsCount * ratio, _outer.width() * kCacheColumsCount * ratio,
_outer.height() * kFramesCount * ratio, _outer.height() * kFramesCount * ratio,
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
_cacheParts.setDevicePixelRatio(ratio); _cacheParts.setDevicePixelRatio(ratio);
_cacheParts.fill(Qt::transparent); _cacheParts.fill(Qt::transparent);
_cacheForPattern = QImage(
QSize(
_outer.width(),
_outer.height() + st::reactionCornerAddedHeightMax) * ratio,
QImage::Format_ARGB32_Premultiplied);
_cacheForPattern.setDevicePixelRatio(ratio);
_shadowBuffer = QImage( _shadowBuffer = QImage(
_outer * ratio, _outer * ratio,
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
@ -404,8 +386,7 @@ void Manager::applyList(std::vector<Data::Reaction> list) {
void Manager::setMainReactionImage(QImage image) { void Manager::setMainReactionImage(QImage image) {
_mainReactionImage = std::move(image); _mainReactionImage = std::move(image);
ranges::fill(_validIn, false); ranges::fill(_validBg, false);
ranges::fill(_validOut, false);
ranges::fill(_validEmoji, false); ranges::fill(_validEmoji, false);
loadOtherReactions(); loadOtherReactions();
} }
@ -576,38 +557,17 @@ void Manager::paintButton(
const auto geometry = button->geometry(); const auto geometry = button->geometry();
const auto position = geometry.topLeft(); const auto position = geometry.topLeft();
const auto size = geometry.size(); const auto size = geometry.size();
const auto style = button->style();
const auto patterned = (style == ButtonStyle::Outgoing)
&& context.bubblesPattern
&& !context.viewport.isEmpty()
&& !context.bubblesPattern->pixmap.size().isEmpty();
const auto shadow = context.st->shadowFg()->c; const auto shadow = context.st->shadowFg()->c;
if (opacity != 1.) { if (opacity != 1.) {
p.setOpacity(opacity); p.setOpacity(opacity);
} }
if (patterned) { const auto background = context.st->windowBg()->c;
const auto source = validateShadow(frameIndex, scale, shadow); const auto source = validateFrame(
paintLongImage(p, geometry, _cacheParts, source); frameIndex,
validateCacheForPattern(frameIndex, scale, geometry, context); scale,
p.drawImage( background,
geometry, shadow);
_cacheForPattern, paintLongImage(p, geometry, _cacheBg, source);
QRect(QPoint(), geometry.size() * style::DevicePixelRatio()));
} else {
const auto background = (style == ButtonStyle::Service)
? context.st->windowBg()->c
: context.st->messageStyle(
(style == ButtonStyle::Outgoing),
false
).msgBg->c;
const auto source = validateFrame(
style,
frameIndex,
scale,
background,
shadow);
paintLongImage(p, geometry, _cacheInOutService, source);
}
const auto mainEmojiPosition = position + (button->expandUp() const auto mainEmojiPosition = position + (button->expandUp()
? QPoint(0, size.height() - _outer.height()) ? QPoint(0, size.height() - _outer.height())
@ -693,32 +653,12 @@ void Manager::paintAllEmoji(
} }
} }
void Manager::validateCacheForPattern(
int frameIndex,
float64 scale,
const QRect &geometry,
const PaintContext &context) {
auto q = QPainter(&_cacheForPattern);
q.setCompositionMode(QPainter::CompositionMode_Source);
const auto source = validateMask(frameIndex, scale);
paintLongImage(q, QRect(QPoint(), geometry.size()), _cacheParts, source);
q.setCompositionMode(QPainter::CompositionMode_SourceIn);
Ui::PaintPatternBubblePart(
q,
context.viewport.translated(-geometry.topLeft()),
context.bubblesPattern->pixmap,
QRect(QPoint(), geometry.size()));
}
void Manager::applyPatternedShadow(const QColor &shadow) { void Manager::applyPatternedShadow(const QColor &shadow) {
if (_shadow == shadow) { if (_shadow == shadow) {
return; return;
} }
_shadow = shadow; _shadow = shadow;
ranges::fill(_validIn, false); ranges::fill(_validBg, false);
ranges::fill(_validOut, false);
ranges::fill(_validShadow, false); ranges::fill(_validShadow, false);
} }
@ -796,40 +736,24 @@ QRect Manager::validateEmoji(int frameIndex, float64 scale) {
} }
QRect Manager::validateFrame( QRect Manager::validateFrame(
ButtonStyle style,
int frameIndex, int frameIndex,
float64 scale, float64 scale,
const QColor &background, const QColor &background,
const QColor &shadow) { const QColor &shadow) {
applyPatternedShadow(shadow); applyPatternedShadow(shadow);
auto &valid = (style == ButtonStyle::Service) if (_background != background) {
? _validService _background = background;
: (style == ButtonStyle::Outgoing) ranges::fill(_validBg, false);
? _validOut
: _validIn;
auto &color = (style == ButtonStyle::Service)
? _backgroundService
: (style == ButtonStyle::Outgoing)
? _backgroundOut
: _backgroundIn;
if (color != background) {
color = background;
ranges::fill(valid, false);
} }
const auto columnIndex = (style == ButtonStyle::Service) const auto result = cacheRect(frameIndex, kBgCacheIndex);
? kServiceCacheIndex if (_validBg[frameIndex]) {
: (style == ButtonStyle::Outgoing)
? kOutCacheIndex
: kInCacheIndex;
const auto result = cacheRect(frameIndex, columnIndex);
if (valid[frameIndex]) {
return result; return result;
} }
const auto shadowSource = validateShadow(frameIndex, scale, shadow); const auto shadowSource = validateShadow(frameIndex, scale, shadow);
const auto position = result.topLeft() / style::DevicePixelRatio(); const auto position = result.topLeft() / style::DevicePixelRatio();
auto p = QPainter(&_cacheInOutService); auto p = QPainter(&_cacheBg);
p.setCompositionMode(QPainter::CompositionMode_Source); p.setCompositionMode(QPainter::CompositionMode_Source);
p.drawImage(position, _cacheParts, shadowSource); p.drawImage(position, _cacheParts, shadowSource);
p.setCompositionMode(QPainter::CompositionMode_SourceOver); p.setCompositionMode(QPainter::CompositionMode_SourceOver);
@ -847,31 +771,7 @@ QRect Manager::validateFrame(
p.drawRoundedRect(inner, radius, radius); p.drawRoundedRect(inner, radius, radius);
p.restore(); p.restore();
p.end(); p.end();
valid[frameIndex] = true; _validBg[frameIndex] = true;
return result;
}
QRect Manager::validateMask(int frameIndex, float64 scale) {
const auto result = cacheRect(frameIndex, kMaskCacheIndex);
if (_validMask[frameIndex]) {
return result;
}
auto p = QPainter(&_cacheParts);
auto hq = PainterHighQualityEnabler(p);
const auto position = result.topLeft() / style::DevicePixelRatio();
const auto inner = _inner.translated(position);
const auto radius = st::reactionCornerRadius;
const auto center = inner.center();
p.setPen(Qt::NoPen);
p.setBrush(Qt::white);
p.save();
p.translate(center);
p.scale(scale, scale);
p.translate(-center);
p.drawRoundedRect(inner, radius, radius);
_validMask[frameIndex] = true;
return result; return result;
} }

View file

@ -26,12 +26,6 @@ struct TextState;
namespace HistoryView::Reactions { namespace HistoryView::Reactions {
enum class ButtonStyle {
Incoming,
Outgoing,
Service,
};
enum class ExpandDirection { enum class ExpandDirection {
Up, Up,
Down, Down,
@ -49,7 +43,6 @@ struct ButtonParameters {
QPoint center; QPoint center;
QPoint pointer; QPoint pointer;
QPoint globalPointer; QPoint globalPointer;
ButtonStyle style = ButtonStyle::Incoming;
int reactionsCount = 1; int reactionsCount = 1;
int visibleTop = 0; int visibleTop = 0;
int visibleBottom = 0; int visibleBottom = 0;
@ -76,7 +69,6 @@ public:
using State = ButtonState; using State = ButtonState;
void applyState(State state); void applyState(State state);
[[nodiscard]] ButtonStyle style() const;
[[nodiscard]] bool expandUp() const; [[nodiscard]] bool expandUp() const;
[[nodiscard]] bool isHidden() const; [[nodiscard]] bool isHidden() const;
[[nodiscard]] QRect geometry() const; [[nodiscard]] QRect geometry() const;
@ -107,7 +99,6 @@ private:
int _finalHeight = 0; int _finalHeight = 0;
int _scroll = 0; int _scroll = 0;
ExpandDirection _expandDirection = ExpandDirection::Up; ExpandDirection _expandDirection = ExpandDirection::Up;
ButtonStyle _style = ButtonStyle::Incoming;
base::Timer _expandTimer; base::Timer _expandTimer;
base::Timer _hideTimer; base::Timer _hideTimer;
@ -182,17 +173,10 @@ private:
const QColor &shadow); const QColor &shadow);
QRect validateEmoji(int frameIndex, float64 scale); QRect validateEmoji(int frameIndex, float64 scale);
QRect validateFrame( QRect validateFrame(
ButtonStyle style,
int frameIndex, int frameIndex,
float64 scale, float64 scale,
const QColor &background, const QColor &background,
const QColor &shadow); const QColor &shadow);
QRect validateMask(int frameIndex, float64 scale);
void validateCacheForPattern(
int frameIndex,
float64 scale,
const QRect &geometry,
const PaintContext &context);
[[nodiscard]] QMargins innerMargins() const; [[nodiscard]] QMargins innerMargins() const;
[[nodiscard]] QRect buttonInner() const; [[nodiscard]] QRect buttonInner() const;
@ -208,19 +192,13 @@ private:
mutable std::vector<ClickHandlerPtr> _links; mutable std::vector<ClickHandlerPtr> _links;
QSize _outer; QSize _outer;
QRect _inner; QRect _inner;
QImage _cacheInOutService; QImage _cacheBg;
QImage _cacheParts; QImage _cacheParts;
QImage _cacheForPattern;
QImage _shadowBuffer; QImage _shadowBuffer;
std::array<bool, kFramesCount> _validIn = { { false } }; std::array<bool, kFramesCount> _validBg = { { false } };
std::array<bool, kFramesCount> _validOut = { { false } };
std::array<bool, kFramesCount> _validService = { { false } };
std::array<bool, kFramesCount> _validShadow = { { false } }; std::array<bool, kFramesCount> _validShadow = { { false } };
std::array<bool, kFramesCount> _validEmoji = { { false } }; std::array<bool, kFramesCount> _validEmoji = { { false } };
std::array<bool, kFramesCount> _validMask = { { false } }; QColor _background;
QColor _backgroundIn;
QColor _backgroundOut;
QColor _backgroundService;
QColor _shadow; QColor _shadow;
std::shared_ptr<Data::DocumentMedia> _mainReactionMedia; std::shared_ptr<Data::DocumentMedia> _mainReactionMedia;