mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added bounce animation on finish of replying with left swipe.
This commit is contained in:
parent
7f70ee1227
commit
6129e5a1cf
3 changed files with 56 additions and 10 deletions
|
@ -27,6 +27,7 @@ void SetupSwipeHandler(
|
||||||
const auto threshold = style::ConvertFloatScale(kThresholdWidth);
|
const auto threshold = style::ConvertFloatScale(kThresholdWidth);
|
||||||
struct State {
|
struct State {
|
||||||
base::unique_qptr<QObject> filter;
|
base::unique_qptr<QObject> filter;
|
||||||
|
Ui::Animations::Simple animationReach;
|
||||||
Ui::Animations::Simple animationEnd;
|
Ui::Animations::Simple animationEnd;
|
||||||
SwipeHandlerFinishData finishByTopData;
|
SwipeHandlerFinishData finishByTopData;
|
||||||
std::optional<Qt::Orientation> orientation;
|
std::optional<Qt::Orientation> orientation;
|
||||||
|
@ -41,6 +42,7 @@ void SetupSwipeHandler(
|
||||||
const auto updateRatio = [=](float64 ratio) {
|
const auto updateRatio = [=](float64 ratio) {
|
||||||
update({
|
update({
|
||||||
.ratio = std::clamp(ratio, 0., 1.),
|
.ratio = std::clamp(ratio, 0., 1.),
|
||||||
|
.reachRatio = state->animationReach.value(0.),
|
||||||
.translation = (-std::clamp(ratio, 0., 1.5) * threshold),
|
.translation = (-std::clamp(ratio, 0., 1.5) * threshold),
|
||||||
.msgBareId = state->finishByTopData.msgBareId,
|
.msgBareId = state->finishByTopData.msgBareId,
|
||||||
.cursorTop = state->cursorTop,
|
.cursorTop = state->cursorTop,
|
||||||
|
@ -82,6 +84,9 @@ void SetupSwipeHandler(
|
||||||
scroll->scrolls() | rpl::start_with_next([=] {
|
scroll->scrolls() | rpl::start_with_next([=] {
|
||||||
processEnd(nullptr);
|
processEnd(nullptr);
|
||||||
}, state->lifetime);
|
}, state->lifetime);
|
||||||
|
const auto animationReachCallback = [=] {
|
||||||
|
updateRatio((state->startAt - state->lastAt).x() / threshold);
|
||||||
|
};
|
||||||
const auto filter = [=](not_null<QEvent*> e) {
|
const auto filter = [=](not_null<QEvent*> e) {
|
||||||
if (e->type() == QEvent::Leave && state->orientation) {
|
if (e->type() == QEvent::Leave && state->orientation) {
|
||||||
processEnd(nullptr);
|
processEnd(nullptr);
|
||||||
|
@ -124,8 +129,15 @@ void SetupSwipeHandler(
|
||||||
const auto ratio = delta.x() / threshold;
|
const auto ratio = delta.x() / threshold;
|
||||||
updateRatio(ratio);
|
updateRatio(ratio);
|
||||||
constexpr auto kResetReachedOn = 0.95;
|
constexpr auto kResetReachedOn = 0.95;
|
||||||
|
constexpr auto kBounceDuration = crl::time(500);
|
||||||
if (!state->reached && ratio >= 1.) {
|
if (!state->reached && ratio >= 1.) {
|
||||||
state->reached = true;
|
state->reached = true;
|
||||||
|
state->animationReach.stop();
|
||||||
|
state->animationReach.start(
|
||||||
|
animationReachCallback,
|
||||||
|
0.,
|
||||||
|
1.,
|
||||||
|
kBounceDuration);
|
||||||
base::Platform::Haptic();
|
base::Platform::Haptic();
|
||||||
} else if (state->reached
|
} else if (state->reached
|
||||||
&& ratio < kResetReachedOn) {
|
&& ratio < kResetReachedOn) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ namespace HistoryView {
|
||||||
|
|
||||||
struct ChatPaintGestureHorizontalData {
|
struct ChatPaintGestureHorizontalData {
|
||||||
float64 ratio = 0.;
|
float64 ratio = 0.;
|
||||||
|
float64 reachRatio = 0.;
|
||||||
float64 translation = 0.;
|
float64 translation = 0.;
|
||||||
int64 msgBareId = 0;
|
int64 msgBareId = 0;
|
||||||
int cursorTop = 0;
|
int cursorTop = 0;
|
||||||
|
|
|
@ -40,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "payments/payments_reaction_process.h" // TryAddingPaidReaction.
|
#include "payments/payments_reaction_process.h" // TryAddingPaidReaction.
|
||||||
#include "ui/text/text_options.h"
|
#include "ui/text/text_options.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
#include "window/themes/window_theme.h" // IsNightMode.
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
|
@ -1491,18 +1492,31 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
||||||
p.translate(-context.gestureHorizontal.translation, 0);
|
p.translate(-context.gestureHorizontal.translation, 0);
|
||||||
|
|
||||||
constexpr auto kShiftRatio = 1.5;
|
constexpr auto kShiftRatio = 1.5;
|
||||||
|
constexpr auto kBouncePart = 0.25;
|
||||||
|
constexpr auto kStrokeWidth = 2.;
|
||||||
|
constexpr auto kWaveWidth = 10.;
|
||||||
|
const auto reachRatio = context.gestureHorizontal.reachRatio;
|
||||||
const auto size = st::historyFastShareSize;
|
const auto size = st::historyFastShareSize;
|
||||||
const auto rect = QRect(
|
const auto rect = QRectF(
|
||||||
width() - (size * kShiftRatio) * context.gestureHorizontal.ratio,
|
width() - (size * kShiftRatio) * context.gestureHorizontal.ratio,
|
||||||
g.y() + (g.height() - size) / 2,
|
g.y() + (g.height() - size) / 2,
|
||||||
size,
|
size,
|
||||||
size);
|
size);
|
||||||
const auto center = rect::center(rect);
|
const auto center = rect::center(rect);
|
||||||
const auto spanAngle = -context.gestureHorizontal.ratio
|
const auto spanAngle = context.gestureHorizontal.ratio
|
||||||
* arc::kFullLength;
|
* arc::kFullLength;
|
||||||
const auto strokeWidth = style::ConvertFloatScale(2.);
|
const auto strokeWidth = style::ConvertFloatScale(kStrokeWidth);
|
||||||
auto pen = QPen(context.st->msgServiceBg());
|
|
||||||
pen.setWidthF(strokeWidth);
|
const auto reachScale = std::clamp(
|
||||||
|
(reachRatio > kBouncePart)
|
||||||
|
? (kBouncePart * 2 - reachRatio)
|
||||||
|
: reachRatio,
|
||||||
|
0.,
|
||||||
|
1.);
|
||||||
|
auto pen = Window::Theme::IsNightMode()
|
||||||
|
? QPen(anim::with_alpha(context.st->msgServiceFg()->c, 0.3))
|
||||||
|
: QPen(context.st->msgServiceBg());
|
||||||
|
pen.setWidthF(strokeWidth - (1. * (reachScale / kBouncePart)));
|
||||||
const auto arcRect = rect - Margins(strokeWidth);
|
const auto arcRect = rect - Margins(strokeWidth);
|
||||||
p.save();
|
p.save();
|
||||||
{
|
{
|
||||||
|
@ -1510,15 +1524,34 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(context.st->msgServiceBg());
|
p.setBrush(context.st->msgServiceBg());
|
||||||
p.setOpacity(context.gestureHorizontal.ratio);
|
p.setOpacity(context.gestureHorizontal.ratio);
|
||||||
|
p.translate(center);
|
||||||
|
if (reachScale) {
|
||||||
|
p.scale(-(1. + 1. * reachScale), (1. + 1. * reachScale));
|
||||||
|
} else {
|
||||||
|
p.scale(-1., 1.);
|
||||||
|
}
|
||||||
|
p.translate(-center);
|
||||||
|
// All the next draws are mirrored.
|
||||||
p.drawEllipse(rect);
|
p.drawEllipse(rect);
|
||||||
|
context.st->historyFastShareIcon().paintInCenter(
|
||||||
|
p,
|
||||||
|
QRect(
|
||||||
|
base::SafeRound(rect.x()),
|
||||||
|
base::SafeRound(rect.y()),
|
||||||
|
base::SafeRound(rect.width()),
|
||||||
|
base::SafeRound(rect.height())));
|
||||||
p.setPen(pen);
|
p.setPen(pen);
|
||||||
p.setBrush(Qt::NoBrush);
|
p.setBrush(Qt::NoBrush);
|
||||||
p.drawArc(arcRect, arc::kQuarterLength, spanAngle);
|
p.drawArc(arcRect, arc::kQuarterLength, spanAngle);
|
||||||
p.drawArc(arcRect, arc::kQuarterLength, spanAngle);
|
// p.drawArc(arcRect, arc::kQuarterLength, spanAngle);
|
||||||
p.translate(center);
|
if (reachRatio) {
|
||||||
p.scale(-1., 1.);
|
const auto w = style::ConvertFloatScale(kWaveWidth);
|
||||||
p.translate(-center);
|
p.setOpacity(context.gestureHorizontal.ratio - reachRatio);
|
||||||
context.st->historyFastShareIcon().paintInCenter(p, rect);
|
p.drawArc(
|
||||||
|
arcRect + Margins(reachRatio * reachRatio * w),
|
||||||
|
arc::kQuarterLength,
|
||||||
|
spanAngle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
p.restore();
|
p.restore();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue