Add ripple animation to poll voting.

This commit is contained in:
John Preston 2018-12-24 14:03:13 +04:00
parent fb7ac874f0
commit 76c06923d5
3 changed files with 100 additions and 1 deletions

View File

@ -529,6 +529,13 @@ historyPollRadialAnimation: InfiniteRadialAnimation(defaultInfiniteRadialAnimati
thickness: 2px;
size: size(18px, 18px);
}
historyPollRippleIn: RippleAnimation(defaultRippleAnimation) {
color: msgWaveformInInactive;
}
historyPollRippleOut: RippleAnimation(defaultRippleAnimation) {
color: msgWaveformOutInactive;
}
historyPollRippleOpacity: 0.3;
boxAttachEmoji: IconButton(historyAttachEmoji) {
width: 30px;

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "calls/calls_instance.h"
#include "ui/text_options.h"
#include "ui/effects/radial_animation.h"
#include "ui/effects/ripple_animation.h"
#include "data/data_media_types.h"
#include "data/data_poll.h"
#include "data/data_session.h"
@ -95,6 +96,7 @@ struct HistoryPoll::Answer {
mutable QString votesPercent;
mutable bool chosen = false;
ClickHandlerPtr handler;
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
};
HistoryPoll::SendingAnimation::SendingAnimation(
@ -169,6 +171,34 @@ bool HistoryPoll::canVote() const {
return !_voted && !_closed;
}
int HistoryPoll::countAnswerTop(
const Answer &answer,
int innerWidth) const {
auto tshift = st::historyPollQuestionTop;
if (!isBubbleTop()) {
tshift -= st::msgFileTopMinus;
}
tshift += _question.countHeight(innerWidth) + st::historyPollSubtitleSkip;
tshift += st::msgDateFont->height + st::historyPollAnswersSkip;
auto &&answers = ranges::view::zip(
_answers,
ranges::view::ints(0, int(_answers.size())));
const auto i = ranges::find(
_answers,
&answer,
[](const Answer &answer) { return &answer; });
const auto countHeight = [&](const Answer &answer) {
return countAnswerHeight(answer, innerWidth);
};
tshift += ranges::accumulate(
begin(_answers),
i,
0,
ranges::plus(),
countHeight);
return tshift;
}
int HistoryPoll::countAnswerHeight(
const Answer &answer,
int innerWidth) const {
@ -466,6 +496,15 @@ int HistoryPoll::paintAnswer(
- st::historyPollAnswerPadding.left()
- st::historyPollAnswerPadding.right();
if (answer.ripple) {
p.setOpacity(st::historyPollRippleOpacity);
answer.ripple->paint(p, left - st::msgPadding.left(), top, outerWidth, ms);
if (answer.ripple->empty()) {
answer.ripple.reset();
}
p.setOpacity(1.);
}
if (animation) {
const auto opacity = animation->opacity.current();
if (opacity < 1.) {
@ -711,6 +750,7 @@ TextState HistoryPoll::textState(QPoint point, StateRequest request) const {
for (const auto &answer : _answers) {
const auto height = countAnswerHeight(answer, paintw);
if (point.y() >= tshift && point.y() < tshift + height) {
_lastLinkPoint = point;
result.link = answer.handler;
return result;
}
@ -719,6 +759,46 @@ TextState HistoryPoll::textState(QPoint point, StateRequest request) const {
return result;
}
void HistoryPoll::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {
if (!handler) return;
const auto i = ranges::find(
_answers,
handler,
&Answer::handler);
if (i != end(_answers)) {
toggleRipple(*i, pressed);
}
}
void HistoryPoll::toggleRipple(Answer &answer, bool pressed) {
if (pressed) {
const auto outerWidth = width();
const auto innerWidth = outerWidth
- st::msgPadding.left()
- st::msgPadding.right();
if (!answer.ripple) {
auto mask = Ui::RippleAnimation::rectMask(QSize(
outerWidth,
countAnswerHeight(answer, innerWidth)));
answer.ripple = std::make_unique<Ui::RippleAnimation>(
(_parent->hasOutLayout()
? st::historyPollRippleOut
: st::historyPollRippleIn),
std::move(mask),
[=] { Auth().data().requestViewRepaint(_parent); });
}
const auto top = countAnswerTop(answer, innerWidth);
answer.ripple->add(_lastLinkPoint - QPoint(0, top));
} else {
if (answer.ripple) {
answer.ripple->lastStop();
}
}
}
HistoryPoll::~HistoryPoll() {
Auth().data().unregisterPollView(_poll, _parent);
}

View File

@ -34,6 +34,10 @@ public:
return false;
}
void clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) override;
~HistoryPoll();
private:
@ -47,7 +51,12 @@ private:
bool canVote() const;
int countAnswerHeight(const Answer &answer, int innerWidth) const;
[[nodiscard]] int countAnswerTop(
const Answer &answer,
int innerWidth) const;
[[nodiscard]] int countAnswerHeight(
const Answer &answer,
int innerWidth) const;
[[nodiscard]] ClickHandlerPtr createAnswerClickHandler(
const Answer &answer) const;
void updateTexts();
@ -102,6 +111,8 @@ private:
void resetAnswersAnimation() const;
void step_radial(TimeMs ms, bool timer);
void toggleRipple(Answer &answer, bool pressed);
not_null<PollData*> _poll;
int _pollVersion = 0;
mutable int _totalVotes = 0;
@ -115,5 +126,6 @@ private:
mutable std::unique_ptr<AnswersAnimation> _answersAnimation;
mutable std::unique_ptr<SendingAnimation> _sendingAnimation;
mutable QPoint _lastLinkPoint;
};