Added ability to keep ratio of swipe within range.

This commit is contained in:
23rd 2025-02-19 22:29:09 +03:00 committed by John Preston
parent de87bed375
commit f0c8e48403
2 changed files with 41 additions and 6 deletions

View file

@ -30,6 +30,33 @@ constexpr auto kSwipeSlow = 0.2;
constexpr auto kMsgBareIdSwipeBack = std::numeric_limits<int64>::max() - 77; constexpr auto kMsgBareIdSwipeBack = std::numeric_limits<int64>::max() - 77;
constexpr auto kSwipedBackSpeedRatio = 0.35; constexpr auto kSwipedBackSpeedRatio = 0.35;
float64 InterpolationRatio(float64 from, float64 to, float64 result) {
return (result - from) / (to - from);
};
class RatioRange final {
public:
[[nodiscard]] float64 calcRatio(float64 value) {
if (value < _min) {
const auto shift = _min - value;
_min -= shift;
_max -= shift;
_max = _min + 1;
} else if (value > _max) {
const auto shift = value - _max;
_min += shift;
_max += shift;
_max = _min + 1;
}
return InterpolationRatio(_min, _max, value);
}
private:
float64 _min = 0;
float64 _max = 1;
};
} // namespace } // namespace
void SetupSwipeHandler( void SetupSwipeHandler(
@ -55,6 +82,7 @@ void SetupSwipeHandler(
std::optional<Qt::Orientation> orientation; std::optional<Qt::Orientation> orientation;
std::optional<Qt::LayoutDirection> direction; std::optional<Qt::LayoutDirection> direction;
float64 threshold = style::ConvertFloatScale(kThresholdWidth); float64 threshold = style::ConvertFloatScale(kThresholdWidth);
RatioRange ratioRange;
int directionInt = 1.; int directionInt = 1.;
QPointF startAt; QPointF startAt;
QPointF delta; QPointF delta;
@ -103,10 +131,13 @@ void SetupSwipeHandler(
}; };
const auto processEnd = [=](std::optional<QPointF> delta = {}) { const auto processEnd = [=](std::optional<QPointF> delta = {}) {
if (state->orientation == Qt::Horizontal) { if (state->orientation == Qt::Horizontal) {
const auto rawRatio = delta.value_or(state->delta).x()
/ state->threshold
* state->directionInt;
const auto ratio = std::clamp( const auto ratio = std::clamp(
delta.value_or(state->delta).x() state->finishByTopData.keepRatioWithinRange
/ state->threshold ? state->ratioRange.calcRatio(rawRatio)
* state->directionInt, : rawRatio,
0., 0.,
kMaxRatio); kMaxRatio);
if ((ratio >= 1) && state->finishByTopData.callback) { if ((ratio >= 1) && state->finishByTopData.callback) {
@ -183,9 +214,11 @@ void SetupSwipeHandler(
} }
} else if (*state->orientation == Qt::Horizontal) { } else if (*state->orientation == Qt::Horizontal) {
state->delta = args.delta; state->delta = args.delta;
const auto ratio = args.delta.x() const auto rawRatio = 0
* state->directionInt + args.delta.x() * state->directionInt / state->threshold;
/ state->threshold; const auto ratio = state->finishByTopData.keepRatioWithinRange
? state->ratioRange.calcRatio(rawRatio)
: rawRatio;
updateRatio(ratio); updateRatio(ratio);
constexpr auto kResetReachedOn = 0.95; constexpr auto kResetReachedOn = 0.95;
constexpr auto kBounceDuration = crl::time(500); constexpr auto kBounceDuration = crl::time(500);
@ -435,6 +468,7 @@ SwipeHandlerFinishData DefaultSwipeBackHandlerFinishData(
.callback = std::move(callback), .callback = std::move(callback),
.msgBareId = kMsgBareIdSwipeBack, .msgBareId = kMsgBareIdSwipeBack,
.speedRatio = kSwipedBackSpeedRatio, .speedRatio = kSwipedBackSpeedRatio,
.keepRatioWithinRange = true,
}; };
} }

View file

@ -22,6 +22,7 @@ struct SwipeHandlerFinishData {
Fn<void(void)> callback; Fn<void(void)> callback;
int64 msgBareId = 0; int64 msgBareId = 0;
float64 speedRatio = 1.0; float64 speedRatio = 1.0;
bool keepRatioWithinRange = false;
}; };
using Scroll = std::variant< using Scroll = std::variant<