From 07689476a6d7f94e8034cc9061de4ebea7261bd9 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 16 Nov 2016 19:04:25 +0300 Subject: [PATCH] Closed beta 10019008: Some more ripple animations added. --- Telegram/Resources/colors.palette | 11 +- Telegram/Resources/sample.tdesktop-theme | 9 +- Telegram/Resources/winrc/Telegram.rc | 8 +- Telegram/Resources/winrc/Updater.rc | 8 +- Telegram/SourceFiles/boxes/autolockbox.h | 2 +- Telegram/SourceFiles/boxes/backgroundbox.h | 2 +- Telegram/SourceFiles/boxes/boxes.style | 28 +- Telegram/SourceFiles/boxes/connectionbox.h | 2 +- Telegram/SourceFiles/boxes/contactsbox.h | 4 +- Telegram/SourceFiles/boxes/downloadpathbox.h | 2 +- Telegram/SourceFiles/boxes/emojibox.h | 2 +- Telegram/SourceFiles/boxes/languagebox.h | 2 +- Telegram/SourceFiles/boxes/localstoragebox.h | 2 +- Telegram/SourceFiles/boxes/members_box.cpp | 28 ++ Telegram/SourceFiles/boxes/members_box.h | 20 +- .../SourceFiles/boxes/notifications_box.h | 2 +- Telegram/SourceFiles/boxes/passcodebox.h | 2 +- Telegram/SourceFiles/boxes/photocropbox.h | 2 +- Telegram/SourceFiles/boxes/photosendbox.h | 2 +- Telegram/SourceFiles/boxes/report_box.h | 2 +- Telegram/SourceFiles/boxes/sessionsbox.h | 2 +- Telegram/SourceFiles/boxes/sharebox.h | 2 +- Telegram/SourceFiles/boxes/stickers_box.cpp | 79 +++- Telegram/SourceFiles/boxes/stickers_box.h | 11 +- Telegram/SourceFiles/boxes/stickersetbox.h | 2 +- Telegram/SourceFiles/boxes/usernamebox.h | 2 +- Telegram/SourceFiles/core/version.h | 2 +- Telegram/SourceFiles/dialogs/dialogs.style | 11 +- Telegram/SourceFiles/history/history.style | 63 ++- Telegram/SourceFiles/history/history_item.cpp | 88 +++-- Telegram/SourceFiles/history/history_item.h | 37 +- .../SourceFiles/history/history_message.cpp | 11 +- .../SourceFiles/history/history_message.h | 4 +- Telegram/SourceFiles/historywidget.cpp | 21 +- Telegram/SourceFiles/historywidget.h | 4 +- Telegram/SourceFiles/intro/intro.style | 3 - .../media/player/media_player.style | 2 - .../SourceFiles/media/view/mediaview.style | 7 +- .../profile/profile_actions_widget.cpp | 2 +- .../profile/profile_members_widget.cpp | 2 +- .../profile/profile_settings_widget.cpp | 2 +- .../profile/profile_shared_media_widget.cpp | 2 +- Telegram/SourceFiles/settings/settings.style | 1 - Telegram/SourceFiles/stickers/emoji_pan.cpp | 63 ++- Telegram/SourceFiles/stickers/emoji_pan.h | 4 + Telegram/SourceFiles/stickers/stickers.style | 5 - .../ui/buttons/history_down_button.cpp | 61 ++- .../ui/buttons/history_down_button.h | 12 +- .../ui/buttons/left_outline_button.cpp | 71 ---- .../ui/buttons/left_outline_button.h | 49 --- .../ui/effects/ripple_animation.cpp | 29 ++ .../SourceFiles/ui/effects/ripple_animation.h | 5 + Telegram/SourceFiles/ui/widgets/buttons.cpp | 361 ++++++++---------- Telegram/SourceFiles/ui/widgets/buttons.h | 154 +++++--- .../SourceFiles/ui/widgets/dropdown_menu.cpp | 9 + .../SourceFiles/ui/widgets/dropdown_menu.h | 4 + Telegram/SourceFiles/ui/widgets/menu.cpp | 65 +++- Telegram/SourceFiles/ui/widgets/menu.h | 13 + .../SourceFiles/ui/widgets/popup_menu.cpp | 9 + Telegram/SourceFiles/ui/widgets/popup_menu.h | 4 + Telegram/SourceFiles/ui/widgets/widgets.style | 81 ++-- .../SourceFiles/window/top_bar_widget.cpp | 10 +- Telegram/SourceFiles/window/window.style | 11 +- .../SourceFiles/window/window_main_menu.cpp | 1 + Telegram/build/version | 2 +- Telegram/gyp/Telegram.gyp | 2 - 66 files changed, 845 insertions(+), 680 deletions(-) delete mode 100644 Telegram/SourceFiles/ui/buttons/left_outline_button.cpp delete mode 100644 Telegram/SourceFiles/ui/buttons/left_outline_button.h diff --git a/Telegram/Resources/colors.palette b/Telegram/Resources/colors.palette index 2547b6c571..033868bc1f 100644 --- a/Telegram/Resources/colors.palette +++ b/Telegram/Resources/colors.palette @@ -53,6 +53,11 @@ lightButtonBgRipple: #c9e4f6; lightButtonFg: #2b99d5; lightButtonFgOver: lightButtonFg; +attentionButtonFg: #d14e4e; +attentionButtonFgOver: #d14e4e; +attentionButtonBgOver: #fcdfde; +attentionButtonBgRipple: #f4c3c2; + menuBg: windowBg; menuBgOver: windowBgOver; menuBgRipple: windowBgRipple; @@ -99,11 +104,6 @@ boxBlockTitleAdditionalFg: #808080; boxBlockTitleCloseFg: cancelIconFg; boxBlockTitleCloseFgOver: cancelIconFgOver; -attentionBoxButtonFg: #d14e4e; -attentionBoxButtonFgOver: #d14e4e; -attentionBoxButtonBgOver: #fcdfde; -attentionBoxButtonBgRipple: #f4c3c2; - membersAboutLimitFg: windowSubTextFgOver; contactsBg: windowBg; @@ -228,6 +228,7 @@ mediaviewFileExtFg: activeButtonFg; mediaviewMenuBg: #383838; mediaviewMenuBgOver: #505050; +mediaviewMenuBgRipple: #676767; mediaviewMenuFg: #ffffff; mediaviewBg: #222222eb; diff --git a/Telegram/Resources/sample.tdesktop-theme b/Telegram/Resources/sample.tdesktop-theme index 33f5875229..fdcb3084bc 100644 --- a/Telegram/Resources/sample.tdesktop-theme +++ b/Telegram/Resources/sample.tdesktop-theme @@ -49,6 +49,10 @@ lightButtonBgOver: #e3f1fa; lightButtonBgRipple: #c9e4f6; lightButtonFg: #2b99d5; lightButtonFgOver: lightButtonFg; +attentionButtonFg: #d14e4e; +attentionButtonFgOver: #d14e4e; +attentionButtonBgOver: #fcdfde; +attentionButtonBgRipple: #f4c3c2; menuBg: windowBg; menuBgOver: windowBgOver; menuBgRipple: windowBgRipple; @@ -84,10 +88,6 @@ boxBlockTitleFg: boxTitleFg; boxBlockTitleAdditionalFg: #808080; boxBlockTitleCloseFg: cancelIconFg; boxBlockTitleCloseFgOver: cancelIconFgOver; -attentionBoxButtonFg: #d14e4e; -attentionBoxButtonFgOver: #d14e4e; -attentionBoxButtonBgOver: #fcdfde; -attentionBoxButtonBgRipple: #f4c3c2; membersAboutLimitFg: windowSubTextFgOver; contactsBg: windowBg; contactsBgOver: windowBgOver; @@ -189,6 +189,7 @@ mediaviewFileBlueCornerFg: #599dcf; mediaviewFileExtFg: activeButtonFg; mediaviewMenuBg: #383838; mediaviewMenuBgOver: #505050; +mediaviewMenuBgRipple: #676767; mediaviewMenuFg: #ffffff; mediaviewBg: #222222eb; mediaviewVideoBg: #000000; diff --git a/Telegram/Resources/winrc/Telegram.rc b/Telegram/Resources/winrc/Telegram.rc index f0e42625af..6f364b3933 100644 --- a/Telegram/Resources/winrc/Telegram.rc +++ b/Telegram/Resources/winrc/Telegram.rc @@ -34,8 +34,8 @@ IDI_ICON1 ICON "..\\art\\icon256.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,19,7 - PRODUCTVERSION 0,10,19,7 + FILEVERSION 0,10,19,8 + PRODUCTVERSION 0,10,19,8 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -51,10 +51,10 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "Telegram Messenger LLP" - VALUE "FileVersion", "0.10.19.7" + VALUE "FileVersion", "0.10.19.8" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.19.7" + VALUE "ProductVersion", "0.10.19.8" END END BLOCK "VarFileInfo" diff --git a/Telegram/Resources/winrc/Updater.rc b/Telegram/Resources/winrc/Updater.rc index 16592aafb0..79ff23db8c 100644 --- a/Telegram/Resources/winrc/Updater.rc +++ b/Telegram/Resources/winrc/Updater.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,10,19,7 - PRODUCTVERSION 0,10,19,7 + FILEVERSION 0,10,19,8 + PRODUCTVERSION 0,10,19,8 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,10 +43,10 @@ BEGIN BEGIN VALUE "CompanyName", "Telegram Messenger LLP" VALUE "FileDescription", "Telegram Updater" - VALUE "FileVersion", "0.10.19.7" + VALUE "FileVersion", "0.10.19.8" VALUE "LegalCopyright", "Copyright (C) 2014-2016" VALUE "ProductName", "Telegram Desktop" - VALUE "ProductVersion", "0.10.19.7" + VALUE "ProductVersion", "0.10.19.8" END END BLOCK "VarFileInfo" diff --git a/Telegram/SourceFiles/boxes/autolockbox.h b/Telegram/SourceFiles/boxes/autolockbox.h index e5b6e6c929..9ef8c31328 100644 --- a/Telegram/SourceFiles/boxes/autolockbox.h +++ b/Telegram/SourceFiles/boxes/autolockbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class Radiobutton; diff --git a/Telegram/SourceFiles/boxes/backgroundbox.h b/Telegram/SourceFiles/boxes/backgroundbox.h index 500ad61d87..b495780a31 100644 --- a/Telegram/SourceFiles/boxes/backgroundbox.h +++ b/Telegram/SourceFiles/boxes/backgroundbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "core/lambda_wrap.h" class BackgroundBox : public ItemListBox { diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 42481fa7c5..138f20a75d 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -37,7 +37,6 @@ defaultBoxButton: RoundButton { padding: margins(0px, 0px, 0px, 0px); textTop: 8px; - downTextTop: 8px; font: boxButtonFont; @@ -51,12 +50,12 @@ cancelBoxButton: RoundButton(defaultBoxButton) { } attentionBoxButton: RoundButton(defaultBoxButton) { - textFg: attentionBoxButtonFg; - textFgOver: attentionBoxButtonFgOver; - textBgOver: attentionBoxButtonBgOver; + textFg: attentionButtonFg; + textFgOver: attentionButtonFgOver; + textBgOver: attentionButtonBgOver; ripple: RippleAnimation(defaultRippleAnimation) { - color: attentionBoxButtonBgRipple; + color: attentionButtonBgRipple; } } @@ -198,12 +197,21 @@ contactUserIcon: icon {{ "add_contact_user", #999999 }}; contactPhoneIcon: icon {{ "add_contact_phone", #999999 }}; contactIconTop: 10px; -contactsAdd: IconButton { +contactsAddIconAbove: icon {{ "contacts_add", activeButtonFg, point(18px, 18px) }}; +contactsAdd: TwoIconButton { width: 52px; height: 52px; - icon: contactsAddIcon; - iconOver: contactsAddIconOver; + iconBelow: contactsAddIconBelow; + iconBelowOver: contactsAddIconBelowOver; + iconAbove: contactsAddIconAbove; + iconAboveOver: contactsAddIconAbove; + + rippleAreaPosition: point(5px, 5px); + rippleAreaSize: 42px; + ripple: RippleAnimation(defaultRippleAnimation) { + color: activeButtonBgRipple; + } } contactsAddPosition: point(14px, 8px); @@ -289,9 +297,7 @@ contactsMultiSelect: MultiSelect { icon: boxSearchCancelIcon; iconOver: boxSearchCancelIconOver; - iconPosition: point(8px, 18px); - iconPositionDown: point(8px, 18px); } fieldCancelSkip: 34px; } @@ -370,9 +376,7 @@ sessionTerminate: IconButton { icon: simpleCloseIcon; iconOver: simpleCloseIconOver; - iconPosition: point(3px, 3px); - iconPositionDown: point(3px, 4px); } sessionTerminateAllButton: LinkButton(boxLinkButton) { color: #d15948; diff --git a/Telegram/SourceFiles/boxes/connectionbox.h b/Telegram/SourceFiles/boxes/connectionbox.h index 65ae47359b..346fcdde4c 100644 --- a/Telegram/SourceFiles/boxes/connectionbox.h +++ b/Telegram/SourceFiles/boxes/connectionbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class InputField; diff --git a/Telegram/SourceFiles/boxes/contactsbox.h b/Telegram/SourceFiles/boxes/contactsbox.h index 41d9520d97..2dd846199d 100644 --- a/Telegram/SourceFiles/boxes/contactsbox.h +++ b/Telegram/SourceFiles/boxes/contactsbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "core/single_timer.h" #include "ui/effects/round_image_checkbox.h" #include "boxes/members_box.h" @@ -93,7 +93,7 @@ private: class Inner; ChildWidget _inner; ChildWidget> _select; - ChildWidget _add = { nullptr }; + ChildWidget _add = { nullptr }; ChildWidget _next; ChildWidget _cancel; diff --git a/Telegram/SourceFiles/boxes/downloadpathbox.h b/Telegram/SourceFiles/boxes/downloadpathbox.h index 070e8889b5..4d543da4b8 100644 --- a/Telegram/SourceFiles/boxes/downloadpathbox.h +++ b/Telegram/SourceFiles/boxes/downloadpathbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "core/observer.h" namespace Ui { diff --git a/Telegram/SourceFiles/boxes/emojibox.h b/Telegram/SourceFiles/boxes/emojibox.h index a04b493788..4dad5370f7 100644 --- a/Telegram/SourceFiles/boxes/emojibox.h +++ b/Telegram/SourceFiles/boxes/emojibox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" class EmojiBox : public AbstractBox { Q_OBJECT diff --git a/Telegram/SourceFiles/boxes/languagebox.h b/Telegram/SourceFiles/boxes/languagebox.h index 53a5852e0d..860fc5ac95 100644 --- a/Telegram/SourceFiles/boxes/languagebox.h +++ b/Telegram/SourceFiles/boxes/languagebox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class Radiobutton; diff --git a/Telegram/SourceFiles/boxes/localstoragebox.h b/Telegram/SourceFiles/boxes/localstoragebox.h index 178135d9e3..9bb5120e8c 100644 --- a/Telegram/SourceFiles/boxes/localstoragebox.h +++ b/Telegram/SourceFiles/boxes/localstoragebox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class RoundButton; diff --git a/Telegram/SourceFiles/boxes/members_box.cpp b/Telegram/SourceFiles/boxes/members_box.cpp index 9120cadac6..737818fe5d 100644 --- a/Telegram/SourceFiles/boxes/members_box.cpp +++ b/Telegram/SourceFiles/boxes/members_box.cpp @@ -30,8 +30,36 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "boxes/confirmbox.h" #include "ui/widgets/buttons.h" #include "ui/widgets/scroll_area.h" +#include "ui/effects/ripple_animation.h" #include "observer_peer.h" + +MembersAddButton::MembersAddButton(QWidget *parent, const style::TwoIconButton &st) : RippleButton(parent, st.ripple) +, _st(st) { + resize(_st.width, _st.height); + setCursor(style::cur_pointer); +} + +void MembersAddButton::paintEvent(QPaintEvent *e) { + Painter p(this); + + auto ms = getms(); + auto over = (_state & StateOver); + auto down = (_state & StateDown); + + ((over || down) ? _st.iconBelowOver : _st.iconBelow).paint(p, _st.iconPosition, width()); + paintRipple(p, _st.rippleAreaPosition.x(), _st.rippleAreaPosition.y(), ms); + ((over || down) ? _st.iconAboveOver : _st.iconAbove).paint(p, _st.iconPosition, width()); +} + +QImage MembersAddButton::prepareRippleMask() const { + return Ui::RippleAnimation::ellipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize)); +} + +QPoint MembersAddButton::prepareRippleStartPosition() const { + return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition; +} + MembersBox::MembersBox(ChannelData *channel, MembersFilter filter) : ItemListBox(st::boxScroll) , _inner(this, channel, filter) { ItemListBox::init(_inner); diff --git a/Telegram/SourceFiles/boxes/members_box.h b/Telegram/SourceFiles/boxes/members_box.h index b2bdffbdde..809f8408e4 100644 --- a/Telegram/SourceFiles/boxes/members_box.h +++ b/Telegram/SourceFiles/boxes/members_box.h @@ -20,9 +20,10 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "core/single_timer.h" #include "ui/effects/round_image_checkbox.h" +#include "ui/widgets/buttons.h" class ContactsBox; class ConfirmBox; @@ -33,6 +34,21 @@ enum class MembersFilter { }; using MembersAlreadyIn = OrderedSet; +class MembersAddButton : public Ui::RippleButton { +public: + MembersAddButton(QWidget *parent, const style::TwoIconButton &st); + +protected: + void paintEvent(QPaintEvent *e) override; + + QImage prepareRippleMask() const override; + QPoint prepareRippleStartPosition() const override; + +private: + const style::TwoIconButton &_st; + +}; + class MembersBox : public ItemListBox { Q_OBJECT @@ -54,7 +70,7 @@ private: class Inner; ChildWidget _inner; - ChildWidget _add = { nullptr }; + ChildWidget _add = { nullptr }; ContactsBox *_addBox = nullptr; diff --git a/Telegram/SourceFiles/boxes/notifications_box.h b/Telegram/SourceFiles/boxes/notifications_box.h index cd91144830..a6c948819c 100644 --- a/Telegram/SourceFiles/boxes/notifications_box.h +++ b/Telegram/SourceFiles/boxes/notifications_box.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class RoundButton; diff --git a/Telegram/SourceFiles/boxes/passcodebox.h b/Telegram/SourceFiles/boxes/passcodebox.h index 9c15dbb943..251da9c91f 100644 --- a/Telegram/SourceFiles/boxes/passcodebox.h +++ b/Telegram/SourceFiles/boxes/passcodebox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class InputField; diff --git a/Telegram/SourceFiles/boxes/photocropbox.h b/Telegram/SourceFiles/boxes/photocropbox.h index 470344acd9..65671f2062 100644 --- a/Telegram/SourceFiles/boxes/photocropbox.h +++ b/Telegram/SourceFiles/boxes/photocropbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class RoundButton; diff --git a/Telegram/SourceFiles/boxes/photosendbox.h b/Telegram/SourceFiles/boxes/photosendbox.h index 64dd01048a..0d15884304 100644 --- a/Telegram/SourceFiles/boxes/photosendbox.h +++ b/Telegram/SourceFiles/boxes/photosendbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "localimageloader.h" namespace Ui { diff --git a/Telegram/SourceFiles/boxes/report_box.h b/Telegram/SourceFiles/boxes/report_box.h index b02bee0217..28520ee200 100644 --- a/Telegram/SourceFiles/boxes/report_box.h +++ b/Telegram/SourceFiles/boxes/report_box.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class Radiobutton; diff --git a/Telegram/SourceFiles/boxes/sessionsbox.h b/Telegram/SourceFiles/boxes/sessionsbox.h index b3d8c96dff..141a4adda0 100644 --- a/Telegram/SourceFiles/boxes/sessionsbox.h +++ b/Telegram/SourceFiles/boxes/sessionsbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "core/single_timer.h" class ConfirmBox; diff --git a/Telegram/SourceFiles/boxes/sharebox.h b/Telegram/SourceFiles/boxes/sharebox.h index f986e14b66..c24e93e266 100644 --- a/Telegram/SourceFiles/boxes/sharebox.h +++ b/Telegram/SourceFiles/boxes/sharebox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "core/lambda_wrap.h" #include "core/observer.h" #include "core/vector_of_moveable.h" diff --git a/Telegram/SourceFiles/boxes/stickers_box.cpp b/Telegram/SourceFiles/boxes/stickers_box.cpp index 6b8514fa28..d883fb7ccb 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.cpp +++ b/Telegram/SourceFiles/boxes/stickers_box.cpp @@ -33,6 +33,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "styles/style_stickers.h" #include "ui/widgets/buttons.h" #include "ui/widgets/scroll_area.h" +#include "ui/effects/ripple_animation.h" namespace { @@ -563,6 +564,7 @@ void StickersBox::Inner::paintEvent(QPaintEvent *e) { _a_shifting.step(); + auto ms = getms(); p.fillRect(r, st::boxBg); p.setClipRect(r); @@ -591,19 +593,26 @@ void StickersBox::Inner::paintEvent(QPaintEvent *e) { p.translate(0, from * _rowHeight); for (int32 i = from; i < to; ++i) { if (i != _above) { - paintRow(p, i); + paintRow(p, i, ms); } p.translate(0, _rowHeight); } if (from <= _above && _above < to) { p.translate(0, (_above - to) * _rowHeight); - paintRow(p, _above); + paintRow(p, _above, ms); } } } -void StickersBox::Inner::paintRow(Painter &p, int32 index) { - const StickerSetRow *s(_rows.at(index)); +QRect StickersBox::Inner::relativeAddButtonRect() const { + int addw = st::stickersAddSize.width(); + int addx = width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - addw; + int addy = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersAddSize.height()) / 2; + return QRect(addx, addy, addw, st::stickersAddSize.height()); +} + +void StickersBox::Inner::paintRow(Painter &p, int32 index, uint64 ms) { + auto s = _rows.at(index); int32 xadd = 0, yadd = s->yadd.current(); if (xadd || yadd) p.translate(xadd, yadd); @@ -639,17 +648,23 @@ void StickersBox::Inner::paintRow(Painter &p, int32 index) { int checkx = width() - (st::contactsPadding.right() + st::contactsCheckPosition.x() + (addw + st::stickersFeaturedInstalled.width()) / 2); int checky = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersFeaturedInstalled.height()) / 2; st::stickersFeaturedInstalled.paint(p, QPoint(checkx, checky), width()); + if (s->ripple) { + s->ripple.reset(); + } } else { - int addw = st::stickersAddSize.width(); - int addx = width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - addw; - int addy = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersAddSize.height()) / 2; - QRect add(myrtlrect(addx, addy, addw, st::stickersAddSize.height())); + auto relativeAdd = relativeAddButtonRect(); + auto add = myrtlrect(relativeAdd); - auto &textBg = (_actionSel == index) ? st::defaultActiveButton.textBgOver : st::defaultActiveButton.textBg; + auto &textBg = (_actionSel == index || _actionDown == index) ? st::defaultActiveButton.textBgOver : st::defaultActiveButton.textBg; App::roundRect(p, add, textBg, ImageRoundRadius::Small); - int iconx = addx + (st::stickersAddSize.width() - st::stickersAddIcon.width()) / 2; - int icony = addy + (st::stickersAddSize.height() - st::stickersAddIcon.height()) / 2; - icony += (_actionSel == index && _actionDown == index) ? (st::defaultActiveButton.downTextTop - st::defaultActiveButton.textTop) : 0; + if (s->ripple) { + s->ripple->paint(p, relativeAdd.x(), relativeAdd.y(), width(), ms); + if (s->ripple->empty()) { + s->ripple.reset(); + } + } + int iconx = relativeAdd.x() + (st::stickersAddSize.width() - st::stickersAddIcon.width()) / 2; + int icony = relativeAdd.y() + (st::stickersAddSize.height() - st::stickersAddIcon.height()) / 2; st::stickersAddIcon.paint(p, QPoint(iconx, icony), width()); } @@ -696,7 +711,7 @@ void StickersBox::Inner::mousePressEvent(QMouseEvent *e) { _pressed = _selected; if (_actionSel >= 0) { - _actionDown = _actionSel; + setActionDown(_actionSel); update(0, _itemsTop + _actionSel * _rowHeight, width(), _rowHeight); } else if (_selected >= 0 && _section == Section::Installed && !_rows.at(_selected)->recent) { _above = _dragging = _started = _selected; @@ -704,6 +719,33 @@ void StickersBox::Inner::mousePressEvent(QMouseEvent *e) { } } +void StickersBox::Inner::setActionDown(int newActionDown) { + if (_actionDown == newActionDown) { + return; + } + if (_actionDown >= 0 && _actionDown < _rows.size()) { + update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight); + auto set = _rows[_actionDown]; + if (set->ripple) { + set->ripple->lastStop(); + } + } + _actionDown = newActionDown; + if (_actionDown >= 0 && _actionDown < _rows.size()) { + update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight); + auto set = _rows[_actionDown]; + if (!set->ripple) { + auto mask = Ui::RippleAnimation::roundRectMask(st::stickersAddSize, st::buttonRadius); + set->ripple = MakeShared(st::defaultActiveButton.ripple, std_::move(mask), [this, index = _actionDown] { + update(0, _itemsTop + index * _rowHeight, width(), _rowHeight); + }); + } + auto relativeAdd = relativeAddButtonRect(); + auto add = myrtlrect(relativeAdd); + set->ripple->add(mapFromGlobal(QCursor::pos()) - QPoint(add.x(), _itemsTop + _actionDown * _rowHeight + add.y())); + } +} + void StickersBox::Inner::mouseMoveEvent(QMouseEvent *e) { if (_saving) return; _mouse = e->globalPos(); @@ -762,10 +804,8 @@ void StickersBox::Inner::onUpdateSelected() { } else if (_rows.at(selected)->installed && !_rows.at(selected)->disabled) { actionSel = -1; } else { - int addw = st::stickersAddSize.width(); - int addx = width() - st::contactsPadding.right() - st::contactsCheckPosition.x() - addw; - int addy = st::contactsPadding.top() + (st::contactsPhotoSize - st::stickersAddSize.height()) / 2; - QRect add(myrtlrect(addx, addy, addw, st::stickersAddSize.height())); + auto relativeAdd = relativeAddButtonRect(); + auto add = myrtlrect(relativeAdd); actionSel = add.contains(local.x(), local.y() - _itemsTop - selected * _rowHeight) ? selected : -1; } } else if (_hasFeaturedButton && QRect(0, st::membersPadding.top(), width(), _buttonHeight).contains(local)) { @@ -878,10 +918,7 @@ void StickersBox::Inner::mouseReleaseEvent(QMouseEvent *e) { } } } - if (_actionDown >= 0) { - update(0, _itemsTop + _actionDown * _rowHeight, width(), _rowHeight); - _actionDown = -1; - } + setActionDown(-1); } void StickersBox::Inner::leaveEvent(QEvent *e) { diff --git a/Telegram/SourceFiles/boxes/stickers_box.h b/Telegram/SourceFiles/boxes/stickers_box.h index aed6e99f66..562f307806 100644 --- a/Telegram/SourceFiles/boxes/stickers_box.h +++ b/Telegram/SourceFiles/boxes/stickers_box.h @@ -20,13 +20,14 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" class ConfirmBox; namespace Ui { class PlainShadow; class RoundButton; +class RippleAnimation; } // namespace Ui class StickersBox : public ItemListBox, public RPCSender { @@ -150,11 +151,13 @@ private slots: void onImageLoaded(); private: + void setActionDown(int newActionDown); void setup(); + QRect relativeAddButtonRect() const; void paintButton(Painter &p, int y, bool selected, const QString &text, int badgeCounter) const; void step_shifting(uint64 ms, bool timer); - void paintRow(Painter &p, int32 index); + void paintRow(Painter &p, int32 index, uint64 ms); void clear(); void setActionSel(int32 actionSel); float64 aboveShadowOpacity() const; @@ -192,6 +195,7 @@ private: bool installed, official, unread, disabled, recent; int32 pixw, pixh; anim::ivalue yadd; + QSharedPointer ripple; }; using StickerSetRows = QList; @@ -236,5 +240,6 @@ private: Ui::RectShadow _aboveShadow; - int32 _scrollbar = 0; + int _scrollbar = 0; + }; diff --git a/Telegram/SourceFiles/boxes/stickersetbox.h b/Telegram/SourceFiles/boxes/stickersetbox.h index 7c052f6220..52ebf0e47c 100644 --- a/Telegram/SourceFiles/boxes/stickersetbox.h +++ b/Telegram/SourceFiles/boxes/stickersetbox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" #include "core/vector_of_moveable.h" class ConfirmBox; diff --git a/Telegram/SourceFiles/boxes/usernamebox.h b/Telegram/SourceFiles/boxes/usernamebox.h index d26a62fc29..afe476fd0f 100644 --- a/Telegram/SourceFiles/boxes/usernamebox.h +++ b/Telegram/SourceFiles/boxes/usernamebox.h @@ -20,7 +20,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org */ #pragma once -#include "abstractbox.h" +#include "boxes/abstractbox.h" namespace Ui { class UsernameInput; diff --git a/Telegram/SourceFiles/core/version.h b/Telegram/SourceFiles/core/version.h index fb6796711f..99f826d4a1 100644 --- a/Telegram/SourceFiles/core/version.h +++ b/Telegram/SourceFiles/core/version.h @@ -22,7 +22,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/utils.h" -#define BETA_VERSION_MACRO (10019007ULL) +#define BETA_VERSION_MACRO (10019008ULL) constexpr int AppVersion = 10020; constexpr str_const AppVersionStr = "0.10.20"; diff --git a/Telegram/SourceFiles/dialogs/dialogs.style b/Telegram/SourceFiles/dialogs/dialogs.style index 64b0d7ec89..0047410664 100644 --- a/Telegram/SourceFiles/dialogs/dialogs.style +++ b/Telegram/SourceFiles/dialogs/dialogs.style @@ -84,7 +84,6 @@ dialogsMenuToggle: IconButton { icon: icon {{ "dialogs_menu", dialogsMenuIconFg }}; iconOver: icon {{ "dialogs_menu", dialogsMenuIconFgOver }}; iconPosition: point(10px, 10px); - iconPositionDown: point(10px, 10px); rippleAreaPosition: point(0px, 0px); rippleAreaSize: 40px; @@ -112,18 +111,14 @@ dialogsFilter: FlatInput(defaultFlatInput) { dialogsCancelSearchInPeer: IconButton(dialogsMenuToggle) { icon: icon {{ "dialogs_cancel_search", dialogsMenuIconFg }}; iconOver: icon {{ "dialogs_cancel_search", dialogsMenuIconFgOver }}; - iconPosition: point(11px, 11px); - iconPositionDown: point(11px, 11px); } dialogsCancelSearch: IconButton(dialogsCancelSearchInPeer) { width: 32px; height: 32px; - iconPosition: point(7px, 7px); - iconPositionDown: point(7px, 7px); - rippleAreaSize: 0px; + ripple: emptyRippleAnimation; } dialogsChatTypeSkip: 22px; @@ -177,8 +172,6 @@ dialogsUpdateButton: FlatButton { height: 46px; textTop: 14px; - overTextTop: 14px; - downTextTop: 15px; font: semiboldFont; overFont: semiboldFont; @@ -197,8 +190,6 @@ dialogsForwardCancel: IconButton { icon: dialogsForwardCancelIcon; iconOver: dialogsForwardCancelIcon; - iconPosition: point(12px, 11px); - iconPositionDown: point(12px, 11px); } dialogsForwardFont: semiboldFont; diff --git a/Telegram/SourceFiles/history/history.style b/Telegram/SourceFiles/history/history.style index 63a650f528..a05310bc47 100644 --- a/Telegram/SourceFiles/history/history.style +++ b/Telegram/SourceFiles/history/history.style @@ -22,14 +22,6 @@ using "basic.style"; using "dialogs/dialogs.style"; using "ui/widgets/widgets.style"; -BotKeyboardButton { - margin: pixels; - padding: pixels; - height: pixels; - textTop: pixels; - downTextTop: pixels; -} - historyScroll: FlatScroll(defaultFlatScroll) { barColor: #89a0b47a; bgColor: #89a0b44c; @@ -47,13 +39,28 @@ historyScroll: FlatScroll(defaultFlatScroll) { bottomsh: -1px; } -historyPaddingBottom: 10px; +historyPaddingBottom: 8px; historyToDownPosition: point(12px, 10px); -historyToDownArrow: icon { - { "history_down_arrow", #b9b9b9, point(17px, 23px) }, -}; +historyToDownAbove: icon {{ "history_down_arrow", #b9b9b9, point(17px, 23px) }}; +historyToDownAboveOver: icon {{ "history_down_arrow", #a3a3a3, point(17px, 23px) }}; historyToDownPaddingTop: 10px; +historyToDown: TwoIconButton { + width: 52px; + height: 62px; + + iconBelow: historyToDownBelow; + iconBelowOver: historyToDownBelowOver; + iconAbove: historyToDownAbove; + iconAboveOver: historyToDownAboveOver; + iconPosition: point(0px, historyToDownPaddingTop); + + rippleAreaPosition: point(5px, 15px); + rippleAreaSize: 42px; + ripple: RippleAnimation(defaultRippleAnimation) { + color: windowBgRipple; + } +} historyToDownBadgeFont: semiboldFont; historyToDownBadgeSize: 22px; @@ -196,8 +203,6 @@ historyComposeButton: FlatButton { height: 46px; textTop: 14px; - overTextTop: 14px; - downTextTop: 14px; font: semiboldFont; overFont: semiboldFont; @@ -217,9 +222,7 @@ historySend: IconButton { icon: icon {{ "send_control_send", historySendIconFg }}; iconOver: icon {{ "send_control_send", historySendIconFgOver }}; - iconPosition: point(11px, 11px); - iconPositionDown: point(11px, 11px); } historyEditSaveIcon: icon {{ "send_control_save", historySendIconFg, point(3px, 7px) }}; historyEditSaveIconOver: icon {{ "send_control_save", historySendIconFgOver, point(3px, 7px) }}; @@ -242,11 +245,9 @@ historyAttachPhotoIconOver: icon {{ "media_type_photo", historyComposeIconFgOver historyAttachEmoji: IconButton(historyAttach) { icon: icon {{ "send_control_emoji", historyComposeIconFg }}; iconOver: icon {{ "send_control_emoji", historyComposeIconFgOver }}; - iconPosition: point(15px, 15px); - iconPositionDown: point(15px, 15px); - rippleAreaSize: 0px; + ripple: emptyRippleAnimation; } historyEmojiCircle: size(20px, 20px); historyEmojiCirclePeriod: 1500; @@ -263,9 +264,7 @@ historyBotKeyboardShow: IconButton(historySend) { historyBotKeyboardHide: IconButton(historySend) { icon: icon {{ "send_control_bot_keyboard_hide", historyComposeIconFg }}; iconOver: icon {{ "send_control_bot_keyboard_hide", historyComposeIconFgOver }}; - iconPosition: point(11px, 16px); - iconPositionDown: point(11px, 16px); } historyBotCommandStart: IconButton(historySend) { icon: icon {{ "send_control_bot_command", historyComposeIconFg }}; @@ -319,9 +318,7 @@ historyReplyCancel: IconButton { icon: historyReplyCancelIcon; iconOver: historyReplyCancelIconOver; - iconPosition: point(-1px, -1px); - iconPositionDown: point(-1px, -1px); rippleAreaPosition: point(4px, 4px); rippleAreaSize: 40px; @@ -349,8 +346,6 @@ reportSpamHide: FlatButton { height: 46px; textTop: 15px; - overTextTop: 15px; - downTextTop: 16px; font: font(fsize); overFont: font(fsize underline); @@ -361,7 +356,7 @@ reportSpamFg: #000000; msgBotKbDuration: 200; msgBotKbFont: semiboldFont; -msgBotKbOverBg: #ffffff1a; +msgBotKbOverBg: #ffffff20; msgBotKbIconPadding: 2px; msgBotKbUrlIcon: icon {{ "inline_button_url", #ffffff }}; msgBotKbSwitchPmIcon: icon {{ "inline_button_switch", #ffffff }}; @@ -370,28 +365,30 @@ msgBotKbButton: BotKeyboardButton { padding: 10px; height: 36px; textTop: 8px; - downTextTop: 9px; + ripple: RippleAnimation(defaultRippleAnimation) { + color: #00000020; + } } botKbDuration: 200; -botKbBg: #edf1f5; -botKbOverBg: #d8e2ec; -botKbDownBg: #d8e2ec; -botKbColor: #4b565f; +botKbBg: menuBgOver; +botKbOverBg: menuBgOver; +botKbDownBg: menuBgRipple; +botKbColor: windowBoldFgOver; botKbFont: font(15px semibold); botKbButton: BotKeyboardButton { margin: 10px; padding: 10px; height: 38px; textTop: 9px; - downTextTop: 9px; + ripple: defaultRippleAnimation; } botKbTinyButton: BotKeyboardButton { margin: 4px; padding: 3px; height: 25px; textTop: 2px; - downTextTop: 2px; + ripple: defaultRippleAnimation; } botKbScroll: FlatScroll(defaultSolidScroll) { deltax: 3px; diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index 007c2cd886..342958c57d 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -27,6 +27,7 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "media/media_clip_reader.h" #include "styles/style_dialogs.h" #include "styles/style_history.h" +#include "ui/effects/ripple_animation.h" #include "fileuploader.h" namespace { @@ -221,7 +222,7 @@ int ReplyKeyboard::naturalHeight() const { return (_rows.size() - 1) * _st->buttonSkip() + _rows.size() * _st->buttonHeight(); } -void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip) const { +void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip, uint64 ms) const { t_assert(_st != nullptr); t_assert(_width > 0); @@ -235,7 +236,7 @@ void ReplyKeyboard::paint(Painter &p, int outerWidth, const QRect &clip) const { // just ignore the buttons that didn't layout well if (rect.x() + rect.width() > _width) break; - _st->paintButton(p, outerWidth, button); + _st->paintButton(p, outerWidth, button, ms); } } } @@ -251,6 +252,7 @@ ClickHandlerPtr ReplyKeyboard::getState(int x, int y) const { if (rect.x() + rect.width() > _width) break; if (rect.contains(x, y)) { + _savedCoords = QPoint(x, y); return button.link; } } @@ -261,34 +263,63 @@ ClickHandlerPtr ReplyKeyboard::getState(int x, int y) const { void ReplyKeyboard::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) { if (!p) return; - bool startAnimation = false; + _savedActive = active ? p : ClickHandlerPtr(); + auto coords = findButtonCoordsByClickHandler(p); + if (coords.i >= 0 && _savedPressed != p) { + startAnimation(coords.i, coords.j, active ? 1 : -1); + } +} + + +ReplyKeyboard::ButtonCoords ReplyKeyboard::findButtonCoordsByClickHandler(const ClickHandlerPtr &p) { for (int i = 0, rows = _rows.size(); i != rows; ++i) { - auto &row = _rows.at(i); + auto &row = _rows[i]; for (int j = 0, cols = row.size(); j != cols; ++j) { - if (row.at(j).link == p) { - bool startAnimation = _animations.isEmpty(); + if (row[j].link == p) { + return { i, j }; + } + } + } + return { -1, -1 }; +} - int indexForAnimation = i * MatrixRowShift + j + 1; - if (!active) { - indexForAnimation = -indexForAnimation; - } +void ReplyKeyboard::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) { + if (!p) return; - _animations.remove(-indexForAnimation); - if (!_animations.contains(indexForAnimation)) { - _animations.insert(indexForAnimation, getms()); - } - - if (startAnimation && !_a_selected.animating()) { - _a_selected.start(); - } - return; + _savedPressed = pressed ? p : ClickHandlerPtr(); + auto coords = findButtonCoordsByClickHandler(p); + if (coords.i >= 0) { + auto &button = _rows[coords.i][coords.j]; + if (pressed) { + if (!button.ripple) { + auto mask = Ui::RippleAnimation::roundRectMask(button.rect.size(), _st->buttonRadius()); + button.ripple = MakeShared(_st->_st->ripple, std_::move(mask), [this] { _st->repaint(_item); }); + } + button.ripple->add(_savedCoords - button.rect.topLeft()); + } else { + if (button.ripple) { + button.ripple->lastStop(); + } + if (_savedActive != p) { + startAnimation(coords.i, coords.j, -1); } } } } -void ReplyKeyboard::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) { - _st->repaint(_item); +void ReplyKeyboard::startAnimation(int i, int j, int direction) { + auto notStarted = _animations.isEmpty(); + + int indexForAnimation = (i * MatrixRowShift + j + 1) * direction; + + _animations.remove(-indexForAnimation); + if (!_animations.contains(indexForAnimation)) { + _animations.insert(indexForAnimation, getms()); + } + + if (notStarted && !_a_selected.animating()) { + _a_selected.start(); + } } void ReplyKeyboard::step_selected(uint64 ms, bool timer) { @@ -330,11 +361,15 @@ int ReplyKeyboard::Style::buttonHeight() const { return _st->height; } -void ReplyKeyboard::Style::paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button) const { +void ReplyKeyboard::Style::paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button, uint64 ms) const { const QRect &rect = button.rect; - bool pressed = ClickHandler::showAsPressed(button.link); - - paintButtonBg(p, rect, pressed, button.howMuchOver); + paintButtonBg(p, rect, button.howMuchOver); + if (button.ripple) { + button.ripple->paint(p, rect.x(), rect.y(), outerWidth, ms); + if (button.ripple->empty()) { + button.ripple.reset(); + } + } paintButtonIcon(p, rect, outerWidth, button.type); if (button.type == HistoryMessageReplyMarkup::Button::Type::Callback || button.type == HistoryMessageReplyMarkup::Button::Type::Game) { @@ -353,8 +388,7 @@ void ReplyKeyboard::Style::paintButton(Painter &p, int outerWidth, const ReplyKe tx += (tw - st::botKbFont->elidew) / 2; tw = st::botKbFont->elidew; } - int textTop = rect.y() + (pressed ? _st->downTextTop : _st->textTop); - button.text.drawElided(p, tx, textTop + ((rect.height() - _st->height) / 2), tw, 1, style::al_top); + button.text.drawElided(p, tx, rect.y() + _st->textTop + ((rect.height() - _st->height) / 2), tw, 1, style::al_top); } void HistoryMessageReplyMarkup::createFromButtonRows(const QVector &v) { diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index ecacda9288..fc12f2673a 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -22,8 +22,13 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org #include "core/runtime_composer.h" +namespace Ui { +class RippleAnimation; +} // namespace Ui + namespace style { struct BotKeyboardButton; +struct RippleAnimation; } // namespace style class HistoryElement { @@ -294,13 +299,14 @@ public: int buttonSkip() const; int buttonPadding() const; int buttonHeight() const; + virtual int buttonRadius() const = 0; virtual void repaint(const HistoryItem *item) const = 0; virtual ~Style() { } protected: - virtual void paintButtonBg(Painter &p, const QRect &rect, bool pressed, float64 howMuchOver) const = 0; + virtual void paintButtonBg(Painter &p, const QRect &rect, float64 howMuchOver) const = 0; virtual void paintButtonIcon(Painter &p, const QRect &rect, int outerWidth, HistoryMessageReplyMarkup::Button::Type type) const = 0; virtual void paintButtonLoading(Painter &p, const QRect &rect) const = 0; virtual int minButtonWidth(HistoryMessageReplyMarkup::Button::Type type) const = 0; @@ -308,7 +314,7 @@ public: private: const style::BotKeyboardButton *_st; - void paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button) const; + void paintButton(Painter &p, int outerWidth, const ReplyKeyboard::Button &button, uint64 ms) const; friend class ReplyKeyboard; }; @@ -326,7 +332,7 @@ public: int naturalWidth() const; int naturalHeight() const; - void paint(Painter &p, int outerWidth, const QRect &clip) const; + void paint(Painter &p, int outerWidth, const QRect &clip, uint64 ms) const; ClickHandlerPtr getState(int x, int y) const; void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active); @@ -336,8 +342,7 @@ public: void updateMessageId(); private: - const HistoryItem *_item; - int _width = 0; + void startAnimation(int i, int j, int direction); friend class Style; using ReplyMarkupClickHandlerPtr = QSharedPointer; @@ -348,17 +353,33 @@ private: float64 howMuchOver = 0.; HistoryMessageReplyMarkup::Button::Type type; ReplyMarkupClickHandlerPtr link; + mutable QSharedPointer ripple; }; using ButtonRow = QVector