Fix visual glitches in bubble shaking.

This commit is contained in:
John Preston 2020-01-24 12:50:20 +03:00
parent 04cfd598e2
commit 66e3b529b7
10 changed files with 59 additions and 16 deletions

View File

@ -1707,7 +1707,9 @@ void InnerWidget::repaintItem(const Element *view) {
if (!view) {
return;
}
update(0, itemTop(view), width(), view->height());
const auto top = itemTop(view);
const auto range = view->verticalRepaintRange();
update(0, top + range.top, width(), range.height);
}
void InnerWidget::resizeItem(not_null<Element*> view) {

View File

@ -242,7 +242,8 @@ void HistoryInner::repaintItem(const Element *view) {
}
const auto top = itemTop(view);
if (top >= 0) {
update(0, top, width(), view->height());
const auto range = view->verticalRepaintRange();
update(0, top + range.top, width(), range.height);
}
}

View File

@ -601,6 +601,13 @@ bool Element::hasVisibleText() const {
return false;
}
auto Element::verticalRepaintRange() const -> VerticalRepaintRange {
return {
.top = 0,
.height = height()
};
}
void Element::unloadHeavyPart() {
if (_media) {
_media->unloadHeavyPart();

View File

@ -263,6 +263,12 @@ public:
virtual TimeId displayedEditDate() const;
virtual bool hasVisibleText() const;
struct VerticalRepaintRange {
int top = 0;
int height = 0;
};
[[nodiscard]] virtual VerticalRepaintRange verticalRepaintRange() const;
virtual void unloadHeavyPart();
// Legacy blocks structure.

View File

@ -2398,7 +2398,9 @@ void ListWidget::repaintItem(const Element *view) {
if (!view) {
return;
}
update(0, itemTop(view), width(), view->height());
const auto top = itemTop(view);
const auto range = view->verticalRepaintRange();
update(0, top + range.top, width(), range.height);
}
void ListWidget::repaintItem(FullMsgId itemId) {

View File

@ -409,7 +409,7 @@ void Message::draw(
paintHighlight(p, g.height());
const auto roll = media ? media->getBubbleRoll() : Media::BubbleRoll();
const auto roll = media ? media->bubbleRoll() : Media::BubbleRoll();
if (roll) {
p.save();
p.translate(g.center());
@ -1293,6 +1293,15 @@ int Message::infoWidth() const {
return result;
}
auto Message::verticalRepaintRange() const -> VerticalRepaintRange {
const auto media = this->media();
const auto add = media ? media->bubbleRollRepaintMargins() : QMargins();
return {
.top = -add.top(),
.height = height() + add.top() + add.bottom()
};
}
void Message::refreshDataIdHook() {
if (base::take(_rightActionLink)) {
_rightActionLink = rightActionLink();

View File

@ -86,6 +86,8 @@ public:
TimeId displayedEditDate() const override;
int infoWidth() const override;
VerticalRepaintRange verticalRepaintRange() const override;
protected:
void refreshDataIdHook() override;

View File

@ -241,9 +241,12 @@ public:
return (rotate != 0.) || (scale != 1.);
}
};
[[nodiscard]] virtual BubbleRoll getBubbleRoll() const {
[[nodiscard]] virtual BubbleRoll bubbleRoll() const {
return BubbleRoll();
}
[[nodiscard]] virtual QMargins bubbleRollRepaintMargins() const {
return QMargins();
}
virtual void unloadHeavyPart() {
}

View File

@ -32,6 +32,10 @@ namespace HistoryView {
namespace {
constexpr auto kShowRecentVotersCount = 3;
constexpr auto kRotateSegments = 8;
constexpr auto kRotateAmplitude = 3.;
constexpr auto kScaleSegments = 2;
constexpr auto kScaleAmplitude = 0.03;
struct PercentCounterItem {
int index = 0;
@ -1142,14 +1146,10 @@ 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;
auto Poll::bubbleRoll() const -> BubbleRoll {
const auto value = _wrongAnswerAnimation.value(1.);
if (value == 1.) {
_wrongAnswerAnimated = (value < 1.);
if (!_wrongAnswerAnimated) {
return BubbleRoll();
}
const auto rotateFull = value * kRotateSegments;
@ -1164,13 +1164,21 @@ auto Poll::getBubbleRoll() const -> BubbleRoll {
}
Unexpected("Value in Poll::getBubbleRollDegrees.");
};
const auto scaleFull = value * kScaleSegments;
return {
.rotate = progress(value * kRotateSegments) * kRotateAmplitude,
.scale = 1. + progress(value * kScaleSegments) * kScaleAmplitude
};
}
QMargins Poll::bubbleRollRepaintMargins() const {
if (!_wrongAnswerAnimated) {
return QMargins();
}
static const auto kAdd = int(std::ceil(
st::msgMaxWidth * std::sin(kRotateAmplitude * M_PI / 180.)));
return QMargins(kAdd, kAdd, kAdd, kAdd);
}
void Poll::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {

View File

@ -41,7 +41,8 @@ public:
return false;
}
BubbleRoll getBubbleRoll() const override;
BubbleRoll bubbleRoll() const override;
QMargins bubbleRollRepaintMargins() const override;
void clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
@ -168,13 +169,15 @@ private:
ClickHandlerPtr _showResultsLink;
ClickHandlerPtr _sendVotesLink;
mutable std::unique_ptr<Ui::RippleAnimation> _linkRipple;
bool _hasSelected = false;
mutable std::unique_ptr<AnswersAnimation> _answersAnimation;
mutable std::unique_ptr<SendingAnimation> _sendingAnimation;
mutable Ui::Animations::Simple _wrongAnswerAnimation;
Ui::Animations::Simple _wrongAnswerAnimation;
mutable QPoint _lastLinkPoint;
bool _hasSelected = false;
mutable bool _wrongAnswerAnimated = false;
};
} // namespace HistoryView