From 59574532c6299f7f9313aefa79f1ff3a9f3a8b5e Mon Sep 17 00:00:00 2001 From: John Preston <johnprestonmail@gmail.com> Date: Mon, 15 Jul 2019 16:30:17 +0200 Subject: [PATCH] Add slowmode send message button state. --- Telegram/SourceFiles/ui/special_buttons.cpp | 115 ++++++++++++++------ Telegram/SourceFiles/ui/special_buttons.h | 15 +++ 2 files changed, 99 insertions(+), 31 deletions(-) diff --git a/Telegram/SourceFiles/ui/special_buttons.cpp b/Telegram/SourceFiles/ui/special_buttons.cpp index cca32ecf9..d68ddf229 100644 --- a/Telegram/SourceFiles/ui/special_buttons.cpp +++ b/Telegram/SourceFiles/ui/special_buttons.cpp @@ -288,12 +288,19 @@ SendButton::SendButton(QWidget *parent) : RippleButton(parent, st::historyReplyC } void SendButton::setType(Type type) { + Expects(isSlowmode() || type != Type::Slowmode); + + if (isSlowmode() && type != Type::Slowmode) { + _afterSlowmodeType = type; + return; + } if (_type != type) { _contentFrom = grabContent(); _type = type; _a_typeChanged.stop(); _contentTo = grabContent(); - _a_typeChanged.start([this] { update(); }, 0., 1., st::historyRecordVoiceDuration); + _a_typeChanged.start([=] { update(); }, 0., 1., st::historyRecordVoiceDuration); + setPointerCursor(_type != Type::Slowmode); update(); } if (_type != Type::Record) { @@ -310,6 +317,20 @@ void SendButton::setRecordActive(bool recordActive) { } } +void SendButton::setSlowmodeDelay(int seconds) { + Expects(seconds >= 0 && seconds < kSlowmodeDelayLimit); + + if (_slowmodeDelay == seconds) { + return; + } + _slowmodeDelay = seconds; + _slowmodeDelayText = isSlowmode() + ? qsl("%1:%2").arg(seconds / 60).arg(seconds % 60, 2, 10, QChar('0')) + : QString(); + setType(isSlowmode() ? Type::Slowmode : _afterSlowmodeType); + update(); +} + void SendButton::finishAnimating() { _a_typeChanged.stop(); _a_recordActive.stop(); @@ -341,37 +362,65 @@ void SendButton::paintEvent(QPaintEvent *e) { auto shownWidth = anim::interpolate((1 - kWideScale) / 2 * width(), 0, changed); auto shownHeight = anim::interpolate((1 - kWideScale) / 2 * height(), 0, changed); p.drawPixmap(targetRect.marginsAdded(QMargins(shownWidth, shownHeight, shownWidth, shownHeight)), _contentTo); - } else if (_type == Type::Record) { - auto recordActive = recordActiveRatio(); - auto rippleColor = anim::color(st::historyAttachEmoji.ripple.color, st::historyRecordVoiceRippleBgActive, recordActive); - paintRipple(p, (width() - st::historyAttachEmoji.rippleAreaSize) / 2, st::historyAttachEmoji.rippleAreaPosition.y(), &rippleColor); - - auto fastIcon = [&] { - if (recordActive == 1.) { - return &st::historyRecordVoiceActive; - } else if (over) { - return &st::historyRecordVoiceOver; - } - return &st::historyRecordVoice; - }; - fastIcon()->paintInCenter(p, rect()); - if (recordActive > 0. && recordActive < 1.) { - p.setOpacity(recordActive); - st::historyRecordVoiceActive.paintInCenter(p, rect()); - p.setOpacity(1.); - } - } else if (_type == Type::Save) { - auto &saveIcon = over ? st::historyEditSaveIconOver : st::historyEditSaveIcon; - saveIcon.paint(p, st::historySendIconPosition, width()); - } else if (_type == Type::Cancel) { - paintRipple(p, (width() - st::historyAttachEmoji.rippleAreaSize) / 2, st::historyAttachEmoji.rippleAreaPosition.y()); - - auto &cancelIcon = over ? st::historyReplyCancelIconOver : st::historyReplyCancelIcon; - cancelIcon.paintInCenter(p, rect()); - } else { - auto &sendIcon = over ? st::historySendIconOver : st::historySendIcon; - sendIcon.paint(p, st::historySendIconPosition, width()); + return; } + switch (_type) { + case Type::Record: paintRecord(p, over); break; + case Type::Save: paintSave(p, over); break; + case Type::Cancel: paintCancel(p, over); break; + case Type::Send: paintSend(p, over); break; + case Type::Slowmode: paintSlowmode(p); break; + } +} + +void SendButton::paintRecord(Painter &p, bool over) { + auto recordActive = recordActiveRatio(); + auto rippleColor = anim::color(st::historyAttachEmoji.ripple.color, st::historyRecordVoiceRippleBgActive, recordActive); + paintRipple(p, (width() - st::historyAttachEmoji.rippleAreaSize) / 2, st::historyAttachEmoji.rippleAreaPosition.y(), &rippleColor); + + auto fastIcon = [&] { + if (recordActive == 1.) { + return &st::historyRecordVoiceActive; + } else if (over) { + return &st::historyRecordVoiceOver; + } + return &st::historyRecordVoice; + }; + fastIcon()->paintInCenter(p, rect()); + if (recordActive > 0. && recordActive < 1.) { + p.setOpacity(recordActive); + st::historyRecordVoiceActive.paintInCenter(p, rect()); + p.setOpacity(1.); + } +} + +void SendButton::paintSave(Painter &p, bool over) { + const auto &saveIcon = over + ? st::historyEditSaveIconOver + : st::historyEditSaveIcon; + saveIcon.paint(p, st::historySendIconPosition, width()); +} + +void SendButton::paintCancel(Painter &p, bool over) { + paintRipple(p, (width() - st::historyAttachEmoji.rippleAreaSize) / 2, st::historyAttachEmoji.rippleAreaPosition.y()); + + const auto &cancelIcon = over + ? st::historyReplyCancelIconOver + : st::historyReplyCancelIcon; + cancelIcon.paintInCenter(p, rect()); +} + +void SendButton::paintSend(Painter &p, bool over) { + const auto &sendIcon = over + ? st::historySendIconOver + : st::historySendIcon; + sendIcon.paint(p, st::historySendIconPosition, width()); +} + +void SendButton::paintSlowmode(Painter &p) { + p.setFont(st::normalFont); + p.setPen(st::windowSubTextFg); + p.drawText(rect(), _slowmodeDelayText, style::al_center); } void SendButton::onStateChanged(State was, StateChangeSource source) { @@ -395,6 +444,10 @@ void SendButton::onStateChanged(State was, StateChangeSource source) { } } +bool SendButton::isSlowmode() const { + return (_slowmodeDelay > 0); +} + QPixmap SendButton::grabContent() { auto result = QImage(kWideScale * size() * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied); result.setDevicePixelRatio(cRetinaFactor()); diff --git a/Telegram/SourceFiles/ui/special_buttons.h b/Telegram/SourceFiles/ui/special_buttons.h index 1a07e5ca0..4261615c2 100644 --- a/Telegram/SourceFiles/ui/special_buttons.h +++ b/Telegram/SourceFiles/ui/special_buttons.h @@ -78,17 +78,21 @@ class SendButton : public RippleButton { public: SendButton(QWidget *parent); + static constexpr auto kSlowmodeDelayLimit = 100 * 60; + enum class Type { Send, Save, Record, Cancel, + Slowmode, }; Type type() const { return _type; } void setType(Type state); void setRecordActive(bool recordActive); + void setSlowmodeDelay(int seconds); void finishAnimating(); void setRecordStartCallback(Fn<void()> callback) { @@ -119,8 +123,16 @@ protected: private: void recordAnimationCallback(); QPixmap grabContent(); + bool isSlowmode() const; + + void paintRecord(Painter &p, bool over); + void paintSave(Painter &p, bool over); + void paintCancel(Painter &p, bool over); + void paintSend(Painter &p, bool over); + void paintSlowmode(Painter &p); Type _type = Type::Send; + Type _afterSlowmodeType = Type::Send; bool _recordActive = false; QPixmap _contentFrom, _contentTo; @@ -133,6 +145,9 @@ private: Fn<void(QPoint globalPos)> _recordUpdateCallback; Fn<void()> _recordAnimationCallback; + int _slowmodeDelay = 0; + QString _slowmodeDelayText; + }; class UserpicButton : public RippleButton {