mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-19 15:47:11 +02:00
Implement nice dropdown collapse animation.
This commit is contained in:
parent
6a1630a84c
commit
cfc2a959cf
3 changed files with 58 additions and 6 deletions
|
@ -116,6 +116,18 @@ int Button::scrollMax() const {
|
|||
return _expandedInnerHeight - _expandedHeight;
|
||||
}
|
||||
|
||||
float64 Button::expandAnimationOpacity(float64 expandRatio) const {
|
||||
return (_collapseType == CollapseType::Fade)
|
||||
? expandRatio
|
||||
: 1.;
|
||||
}
|
||||
|
||||
int Button::expandAnimationScroll(float64 expandRatio) const {
|
||||
return (_collapseType == CollapseType::Scroll && expandRatio < 1.)
|
||||
? std::clamp(int(base::SafeRound(expandRatio * _scroll)), 0, _scroll)
|
||||
: _scroll;
|
||||
}
|
||||
|
||||
bool Button::expandUp() const {
|
||||
return (_expandDirection == ExpandDirection::Up);
|
||||
}
|
||||
|
@ -247,6 +259,11 @@ void Button::applyState(State state, Fn<void(QRect)> update) {
|
|||
if (state == State::Hidden) {
|
||||
_heightAnimation.stop();
|
||||
} else {
|
||||
if (!_heightAnimation.animating()) {
|
||||
_collapseType = (_scroll < st::reactionCollapseFadeThreshold)
|
||||
? CollapseType::Scroll
|
||||
: CollapseType::Fade;
|
||||
}
|
||||
_heightAnimation.start(
|
||||
[=] { updateGeometry(_update); },
|
||||
_finalHeight,
|
||||
|
@ -736,7 +753,10 @@ void Manager::paintButton(
|
|||
|
||||
const auto current = (button == _button.get());
|
||||
const auto expandRatio = expanded
|
||||
? (float64(expanded) / (button->expandedHeight() - _outer.height()))
|
||||
? std::clamp(
|
||||
float64(expanded) / (button->expandedHeight() - _outer.height()),
|
||||
0.,
|
||||
1.)
|
||||
: 0.;
|
||||
const auto expandedSkip = int(base::SafeRound(
|
||||
expandRatio * st::reactionExpandedSkip));
|
||||
|
@ -745,17 +765,36 @@ void Manager::paintButton(
|
|||
: button->expandUp()
|
||||
? QPoint(0, expanded - expandedSkip)
|
||||
: QPoint(0, expandedSkip);
|
||||
const auto source = validateEmoji(frameIndex, scale);
|
||||
if (expanded || (current && !onlyMainEmojiVisible())) {
|
||||
const auto origin = expanded ? QPoint() : position;
|
||||
paintAllEmoji(*q, button, scale, origin, mainEmojiPosition);
|
||||
const auto scroll = button->expandAnimationScroll(expandRatio);
|
||||
const auto opacity = button->expandAnimationOpacity(expandRatio);
|
||||
if (opacity != 1.) {
|
||||
q->setOpacity(opacity);
|
||||
}
|
||||
paintAllEmoji(*q, button, scroll, scale, origin, mainEmojiPosition);
|
||||
if (opacity != 1.) {
|
||||
q->setOpacity(1.);
|
||||
}
|
||||
if (current && expanded) {
|
||||
_showingAll = true;
|
||||
}
|
||||
if (expanded) {
|
||||
paintInnerGradients(*q, background, button, expandRatio);
|
||||
paintInnerGradients(*q, background, button, scroll, expandRatio);
|
||||
}
|
||||
if (opacity != 1.) {
|
||||
const auto appearShift = st::reactionMainAppearShift * opacity;
|
||||
const auto appearPosition = !expanded
|
||||
? position
|
||||
: button->expandUp()
|
||||
? QPoint(0, expanded - appearShift)
|
||||
: QPoint(0, appearShift);
|
||||
q->setOpacity(1. - opacity);
|
||||
q->drawImage(appearPosition, _cacheParts, source);
|
||||
q->setOpacity(1.);
|
||||
}
|
||||
} else {
|
||||
const auto source = validateEmoji(frameIndex, scale);
|
||||
p.drawImage(mainEmojiPosition, _cacheParts, source);
|
||||
}
|
||||
if (current && !expanded) {
|
||||
|
@ -779,8 +818,8 @@ void Manager::paintInnerGradients(
|
|||
Painter &p,
|
||||
const QColor &background,
|
||||
not_null<Button*> button,
|
||||
int scroll,
|
||||
float64 expandRatio) {
|
||||
const auto scroll = button->scroll();
|
||||
const auto endScroll = button->scrollMax() - scroll;
|
||||
const auto size = st::reactionGradientSize;
|
||||
const auto ensureGradient = [&](QImage &gradient, bool top) {
|
||||
|
@ -970,6 +1009,7 @@ void Manager::paintLongImage(
|
|||
void Manager::paintAllEmoji(
|
||||
Painter &p,
|
||||
not_null<Button*> button,
|
||||
int scroll,
|
||||
float64 scale,
|
||||
QPoint position,
|
||||
QPoint mainEmojiPosition) {
|
||||
|
@ -1013,7 +1053,7 @@ void Manager::paintAllEmoji(
|
|||
const auto expandUp = button->expandUp();
|
||||
const auto shift = QPoint(0, oneHeight * (expandUp ? -1 : 1));
|
||||
auto emojiPosition = mainEmojiPosition
|
||||
+ QPoint(0, button->scroll() * (expandUp ? 1 : -1));
|
||||
+ QPoint(0, scroll * (expandUp ? 1 : -1));
|
||||
const auto update = [=] {
|
||||
updateCurrentButton();
|
||||
};
|
||||
|
|
|
@ -81,12 +81,19 @@ public:
|
|||
[[nodiscard]] int scrollMax() const;
|
||||
[[nodiscard]] float64 currentScale() const;
|
||||
[[nodiscard]] float64 currentOpacity() const;
|
||||
[[nodiscard]] float64 expandAnimationOpacity(float64 expandRatio) const;
|
||||
[[nodiscard]] int expandAnimationScroll(float64 expandRatio) const;
|
||||
[[nodiscard]] bool consumeWheelEvent(not_null<QWheelEvent*> e);
|
||||
|
||||
[[nodiscard]] static float64 ScaleForState(State state);
|
||||
[[nodiscard]] static float64 OpacityForScale(float64 scale);
|
||||
|
||||
private:
|
||||
enum class CollapseType {
|
||||
Scroll,
|
||||
Fade,
|
||||
};
|
||||
|
||||
void updateGeometry(Fn<void(QRect)> update);
|
||||
void applyState(State satte, Fn<void(QRect)> update);
|
||||
void applyParameters(
|
||||
|
@ -108,6 +115,7 @@ private:
|
|||
int _finalHeight = 0;
|
||||
int _scroll = 0;
|
||||
ExpandDirection _expandDirection = ExpandDirection::Up;
|
||||
CollapseType _collapseType = CollapseType::Scroll;
|
||||
|
||||
base::Timer _expandTimer;
|
||||
base::Timer _hideTimer;
|
||||
|
@ -174,6 +182,7 @@ private:
|
|||
void paintAllEmoji(
|
||||
Painter &p,
|
||||
not_null<Button*> button,
|
||||
int scroll,
|
||||
float64 scale,
|
||||
QPoint position,
|
||||
QPoint mainEmojiPosition);
|
||||
|
@ -181,6 +190,7 @@ private:
|
|||
Painter &p,
|
||||
const QColor &background,
|
||||
not_null<Button*> button,
|
||||
int scroll,
|
||||
float64 expandRatio);
|
||||
void overlayExpandedBorder(
|
||||
Painter &p,
|
||||
|
|
|
@ -987,3 +987,5 @@ reactionGradientStart: 8px;
|
|||
reactionGradientSize: 24px;
|
||||
reactionGradientFadeSize: 24px;
|
||||
reactionAppearStartSkip: 2px;
|
||||
reactionMainAppearShift: 20px;
|
||||
reactionCollapseFadeThreshold: 40px;
|
||||
|
|
Loading…
Add table
Reference in a new issue