mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Improve animation in pinned bar.
This commit is contained in:
parent
c2753a9caf
commit
ea6821aca2
2 changed files with 94 additions and 3 deletions
|
@ -13,6 +13,33 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "styles/palette.h"
|
#include "styles/palette.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
[[nodiscard]] int SameFirstPartLength(const QString &a, const QString &b) {
|
||||||
|
const auto [i, j] = ranges::mismatch(a, b);
|
||||||
|
return (i - a.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool MuchDifferent(
|
||||||
|
int same,
|
||||||
|
const QString &a,
|
||||||
|
const QString &b) {
|
||||||
|
return (same * 2 < a.size()) || (same * 2 < b.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool MuchDifferent(const QString &a, const QString &b) {
|
||||||
|
return MuchDifferent(SameFirstPartLength(a, b), a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] bool ComplexTitleAnimation(
|
||||||
|
int same,
|
||||||
|
const QString &a,
|
||||||
|
const QString &b) {
|
||||||
|
return !MuchDifferent(same, a, b)
|
||||||
|
&& (same != a.size() || same != b.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
MessageBar::MessageBar(not_null<QWidget*> parent, const style::MessageBar &st)
|
MessageBar::MessageBar(not_null<QWidget*> parent, const style::MessageBar &st)
|
||||||
: _st(st)
|
: _st(st)
|
||||||
|
@ -51,10 +78,11 @@ MessageBar::BodyAnimation MessageBar::DetectBodyAnimationType(
|
||||||
? currentAnimation->bodyAnimation
|
? currentAnimation->bodyAnimation
|
||||||
: BodyAnimation::None;
|
: BodyAnimation::None;
|
||||||
const auto somethingChanged = (currentContent.text != nextContent.text)
|
const auto somethingChanged = (currentContent.text != nextContent.text)
|
||||||
|
|| (currentContent.title != nextContent.title)
|
||||||
|| (currentContent.index != nextContent.index)
|
|| (currentContent.index != nextContent.index)
|
||||||
|| (currentContent.count != nextContent.count);
|
|| (currentContent.count != nextContent.count);
|
||||||
return (now == BodyAnimation::Full
|
return (now == BodyAnimation::Full
|
||||||
|| currentContent.title != nextContent.title
|
|| MuchDifferent(currentContent.title, nextContent.title)
|
||||||
|| (currentContent.title.isEmpty() && somethingChanged))
|
|| (currentContent.title.isEmpty() && somethingChanged))
|
||||||
? BodyAnimation::Full
|
? BodyAnimation::Full
|
||||||
: (now == BodyAnimation::Text || somethingChanged)
|
: (now == BodyAnimation::Text || somethingChanged)
|
||||||
|
@ -93,10 +121,21 @@ void MessageBar::tweenTo(MessageBarContent &&content) {
|
||||||
: RectPart::None;
|
: RectPart::None;
|
||||||
animation.imageFrom = grabImagePart();
|
animation.imageFrom = grabImagePart();
|
||||||
animation.bodyOrTextFrom = grabBodyOrTextPart(animation.bodyAnimation);
|
animation.bodyOrTextFrom = grabBodyOrTextPart(animation.bodyAnimation);
|
||||||
|
const auto sameLength = SameFirstPartLength(
|
||||||
|
_content.title,
|
||||||
|
content.title);
|
||||||
|
if (animation.bodyAnimation == BodyAnimation::Text
|
||||||
|
&& ComplexTitleAnimation(sameLength, _content.title, content.title)) {
|
||||||
|
animation.titleSame = grabTitleBase(sameLength);
|
||||||
|
animation.titleFrom = grabTitlePart(sameLength);
|
||||||
|
}
|
||||||
auto was = std::move(_animation);
|
auto was = std::move(_animation);
|
||||||
updateFromContent(std::move(content));
|
updateFromContent(std::move(content));
|
||||||
animation.imageTo = grabImagePart();
|
animation.imageTo = grabImagePart();
|
||||||
animation.bodyOrTextTo = grabBodyOrTextPart(animation.bodyAnimation);
|
animation.bodyOrTextTo = grabBodyOrTextPart(animation.bodyAnimation);
|
||||||
|
if (!animation.titleSame.isNull()) {
|
||||||
|
animation.titleTo = grabTitlePart(sameLength);
|
||||||
|
}
|
||||||
if (was) {
|
if (was) {
|
||||||
_animation = std::move(was);
|
_animation = std::move(was);
|
||||||
std::swap(*_animation, animation);
|
std::swap(*_animation, animation);
|
||||||
|
@ -154,6 +193,20 @@ QRect MessageBar::imageRect() const {
|
||||||
return QRect(left, top, size, size);
|
return QRect(left, top, size, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect MessageBar::titleRangeRect(int from, int till) const {
|
||||||
|
auto result = bodyRect();
|
||||||
|
result.setHeight(st::msgServiceNameFont->height);
|
||||||
|
const auto left = from
|
||||||
|
? st::msgServiceNameFont->width(_content.title.mid(0, from))
|
||||||
|
: 0;
|
||||||
|
const auto right = (till <= _content.title.size())
|
||||||
|
? st::msgServiceNameFont->width(_content.title.mid(0, till))
|
||||||
|
: result.width();
|
||||||
|
result.setLeft(result.left() + left);
|
||||||
|
result.setWidth(right - left);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
QRect MessageBar::bodyRect(bool withImage) const {
|
QRect MessageBar::bodyRect(bool withImage) const {
|
||||||
const auto innerLeft = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
const auto innerLeft = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||||
const auto imageSkip = st::msgReplyBarSize.height()
|
const auto imageSkip = st::msgReplyBarSize.height()
|
||||||
|
@ -196,6 +249,21 @@ QPixmap MessageBar::grabBodyOrTextPart(BodyAnimation type) {
|
||||||
: QPixmap();
|
: QPixmap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPixmap MessageBar::grabTitleBase(int till) {
|
||||||
|
return grabTitleRange(0, till);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap MessageBar::grabTitlePart(int from) {
|
||||||
|
Expects(from <= _content.title.size());
|
||||||
|
|
||||||
|
return grabTitleRange(from, _content.title.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap MessageBar::grabTitleRange(int from, int till) {
|
||||||
|
const auto guard = makeGrabGuard();
|
||||||
|
return GrabWidget(widget(), titleRangeRect(from, till));
|
||||||
|
}
|
||||||
|
|
||||||
QPixmap MessageBar::grabBodyPart() {
|
QPixmap MessageBar::grabBodyPart() {
|
||||||
const auto guard = makeGrabGuard();
|
const auto guard = makeGrabGuard();
|
||||||
return GrabWidget(widget(), bodyRect());
|
return GrabWidget(widget(), bodyRect());
|
||||||
|
@ -324,8 +392,24 @@ void MessageBar::paint(Painter &p) {
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
}
|
}
|
||||||
if (!_animation || _animation->bodyAnimation != BodyAnimation::Full) {
|
if (!_animation || _animation->bodyAnimation != BodyAnimation::Full) {
|
||||||
p.setPen(_st.titleFg);
|
if (_animation && !_animation->titleSame.isNull()) {
|
||||||
_title.drawLeftElided(p, body.x(), body.y(), body.width(), width);
|
const auto factor = style::DevicePixelRatio();
|
||||||
|
p.drawPixmap(body.x(), body.y(), _animation->titleSame);
|
||||||
|
p.setOpacity(1. - progress);
|
||||||
|
p.drawPixmap(
|
||||||
|
body.x() + (_animation->titleSame.width() / factor),
|
||||||
|
body.y() + shiftFrom,
|
||||||
|
_animation->titleFrom);
|
||||||
|
p.setOpacity(progress);
|
||||||
|
p.drawPixmap(
|
||||||
|
body.x() + (_animation->titleSame.width() / factor),
|
||||||
|
body.y() + shiftTo,
|
||||||
|
_animation->titleTo);
|
||||||
|
p.setOpacity(1.);
|
||||||
|
} else {
|
||||||
|
p.setPen(_st.titleFg);
|
||||||
|
_title.drawLeftElided(p, body.x(), body.y(), body.width(), width);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
p.setOpacity(1. - progress);
|
p.setOpacity(1. - progress);
|
||||||
p.drawPixmap(
|
p.drawPixmap(
|
||||||
|
|
|
@ -52,6 +52,9 @@ private:
|
||||||
Ui::Animations::Simple barTop;
|
Ui::Animations::Simple barTop;
|
||||||
QPixmap bodyOrTextFrom;
|
QPixmap bodyOrTextFrom;
|
||||||
QPixmap bodyOrTextTo;
|
QPixmap bodyOrTextTo;
|
||||||
|
QPixmap titleSame;
|
||||||
|
QPixmap titleFrom;
|
||||||
|
QPixmap titleTo;
|
||||||
QPixmap imageFrom;
|
QPixmap imageFrom;
|
||||||
QPixmap imageTo;
|
QPixmap imageTo;
|
||||||
BodyAnimation bodyAnimation = BodyAnimation::None;
|
BodyAnimation bodyAnimation = BodyAnimation::None;
|
||||||
|
@ -71,12 +74,16 @@ private:
|
||||||
[[nodiscard]] QPixmap prepareImage(const QImage &preview);
|
[[nodiscard]] QPixmap prepareImage(const QImage &preview);
|
||||||
|
|
||||||
[[nodiscard]] QRect imageRect() const;
|
[[nodiscard]] QRect imageRect() const;
|
||||||
|
[[nodiscard]] QRect titleRangeRect(int from, int till) const;
|
||||||
[[nodiscard]] QRect bodyRect(bool withImage) const;
|
[[nodiscard]] QRect bodyRect(bool withImage) const;
|
||||||
[[nodiscard]] QRect bodyRect() const;
|
[[nodiscard]] QRect bodyRect() const;
|
||||||
[[nodiscard]] QRect textRect() const;
|
[[nodiscard]] QRect textRect() const;
|
||||||
|
|
||||||
auto makeGrabGuard();
|
auto makeGrabGuard();
|
||||||
[[nodiscard]] QPixmap grabBodyOrTextPart(BodyAnimation type);
|
[[nodiscard]] QPixmap grabBodyOrTextPart(BodyAnimation type);
|
||||||
|
[[nodiscard]] QPixmap grabTitleBase(int till);
|
||||||
|
[[nodiscard]] QPixmap grabTitlePart(int from);
|
||||||
|
[[nodiscard]] QPixmap grabTitleRange(int from, int till);
|
||||||
[[nodiscard]] QPixmap grabImagePart();
|
[[nodiscard]] QPixmap grabImagePart();
|
||||||
[[nodiscard]] QPixmap grabBodyPart();
|
[[nodiscard]] QPixmap grabBodyPart();
|
||||||
[[nodiscard]] QPixmap grabTextPart();
|
[[nodiscard]] QPixmap grabTextPart();
|
||||||
|
|
Loading…
Add table
Reference in a new issue