mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Show react button and dropdown with a delay.
This commit is contained in:
parent
87e97ad533
commit
71d52d26c3
3 changed files with 68 additions and 21 deletions
|
@ -2991,6 +2991,7 @@ auto HistoryInner::reactionButtonParameters(
|
|||
).translated({ 0, itemTop(view) });
|
||||
result.visibleTop = _visibleAreaTop;
|
||||
result.visibleBottom = _visibleAreaBottom;
|
||||
result.globalPointer = _mousePosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ constexpr auto kShadowCacheIndex = 0;
|
|||
constexpr auto kEmojiCacheIndex = 1;
|
||||
constexpr auto kMaskCacheIndex = 2;
|
||||
constexpr auto kCacheColumsCount = 3;
|
||||
constexpr auto kButtonShowDelay = crl::time(300);
|
||||
constexpr auto kButtonExpandDelay = crl::time(300);
|
||||
|
||||
[[nodiscard]] QPoint LocalPosition(not_null<QWheelEvent*> e) {
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
|
@ -81,7 +83,8 @@ Button::Button(
|
|||
ButtonParameters parameters)
|
||||
: _update(std::move(update))
|
||||
, _collapsed(QPoint(), CountOuterSize())
|
||||
, _finalHeight(_collapsed.height()) {
|
||||
, _finalHeight(_collapsed.height())
|
||||
, _expandTimer([=] { applyState(State::Inside, _update); }) {
|
||||
applyParameters(parameters, nullptr);
|
||||
}
|
||||
|
||||
|
@ -145,7 +148,19 @@ void Button::applyParameters(
|
|||
if (_state != State::Inside && !_heightAnimation.animating()) {
|
||||
updateExpandDirection(parameters);
|
||||
}
|
||||
const auto state = inside
|
||||
const auto delayInside = inside && (_state != State::Inside);
|
||||
if (!delayInside) {
|
||||
_expandTimer.cancel();
|
||||
_lastGlobalPosition = std::nullopt;
|
||||
} else {
|
||||
const auto globalPositionChanged = _lastGlobalPosition
|
||||
&& (*_lastGlobalPosition != parameters.globalPointer);
|
||||
if (globalPositionChanged || _state == State::Hidden) {
|
||||
_expandTimer.callOnce(kButtonExpandDelay);
|
||||
}
|
||||
_lastGlobalPosition = parameters.globalPointer;
|
||||
}
|
||||
const auto state = (inside && !delayInside)
|
||||
? State::Inside
|
||||
: active
|
||||
? State::Active
|
||||
|
@ -256,10 +271,11 @@ float64 Button::currentScale() const {
|
|||
Manager::Manager(
|
||||
QWidget *wheelEventsTarget,
|
||||
Fn<void(QRect)> buttonUpdate)
|
||||
: _outer(CountOuterSize())
|
||||
, _inner(QRectF({}, st::reactionCornerSize))
|
||||
, _innerActive(QRect({}, CountMaxSizeWithMargins({})))
|
||||
, _buttonUpdate(std::move(buttonUpdate)) {
|
||||
: _outer(CountOuterSize())
|
||||
, _inner(QRectF({}, st::reactionCornerSize))
|
||||
, _innerActive(QRect({}, CountMaxSizeWithMargins({})))
|
||||
, _buttonShowTimer([=] { showButtonDelayed(); })
|
||||
, _buttonUpdate(std::move(buttonUpdate)) {
|
||||
_inner.translate(QRectF({}, _outer).center() - _inner.center());
|
||||
_innerActive.translate(
|
||||
QRect({}, _outer).center() - _innerActive.center());
|
||||
|
@ -290,6 +306,18 @@ Manager::Manager(
|
|||
if (wheelEventsTarget) {
|
||||
stealWheelEvents(wheelEventsTarget);
|
||||
}
|
||||
|
||||
_createChooseCallback = [=](QString emoji) {
|
||||
return [=] {
|
||||
if (const auto context = _buttonContext) {
|
||||
updateButton({});
|
||||
_chosen.fire({
|
||||
.context = context,
|
||||
.emoji = emoji,
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void Manager::stealWheelEvents(not_null<QWidget*> target) {
|
||||
|
@ -304,19 +332,36 @@ void Manager::stealWheelEvents(not_null<QWidget*> target) {
|
|||
Manager::~Manager() = default;
|
||||
|
||||
void Manager::updateButton(ButtonParameters parameters) {
|
||||
if (_button && _buttonContext != parameters.context) {
|
||||
_button->applyState(ButtonState::Hidden);
|
||||
_buttonHiding.push_back(std::move(_button));
|
||||
const auto contextChanged = (_buttonContext != parameters.context);
|
||||
if (contextChanged) {
|
||||
if (_button) {
|
||||
_button->applyState(ButtonState::Hidden);
|
||||
_buttonHiding.push_back(std::move(_button));
|
||||
}
|
||||
_buttonShowTimer.cancel();
|
||||
_scheduledParameters = std::nullopt;
|
||||
}
|
||||
_buttonContext = parameters.context;
|
||||
parameters.reactionsCount = _list.size();
|
||||
if (!_buttonContext || _list.empty()) {
|
||||
return;
|
||||
} else if (!_button) {
|
||||
_button = std::make_unique<Button>(_buttonUpdate, parameters);
|
||||
} else {
|
||||
} else if (_button) {
|
||||
_button->applyParameters(parameters);
|
||||
return;
|
||||
}
|
||||
const auto globalPositionChanged = _scheduledParameters
|
||||
&& (_scheduledParameters->globalPointer != parameters.globalPointer);
|
||||
const auto positionChanged = _scheduledParameters
|
||||
&& (_scheduledParameters->pointer != parameters.pointer);
|
||||
_scheduledParameters = parameters;
|
||||
if ((_buttonShowTimer.isActive() && positionChanged)
|
||||
|| globalPositionChanged) {
|
||||
_buttonShowTimer.callOnce(kButtonShowDelay);
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::showButtonDelayed() {
|
||||
_button = std::make_unique<Button>(_buttonUpdate, *_scheduledParameters);
|
||||
}
|
||||
|
||||
void Manager::applyList(std::vector<Data::Reaction> list) {
|
||||
|
@ -458,17 +503,10 @@ ClickHandlerPtr Manager::resolveButtonLink(
|
|||
if (i != end(_reactionsLinks)) {
|
||||
return i->second;
|
||||
}
|
||||
const auto handler = crl::guard(this, [=] {
|
||||
if (_buttonContext) {
|
||||
_chosen.fire({
|
||||
.context = _buttonContext,
|
||||
.emoji = emoji,
|
||||
});
|
||||
}
|
||||
});
|
||||
return _reactionsLinks.emplace(
|
||||
emoji,
|
||||
std::make_shared<LambdaClickHandler>(handler)
|
||||
std::make_shared<LambdaClickHandler>(
|
||||
crl::guard(this, _createChooseCallback(emoji)))
|
||||
).first->second;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ struct ButtonParameters {
|
|||
FullMsgId context;
|
||||
QPoint center;
|
||||
QPoint pointer;
|
||||
QPoint globalPointer;
|
||||
ButtonStyle style = ButtonStyle::Incoming;
|
||||
int reactionsCount = 1;
|
||||
int visibleTop = 0;
|
||||
|
@ -104,6 +105,9 @@ private:
|
|||
ExpandDirection _expandDirection = ExpandDirection::Up;
|
||||
ButtonStyle _style = ButtonStyle::Incoming;
|
||||
|
||||
base::Timer _expandTimer;
|
||||
std::optional<QPoint> _lastGlobalPosition;
|
||||
|
||||
};
|
||||
|
||||
class Manager final : public base::has_weak_ptr {
|
||||
|
@ -137,6 +141,7 @@ private:
|
|||
};
|
||||
static constexpr auto kFramesCount = 30;
|
||||
|
||||
void showButtonDelayed();
|
||||
void stealWheelEvents(not_null<QWidget*> target);
|
||||
|
||||
[[nodiscard]] bool overCurrentButton(QPoint position) const;
|
||||
|
@ -223,11 +228,14 @@ private:
|
|||
OtherReactionImage> _otherReactions;
|
||||
rpl::lifetime _otherReactionsLifetime;
|
||||
|
||||
std::optional<ButtonParameters> _scheduledParameters;
|
||||
base::Timer _buttonShowTimer;
|
||||
const Fn<void(QRect)> _buttonUpdate;
|
||||
std::unique_ptr<Button> _button;
|
||||
std::vector<std::unique_ptr<Button>> _buttonHiding;
|
||||
FullMsgId _buttonContext;
|
||||
mutable base::flat_map<QString, ClickHandlerPtr> _reactionsLinks;
|
||||
Fn<Fn<void()>(QString)> _createChooseCallback;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue