Add ripple effect to reply button.

This commit is contained in:
John Preston
2026-03-09 17:16:45 +04:00
parent 5f1121123c
commit 4212be1b6c
4 changed files with 54 additions and 3 deletions
@@ -4442,7 +4442,7 @@ void HistoryInner::mouseActionUpdate() {
lnkhost = reactionView;
} else if (overReplyBtn) {
dragState = replyBtnState;
lnkhost = replyBtnView;
lnkhost = _replyButtonManager.get();
} else if (item) {
if (item != _mouseActionItem || ((m + selectionViewOffset) - _dragStartPosition).manhattanLength() >= QApplication::startDragDistance()) {
if (_mouseAction == MouseAction::PrepareDrag) {
@@ -3871,7 +3871,7 @@ void ListWidget::mouseActionUpdate() {
lnkhost = reactionView;
} else if (overReplyBtn) {
dragState = replyBtnState;
lnkhost = replyBtnView;
lnkhost = _replyButtonManager.get();
} else if (view) {
auto cursorDeltaLength = [&] {
auto cursorDelta = (_overState.point - _pressState.point);
@@ -9,8 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "ui/chat/chat_style.h"
#include "ui/effects/ripple_animation.h"
#include "lang/lang_keys.h"
#include "styles/style_chat.h"
#include "styles/style_widgets.h"
namespace HistoryView::ReplyButton {
namespace {
@@ -182,8 +184,10 @@ void Manager::updateButton(ButtonParameters parameters) {
}
_buttonShowTimer.cancel();
_scheduledParameters = std::nullopt;
_ripple = nullptr;
}
_buttonContext = parameters.context;
_lastPointer = parameters.pointer;
if (parameters.link) {
_link = parameters.link;
}
@@ -279,6 +283,19 @@ void Manager::paintButton(
radius);
p.drawImage(position, *frame.image, frame.rect);
if (_ripple && !_ripple->empty() && _button && button == _button.get()) {
const auto color = context.st->windowBgOver()->c;
_ripple->paint(
p,
position.x() + _inner.x(),
position.y() + _inner.y(),
_inner.width(),
&color);
if (_ripple->empty()) {
_ripple.reset();
}
}
const auto textLeft = position.x()
+ _inner.x()
+ st::replyCornerTextPadding.left();
@@ -334,6 +351,30 @@ void Manager::remove(FullMsgId context) {
if (_buttonContext == context) {
_buttonContext = {};
_button = nullptr;
_ripple = nullptr;
}
}
void Manager::clickHandlerPressedChanged(
const ClickHandlerPtr &action,
bool pressed) {
if (action != _link || !_button) {
return;
}
if (pressed) {
const auto inner = buttonInner();
if (!_ripple) {
const auto mask = Ui::RippleAnimation::RoundRectMask(
inner.size(),
inner.height() / 2);
_ripple = std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
mask,
[=] { if (_button) _buttonUpdate(_button->geometry()); });
}
_ripple->add(_lastPointer - inner.topLeft());
} else if (_ripple) {
_ripple->lastStop();
}
}
@@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/text/text.h"
namespace Ui {
class RippleAnimation;
struct ChatPaintContext;
} // namespace Ui
@@ -93,7 +94,9 @@ private:
};
class Manager final : public base::has_weak_ptr {
class Manager final
: public base::has_weak_ptr
, public ClickHandlerHost {
public:
Manager(Fn<void(QRect)> buttonUpdate);
~Manager();
@@ -103,6 +106,11 @@ public:
[[nodiscard]] TextState buttonTextState(QPoint position) const;
void remove(FullMsgId context);
protected:
void clickHandlerPressedChanged(
const ClickHandlerPtr &action,
bool pressed) override;
private:
void showButtonDelayed();
[[nodiscard]] bool overCurrentButton(QPoint position) const;
@@ -136,6 +144,8 @@ private:
std::vector<std::unique_ptr<Button>> _buttonHiding;
Ui::Text::String _text;
std::unique_ptr<Ui::RippleAnimation> _ripple;
QPoint _lastPointer;
};