Try to show the reaction button outside of the bubble.

This commit is contained in:
John Preston 2021-12-30 23:28:59 +03:00
parent 9486c266b5
commit e722645e7c
4 changed files with 35 additions and 9 deletions

View file

@ -1867,11 +1867,16 @@ Reactions::ButtonParameters Message::reactionButtonParameters(
st::reactionCornerCenter.y())) st::reactionCornerCenter.y()))
: (QPoint(contentRect.width(), innerHeight) : (QPoint(contentRect.width(), innerHeight)
+ st::reactionCornerCenter)); + st::reactionCornerCenter));
if (reactionState.itemId != result.context) { if (reactionState.itemId != result.context
if (!contentRect.contains(position)) { && !contentRect.contains(position)) {
return {}; result.outside = true;
}
} }
const auto minSkip = (st::reactionCornerShadow.left()
+ st::reactionCornerSize.width()
+ st::reactionCornerShadow.right()) / 2;
result.center = QPoint(
std::min(std::max(result.center.x(), minSkip), width() - minSkip),
result.center.y());
return result; return result;
} }

View file

@ -32,6 +32,7 @@ constexpr auto kMaskCacheIndex = 2;
constexpr auto kCacheColumsCount = 3; constexpr auto kCacheColumsCount = 3;
constexpr auto kButtonShowDelay = crl::time(300); constexpr auto kButtonShowDelay = crl::time(300);
constexpr auto kButtonExpandDelay = crl::time(300); constexpr auto kButtonExpandDelay = crl::time(300);
constexpr auto kButtonHideDelay = crl::time(200);
[[nodiscard]] QPoint LocalPosition(not_null<QWheelEvent*> e) { [[nodiscard]] QPoint LocalPosition(not_null<QWheelEvent*> e) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
@ -60,11 +61,13 @@ constexpr auto kButtonExpandDelay = crl::time(300);
Button::Button( Button::Button(
Fn<void(QRect)> update, Fn<void(QRect)> update,
ButtonParameters parameters) ButtonParameters parameters,
Fn<void()> hideMe)
: _update(std::move(update)) : _update(std::move(update))
, _collapsed(QPoint(), CountOuterSize()) , _collapsed(QPoint(), CountOuterSize())
, _finalHeight(_collapsed.height()) , _finalHeight(_collapsed.height())
, _expandTimer([=] { applyState(State::Inside, _update); }) { , _expandTimer([=] { applyState(State::Inside, _update); })
, _hideTimer(hideMe) {
applyParameters(parameters, nullptr); applyParameters(parameters, nullptr);
} }
@ -152,6 +155,11 @@ void Button::applyParameters(
update(_geometry); update(_geometry);
} }
} }
if (parameters.outside && _state == State::Shown) {
_hideTimer.callOnce(kButtonHideDelay);
} else {
_hideTimer.cancel();
}
} }
void Button::updateExpandDirection(const ButtonParameters &parameters) { void Button::updateExpandDirection(const ButtonParameters &parameters) {
@ -202,6 +210,7 @@ void Button::applyState(State state) {
void Button::applyState(State state, Fn<void(QRect)> update) { void Button::applyState(State state, Fn<void(QRect)> update) {
if (state == State::Hidden) { if (state == State::Hidden) {
_expandTimer.cancel(); _expandTimer.cancel();
_hideTimer.cancel();
} }
const auto finalHeight = (state == State::Inside) const auto finalHeight = (state == State::Inside)
? _expandedHeight ? _expandedHeight
@ -332,6 +341,10 @@ void Manager::updateButton(ButtonParameters parameters) {
} else if (_button) { } else if (_button) {
_button->applyParameters(parameters); _button->applyParameters(parameters);
return; return;
} else if (parameters.outside) {
_buttonShowTimer.cancel();
_scheduledParameters = std::nullopt;
return;
} }
const auto globalPositionChanged = _scheduledParameters const auto globalPositionChanged = _scheduledParameters
&& (_scheduledParameters->globalPointer != parameters.globalPointer); && (_scheduledParameters->globalPointer != parameters.globalPointer);
@ -345,7 +358,10 @@ void Manager::updateButton(ButtonParameters parameters) {
} }
void Manager::showButtonDelayed() { void Manager::showButtonDelayed() {
_button = std::make_unique<Button>(_buttonUpdate, *_scheduledParameters); _button = std::make_unique<Button>(
_buttonUpdate,
*_scheduledParameters,
[=]{ updateButton({}); });
} }
void Manager::applyList(std::vector<Data::Reaction> list) { void Manager::applyList(std::vector<Data::Reaction> list) {

View file

@ -53,6 +53,7 @@ struct ButtonParameters {
int reactionsCount = 1; int reactionsCount = 1;
int visibleTop = 0; int visibleTop = 0;
int visibleBottom = 0; int visibleBottom = 0;
bool outside = false;
}; };
enum class ButtonState { enum class ButtonState {
@ -64,7 +65,10 @@ enum class ButtonState {
class Button final { class Button final {
public: public:
Button(Fn<void(QRect)> update, ButtonParameters parameters); Button(
Fn<void(QRect)> update,
ButtonParameters parameters,
Fn<void()> hideMe);
~Button(); ~Button();
void applyParameters(ButtonParameters parameters); void applyParameters(ButtonParameters parameters);
@ -106,6 +110,7 @@ private:
ButtonStyle _style = ButtonStyle::Incoming; ButtonStyle _style = ButtonStyle::Incoming;
base::Timer _expandTimer; base::Timer _expandTimer;
base::Timer _hideTimer;
std::optional<QPoint> _lastGlobalPosition; std::optional<QPoint> _lastGlobalPosition;
}; };

View file

@ -976,7 +976,7 @@ reactionInfoBetween: 3px;
reactionCornerSize: size(40px, 32px); reactionCornerSize: size(40px, 32px);
reactionCornerRadius: 14px; reactionCornerRadius: 14px;
reactionCornerCenter: point(-10px, -8px); reactionCornerCenter: point(12px, -12px);
reactionCornerImage: 24px; reactionCornerImage: 24px;
reactionCornerShadow: margins(4px, 4px, 4px, 8px); reactionCornerShadow: margins(4px, 4px, 4px, 8px);
reactionCornerActiveAreaPadding: margins(10px, 10px, 10px, 10px); reactionCornerActiveAreaPadding: margins(10px, 10px, 10px, 10px);