Support shaking bubble for wrong quiz answer.

This commit is contained in:
John Preston 2020-01-24 11:49:12 +03:00
parent 5aacf867cd
commit dbfc555d9c
5 changed files with 82 additions and 2 deletions

View File

@ -537,10 +537,10 @@ historyPollQuestionStyle: TextStyle(defaultTextStyle) {
historyPollAnswerStyle: defaultTextStyle;
historyPollQuestionTop: 7px;
historyPollSubtitleSkip: 4px;
historyPollAnswerPadding: margins(31px, 10px, 0px, 10px);
historyPollAnswerPadding: margins(32px, 10px, 0px, 10px);
historyPollAnswersSkip: 2px;
historyPollPercentFont: semiboldFont;
historyPollPercentSkip: 6px;
historyPollPercentSkip: 5px;
historyPollPercentTop: 0px;
historyPollTotalVotesSkip: 5px;
historyPollFillingMin: 4px;

View File

@ -409,6 +409,15 @@ void Message::draw(
paintHighlight(p, g.height());
const auto roll = media ? media->getBubbleRoll() : Media::BubbleRoll();
if (roll) {
p.save();
p.translate(g.center());
p.rotate(roll.rotate);
p.scale(roll.scale, roll.scale);
p.translate(-g.center());
}
p.setTextPalette(selected
? (outbg ? st::outTextPaletteSelected : st::inTextPaletteSelected)
: (outbg ? st::outTextPalette : st::inTextPalette));
@ -504,6 +513,10 @@ void Message::draw(
p.restoreTextPalette();
if (roll) {
p.restore();
}
const auto reply = item->Get<HistoryMessageReply>();
if (reply && reply->isNameUpdated()) {
const_cast<Message*>(this)->setPendingResize();

View File

@ -233,6 +233,18 @@ public:
return true;
}
struct BubbleRoll {
float64 rotate = 0.;
float64 scale = 1.;
explicit operator bool() const {
return (rotate != 0.) || (scale != 1.);
}
};
[[nodiscard]] virtual BubbleRoll getBubbleRoll() const {
return BubbleRoll();
}
virtual void unloadHeavyPart() {
}

View File

@ -344,6 +344,7 @@ void Poll::updateTexts() {
_pollVersion = _poll->version;
const auto willStartAnimation = checkAnimationStart();
const auto voted = _voted;
if (_question.toString() != _poll->question) {
auto options = Ui::WebpageTextTitleOptions();
@ -374,9 +375,29 @@ void Poll::updateTexts() {
if (willStartAnimation) {
startAnswersAnimation();
if (!voted) {
checkQuizAnsweredWrong();
}
}
}
void Poll::checkQuizAnsweredWrong() {
if (!_voted || !_poll->quiz()) {
return;
}
const auto i = ranges::find(_answers, true, &Answer::chosen);
if (i == end(_answers) || i->correct) {
return;
}
constexpr auto kDuration = crl::time(400);
_wrongAnswerAnimation.start(
[=] { history()->owner().requestViewRepaint(_parent); },
0.,
1.,
kDuration,
anim::linear);
}
void Poll::updateRecentVoters() {
auto &&sliced = ranges::view::all(
_poll->recentVoters
@ -1121,6 +1142,35 @@ TextState Poll::textState(QPoint point, StateRequest request) const {
return result;
}
auto Poll::getBubbleRoll() const -> BubbleRoll {
constexpr auto kRotateSegments = 8;
constexpr auto kRotateAmplitude = 2.5;
constexpr auto kScaleSegments = 2;
constexpr auto kScaleAmplitude = 0.025;
const auto value = _wrongAnswerAnimation.value(1.);
if (value == 1.) {
return BubbleRoll();
}
const auto rotateFull = value * kRotateSegments;
const auto progress = [](float64 full) {
const auto lower = std::floor(full);
const auto shift = (full - lower);
switch (int(lower) % 4) {
case 0: return -shift;
case 1: return (shift - 1.);
case 2: return shift;
case 3: return (1. - shift);
}
Unexpected("Value in Poll::getBubbleRollDegrees.");
};
const auto scaleFull = value * kScaleSegments;
return {
.rotate = progress(value * kRotateSegments) * kRotateAmplitude,
.scale = 1. + progress(value * kScaleSegments) * kScaleAmplitude
};
}
void Poll::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "history/view/media/history_view_media.h"
#include "ui/effects/animations.h"
#include "data/data_poll.h"
#include "base/weak_ptr.h"
@ -40,6 +41,8 @@ public:
return false;
}
BubbleRoll getBubbleRoll() const override;
void clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) override;
@ -145,6 +148,7 @@ private:
void toggleMultiOption(const QByteArray &option);
void sendMultiOptions();
void showResults();
void checkQuizAnsweredWrong();
[[nodiscard]] int bottomButtonHeight() const;
@ -168,6 +172,7 @@ private:
mutable std::unique_ptr<AnswersAnimation> _answersAnimation;
mutable std::unique_ptr<SendingAnimation> _sendingAnimation;
mutable Ui::Animations::Simple _wrongAnswerAnimation;
mutable QPoint _lastLinkPoint;
};