From 66e3b529b73a7f327c53e664da601214545cc4eb Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 24 Jan 2020 12:50:20 +0300 Subject: [PATCH] Fix visual glitches in bubble shaking. --- .../admin_log/history_admin_log_inner.cpp | 4 +++- .../history/history_inner_widget.cpp | 3 ++- .../history/view/history_view_element.cpp | 7 ++++++ .../history/view/history_view_element.h | 6 +++++ .../history/view/history_view_list_widget.cpp | 4 +++- .../history/view/history_view_message.cpp | 11 ++++++++- .../history/view/history_view_message.h | 2 ++ .../history/view/media/history_view_media.h | 5 +++- .../history/view/media/history_view_poll.cpp | 24 ++++++++++++------- .../history/view/media/history_view_poll.h | 9 ++++--- 10 files changed, 59 insertions(+), 16 deletions(-) diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 7e84e1748..bb4dd9320 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -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 view) { diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 62690eed2..d9cec64fc 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -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); } } diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 0e20f1716..96a84ecaa 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -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(); diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index 9575879e9..41bbd4feb 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -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. diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index 5b60bab43..c5f449cf7 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -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) { diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 1ad134e55..a5a325926 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -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(); diff --git a/Telegram/SourceFiles/history/view/history_view_message.h b/Telegram/SourceFiles/history/view/history_view_message.h index 149b7db30..2e9212bd3 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.h +++ b/Telegram/SourceFiles/history/view/history_view_message.h @@ -86,6 +86,8 @@ public: TimeId displayedEditDate() const override; int infoWidth() const override; + VerticalRepaintRange verticalRepaintRange() const override; + protected: void refreshDataIdHook() override; diff --git a/Telegram/SourceFiles/history/view/media/history_view_media.h b/Telegram/SourceFiles/history/view/media/history_view_media.h index 3db33a4af..4d3b6c0a0 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_media.h +++ b/Telegram/SourceFiles/history/view/media/history_view_media.h @@ -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() { } diff --git a/Telegram/SourceFiles/history/view/media/history_view_poll.cpp b/Telegram/SourceFiles/history/view/media/history_view_poll.cpp index 5c054f5d9..3ec1e633a 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_poll.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_poll.cpp @@ -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) { diff --git a/Telegram/SourceFiles/history/view/media/history_view_poll.h b/Telegram/SourceFiles/history/view/media/history_view_poll.h index 015ad75e6..404c050ca 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_poll.h +++ b/Telegram/SourceFiles/history/view/media/history_view_poll.h @@ -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 _linkRipple; - bool _hasSelected = false; mutable std::unique_ptr _answersAnimation; mutable std::unique_ptr _sendingAnimation; - mutable Ui::Animations::Simple _wrongAnswerAnimation; + Ui::Animations::Simple _wrongAnswerAnimation; mutable QPoint _lastLinkPoint; + bool _hasSelected = false; + mutable bool _wrongAnswerAnimated = false; + }; } // namespace HistoryView