mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Formatted classes for send actions.
This commit is contained in:
parent
ccea6ce492
commit
0852dbc40f
3 changed files with 185 additions and 49 deletions
Telegram/SourceFiles
history/view
ui/effects
|
@ -67,9 +67,13 @@ bool SendActionPainter::updateNeedsAnimating(
|
|||
}, [&](const MTPDsendMessageRecordRoundAction &) {
|
||||
emplaceAction(Type::RecordRound, kStatusShowClientsideRecordRound);
|
||||
}, [&](const MTPDsendMessageGeoLocationAction &) {
|
||||
emplaceAction(Type::ChooseLocation, kStatusShowClientsideChooseLocation);
|
||||
emplaceAction(
|
||||
Type::ChooseLocation,
|
||||
kStatusShowClientsideChooseLocation);
|
||||
}, [&](const MTPDsendMessageChooseContactAction &) {
|
||||
emplaceAction(Type::ChooseContact, kStatusShowClientsideChooseContact);
|
||||
emplaceAction(
|
||||
Type::ChooseContact,
|
||||
kStatusShowClientsideChooseContact);
|
||||
}, [&](const MTPDsendMessageUploadVideoAction &data) {
|
||||
emplaceAction(
|
||||
Type::UploadVideo,
|
||||
|
@ -221,19 +225,41 @@ bool SendActionPainter::updateNeedsAnimating(crl::time now, bool force) {
|
|||
} else if (!_sendActions.empty()) {
|
||||
// Handles all actions except game playing.
|
||||
using Type = Api::SendProgressType;
|
||||
auto sendActionString = [](Type type, const QString &name) -> QString {
|
||||
const auto sendActionString = [](
|
||||
Type type,
|
||||
const QString &name) -> QString {
|
||||
switch (type) {
|
||||
case Type::RecordVideo: return name.isEmpty() ? tr::lng_send_action_record_video(tr::now) : tr::lng_user_action_record_video(tr::now, lt_user, name);
|
||||
case Type::UploadVideo: return name.isEmpty() ? tr::lng_send_action_upload_video(tr::now) : tr::lng_user_action_upload_video(tr::now, lt_user, name);
|
||||
case Type::RecordVoice: return name.isEmpty() ? tr::lng_send_action_record_audio(tr::now) : tr::lng_user_action_record_audio(tr::now, lt_user, name);
|
||||
case Type::UploadVoice: return name.isEmpty() ? tr::lng_send_action_upload_audio(tr::now) : tr::lng_user_action_upload_audio(tr::now, lt_user, name);
|
||||
case Type::RecordRound: return name.isEmpty() ? tr::lng_send_action_record_round(tr::now) : tr::lng_user_action_record_round(tr::now, lt_user, name);
|
||||
case Type::UploadRound: return name.isEmpty() ? tr::lng_send_action_upload_round(tr::now) : tr::lng_user_action_upload_round(tr::now, lt_user, name);
|
||||
case Type::UploadPhoto: return name.isEmpty() ? tr::lng_send_action_upload_photo(tr::now) : tr::lng_user_action_upload_photo(tr::now, lt_user, name);
|
||||
case Type::UploadFile: return name.isEmpty() ? tr::lng_send_action_upload_file(tr::now) : tr::lng_user_action_upload_file(tr::now, lt_user, name);
|
||||
case Type::RecordVideo: return name.isEmpty()
|
||||
? tr::lng_send_action_record_video({})
|
||||
: tr::lng_user_action_record_video({}, lt_user, name);
|
||||
case Type::UploadVideo: return name.isEmpty()
|
||||
? tr::lng_send_action_upload_video({})
|
||||
: tr::lng_user_action_upload_video({}, lt_user, name);
|
||||
case Type::RecordVoice: return name.isEmpty()
|
||||
? tr::lng_send_action_record_audio({})
|
||||
: tr::lng_user_action_record_audio({}, lt_user, name);
|
||||
case Type::UploadVoice: return name.isEmpty()
|
||||
? tr::lng_send_action_upload_audio({})
|
||||
: tr::lng_user_action_upload_audio({}, lt_user, name);
|
||||
case Type::RecordRound: return name.isEmpty()
|
||||
? tr::lng_send_action_record_round({})
|
||||
: tr::lng_user_action_record_round({}, lt_user, name);
|
||||
case Type::UploadRound: return name.isEmpty()
|
||||
? tr::lng_send_action_upload_round({})
|
||||
: tr::lng_user_action_upload_round({}, lt_user, name);
|
||||
case Type::UploadPhoto: return name.isEmpty()
|
||||
? tr::lng_send_action_upload_photo({})
|
||||
: tr::lng_user_action_upload_photo({}, lt_user, name);
|
||||
case Type::UploadFile: return name.isEmpty()
|
||||
? tr::lng_send_action_upload_file({})
|
||||
: tr::lng_user_action_upload_file({}, lt_user, name);
|
||||
case Type::ChooseLocation:
|
||||
case Type::ChooseContact: return name.isEmpty() ? tr::lng_typing(tr::now) : tr::lng_user_typing(tr::now, lt_user, name);
|
||||
case Type::ChooseSticker: return name.isEmpty() ? tr::lng_send_action_choose_sticker(tr::now) : tr::lng_user_action_choose_sticker(tr::now, lt_user, name);
|
||||
case Type::ChooseContact: return name.isEmpty()
|
||||
? tr::lng_typing({})
|
||||
: tr::lng_user_typing({}, lt_user, name);
|
||||
case Type::ChooseSticker: return name.isEmpty()
|
||||
? tr::lng_send_action_choose_sticker({})
|
||||
: tr::lng_user_action_choose_sticker({}, lt_user, name);
|
||||
default: break;
|
||||
};
|
||||
return QString();
|
||||
|
|
|
@ -62,7 +62,9 @@ protected:
|
|||
return _started;
|
||||
}
|
||||
[[nodiscard]] int frameTime(crl::time now) const {
|
||||
return anim::Disabled() ? 0 : (std::max(now - _started, crl::time(0)) % _period);
|
||||
return anim::Disabled()
|
||||
? 0
|
||||
: (std::max(now - _started, crl::time(0)) % _period);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -73,7 +75,9 @@ private:
|
|||
|
||||
namespace {
|
||||
|
||||
using ImplementationsMap = QMap<Api::SendProgressType, const SendActionAnimation::Impl::MetaData*>;
|
||||
using ImplementationsMap = QMap<
|
||||
Api::SendProgressType,
|
||||
const SendActionAnimation::Impl::MetaData*>;
|
||||
NeverFreedPointer<ImplementationsMap> Implementations;
|
||||
|
||||
class TypingAnimation : public SendActionAnimation::Impl {
|
||||
|
@ -90,34 +94,64 @@ public:
|
|||
}
|
||||
|
||||
int width() const override {
|
||||
return st::historySendActionTypingPosition.x() + kTypingDotsCount * st::historySendActionTypingDelta;
|
||||
return st::historySendActionTypingPosition.x()
|
||||
+ kTypingDotsCount * st::historySendActionTypingDelta;
|
||||
}
|
||||
|
||||
void paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time now) override;
|
||||
void paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time now) override;
|
||||
|
||||
};
|
||||
|
||||
const TypingAnimation::MetaData TypingAnimation::kMeta = { 0, &TypingAnimation::create };
|
||||
const TypingAnimation::MetaData TypingAnimation::kMeta = {
|
||||
0,
|
||||
&TypingAnimation::create,
|
||||
};
|
||||
|
||||
void TypingAnimation::paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time now) {
|
||||
void TypingAnimation::paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time now) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(color);
|
||||
auto frameMs = frameTime(now);
|
||||
auto position = QPointF(x + 0.5, y - 0.5) + st::historySendActionTypingPosition;
|
||||
auto position = QPointF(x + 0.5, y - 0.5)
|
||||
+ st::historySendActionTypingPosition;
|
||||
for (auto i = 0; i != kTypingDotsCount; ++i) {
|
||||
auto r = st::historySendActionTypingSmallNumerator / st::historySendActionTypingDenominator;
|
||||
auto r = st::historySendActionTypingSmallNumerator
|
||||
/ st::historySendActionTypingDenominator;
|
||||
if (frameMs < 2 * st::historySendActionTypingHalfPeriod) {
|
||||
auto delta = (st::historySendActionTypingLargeNumerator - st::historySendActionTypingSmallNumerator) / st::historySendActionTypingDenominator;
|
||||
const auto delta = (st::historySendActionTypingLargeNumerator
|
||||
- st::historySendActionTypingSmallNumerator)
|
||||
/ st::historySendActionTypingDenominator;
|
||||
if (frameMs < st::historySendActionTypingHalfPeriod) {
|
||||
r += delta * anim::easeOutCirc(1., float64(frameMs) / st::historySendActionTypingHalfPeriod);
|
||||
r += delta
|
||||
* anim::easeOutCirc(
|
||||
1.,
|
||||
float64(frameMs)
|
||||
/ st::historySendActionTypingHalfPeriod);
|
||||
} else {
|
||||
r += delta * (1. - anim::easeOutCirc(1., float64(frameMs - st::historySendActionTypingHalfPeriod) / st::historySendActionTypingHalfPeriod));
|
||||
r += delta
|
||||
* (1. - anim::easeOutCirc(
|
||||
1.,
|
||||
float64(frameMs
|
||||
- st::historySendActionTypingHalfPeriod)
|
||||
/ st::historySendActionTypingHalfPeriod));
|
||||
}
|
||||
}
|
||||
p.drawEllipse(position, r, r);
|
||||
position.setX(position.x() + st::historySendActionTypingDelta);
|
||||
frameMs = (frameMs + st::historySendActionTypingDuration - st::historySendActionTypingDeltaTime) % st::historySendActionTypingDuration;
|
||||
frameMs = (frameMs + period() - st::historySendActionTypingDeltaTime)
|
||||
% period();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,29 +169,51 @@ public:
|
|||
}
|
||||
|
||||
int width() const override {
|
||||
return st::historySendActionRecordPosition.x() + (kRecordArcsCount + 1) * st::historySendActionRecordDelta;
|
||||
return st::historySendActionRecordPosition.x()
|
||||
+ (kRecordArcsCount + 1) * st::historySendActionRecordDelta;
|
||||
}
|
||||
|
||||
void paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time now) override;
|
||||
void paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time now) override;
|
||||
|
||||
};
|
||||
|
||||
const RecordAnimation::MetaData RecordAnimation::kMeta = { 0, &RecordAnimation::create };
|
||||
const RecordAnimation::MetaData RecordAnimation::kMeta = {
|
||||
0,
|
||||
&RecordAnimation::create,
|
||||
};
|
||||
|
||||
void RecordAnimation::paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time now) {
|
||||
void RecordAnimation::paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time now) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
const auto frameMs = frameTime(now);
|
||||
auto pen = color->p;
|
||||
pen.setWidth(st::historySendActionRecordStrokeNumerator / st::historySendActionRecordDenominator);
|
||||
pen.setWidth(st::historySendActionRecordStrokeNumerator
|
||||
/ st::historySendActionRecordDenominator);
|
||||
pen.setJoinStyle(Qt::RoundJoin);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
p.setPen(pen);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
auto progress = frameMs / float64(st::historySendActionRecordDuration);
|
||||
auto size = st::historySendActionRecordPosition.x() + st::historySendActionRecordDelta * progress;
|
||||
auto progress = frameMs / float64(period());
|
||||
auto size = st::historySendActionRecordPosition.x()
|
||||
+ st::historySendActionRecordDelta * progress;
|
||||
y += st::historySendActionRecordPosition.y();
|
||||
for (auto i = 0; i != kRecordArcsCount; ++i) {
|
||||
p.setOpacity((i == 0) ? progress : (i == kRecordArcsCount - 1) ? (1. - progress) : 1.);
|
||||
p.setOpacity((i == 0)
|
||||
? progress
|
||||
: (i == kRecordArcsCount - 1)
|
||||
? (1. - progress)
|
||||
: 1.);
|
||||
auto rect = QRectF(x - size, y - size, 2 * size, 2 * size);
|
||||
p.drawArc(rect, -FullArcLength / 24, FullArcLength / 12);
|
||||
size += st::historySendActionRecordDelta;
|
||||
|
@ -179,33 +235,64 @@ public:
|
|||
}
|
||||
|
||||
int width() const override {
|
||||
return st::historySendActionUploadPosition.x() + (kUploadArrowsCount + 1) * st::historySendActionUploadDelta;
|
||||
return st::historySendActionUploadPosition.x()
|
||||
+ (kUploadArrowsCount + 1) * st::historySendActionUploadDelta;
|
||||
}
|
||||
|
||||
void paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time now) override;
|
||||
void paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time now) override;
|
||||
|
||||
};
|
||||
|
||||
const UploadAnimation::MetaData UploadAnimation::kMeta = { 0, &UploadAnimation::create };
|
||||
const UploadAnimation::MetaData UploadAnimation::kMeta = {
|
||||
0,
|
||||
&UploadAnimation::create,
|
||||
};
|
||||
|
||||
void UploadAnimation::paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time now) {
|
||||
void UploadAnimation::paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time now) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
const auto frameMs = frameTime(now);
|
||||
auto pen = color->p;
|
||||
pen.setWidth(st::historySendActionUploadStrokeNumerator / st::historySendActionUploadDenominator);
|
||||
pen.setWidth(st::historySendActionUploadStrokeNumerator
|
||||
/ st::historySendActionUploadDenominator);
|
||||
pen.setJoinStyle(Qt::RoundJoin);
|
||||
pen.setCapStyle(Qt::RoundCap);
|
||||
p.setPen(pen);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
auto progress = frameMs / float64(st::historySendActionUploadDuration);
|
||||
auto position = QPointF(x + st::historySendActionUploadDelta * progress, y) + st::historySendActionUploadPosition;
|
||||
auto progress = frameMs / float64(period());
|
||||
auto position = st::historySendActionUploadPosition
|
||||
+ QPointF(x + st::historySendActionUploadDelta * progress, y);
|
||||
auto path = QPainterPath();
|
||||
path.moveTo(0., -st::historySendActionUploadSizeNumerator / st::historySendActionUploadDenominator);
|
||||
path.lineTo(st::historySendActionUploadSizeNumerator / st::historySendActionUploadDenominator, 0.);
|
||||
path.lineTo(0., st::historySendActionUploadSizeNumerator / st::historySendActionUploadDenominator);
|
||||
path.moveTo(
|
||||
0.,
|
||||
-st::historySendActionUploadSizeNumerator
|
||||
/ st::historySendActionUploadDenominator);
|
||||
path.lineTo(
|
||||
st::historySendActionUploadSizeNumerator
|
||||
/ st::historySendActionUploadDenominator,
|
||||
0.);
|
||||
path.lineTo(
|
||||
0.,
|
||||
st::historySendActionUploadSizeNumerator
|
||||
/ st::historySendActionUploadDenominator);
|
||||
p.translate(position);
|
||||
for (auto i = 0; i != kUploadArrowsCount; ++i) {
|
||||
p.setOpacity((i == 0) ? progress : (i == kUploadArrowsCount - 1) ? (1. - progress) : 1.);
|
||||
p.setOpacity((i == 0)
|
||||
? progress
|
||||
: (i == kUploadArrowsCount - 1)
|
||||
? (1. - progress)
|
||||
: 1.);
|
||||
p.drawPath(path);
|
||||
position.setX(position.x() + st::historySendActionUploadDelta);
|
||||
p.translate(st::historySendActionUploadDelta, 0);
|
||||
|
@ -570,7 +657,8 @@ SendActionAnimation::~SendActionAnimation() = default;
|
|||
|
||||
bool SendActionAnimation::Impl::supports(Type type) const {
|
||||
CreateImplementationsMap();
|
||||
return Implementations->value(type, &TypingAnimation::kMeta) == metaData();
|
||||
return Implementations->value(type, &TypingAnimation::kMeta)
|
||||
== metaData();
|
||||
}
|
||||
|
||||
void SendActionAnimation::start(Type type) {
|
||||
|
@ -593,13 +681,24 @@ int SendActionAnimation::width() const {
|
|||
return _impl ? _impl->width() : 0;
|
||||
}
|
||||
|
||||
void SendActionAnimation::paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time ms) const {
|
||||
void SendActionAnimation::paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time ms) const {
|
||||
if (_impl) {
|
||||
_impl->paint(p, color, x, y, outerWidth, ms);
|
||||
}
|
||||
}
|
||||
|
||||
void SendActionAnimation::PaintSpeakingIdle(Painter &p, style::color color, int x, int y, int outerWidth) {
|
||||
void SendActionAnimation::PaintSpeakingIdle(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth) {
|
||||
SpeakingAnimation::PaintIdle(p, color, x, y, outerWidth);
|
||||
}
|
||||
|
||||
|
|
|
@ -25,13 +25,24 @@ public:
|
|||
void tryToFinish();
|
||||
|
||||
int width() const;
|
||||
void paint(Painter &p, style::color color, int x, int y, int outerWidth, crl::time ms) const;
|
||||
void paint(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
crl::time ms) const;
|
||||
|
||||
explicit operator bool() const {
|
||||
return _impl != nullptr;
|
||||
}
|
||||
|
||||
static void PaintSpeakingIdle(Painter &p, style::color color, int x, int y, int outerWidth);
|
||||
static void PaintSpeakingIdle(
|
||||
Painter &p,
|
||||
style::color color,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth);
|
||||
|
||||
private:
|
||||
[[nodiscard]] static std::unique_ptr<Impl> CreateByType(Type type);
|
||||
|
|
Loading…
Add table
Reference in a new issue