Fix slide animations with new layer rounding.

This commit is contained in:
John Preston 2022-02-23 13:53:27 +03:00
parent 1a664edd39
commit ffd65e1fe4
11 changed files with 67 additions and 60 deletions

View file

@ -458,11 +458,10 @@ void Widget::resizeEvent(QResizeEvent *e) {
}
void Widget::paintEvent(QPaintEvent *e) {
if (animating()) {
if (animatingShow()) {
SectionWidget::paintEvent(e);
return;
}
if (Ui::skipPaintEvent(this, e)) {
} else if (Ui::skipPaintEvent(this, e)) {
return;
}
//if (hasPendingResizedItems()) {

View file

@ -270,7 +270,7 @@ bool PinnedWidget::showAtPositionNow(
}
void PinnedWidget::updateScrollDownVisibility() {
if (animating()) {
if (animatingShow()) {
return;
}
@ -467,7 +467,7 @@ void PinnedWidget::updateControlsGeometry() {
}
void PinnedWidget::paintEvent(QPaintEvent *e) {
if (animating()) {
if (animatingShow()) {
SectionWidget::paintEvent(e);
return;
} else if (Ui::skipPaintEvent(this, e)) {

View file

@ -1344,7 +1344,7 @@ bool RepliesWidget::showAtPositionNow(
}
void RepliesWidget::updateScrollDownVisibility() {
if (animating()) {
if (animatingShow()) {
return;
}
@ -1617,7 +1617,7 @@ void RepliesWidget::updateControlsGeometry() {
}
void RepliesWidget::paintEvent(QPaintEvent *e) {
if (animating()) {
if (animatingShow()) {
SectionWidget::paintEvent(e);
return;
} else if (Ui::skipPaintEvent(this, e)) {
@ -1667,28 +1667,28 @@ void RepliesWidget::updatePinnedVisibility() {
}
void RepliesWidget::setPinnedVisibility(bool shown) {
if (!animating()) {
if (!_rootViewInited) {
const auto height = shown ? st::historyReplyHeight : 0;
if (const auto delta = height - _rootViewHeight) {
_rootViewHeight = height;
if (_scroll->scrollTop() == _scroll->scrollTopMax()) {
setGeometryWithTopMoved(geometry(), delta);
} else {
updateControlsGeometry();
}
}
if (shown) {
_rootView->show();
if (animatingShow()) {
return;
} else if (!_rootViewInited) {
const auto height = shown ? st::historyReplyHeight : 0;
if (const auto delta = height - _rootViewHeight) {
_rootViewHeight = height;
if (_scroll->scrollTop() == _scroll->scrollTopMax()) {
setGeometryWithTopMoved(geometry(), delta);
} else {
_rootView->hide();
updateControlsGeometry();
}
_rootVisible = shown;
_rootView->finishAnimating();
_rootViewInited = true;
} else {
_rootVisible = shown;
}
if (shown) {
_rootView->show();
} else {
_rootView->hide();
}
_rootVisible = shown;
_rootView->finishAnimating();
_rootViewInited = true;
} else {
_rootVisible = shown;
}
}

View file

@ -842,7 +842,7 @@ bool ScheduledWidget::showAtPositionNow(Data::MessagePosition position) {
}
void ScheduledWidget::updateScrollDownVisibility() {
if (animating()) {
if (animatingShow()) {
return;
}
@ -1011,11 +1011,10 @@ void ScheduledWidget::updateControlsGeometry() {
}
void ScheduledWidget::paintEvent(QPaintEvent *e) {
if (animating()) {
if (animatingShow()) {
SectionWidget::paintEvent(e);
return;
}
if (Ui::skipPaintEvent(this, e)) {
} else if (Ui::skipPaintEvent(this, e)) {
return;
}
//if (hasPendingResizedItems()) {

View file

@ -264,17 +264,20 @@ void LayerWidget::doSetInnerFocus() {
void LayerWidget::paintEvent(QPaintEvent *e) {
Painter p(this);
auto clip = e->rect();
auto r = st::boxRadius;
const auto clip = e->rect();
const auto radius = st::boxRadius;
auto parts = RectPart::None | 0;
if (clip.intersects({ 0, 0, width(), r })) {
parts |= RectPart::FullTop;
}
if (!_tillBottom) {
if (clip.intersects({ 0, height() - r, width(), r })) {
if (clip.intersects({ 0, height() - radius, width(), radius })) {
parts |= RectPart::FullBottom;
}
}
if (_content->animatingShow()) {
if (clip.intersects({ 0, 0, width(), radius })) {
parts |= RectPart::FullTop;
}
parts |= RectPart::Left | RectPart::Center | RectPart::Right;
}
if (parts) {
Ui::FillRoundRect(
p,

View file

@ -38,6 +38,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "styles/style_info.h"
#include "styles/style_profile.h"
#include "styles/style_menu_icons.h"
#include "styles/style_layers.h"
namespace Info {
namespace {
@ -855,7 +856,9 @@ void WrapWidget::showNewContent(
&& newContent->hasTopBarShadow();
animationParams.oldContentCache = grabForShowAnimation(
animationParams);
animationParams.withFade = (wrap() == Wrap::Layer);
const auto layer = (wrap() == Wrap::Layer);
animationParams.withFade = layer;
animationParams.topSkip = layer ? st::boxRadius : 0;
}
if (saveToStack) {
auto item = StackItem();

View file

@ -102,7 +102,6 @@ object_ptr<Ui::RpWidget> CreateIntroSettings(
AddDivider(result);
AddSkip(result);
SetupFaq(result, false);
AddSkip(result);
return result;
}
@ -110,7 +109,6 @@ object_ptr<Ui::RpWidget> CreateIntroSettings(
TopBar::TopBar(QWidget *parent, const style::InfoTopBar &st)
: RpWidget(parent)
, _st(st) {
setAttribute(Qt::WA_OpaquePaintEvent);
}
void TopBar::setTitle(rpl::producer<QString> &&title) {
@ -156,8 +154,10 @@ void TopBar::updateControlsGeometry(int newWidth) {
}
void TopBar::paintEvent(QPaintEvent *e) {
Painter p(this);
p.fillRect(e->rect(), _st.bg);
const auto radius = st::boxRadius;
QPainter(this).fillRect(
e->rect().intersected({ 0, radius, width(), height() - radius }),
_st.bg);
}
} // namespace
@ -452,11 +452,7 @@ int LayerWidget::resizeGetHeight(int newWidth) {
auto windowHeight = parentSize.height();
auto newLeft = (windowWidth - newWidth) / 2;
if (!newLeft) {
_content->updateGeometry({
0,
st::boxRadius,
windowWidth,
windowHeight - st::boxRadius }, 0);
_content->updateGeometry({ 0, 0, windowWidth, windowHeight }, 0);
auto newGeometry = QRect(0, 0, windowWidth, windowHeight);
if (newGeometry != geometry()) {
_content->forceContentRepaint();
@ -472,12 +468,12 @@ int LayerWidget::resizeGetHeight(int newWidth) {
st::infoLayerTopMinimal,
st::infoLayerTopMaximal);
auto newBottom = newTop;
auto desiredHeight = st::boxRadius + _desiredHeight + st::boxRadius;
auto desiredHeight = _desiredHeight + st::boxRadius;
accumulate_min(desiredHeight, windowHeight - newTop - newBottom);
// First resize content to new width and get the new desired height.
auto contentLeft = 0;
auto contentTop = st::boxRadius;
auto contentTop = 0;
auto contentBottom = st::boxRadius;
auto contentWidth = newWidth;
auto contentHeight = desiredHeight - contentTop - contentBottom;

View file

@ -153,6 +153,7 @@ void SectionWidget::showAnimated(
myContentCache);
_showAnimation->setTopBarShadow(params.withTopBarShadow);
_showAnimation->setWithFade(params.withFade);
_showAnimation->setTopSkip(params.topSkip);
_showAnimation->start();
show();
@ -271,10 +272,14 @@ void SectionWidget::PaintBackground(
void SectionWidget::paintEvent(QPaintEvent *e) {
if (_showAnimation) {
Painter p(this);
_showAnimation->paintContents(p, e->rect());
_showAnimation->paintContents(p);
}
}
bool SectionWidget::animatingShow() const {
return (_showAnimation != nullptr);
}
void SectionWidget::showFinished() {
_showAnimation.reset();
if (isHidden()) return;

View file

@ -72,6 +72,7 @@ class SectionMemento;
struct SectionSlideParams {
QPixmap oldContentCache;
int topSkip = 0;
bool withTopBarShadow = false;
bool withTabs = false;
bool withFade = false;
@ -111,6 +112,7 @@ public:
SlideDirection direction,
const SectionSlideParams &params);
void showFast();
[[nodiscard]] bool animatingShow() const;
// This can be used to grab with or without top bar shadow.
// This will be protected when animation preparation will be done inside.
@ -187,10 +189,6 @@ protected:
setFocus();
}
bool animating() const {
return _showAnimation != nullptr;
}
~SectionWidget();
private:

View file

@ -12,13 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Window {
void SlideAnimation::paintContents(Painter &p, const QRect &update) const {
int retina = cIntRetinaFactor();
void SlideAnimation::paintContents(Painter &p) const {
const auto retina = style::DevicePixelRatio();
auto progress = _animation.value((_direction == SlideDirection::FromLeft) ? 0. : 1.);
if (_withFade) {
p.fillRect(update, st::boxBg);
auto slideLeft = (_direction == SlideDirection::FromLeft);
auto dt = slideLeft
? (1. - progress)
@ -37,12 +35,12 @@ void SlideAnimation::paintContents(Painter &p, const QRect &update) const {
auto leftWidth = (leftWidthFull + leftCoord);
if (leftWidth > 0) {
p.setOpacity(leftAlpha);
p.drawPixmap(0, 0, leftWidth, _cacheUnder.height() / retina, _cacheUnder, (_cacheUnder.width() - leftWidth * cIntRetinaFactor()), 0, leftWidth * cIntRetinaFactor(), _cacheUnder.height());
p.drawPixmap(0, _topSkip, _cacheUnder, (_cacheUnder.width() - leftWidth * cIntRetinaFactor()), _topSkip * retina, leftWidth * cIntRetinaFactor(), _cacheUnder.height() - _topSkip * retina);
}
auto rightWidth = rightWidthFull - rightCoord;
if (rightWidth > 0) {
p.setOpacity(rightAlpha);
p.drawPixmap(rightCoord, 0, _cacheOver, 0, 0, rightWidth * cIntRetinaFactor(), _cacheOver.height());
p.drawPixmap(rightCoord, _topSkip, _cacheOver, 0, _topSkip * retina, rightWidth * cIntRetinaFactor(), _cacheOver.height() - _topSkip * retina);
}
} else {
auto coordUnder = anim::interpolate(0, -st::slideShift, progress);
@ -72,6 +70,10 @@ void SlideAnimation::setTopBarShadow(bool enabled) {
_topBarShadowEnabled = enabled;
}
void SlideAnimation::setTopSkip(int skip) {
_topSkip = skip;
}
void SlideAnimation::setWithFade(bool withFade) {
_withFade = withFade;
}

View file

@ -18,11 +18,12 @@ enum class SlideDirection {
class SlideAnimation {
public:
void paintContents(Painter &p, const QRect &update) const;
void paintContents(Painter &p) const;
void setDirection(SlideDirection direction);
void setPixmaps(const QPixmap &oldContentCache, const QPixmap &newContentCache);
void setTopBarShadow(bool enabled);
void setTopSkip(int skip);
void setWithFade(bool withFade);
using RepaintCallback = Fn<void()>;
@ -41,6 +42,7 @@ private:
void animationCallback();
SlideDirection _direction = SlideDirection::FromRight;
int _topSkip = 0;
bool _topBarShadowEnabled = false;
bool _withFade = false;