| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- /*
- This file is part of Telegram Desktop,
- the official desktop application for the Telegram messaging service.
- For license and copyright information please follow this link:
- https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
- */
- #include "ui/controls/emoji_button.h"
- #include "ui/effects/radial_animation.h"
- #include "ui/effects/ripple_animation.h"
- #include "ui/painter.h"
- #include "styles/style_chat_helpers.h"
- namespace Ui {
- EmojiButton::EmojiButton(QWidget *parent, const style::EmojiButton &st)
- : RippleButton(parent, st.inner.ripple)
- , _st(st) {
- resize(_st.inner.width, _st.inner.height);
- setCursor(style::cur_pointer);
- }
- void EmojiButton::paintEvent(QPaintEvent *e) {
- auto p = QPainter(this);
- p.fillRect(e->rect(), _st.bg);
- const auto &st = _st.inner;
- paintRipple(p, st.rippleAreaPosition.x(), st.rippleAreaPosition.y(), _rippleOverride ? &(*_rippleOverride)->c : nullptr);
- const auto over = isOver();
- const auto loadingState = _loading
- ? _loading->computeState()
- : RadialState{ 0., 0, RadialState::kFull };
- const auto icon = _iconOverride ? _iconOverride : &(over ? st.iconOver : st.icon);
- auto position = st.iconPosition;
- if (position.x() < 0) {
- position.setX((width() - icon->width()) / 2);
- }
- if (position.y() < 0) {
- position.setY((height() - icon->height()) / 2);
- }
- const auto skipx = icon->width() / 4;
- const auto skipy = icon->height() / 4;
- const auto inner = QRect(
- position + QPoint(skipx, skipy),
- QSize(icon->width() - 2 * skipx, icon->height() - 2 * skipy));
- if (loadingState.shown < 1.) {
- p.setOpacity(1. - loadingState.shown);
- icon->paint(p, position, width());
- p.setOpacity(1.);
- }
- const auto color = (_colorOverride
- ? *_colorOverride
- : (over ? _st.lineFgOver : _st.lineFg));
- const auto line = style::ConvertScaleExact(st::historyEmojiCircleLine);
- if (anim::Disabled() && _loading && _loading->animating()) {
- anim::DrawStaticLoading(p, inner, line, color);
- } else {
- auto pen = color->p;
- pen.setWidthF(line);
- pen.setCapStyle(Qt::RoundCap);
- p.setPen(pen);
- p.setBrush(Qt::NoBrush);
- PainterHighQualityEnabler hq(p);
- if (loadingState.arcLength < RadialState::kFull) {
- p.drawArc(inner, loadingState.arcFrom, loadingState.arcLength);
- } else {
- p.drawEllipse(inner);
- }
- }
- }
- void EmojiButton::loadingAnimationCallback() {
- if (!anim::Disabled()) {
- update();
- }
- }
- void EmojiButton::setLoading(bool loading) {
- if (loading && !_loading) {
- _loading = std::make_unique<InfiniteRadialAnimation>(
- [=] { loadingAnimationCallback(); },
- st::defaultInfiniteRadialAnimation);
- }
- if (loading) {
- _loading->start();
- update();
- } else if (_loading) {
- _loading->stop();
- update();
- }
- }
- void EmojiButton::setColorOverrides(const style::icon *iconOverride, const style::color *colorOverride, const style::color *rippleOverride) {
- _iconOverride = iconOverride;
- _colorOverride = colorOverride;
- _rippleOverride = rippleOverride;
- update();
- }
- void EmojiButton::onStateChanged(State was, StateChangeSource source) {
- RippleButton::onStateChanged(was, source);
- auto wasOver = static_cast<bool>(was & StateFlag::Over);
- if (isOver() != wasOver) {
- update();
- }
- }
- QPoint EmojiButton::prepareRippleStartPosition() const {
- if (!_st.inner.rippleAreaSize) {
- return DisabledRippleStartPosition();
- }
- return mapFromGlobal(QCursor::pos()) - _st.inner.rippleAreaPosition;
- }
- QImage EmojiButton::prepareRippleMask() const {
- const auto size = _st.inner.rippleAreaSize;
- return RippleAnimation::EllipseMask(QSize(size, size));
- }
- } // namespace Ui
|