Support new rounding in bot inline keyboards.

This commit is contained in:
John Preston 2022-10-03 15:11:05 +04:00
parent 9cab06e17d
commit e5f2d83548
58 changed files with 498 additions and 305 deletions

View file

@ -373,8 +373,8 @@ void Rows::ensureRippleBySelection(not_null<Row*> row, Selection selected) {
const auto menu = v::is<MenuSelection>(selected);
const auto menuArea = menuToggleArea(row);
auto mask = menu
? Ui::RippleAnimation::ellipseMask(menuArea.size())
: Ui::RippleAnimation::rectMask({ width(), row->height });
? Ui::RippleAnimation::EllipseMask(menuArea.size())
: Ui::RippleAnimation::RectMask({ width(), row->height });
ripple = std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
std::move(mask),

View file

@ -1410,7 +1410,7 @@ void PeerListContent::mousePressEvent(QMouseEvent *e) {
row->addRipple(_st.item, _controller->customRowRippleMaskGenerator(), point, std::move(updateCallback));
} else {
const auto maskGenerator = [&] {
return Ui::RippleAnimation::rectMask(
return Ui::RippleAnimation::RectMask(
QSize(width(), _rowHeight));
};
row->addRipple(_st.item, maskGenerator, point, std::move(updateCallback));

View file

@ -60,7 +60,7 @@ constexpr auto kSortByOnlineThrottle = 3 * crl::time(1000);
//}
//
//QImage MembersAddButton::prepareRippleMask() const {
// return Ui::RippleAnimation::ellipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize));
// return Ui::RippleAnimation::EllipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize));
//}
//
//QPoint MembersAddButton::prepareRippleStartPosition() const {

View file

@ -138,7 +138,7 @@ void Row::elementAddRipple(
}
auto &ripple = *pointer;
if (!ripple) {
auto mask = Ui::RippleAnimation::roundRectMask(
auto mask = Ui::RippleAnimation::RoundRectMask(
(element == kAcceptButton
? _delegate->rowAcceptButtonSize()
: _delegate->rowRejectButtonSize()),

View file

@ -256,7 +256,9 @@ private:
const Section _section;
const bool _isInstalled;
int32 _rowHeight;
Ui::RoundRect _buttonBgOver, _buttonBg;
int32 _rowHeight = 0;
std::vector<std::unique_ptr<Row>> _rows;
std::vector<std::unique_ptr<Row>> _oldRows;
@ -1126,6 +1128,16 @@ StickersBox::Inner::Inner(
, _api(&_controller->session().mtp())
, _section(section)
, _isInstalled(_section == Section::Installed || _section == Section::Masks)
, _buttonBgOver(
ImageRoundRadius::Small,
(_isInstalled
? st::stickersUndoRemove
: st::stickersTrendingAdd).textBgOver)
, _buttonBg(
ImageRoundRadius::Small,
(_isInstalled
? st::stickersUndoRemove
: st::stickersTrendingAdd).textBg)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) {
return shiftingAnimationCallback(now);
@ -1147,6 +1159,16 @@ StickersBox::Inner::Inner(
, _api(&_controller->session().mtp())
, _section(StickersBox::Section::Installed)
, _isInstalled(_section == Section::Installed || _section == Section::Masks)
, _buttonBgOver(
ImageRoundRadius::Small,
(_isInstalled
? st::stickersUndoRemove
: st::stickersTrendingAdd).textBgOver)
, _buttonBg(
ImageRoundRadius::Small,
(_isInstalled
? st::stickersUndoRemove
: st::stickersTrendingAdd).textBg)
, _rowHeight(st::contactsPadding.top() + st::contactsPhotoSize + st::contactsPadding.bottom())
, _shiftingAnimation([=](crl::time now) {
return shiftingAnimationCallback(now);
@ -1566,8 +1588,7 @@ void StickersBox::Inner::paintFakeButton(Painter &p, not_null<Row*> row, int ind
: st::stickersTrendingAdd;
const auto textWidth = _isInstalled ? _undoWidth : _addWidth;
const auto &text = _isInstalled ? _undoText : _addText;
const auto &textBg = selected ? st.textBgOver : st.textBg;
Ui::FillRoundRect(p, myrtlrect(rect), textBg, ImageRoundRadius::Small);
(selected ? _buttonBgOver : _buttonBg).paint(p, myrtlrect(rect));
if (row->ripple) {
row->ripple->paint(p, rect.x(), rect.y(), width());
if (row->ripple->empty()) {
@ -1618,16 +1639,16 @@ void StickersBox::Inner::setActionDown(int newActionDown) {
if (_isInstalled) {
if (row->removed) {
auto rippleSize = QSize(_undoWidth - st::stickersUndoRemove.width, st::stickersUndoRemove.height);
auto rippleMask = Ui::RippleAnimation::roundRectMask(rippleSize, st::roundRadiusSmall);
auto rippleMask = Ui::RippleAnimation::RoundRectMask(rippleSize, st::roundRadiusSmall);
ensureRipple(st::stickersUndoRemove.ripple, std::move(rippleMask), removeButton);
} else {
auto rippleSize = st::stickersRemove.rippleAreaSize;
auto rippleMask = Ui::RippleAnimation::ellipseMask(QSize(rippleSize, rippleSize));
auto rippleMask = Ui::RippleAnimation::EllipseMask(QSize(rippleSize, rippleSize));
ensureRipple(st::stickersRemove.ripple, std::move(rippleMask), removeButton);
}
} else if (!row->isInstalled() || row->isArchived() || row->removed) {
auto rippleSize = QSize(_addWidth - st::stickersTrendingAdd.width, st::stickersTrendingAdd.height);
auto rippleMask = Ui::RippleAnimation::roundRectMask(rippleSize, st::roundRadiusSmall);
auto rippleMask = Ui::RippleAnimation::RoundRectMask(rippleSize, st::roundRadiusSmall);
ensureRipple(st::stickersTrendingAdd.ripple, std::move(rippleMask), removeButton);
}
}
@ -1683,7 +1704,7 @@ void StickersBox::Inner::setPressed(SelectedRow pressed) {
if (_megagroupSet && pressedIndex >= 0 && pressedIndex < _rows.size()) {
update(0, _itemsTop + pressedIndex * _rowHeight, width(), _rowHeight);
auto &set = _rows[pressedIndex];
auto rippleMask = Ui::RippleAnimation::rectMask(QSize(width(), _rowHeight));
auto rippleMask = Ui::RippleAnimation::RectMask(QSize(width(), _rowHeight));
if (!set->ripple) {
set->ripple = std::make_unique<Ui::RippleAnimation>(st::defaultRippleAnimation, std::move(rippleMask), [this, pressedIndex] {
update(0, _itemsTop + pressedIndex * _rowHeight, width(), _rowHeight);

View file

@ -258,7 +258,7 @@ BoxController::Row::CallType BoxController::Row::ComputeCallType(
void BoxController::Row::rightActionAddRipple(QPoint point, Fn<void()> updateCallback) {
if (!_actionRipple) {
auto mask = Ui::RippleAnimation::ellipseMask(
auto mask = Ui::RippleAnimation::EllipseMask(
QSize(_st->rippleAreaSize, _st->rippleAreaSize));
_actionRipple = std::make_unique<Ui::RippleAnimation>(
_st->ripple,

View file

@ -747,7 +747,7 @@ void MembersRow::rightActionAddRipple(
QPoint point,
Fn<void()> updateCallback) {
if (!_actionRipple) {
auto mask = Ui::RippleAnimation::ellipseMask(QSize(
auto mask = Ui::RippleAnimation::EllipseMask(QSize(
st::groupCallActiveButton.rippleAreaSize,
st::groupCallActiveButton.rippleAreaSize));
_actionRipple = std::make_unique<Ui::RippleAnimation>(

View file

@ -217,7 +217,7 @@ QPoint JoinAsAction::prepareRippleStartPosition() const {
}
QImage JoinAsAction::prepareRippleMask() const {
return Ui::RippleAnimation::rectMask(size());
return Ui::RippleAnimation::RectMask(size());
}
int JoinAsAction::contentHeight() const {
@ -365,7 +365,7 @@ QPoint RecordingAction::prepareRippleStartPosition() const {
}
QImage RecordingAction::prepareRippleMask() const {
return Ui::RippleAnimation::rectMask(size());
return Ui::RippleAnimation::RectMask(size());
}
int RecordingAction::contentHeight() const {

View file

@ -50,7 +50,7 @@ private:
};
QImage SourceButton::prepareRippleMask() const {
return RippleAnimation::roundRectMask(size(), st::roundRadiusLarge);
return RippleAnimation::RoundRectMask(size(), st::roundRadiusLarge);
}
class Source final {

View file

@ -28,7 +28,9 @@ public:
not_null<BotKeyboard*> parent,
const style::BotKeyboardButton &st);
int buttonRadius() const override;
Images::CornersMaskRef buttonRounding(
Ui::BubbleRounding outer,
RectParts sides) const override;
void startPaint(QPainter &p, const Ui::ChatStyle *st) const override;
const style::TextStyle &textStyle() const override;
@ -39,6 +41,7 @@ protected:
QPainter &p,
const Ui::ChatStyle *st,
const QRect &rect,
Ui::BubbleRounding rounding,
float64 howMuchOver) const override;
void paintButtonIcon(
QPainter &p,
@ -76,14 +79,18 @@ void Style::repaint(not_null<const HistoryItem*> item) const {
_parent->update();
}
int Style::buttonRadius() const {
return st::roundRadiusSmall;
Images::CornersMaskRef Style::buttonRounding(
Ui::BubbleRounding outer,
RectParts sides) const {
using namespace Images;
return CornersMaskRef(CornersMask(ImageRoundRadius::Small));
}
void Style::paintButtonBg(
QPainter &p,
const Ui::ChatStyle *st,
const QRect &rect,
Ui::BubbleRounding rounding,
float64 howMuchOver) const {
Ui::FillRoundRect(p, rect, st::botKbBg, Ui::BotKeyboardCorners);
}
@ -131,7 +138,12 @@ void BotKeyboard::paintEvent(QPaintEvent *e) {
if (_impl) {
int x = rtl() ? st::botKbScroll.width : _st->margin;
p.translate(x, st::botKbScroll.deltat);
_impl->paint(p, nullptr, width(), clip.translated(-x, -st::botKbScroll.deltat));
_impl->paint(
p,
nullptr,
{},
width(),
clip.translated(-x, -st::botKbScroll.deltat));
}
}
@ -237,7 +249,7 @@ void BotKeyboard::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool activ
void BotKeyboard::clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed) {
if (!_impl) return;
_impl->clickHandlerPressedChanged(p, pressed);
_impl->clickHandlerPressedChanged(p, pressed, {});
}
bool BotKeyboard::updateMarkup(HistoryItem *to, bool force) {

View file

@ -1966,7 +1966,7 @@ std::unique_ptr<Ui::RippleAnimation> EmojiListWidget::createButtonRipple(
? st::stickerPanRemoveSet.ripple
: st::emojiPanButton.ripple;
auto mask = remove
? Ui::RippleAnimation::ellipseMask(QSize(
? Ui::RippleAnimation::EllipseMask(QSize(
st::stickerPanRemoveSet.rippleAreaSize,
st::stickerPanRemoveSet.rippleAreaSize))
: rightButton(section).rippleMask;

View file

@ -177,6 +177,16 @@ StickersListWidget::StickersListWidget(
, _isMasks(masks)
, _updateItemsTimer([=] { updateItems(); })
, _updateSetsTimer([=] { updateSets(); })
, _trendingAddBgOver(
ImageRoundRadius::Small,
st::stickersTrendingAdd.textBgOver)
, _trendingAddBg(ImageRoundRadius::Small, st::stickersTrendingAdd.textBg)
, _groupCategoryAddBgOver(
ImageRoundRadius::Small,
st::stickerGroupCategoryAdd.textBgOver)
, _groupCategoryAddBg(
ImageRoundRadius::Small,
st::stickerGroupCategoryAdd.textBg)
, _pathGradient(std::make_unique<Ui::PathShiftGradient>(
st::windowBgRipple,
st::windowBgOver,
@ -840,9 +850,7 @@ void StickersListWidget::paintStickers(Painter &p, QRect clip) {
if (featuredHasAddButton(info.section)) {
auto add = featuredAddRect(info);
auto selected = selectedButton ? (selectedButton->section == info.section) : false;
auto &textBg = selected ? st::stickersTrendingAdd.textBgOver : st::stickersTrendingAdd.textBg;
Ui::FillRoundRect(p, myrtlrect(add), textBg, ImageRoundRadius::Small);
(selected ? _trendingAddBgOver : _trendingAddBg).paint(p, myrtlrect(add));
if (set.ripple) {
set.ripple->paint(p, add.x(), add.y(), width());
if (set.ripple->empty()) {
@ -1068,12 +1076,10 @@ void StickersListWidget::paintMegagroupEmptySet(Painter &p, int y, bool buttonSe
auto infoLeft = megagroupSetInfoLeft();
_megagroupSetAbout.drawLeft(p, infoLeft, y, width() - infoLeft, width());
auto &textBg = buttonSelected
? st::stickerGroupCategoryAdd.textBgOver
: st::stickerGroupCategoryAdd.textBg;
auto button = _megagroupSetButtonRect.translated(0, y);
Ui::FillRoundRect(p, myrtlrect(button), textBg, ImageRoundRadius::Small);
(buttonSelected ? _groupCategoryAddBgOver : _groupCategoryAddBg).paint(
p,
myrtlrect(button));
if (_megagroupSetButtonRipple) {
_megagroupSetButtonRipple->paint(p, button.x(), button.y(), width());
if (_megagroupSetButtonRipple->empty()) {
@ -1486,7 +1492,7 @@ void StickersListWidget::setPressed(OverState newPressed) {
} else if (std::get_if<OverGroupAdd>(&_pressed)) {
if (!_megagroupSetButtonRipple) {
auto maskSize = _megagroupSetButtonRect.size();
auto mask = Ui::RippleAnimation::roundRectMask(maskSize, st::roundRadiusSmall);
auto mask = Ui::RippleAnimation::RoundRectMask(maskSize, st::roundRadiusSmall);
_megagroupSetButtonRipple = std::make_unique<Ui::RippleAnimation>(st::stickerGroupCategoryAdd.ripple, std::move(mask), [this] {
rtlupdate(megagroupSetButtonRectFinal());
});
@ -1514,14 +1520,14 @@ std::unique_ptr<Ui::RippleAnimation> StickersListWidget::createButtonRipple(int
if (shownSets()[section].externalLayout) {
auto maskSize = QSize(_addWidth - st::stickersTrendingAdd.width, st::stickersTrendingAdd.height);
auto mask = Ui::RippleAnimation::roundRectMask(maskSize, st::roundRadiusSmall);
auto mask = Ui::RippleAnimation::RoundRectMask(maskSize, st::roundRadiusSmall);
return std::make_unique<Ui::RippleAnimation>(
st::stickersTrendingAdd.ripple,
std::move(mask),
[this, section] { rtlupdate(featuredAddRect(section)); });
}
auto maskSize = QSize(st::stickerPanRemoveSet.rippleAreaSize, st::stickerPanRemoveSet.rippleAreaSize);
auto mask = Ui::RippleAnimation::ellipseMask(maskSize);
auto mask = Ui::RippleAnimation::EllipseMask(maskSize);
return std::make_unique<Ui::RippleAnimation>(
st::stickerPanRemoveSet.ripple,
std::move(mask),

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "chat_helpers/tabbed_selector.h"
#include "data/stickers/data_stickers.h"
#include "ui/round_rect.h"
#include "base/variant.h"
#include "base/timer.h"
@ -365,6 +366,9 @@ private:
OverState _pressed;
QPoint _lastMousePosition;
Ui::RoundRect _trendingAddBgOver, _trendingAddBg;
Ui::RoundRect _groupCategoryAddBgOver, _groupCategoryAddBg;
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
Ui::Text::String _megagroupSetAbout;

View file

@ -298,6 +298,12 @@ TabbedSelector::TabbedSelector(
, _controller(controller)
, _level(level)
, _mode(mode)
, _panelRounding(Ui::PrepareCornerPixmaps(
ImageRoundRadius::Small,
st::emojiPanBg))
, _categoriesRounding(Ui::PrepareCornerPixmaps(
ImageRoundRadius::Small,
st::emojiPanCategories))
, _topShadow(full() ? object_ptr<Ui::PlainShadow>(this) : nullptr)
, _bottomShadow(this)
, _scroll(this, st::emojiScroll)
@ -410,6 +416,16 @@ TabbedSelector::TabbedSelector(
}, lifetime());
}
style::PaletteChanged(
) | rpl::start_with_next([=] {
_panelRounding = Ui::PrepareCornerPixmaps(
ImageRoundRadius::Small,
st::emojiPanBg);
_categoriesRounding = Ui::PrepareCornerPixmaps(
ImageRoundRadius::Small,
st::emojiPanCategories);
}, lifetime());
if (hasEmojiTab()) {
session().data().stickers().emojiSetInstalled(
) | rpl::start_with_next([=](uint64 setId) {
@ -646,26 +662,19 @@ void TabbedSelector::paintSlideFrame(QPainter &p) {
}
void TabbedSelector::paintBgRoundedPart(QPainter &p) {
const auto threeRadius = 3 * _roundRadius;
const auto topOrBottomPart = _dropDown
? QRect(0, height() - threeRadius, width(), threeRadius)
: QRect(
0,
0,
width(),
(_tabsSlider
? _tabsSlider->height() + _roundRadius
: threeRadius));
Ui::FillRoundRect(
p,
topOrBottomPart,
st::emojiPanBg,
ImageRoundRadius::Small,
(_dropDown
? RectPart::FullBottom
: tabbed()
? (RectPart::FullTop | RectPart::NoTopBottom)
: RectPart::FullTop));
const auto fill = _dropDown
? QRect(0, height() - _roundRadius, width(), _roundRadius)
: _tabsSlider
? QRect(0, 0, width(), _tabsSlider->height())
: QRect(0, 0, width(), _roundRadius);
Ui::FillRoundRect(p, fill, st::emojiPanBg, {
.p = {
_dropDown ? QPixmap() : _panelRounding.p[0],
_dropDown ? QPixmap() : _panelRounding.p[1],
_dropDown ? _panelRounding.p[2] : QPixmap(),
_dropDown ? _panelRounding.p[3] : QPixmap(),
},
});
}
void TabbedSelector::paintContent(QPainter &p) {
@ -675,18 +684,22 @@ void TabbedSelector::paintContent(QPainter &p) {
if (_roundRadius > 0) {
paintBgRoundedPart(p);
const auto &pixmaps = hasSectionIcons()
? _categoriesRounding
: _panelRounding;
const auto footerPart = QRect(
0,
_footerTop - (_dropDown ? 0 : _roundRadius),
_footerTop,
width(),
_st.footer + _roundRadius);
Ui::FillRoundRect(
p,
footerPart,
footerBg,
ImageRoundRadius::Small,
(RectPart::NoTopBottom
| (_dropDown ? RectPart::FullTop : RectPart::FullBottom)));
_st.footer);
Ui::FillRoundRect(p, footerPart, footerBg, {
.p = {
_dropDown ? pixmaps.p[0] : QPixmap(),
_dropDown ? pixmaps.p[1] : QPixmap(),
_dropDown ? QPixmap() : pixmaps.p[2],
_dropDown ? QPixmap() : pixmaps.p[3],
},
});
} else {
if (_tabsSlider) {
p.fillRect(0, 0, width(), _tabsSlider->height(), st::emojiPanBg);

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/effects/animations.h"
#include "ui/effects/message_sending_animation_common.h"
#include "ui/effects/panel_animation.h"
#include "ui/cached_round_corners.h"
#include "mtproto/sender.h"
#include "base/object_ptr.h"
@ -252,6 +253,8 @@ private:
Mode _mode = Mode::Full;
int _roundRadius = 0;
int _footerTop = 0;
Ui::CornersPixmaps _panelRounding;
Ui::CornersPixmaps _categoriesRounding;
PeerData *_currentPeer = nullptr;
class SlideAnimation;

View file

@ -93,7 +93,7 @@ void BasicRow::addRipple(
QSize size,
Fn<void()> updateCallback) {
if (!_ripple) {
auto mask = Ui::RippleAnimation::rectMask(size);
auto mask = Ui::RippleAnimation::RectMask(size);
_ripple = std::make_unique<Ui::RippleAnimation>(
st::dialogsRipple,
std::move(mask),

View file

@ -922,7 +922,23 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
const auto stm = &st->messageStyle(false, false);
if (clip.y() < _botAbout->rect.y() + _botAbout->rect.height() && clip.y() + clip.height() > _botAbout->rect.y()) {
p.setTextPalette(stm->textPalette);
Ui::FillRoundRect(p, _botAbout->rect, stm->msgBg, stm->msgBgCornersLarge, &stm->msgShadow);
using Corner = Ui::BubbleCornerRounding;
const auto rounding = Ui::BubbleRounding{
Corner::Large,
Corner::Large,
Corner::Large,
Corner::Large,
};
Ui::PaintBubble(p, Ui::SimpleBubble{
.st = st,
.geometry = _botAbout->rect,
.pattern = context.bubblesPattern,
.patternViewport = context.viewport,
.outerWidth = width(),
.selected = false,
.outbg = false,
.rounding = rounding,
});
auto top = _botAbout->rect.top() + st::msgPadding.top();
if (!_history->peer->isRepliesChat()) {

View file

@ -724,14 +724,16 @@ int ReplyKeyboard::naturalHeight() const {
void ReplyKeyboard::paint(
Painter &p,
const Ui::ChatStyle *st,
Ui::BubbleRounding rounding,
int outerWidth,
const QRect &clip) const {
Assert(_st != nullptr);
Assert(_width > 0);
_st->startPaint(p, st);
for (const auto &row : _rows) {
for (const auto &button : row) {
for (auto y = 0, rowsCount = int(_rows.size()); y != rowsCount; ++y) {
for (auto x = 0, count = int(_rows[y].size()); x != count; ++x) {
const auto &button = _rows[y][x];
const auto rect = button.rect;
if (rect.y() >= clip.y() + clip.height()) return;
if (rect.y() + rect.height() < clip.y()) continue;
@ -739,7 +741,20 @@ void ReplyKeyboard::paint(
// just ignore the buttons that didn't layout well
if (rect.x() + rect.width() > _width) break;
_st->paintButton(p, st, outerWidth, button);
auto buttonRounding = Ui::BubbleRounding();
using Corner = Ui::BubbleCornerRounding;
buttonRounding.topLeft = buttonRounding.topRight = Corner::Small;
buttonRounding.bottomLeft = ((y + 1 == rowsCount)
&& !x
&& (rounding.bottomLeft == Corner::Large))
? Corner::Large
: Corner::Small;
buttonRounding.bottomRight = ((y + 1 == rowsCount)
&& (x + 1 == count)
&& (rounding.bottomRight == Corner::Large))
? Corner::Large
: Corner::Small;
_st->paintButton(p, st, outerWidth, button, buttonRounding);
}
}
}
@ -787,7 +802,8 @@ ReplyKeyboard::ButtonCoords ReplyKeyboard::findButtonCoordsByClickHandler(const
void ReplyKeyboard::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {
bool pressed,
Ui::BubbleRounding rounding) {
if (!handler) return;
_savedPressed = pressed ? handler : ClickHandlerPtr();
@ -796,13 +812,22 @@ void ReplyKeyboard::clickHandlerPressedChanged(
auto &button = _rows[coords.i][coords.j];
if (pressed) {
if (!button.ripple) {
auto mask = Ui::RippleAnimation::roundRectMask(
const auto sides = RectPart()
| (!coords.i ? RectPart::Top : RectPart())
| (!coords.j ? RectPart::Left : RectPart())
| ((coords.i + 1 == _rows.size())
? RectPart::Bottom
: RectPart())
| ((coords.j + 1 == _rows[coords.i].size())
? RectPart::Right
: RectPart());
auto mask = Ui::RippleAnimation::RoundRectMask(
button.rect.size(),
_st->buttonRadius());
_st->buttonRounding(rounding, sides));
button.ripple = std::make_unique<Ui::RippleAnimation>(
_st->_st->ripple,
std::move(mask),
[this] { _st->repaint(_item); });
[=] { _st->repaint(_item); });
}
button.ripple->add(_savedCoords - button.rect.topLeft());
} else {
@ -877,9 +902,10 @@ void ReplyKeyboard::Style::paintButton(
Painter &p,
const Ui::ChatStyle *st,
int outerWidth,
const ReplyKeyboard::Button &button) const {
const ReplyKeyboard::Button &button,
Ui::BubbleRounding rounding) const {
const QRect &rect = button.rect;
paintButtonBg(p, st, rect, button.howMuchOver);
paintButtonBg(p, st, rect, rounding, button.howMuchOver);
if (button.ripple) {
const auto color = st ? &st->msgBotKbRippleBg()->c : nullptr;
button.ripple->paint(p, rect.x(), rect.y(), outerWidth, color);

View file

@ -25,6 +25,10 @@ namespace Data {
class Session;
} // namespace Data
namespace Images {
struct CornersMaskRef;
} // namespace Images
namespace HistoryView {
class Element;
class Document;
@ -323,7 +327,9 @@ public:
int buttonSkip() const;
int buttonPadding() const;
int buttonHeight() const;
virtual int buttonRadius() const = 0;
[[nodiscard]] virtual Images::CornersMaskRef buttonRounding(
Ui::BubbleRounding outer,
RectParts sides) const = 0;
virtual void repaint(not_null<const HistoryItem*> item) const = 0;
virtual ~Style() {
@ -334,6 +340,7 @@ public:
QPainter &p,
const Ui::ChatStyle *st,
const QRect &rect,
Ui::BubbleRounding rounding,
float64 howMuchOver) const = 0;
virtual void paintButtonIcon(
QPainter &p,
@ -355,7 +362,8 @@ public:
Painter &p,
const Ui::ChatStyle *st,
int outerWidth,
const ReplyKeyboard::Button &button) const;
const ReplyKeyboard::Button &button,
Ui::BubbleRounding rounding) const;
friend class ReplyKeyboard;
};
@ -377,12 +385,18 @@ public:
void paint(
Painter &p,
const Ui::ChatStyle *st,
Ui::BubbleRounding rounding,
int outerWidth,
const QRect &clip) const;
ClickHandlerPtr getLink(QPoint point) const;
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active);
void clickHandlerPressedChanged(const ClickHandlerPtr &p, bool pressed);
void clickHandlerActiveChanged(
const ClickHandlerPtr &p,
bool active);
void clickHandlerPressedChanged(
const ClickHandlerPtr &p,
bool pressed,
Ui::BubbleRounding rounding);
void clearSelection();
void updateMessageId();

View file

@ -912,7 +912,7 @@ rpl::producer<> RecordLock::locks() const {
}
QImage RecordLock::prepareRippleMask() const {
return Ui::RippleAnimation::ellipseMask(_rippleRect.size());
return Ui::RippleAnimation::EllipseMask(_rippleRect.size());
}
QPoint RecordLock::prepareRippleStartPosition() const {
@ -976,7 +976,7 @@ void CancelButton::init() {
}
QImage CancelButton::prepareRippleMask() const {
return Ui::RippleAnimation::ellipseMask(_rippleRect.size());
return Ui::RippleAnimation::EllipseMask(_rippleRect.size());
}
QPoint CancelButton::prepareRippleStartPosition() const {

View file

@ -1216,11 +1216,6 @@ void Element::clickHandlerActiveChanged(
void Element::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {
if (const auto markup = _data->Get<HistoryMessageReplyMarkup>()) {
if (const auto keyboard = markup->inlineKeyboard.get()) {
keyboard->clickHandlerPressedChanged(handler, pressed);
}
}
PressedLink(pressed ? this : nullptr);
repaint();
if (const auto media = this->media()) {

View file

@ -63,7 +63,9 @@ class KeyboardStyle : public ReplyKeyboard::Style {
public:
using ReplyKeyboard::Style::Style;
int buttonRadius() const override;
Images::CornersMaskRef buttonRounding(
Ui::BubbleRounding outer,
RectParts sides) const override;
void startPaint(
QPainter &p,
@ -76,6 +78,7 @@ protected:
QPainter &p,
const Ui::ChatStyle *st,
const QRect &rect,
Ui::BubbleRounding rounding,
float64 howMuchOver) const override;
void paintButtonIcon(
QPainter &p,
@ -107,23 +110,54 @@ void KeyboardStyle::repaint(not_null<const HistoryItem*> item) const {
item->history()->owner().requestItemRepaint(item);
}
int KeyboardStyle::buttonRadius() const {
return st::dateRadius;
Images::CornersMaskRef KeyboardStyle::buttonRounding(
Ui::BubbleRounding outer,
RectParts sides) const {
using namespace Images;
using namespace Ui;
using Radius = CachedCornerRadius;
using Corner = BubbleCornerRounding;
auto result = CornersMaskRef(CachedCornersMasks(Radius::BubbleSmall));
if (sides & RectPart::Bottom) {
const auto &large = CachedCornersMasks(Radius::BubbleLarge);
auto round = [&](RectPart side, int index) {
if ((sides & side) && (outer[index] == Corner::Large)) {
result.p[index] = &large[index];
}
};
round(RectPart::Left, kBottomLeft);
round(RectPart::Right, kBottomRight);
}
return result;
}
void KeyboardStyle::paintButtonBg(
QPainter &p,
const Ui::ChatStyle *st,
const QRect &rect,
Ui::BubbleRounding rounding,
float64 howMuchOver) const {
Expects(st != nullptr);
const auto sti = &st->imageStyle(false);
Ui::FillRoundRect(p, rect, sti->msgServiceBg, sti->msgServiceBgCorners);
const auto &small = sti->msgServiceBgCornersSmall;
const auto &large = sti->msgServiceBgCornersLarge;
auto corners = Ui::CornersPixmaps();
using Corner = Ui::BubbleCornerRounding;
for (auto i = 0; i != 4; ++i) {
corners.p[i] = (rounding[i] == Corner::Large ? large : small).p[i];
}
Ui::FillRoundRect(p, rect, sti->msgServiceBg, corners);
if (howMuchOver > 0) {
auto o = p.opacity();
p.setOpacity(o * howMuchOver);
Ui::FillRoundRect(p, rect, st->msgBotKbOverBgAdd(), st->msgBotKbOverBgAddCorners());
const auto &small = st->msgBotKbOverBgAddCornersSmall();
const auto &large = st->msgBotKbOverBgAddCornersLarge();
auto over = Ui::CornersPixmaps();
for (auto i = 0; i != 4; ++i) {
over.p[i] = (rounding[i] == Corner::Large ? large : small).p[i];
}
Ui::FillRoundRect(p, rect, st->msgBotKbOverBgAdd(), over);
p.setOpacity(o);
}
}
@ -354,7 +388,7 @@ void Message::animateReaction(Reactions::AnimationArgs &&args) {
const auto bubble = drawBubble();
const auto reactionsInBubble = _reactions && embedReactionsInBubble();
const auto mediaDisplayed = media && media->isDisplayed();
auto keyboard = item->inlineReplyKeyboard();
const auto keyboard = item->inlineReplyKeyboard();
auto keyboardHeight = 0;
if (keyboard) {
keyboardHeight = keyboard->naturalHeight();
@ -729,13 +763,19 @@ void Message::draw(Painter &p, const PaintContext &context) const {
p.setTextPalette(stm->textPalette);
auto keyboard = item->inlineReplyKeyboard();
const auto keyboard = item->inlineReplyKeyboard();
const auto messageRounding = countMessageRounding();
if (keyboard) {
const auto keyboardHeight = st::msgBotKbButton.margin + keyboard->naturalHeight();
g.setHeight(g.height() - keyboardHeight);
const auto keyboardPosition = QPoint(g.left(), g.top() + g.height() + st::msgBotKbButton.margin);
p.translate(keyboardPosition);
keyboard->paint(p, context.st, g.width(), context.clip.translated(-keyboardPosition));
keyboard->paint(
p,
context.st,
messageRounding,
g.width(),
context.clip.translated(-keyboardPosition));
p.translate(-keyboardPosition);
}
@ -772,7 +812,7 @@ void Message::draw(Painter &p, const PaintContext &context) const {
.outerWidth = width(),
.selected = context.selected(),
.outbg = context.outbg,
.rounding = countBubbleRounding(),
.rounding = countBubbleRounding(messageRounding),
},
.selection = mediaSelectionIntervals,
});
@ -1375,8 +1415,15 @@ bool Message::displayFromPhoto() const {
void Message::clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) {
if (const auto markup = data()->Get<HistoryMessageReplyMarkup>()) {
if (const auto keyboard = markup->inlineKeyboard.get()) {
keyboard->clickHandlerPressedChanged(
handler,
pressed,
countMessageRounding());
}
}
Element::clickHandlerPressedChanged(handler, pressed);
if (!handler) {
return;
} else if (_comments && (handler == _comments->link)) {
@ -1408,7 +1455,7 @@ void Message::toggleCommentsButtonRipple(bool pressed) {
radius);
p.fillRect(0, 0, linkWidth, radius * 2, Qt::white);
};
auto mask = Ui::RippleAnimation::maskByDrawer(
auto mask = Ui::RippleAnimation::MaskByDrawer(
QSize(linkWidth, linkHeight),
false,
drawMask);
@ -2161,7 +2208,7 @@ void Message::drawInfo(
} else if (type == InfoDisplayType::Background) {
const auto dateW = size.width() + 2 * st::msgDateImgPadding.x();
const auto dateH = size.height() + 2 * st::msgDateImgPadding.y();
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, sti->msgServiceBg, sti->msgServiceBgCorners);
Ui::FillRoundRect(p, dateX - st::msgDateImgPadding.x(), dateY - st::msgDateImgPadding.y(), dateW, dateH, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
}
_bottomInfo.paint(
p,
@ -2988,7 +3035,7 @@ QRect Message::countGeometry() const {
height() - contentTop - marginBottom());
}
Ui::BubbleRounding Message::countBubbleRounding() const {
Ui::BubbleRounding Message::countMessageRounding() const {
const auto smallTop = isAttachedToPrevious();
const auto smallBottom = isAttachedToNext();
const auto media = smallBottom ? nullptr : this->media();
@ -3015,6 +3062,20 @@ Ui::BubbleRounding Message::countBubbleRounding() const {
};
}
Ui::BubbleRounding Message::countBubbleRounding(
Ui::BubbleRounding messageRounding) const {
if (const auto keyboard = data()->inlineReplyKeyboard()) {
messageRounding.bottomLeft
= messageRounding.bottomRight
= Ui::BubbleCornerRounding::Small;
}
return messageRounding;
}
Ui::BubbleRounding Message::countBubbleRounding() const {
return countBubbleRounding(countMessageRounding());
}
int Message::resizeContentGetHeight(int newWidth) {
if (isHidden()) {
return marginTop() + marginBottom();

View file

@ -225,6 +225,9 @@ private:
void updateMediaInBubbleState();
QRect countGeometry() const;
[[nodiscard]] Ui::BubbleRounding countMessageRounding() const;
[[nodiscard]] Ui::BubbleRounding countBubbleRounding(
Ui::BubbleRounding messageRounding) const;
[[nodiscard]] Ui::BubbleRounding countBubbleRounding() const;
int resizeContentGetHeight(int newWidth);

View file

@ -169,7 +169,7 @@ ViewButton::Inner::Inner(
void ViewButton::Inner::updateMask(int height) {
ripple = std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
Ui::RippleAnimation::roundRectMask(
Ui::RippleAnimation::RoundRectMask(
QSize(lastWidth, height - margins.top() - margins.bottom()),
st::roundRadiusLarge),
updateCallback);

View file

@ -564,7 +564,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
if (mediaUnread) {
statusW += st::mediaUnreadSkip + st::mediaUnreadSize;
}
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), sti->msgServiceBg, sti->msgServiceBgCorners);
Ui::FillRoundRect(p, style::rtlrect(statusX - st::msgDateImgPadding.x(), statusY - st::msgDateImgPadding.y(), statusW, statusH, width()), sti->msgServiceBg, sti->msgServiceBgCornersSmall);
p.setFont(st::normalFont);
p.setPen(st->msgServiceFg());
p.drawTextLeft(statusX, statusY, width(), _statusText, statusW - 2 * st::msgDateImgPadding.x());
@ -596,7 +596,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
int recty = painty;
if (rtl()) rectx = width() - rectx - rectw;
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCorners);
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
p.setPen(st->msgServiceFg());
rectx += st::msgReplyPadding.left();
rectw = innerw;

View file

@ -227,7 +227,7 @@ void UnwrappedMedia::drawSurrounding(
int recty = 0;
if (rtl()) rectx = width() - rectx - rectw;
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCorners);
Ui::FillRoundRect(p, rectx, recty, rectw, recth, sti->msgServiceBg, sti->msgServiceBgCornersSmall);
p.setPen(st->msgServiceFg());
rectx += st::msgReplyPadding.left();
rectw -= st::msgReplyPadding.left() + st::msgReplyPadding.right();

View file

@ -1519,7 +1519,7 @@ void Poll::toggleRipple(Answer &answer, bool pressed) {
- st::msgPadding.left()
- st::msgPadding.right();
if (!answer.ripple) {
auto mask = Ui::RippleAnimation::rectMask(QSize(
auto mask = Ui::RippleAnimation::RectMask(QSize(
outerWidth,
countAnswerHeight(answer, innerWidth)));
answer.ripple = std::make_unique<Ui::RippleAnimation>(
@ -1581,11 +1581,11 @@ void Poll::toggleLinkRipple(bool pressed) {
p.fillRect(0, 0, linkWidth, radius * 2, Qt::white);
};
auto mask = isRoundedInBubbleBottom()
? Ui::RippleAnimation::maskByDrawer(
? Ui::RippleAnimation::MaskByDrawer(
QSize(linkWidth, linkHeight),
false,
drawMask)
: Ui::RippleAnimation::rectMask({ linkWidth, linkHeight });
: Ui::RippleAnimation::RectMask({ linkWidth, linkHeight });
_linkRipple = std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
std::move(mask),

View file

@ -259,7 +259,7 @@ void MediaGift::Button::toggleRipple(bool pressed) {
const auto linkHeight = size.height();
if (!ripple) {
const auto drawMask = [&](QPainter &p) { drawBg(p); };
auto mask = Ui::RippleAnimation::maskByDrawer(
auto mask = Ui::RippleAnimation::MaskByDrawer(
QSize(linkWidth, linkHeight),
false,
drawMask);

View file

@ -326,14 +326,16 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
const auto clip = e->rect();
const auto radius = st::boxRadius;
auto parts = RectPart::None | 0;
const auto &corners = Ui::CachedCornerPixmaps(Ui::BoxCorners);
if (!_tillBottom) {
const auto bottom = QRect{ 0, height() - radius, width(), radius };
if (clip.intersects(bottom)) {
if (const auto rounding = _content->bottomSkipRounding()) {
rounding->paint(p, rect(), RectPart::FullBottom);
} else {
parts |= RectPart::FullBottom;
Ui::FillRoundRect(p, bottom, st::boxBg, {
.p = { QPixmap(), QPixmap(), corners.p[2], corners.p[3] }
});
}
}
} else if (!_contentTillBottom) {
@ -342,19 +344,13 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
p.fillRect(0, height() - radius, width(), radius, color);
}
if (_content->animatingShow()) {
if (clip.intersects({ 0, 0, width(), radius })) {
parts |= RectPart::FullTop;
const auto top = QRect{ 0, 0, width(), radius };
if (clip.intersects(top)) {
Ui::FillRoundRect(p, top, st::boxBg, {
.p = { corners.p[0], corners.p[1], QPixmap(), QPixmap() }
});
}
parts |= RectPart::Left | RectPart::Center | RectPart::Right;
}
if (parts) {
Ui::FillRoundRect(
p,
rect(),
st::boxBg,
Ui::BoxCorners,
nullptr,
parts);
p.fillRect(0, radius, width(), height() - 2 * radius, st::boxBg);
}
}

View file

@ -18,7 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "settings/settings_chat.h"
#include "settings/settings_main.h"
#include "settings/settings_premium.h"
#include "ui/effects/ripple_animation.h" // maskByDrawer.
#include "ui/effects/ripple_animation.h" // MaskByDrawer.
#include "ui/widgets/discrete_sliders.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/shadow.h"
@ -986,7 +986,7 @@ void WrapWidget::showNewContent(
const auto s = QSize(
newContent->width(),
animationParams.topSkip);
auto image = Ui::RippleAnimation::maskByDrawer(s, false, [&](
auto image = Ui::RippleAnimation::MaskByDrawer(s, false, [&](
QPainter &p) {
const auto r = QRect(0, 0, s.width(), s.height() * 2);
p.drawRoundedRect(r, st::boxRadius, st::boxRadius);

View file

@ -777,8 +777,7 @@ void ListWidget::paintEvent(QPaintEvent *e) {
if (_dateBadge->corners.p[0].isNull()) {
_dateBadge->corners = Ui::PrepareCornerPixmaps(
Ui::HistoryServiceMsgRadius(),
st::roundedBg,
nullptr);
st::roundedBg);
}
HistoryView::ServiceMessagePainter::PaintDate(
p,

View file

@ -336,7 +336,7 @@ QPoint BotAction::prepareRippleStartPosition() const {
}
QImage BotAction::prepareRippleMask() const {
return Ui::RippleAnimation::rectMask(size());
return Ui::RippleAnimation::RectMask(size());
}
int BotAction::contentHeight() const {

View file

@ -36,6 +36,9 @@ Widget::Widget(
, _contentMaxHeight(st::emojiPanMaxHeight)
, _contentHeight(_contentMaxHeight)
, _scroll(this, st::inlineBotsScroll)
, _innerRounding(Ui::PrepareCornerPixmaps(
ImageRoundRadius::Small,
st::emojiPanBg))
, _inlineRequestTimer([=] { onInlineRequest(); }) {
resize(QRect(0, 0, st::emojiPanWidth, _contentHeight).marginsAdded(innerPadding()).size());
_width = width();
@ -59,6 +62,13 @@ Widget::Widget(
_inner->clearInlineRowsPanel();
}, lifetime());
style::PaletteChanged(
) | rpl::start_with_next([=] {
_innerRounding = Ui::PrepareCornerPixmaps(
ImageRoundRadius::Small,
st::emojiPanBg);
}, lifetime());
macWindowDeactivateEvents(
) | rpl::filter([=] {
return !isHidden();
@ -150,7 +160,17 @@ void Widget::paintEvent(QPaintEvent *e) {
void Widget::paintContent(QPainter &p) {
auto inner = innerRect();
Ui::FillRoundRect(p, inner, st::emojiPanBg, ImageRoundRadius::Small, RectPart::FullTop | RectPart::FullBottom);
const auto radius = st::roundRadiusSmall;
const auto top = Ui::CornersPixmaps{
.p = { _innerRounding.p[0], _innerRounding.p[1], QPixmap(), QPixmap() },
};
Ui::FillRoundRect(p, inner.x(), inner.y(), inner.width(), radius, st::emojiPanBg, top);
const auto bottom = Ui::CornersPixmaps{
.p = { QPixmap(), QPixmap(), _innerRounding.p[2], _innerRounding.p[3] },
};
Ui::FillRoundRect(p, inner.x(), inner.y() + inner.height() - radius, inner.width(), radius, st::emojiPanBg, bottom);
auto horizontal = horizontalRect();
auto sidesTop = horizontal.y();

View file

@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/rp_widget.h"
#include "ui/abstract_button.h"
#include "ui/cached_round_corners.h"
#include "ui/widgets/tooltip.h"
#include "ui/effects/animations.h"
#include "ui/effects/panel_animation.h"
@ -144,6 +145,7 @@ private:
object_ptr<Ui::ScrollArea> _scroll;
QPointer<Inner> _inner;
Ui::CornersPixmaps _innerRounding;
std::map<QString, std::unique_ptr<CacheEntry>> _inlineCache;
base::Timer _inlineRequestTimer;

View file

@ -71,8 +71,18 @@ void Dropdown::paintEvent(QPaintEvent *e) {
auto shadowedRect = rect().marginsRemoved(getMargin());
auto shadowedSides = RectPart::Left | RectPart::Right | RectPart::Bottom;
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
auto parts = RectPart::NoTopBottom | RectPart::FullBottom;
Ui::FillRoundRect(p, QRect(shadowedRect.x(), -st::roundRadiusSmall, shadowedRect.width(), shadowedRect.y() + shadowedRect.height() + st::roundRadiusSmall), st::menuBg, Ui::MenuCorners, nullptr, parts);
const auto &corners = Ui::CachedCornerPixmaps(Ui::MenuCorners);
const auto fill = Ui::CornersPixmaps{
.p = { QPixmap(), QPixmap(), corners.p[2], corners.p[3] },
};
Ui::FillRoundRect(
p,
shadowedRect.x(),
0,
shadowedRect.width(),
shadowedRect.y() + shadowedRect.height(),
st::menuBg,
fill);
}
void Dropdown::enterEventHook(QEnterEvent *e) {

View file

@ -160,8 +160,7 @@ void Panel::paintEvent(QPaintEvent *e) {
| (rtl() ? RectPart::Left : RectPart::Right)
| RectPart::Top;
Ui::Shadow::paint(p, shadowedRect, width(), st::defaultRoundShadow, shadowedSides);
auto parts = RectPart::Full;
Ui::FillRoundRect(p, shadowedRect, st::menuBg, Ui::MenuCorners, nullptr, parts);
Ui::FillRoundRect(p, shadowedRect, st::menuBg, Ui::MenuCorners);
}
void Panel::enterEventHook(QEnterEvent *e) {

View file

@ -149,7 +149,7 @@ void PeerListWidget::mousePressEvent(QMouseEvent *e) {
const auto item = _items[_pressed];
if (!item->ripple) {
auto memberRowWidth = rowWidth();
auto mask = Ui::RippleAnimation::rectMask(QSize(memberRowWidth, _st.height));
auto mask = Ui::RippleAnimation::RectMask(QSize(memberRowWidth, _st.height));
item->ripple = std::make_unique<Ui::RippleAnimation>(_st.button.ripple, std::move(mask), [this, index = _pressed] {
repaintRow(index);
});

View file

@ -515,20 +515,16 @@ void LayerWidget::paintEvent(QPaintEvent *e) {
auto clip = e->rect();
auto r = st::boxRadius;
auto parts = RectPart::None | 0;
const auto &pixmaps = Ui::CachedCornerPixmaps(Ui::BoxCorners);
if (!_tillTop && clip.intersects({ 0, 0, width(), r })) {
parts |= RectPart::FullTop;
Ui::FillRoundRect(p, 0, 0, width(), r, st::boxBg, {
.p = { pixmaps.p[0], pixmaps.p[1], QPixmap(), QPixmap() },
});
}
if (!_tillBottom && clip.intersects({ 0, height() - r, width(), r })) {
parts |= RectPart::FullBottom;
}
if (parts) {
Ui::FillRoundRect(
p,
rect(),
st::boxBg,
Ui::BoxCorners,
nullptr,
parts);
Ui::FillRoundRect(p, 0, height() - r, width(), r, st::boxBg, {
.p = { QPixmap(), QPixmap(), pixmaps.p[2], pixmaps.p[3] },
});
}
if (_tillTop) {
p.fillRect(0, 0, width(), r, st::boxBg);

View file

@ -277,14 +277,13 @@ struct ForwardedTooltip {
{ line, line, line, line + arrowSize });
const auto origin = full.topLeft();
const auto rounded = std::make_shared<Ui::RoundRect>(
ImageRoundRadius::Large,
st::toastBg);
const auto paint = [=](QPainter &p) {
p.translate(-origin);
Ui::FillRoundRect(
p,
geometry,
st::toastBg,
ImageRoundRadius::Large);
rounded->paint(p, geometry);
p.setFont(font);
p.setPen(st::toastFg);

View file

@ -416,8 +416,7 @@ CalendarBox::FloatingDate::FloatingDate(
, _corners(
PrepareCornerPixmaps(
HistoryServiceMsgRadius(),
st::roundedBg,
nullptr)) {
st::roundedBg)) {
_context->monthValue(
) | rpl::start_with_next([=](QDate month) {
_text = langMonthOfYearFull(month.month(), month.year());
@ -670,7 +669,7 @@ void CalendarBox::Inner::mousePressEvent(QMouseEvent *e) {
auto cell = QRect(rowsLeft() + col * _st.cellSize.width(), rowsTop() + row * _st.cellSize.height(), _st.cellSize.width(), _st.cellSize.height());
auto it = _ripples.find(_selected);
if (it == _ripples.cend()) {
auto mask = RippleAnimation::ellipseMask(QSize(_st.cellInner, _st.cellInner));
auto mask = RippleAnimation::EllipseMask(QSize(_st.cellInner, _st.cellInner));
auto update = [this, cell] { rtlupdate(cell); };
it = _ripples.emplace(_selected, std::make_unique<RippleAnimation>(st::defaultRippleAnimation, std::move(mask), std::move(update))).first;
}

View file

@ -347,7 +347,7 @@ void CountrySelectBox::Inner::mousePressEvent(QMouseEvent *e) {
}
}
if (!_ripples[_pressed]) {
auto mask = RippleAnimation::rectMask(QSize(width(), _rowHeight));
auto mask = RippleAnimation::RectMask(QSize(width(), _rowHeight));
_ripples[_pressed] = std::make_unique<RippleAnimation>(st::countryRipple, std::move(mask), [this, index = _pressed] {
updateRow(index);
});

View file

@ -22,7 +22,6 @@ namespace {
constexpr auto kCachedCornerRadiusCount = int(CachedCornerRadius::kCount);
std::vector<CornersPixmaps> Corners;
base::flat_map<uint32, CornersPixmaps> CornersMap;
QImage CornersMaskLarge[4], CornersMaskSmall[4];
rpl::lifetime PaletteChangedLifetime;
@ -109,56 +108,84 @@ void StartCachedCorners() {
void FinishCachedCorners() {
Corners.clear();
CornersMap.clear();
PaletteChangedLifetime.destroy();
}
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow, RectParts parts) {
auto cornerWidth = corner.p[0].width() / style::DevicePixelRatio();
auto cornerHeight = corner.p[0].height() / style::DevicePixelRatio();
if (w < 2 * cornerWidth || h < 2 * cornerHeight) return;
if (w > 2 * cornerWidth) {
if (parts & RectPart::Top) {
p.fillRect(x + cornerWidth, y, w - 2 * cornerWidth, cornerHeight, bg);
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corners) {
using namespace Images;
const auto fillBg = [&](QRect rect) {
p.fillRect(rect, bg);
};
const auto fillCorner = [&](int x, int y, int index) {
if (const auto &pix = corners.p[index]; !pix.isNull()) {
p.drawPixmap(x, y, pix);
}
if (parts & RectPart::Bottom) {
p.fillRect(x + cornerWidth, y + h - cornerHeight, w - 2 * cornerWidth, cornerHeight, bg);
if (shadow) {
p.fillRect(x + cornerWidth, y + h, w - 2 * cornerWidth, st::msgShadow, *shadow);
};
if (corners.p[kTopLeft].isNull()
&& corners.p[kTopRight].isNull()
&& corners.p[kBottomLeft].isNull()
&& corners.p[kBottomRight].isNull()) {
p.fillRect(x, y, w, h, bg);
return;
}
const auto ratio = style::DevicePixelRatio();
const auto cornerSize = [&](int index) {
return corners.p[index].isNull()
? 0
: (corners.p[index].width() / ratio);
};
const auto verticalSkip = [&](int left, int right) {
return std::max(cornerSize(left), cornerSize(right));
};
const auto top = verticalSkip(kTopLeft, kTopRight);
const auto bottom = verticalSkip(kBottomLeft, kBottomRight);
if (top) {
const auto left = cornerSize(kTopLeft);
const auto right = cornerSize(kTopRight);
if (left) {
fillCorner(x, y, kTopLeft);
if (const auto add = top - left) {
fillBg({ x, y + left, left, add });
}
}
if (const auto fill = w - left - right; fill > 0) {
fillBg({ x + left, y, fill, top });
}
if (right) {
fillCorner(x + w - right, y, kTopRight);
if (const auto add = top - right) {
fillBg({ x + w - right, y + right, right, add });
}
}
}
if (h > 2 * cornerHeight) {
if ((parts & RectPart::NoTopBottom) == RectPart::NoTopBottom) {
p.fillRect(x, y + cornerHeight, w, h - 2 * cornerHeight, bg);
} else {
if (parts & RectPart::Left) {
p.fillRect(x, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
}
if ((parts & RectPart::Center) && w > 2 * cornerWidth) {
p.fillRect(x + cornerWidth, y + cornerHeight, w - 2 * cornerWidth, h - 2 * cornerHeight, bg);
}
if (parts & RectPart::Right) {
p.fillRect(x + w - cornerWidth, y + cornerHeight, cornerWidth, h - 2 * cornerHeight, bg);
if (const auto fill = h - top - bottom; fill > 0) {
fillBg({ x, y + top, w, fill });
}
if (bottom) {
const auto left = cornerSize(kBottomLeft);
const auto right = cornerSize(kBottomRight);
if (left) {
fillCorner(x, y + h - left, kBottomLeft);
if (const auto add = bottom - left) {
fillBg({ x, y + h - bottom, left, add });
}
}
if (const auto fill = w - left - right; fill > 0) {
fillBg({ x + left, y + h - bottom, fill, bottom });
}
if (right) {
fillCorner(x + w - right, y + h - right, kBottomRight);
if (const auto add = bottom - right) {
fillBg({ x + w - right, y + h - bottom, right, add });
}
}
}
if (parts & RectPart::TopLeft) {
p.drawPixmap(x, y, corner.p[0]);
}
if (parts & RectPart::TopRight) {
p.drawPixmap(x + w - cornerWidth, y, corner.p[1]);
}
if (parts & RectPart::BottomLeft) {
p.drawPixmap(x, y + h - cornerHeight, corner.p[2]);
}
if (parts & RectPart::BottomRight) {
p.drawPixmap(x + w - cornerWidth, y + h - cornerHeight, corner.p[3]);
}
}
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, CachedRoundCorners index, const style::color *shadow, RectParts parts) {
FillRoundRect(p, x, y, w, h, bg, Corners[index], shadow, parts);
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, CachedRoundCorners index) {
FillRoundRect(p, x, y, w, h, bg, CachedCornerPixmaps(index));
}
void FillRoundShadow(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, const CornersPixmaps &corners) {
@ -188,6 +215,12 @@ void FillRoundShadow(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::col
fillCorner(x + w - right, y + h + st::msgShadow, kRight);
}
const CornersPixmaps &CachedCornerPixmaps(CachedRoundCorners index) {
Expects(index >= 0 && index < RoundCornersCount);
return Corners[index];
}
CornersPixmaps PrepareCornerPixmaps(int32 radius, style::color bg, const style::color *sh) {
auto images = PrepareCorners(radius, bg, sh);
auto result = CornersPixmaps();
@ -208,24 +241,6 @@ CornersPixmaps PrepareCornerPixmaps(ImageRoundRadius radius, style::color bg, co
Unexpected("Image round radius in PrepareCornerPixmaps.");
}
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts) {
if (radius == ImageRoundRadius::None) {
p.fillRect(x, y, w, h, bg);
return;
}
const auto colorKey = ((uint32(bg->c.alpha()) & 0xFF) << 24)
| ((uint32(bg->c.red()) & 0xFF) << 16)
| ((uint32(bg->c.green()) & 0xFF) << 8)
| ((uint32(bg->c.blue()) & 0xFF));
auto i = CornersMap.find(colorKey);
if (i == end(CornersMap)) {
i = CornersMap.emplace(
colorKey,
PrepareCornerPixmaps(radius, bg, nullptr)).first;
}
FillRoundRect(p, x, y, w, h, bg, i->second, nullptr, parts);
}
[[nodiscard]] int CachedCornerRadiusValue(CachedCornerRadius tag) {
using Radius = CachedCornerRadius;
switch (tag) {

View file

@ -36,26 +36,23 @@ enum CachedRoundCorners : int {
RoundCornersCount
};
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, CachedRoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
inline void FillRoundRect(QPainter &p, const QRect &rect, style::color bg, CachedRoundCorners index, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index, shadow, parts);
}
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full);
inline void FillRoundRect(QPainter &p, const QRect &rect, style::color bg, ImageRoundRadius radius, RectParts parts = RectPart::Full) {
FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, radius, parts);
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, CachedRoundCorners index);
inline void FillRoundRect(QPainter &p, const QRect &rect, style::color bg, CachedRoundCorners index) {
FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, index);
}
[[nodiscard]] const CornersPixmaps &CachedCornerPixmaps(CachedRoundCorners index);
[[nodiscard]] CornersPixmaps PrepareCornerPixmaps(
int32 radius,
style::color bg,
const style::color *sh);
const style::color *sh = nullptr);
[[nodiscard]] CornersPixmaps PrepareCornerPixmaps(
ImageRoundRadius radius,
style::color bg,
const style::color *sh);
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corner, const style::color *shadow = nullptr, RectParts parts = RectPart::Full);
inline void FillRoundRect(QPainter &p, const QRect &rect, style::color bg, const CornersPixmaps &corner, const style::color *shadow = nullptr, RectParts parts = RectPart::Full) {
return FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, corner, shadow, parts);
const style::color *sh = nullptr);
void FillRoundRect(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color bg, const CornersPixmaps &corners);
inline void FillRoundRect(QPainter &p, const QRect &rect, style::color bg, const CornersPixmaps &corners) {
return FillRoundRect(p, rect.x(), rect.y(), rect.width(), rect.height(), bg, corners);
}
void FillRoundShadow(QPainter &p, int32 x, int32 y, int32 w, int32 h, style::color shadow, const CornersPixmaps &corners);
inline void FillRoundShadow(QPainter &p, const QRect &rect, style::color shadow, const CornersPixmaps &corners) {

View file

@ -307,13 +307,12 @@ void Panel::Button::paintEvent(QPaintEvent *e) {
}
QImage Panel::Button::prepareRippleMask() const {
const auto drawMask = [&](QPainter &p) {
return RippleAnimation::MaskByDrawer(size(), false, [&](QPainter &p) {
p.drawRoundedRect(
rect().marginsAdded({ 0, st::callRadius * 2, 0, 0 }),
st::callRadius,
st::callRadius);
};
return RippleAnimation::maskByDrawer(size(), false, drawMask);
});
}
QPoint Panel::Button::prepareRippleStartPosition() const {

View file

@ -657,7 +657,7 @@ msgBotKbSwitchPmIcon: icon {{ "inline_button_switch", msgBotKbIconFg }};
msgBotKbPaymentIcon: icon {{ "inline_button_card", msgBotKbIconFg }};
msgBotKbWebviewIcon: icon {{ "inline_button_web", msgBotKbIconFg }};
msgBotKbButton: BotKeyboardButton {
margin: 5px;
margin: 2px;
padding: 10px;
height: 36px;
textTop: 8px;

View file

@ -28,49 +28,6 @@ void EnsureCorners(
}
}
void RectWithCorners(
QPainter &p,
QRect rect,
const style::color &bg,
const CornersPixmaps &corners,
RectParts roundCorners) {
const auto parts = RectPart::Top
| RectPart::NoTopBottom
| RectPart::Bottom
| roundCorners;
FillRoundRect(p, rect, bg, corners, nullptr, parts);
if ((roundCorners & RectPart::AllCorners) != RectPart::AllCorners) {
const auto size = corners.p[0].width() / style::DevicePixelRatio();
if (!(roundCorners & RectPart::TopLeft)) {
p.fillRect(rect.x(), rect.y(), size, size, bg);
}
if (!(roundCorners & RectPart::TopRight)) {
p.fillRect(
rect.x() + rect.width() - size,
rect.y(),
size,
size,
bg);
}
if (!(roundCorners & RectPart::BottomLeft)) {
p.fillRect(
rect.x(),
rect.y() + rect.height() - size,
size,
size,
bg);
}
if (!(roundCorners & RectPart::BottomRight)) {
p.fillRect(
rect.x() + rect.width() - size,
rect.y() + rect.height() - size,
size,
size,
bg);
}
}
}
} // namespace
not_null<const MessageStyle*> ChatPaintContext::messageStyle() const {
@ -485,13 +442,15 @@ void ChatStyle::assignPalette(not_null<const style::palette*> palette) {
}
for (auto &style : _imageStyles) {
style.msgDateImgBgCorners = {};
style.msgServiceBgCorners = {};
style.msgServiceBgCornersSmall = {};
style.msgServiceBgCornersLarge = {};
style.msgShadowCornersSmall = {};
style.msgShadowCornersLarge = {};
}
_serviceBgCornersNormal = {};
_serviceBgCornersInverted = {};
_msgBotKbOverBgAddCorners = {};
_msgBotKbOverBgAddCornersSmall = {};
_msgBotKbOverBgAddCornersLarge = {};
for (auto &corners : _msgSelectOverlayCorners) {
corners = {};
}
@ -555,8 +514,12 @@ const MessageImageStyle &ChatStyle::imageStyle(bool selected) const {
(st::msgDateImgPadding.y() * 2 + st::normalFont->height) / 2,
result.msgDateImgBg);
EnsureCorners(
result.msgServiceBgCorners,
st::dateRadius,
result.msgServiceBgCornersSmall,
st::bubbleRadiusSmall,
result.msgServiceBg);
EnsureCorners(
result.msgServiceBgCornersLarge,
st::bubbleRadiusLarge,
result.msgServiceBg);
EnsureCorners(
result.msgShadowCornersSmall,
@ -569,12 +532,20 @@ const MessageImageStyle &ChatStyle::imageStyle(bool selected) const {
return result;
}
const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCorners() const {
const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCornersSmall() const {
EnsureCorners(
_msgBotKbOverBgAddCorners,
st::dateRadius,
_msgBotKbOverBgAddCornersSmall,
st::bubbleRadiusSmall,
msgBotKbOverBgAdd());
return _msgBotKbOverBgAddCorners;
return _msgBotKbOverBgAddCornersSmall;
}
const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCornersLarge() const {
EnsureCorners(
_msgBotKbOverBgAddCornersLarge,
st::bubbleRadiusLarge,
msgBotKbOverBgAdd());
return _msgBotKbOverBgAddCornersLarge;
}
const CornersPixmaps &ChatStyle::msgSelectOverlayCorners(

View file

@ -80,7 +80,8 @@ struct MessageStyle {
struct MessageImageStyle {
CornersPixmaps msgDateImgBgCorners;
CornersPixmaps msgServiceBgCorners;
CornersPixmaps msgServiceBgCornersSmall;
CornersPixmaps msgServiceBgCornersLarge;
CornersPixmaps msgShadowCornersSmall;
CornersPixmaps msgShadowCornersLarge;
style::color msgServiceBg;
@ -191,7 +192,8 @@ public:
bool selected) const;
[[nodiscard]] const MessageImageStyle &imageStyle(bool selected) const;
[[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCorners() const;
[[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCornersSmall() const;
[[nodiscard]] const CornersPixmaps &msgBotKbOverBgAddCornersLarge() const;
[[nodiscard]] const CornersPixmaps &msgSelectOverlayCorners(
CachedCornerRadius radius) const;
@ -318,7 +320,8 @@ private:
mutable std::array<MessageStyle, 4> _messageStyles;
mutable std::array<MessageImageStyle, 2> _imageStyles;
mutable CornersPixmaps _msgBotKbOverBgAddCorners;
mutable CornersPixmaps _msgBotKbOverBgAddCornersSmall;
mutable CornersPixmaps _msgBotKbOverBgAddCornersLarge;
mutable CornersPixmaps _msgSelectOverlayCorners[
int(CachedCornerRadius::kCount)];

View file

@ -28,6 +28,8 @@ void PaintBubbleGeneric(
FillSh &&fillSh,
FillCorner &&fillCorner,
PaintTail &&paintTail) {
using namespace Images;
const auto topLeft = args.rounding.topLeft;
const auto topRight = args.rounding.topRight;
const auto bottomWithTailLeft = args.rounding.bottomLeft;
@ -64,7 +66,7 @@ void PaintBubbleGeneric(
const auto left = cornerSize(topLeft);
const auto right = cornerSize(topRight);
if (left) {
fillCorner(rect.left(), rect.top(), 0, topLeft);
fillCorner(rect.left(), rect.top(), kTopLeft, topLeft);
if (const auto add = top - left) {
fillBg({ rect.left(), rect.top() + left, left, add });
}
@ -76,7 +78,7 @@ void PaintBubbleGeneric(
fillCorner(
rect.left() + rect.width() - right,
rect.top(),
1,
kTopRight,
topRight);
if (const auto add = top - right) {
fillBg({
@ -88,8 +90,8 @@ void PaintBubbleGeneric(
}
}
}
if (const auto h = rect.height() - top - bottom; h > 0) {
fillBg({ rect.left(), rect.top() + top, rect.width(), h });
if (const auto fill = rect.height() - top - bottom; fill > 0) {
fillBg({ rect.left(), rect.top() + top, rect.width(), fill });
}
if (bottom) {
const auto left = cornerSize(bottomLeft);
@ -98,7 +100,7 @@ void PaintBubbleGeneric(
fillCorner(
rect.left(),
rect.top() + rect.height() - left,
2,
kBottomLeft,
bottomLeft);
if (const auto add = bottom - left) {
fillBg({
@ -121,7 +123,7 @@ void PaintBubbleGeneric(
fillCorner(
rect.left() + rect.width() - right,
rect.top() + rect.height() - right,
3,
kBottomRight,
bottomRight);
if (const auto add = bottom - right) {
fillBg({

View file

@ -213,7 +213,7 @@ QPoint ActionWithTimer::prepareRippleStartPosition() const {
}
QImage ActionWithTimer::prepareRippleMask() const {
return Ui::RippleAnimation::rectMask(size());
return Ui::RippleAnimation::RectMask(size());
}
int ActionWithTimer::contentHeight() const {

View file

@ -122,7 +122,7 @@ QPoint EmojiButton::prepareRippleStartPosition() const {
}
QImage EmojiButton::prepareRippleMask() const {
return RippleAnimation::ellipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize));
return RippleAnimation::EllipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize));
}
} // namespace Ui

View file

@ -202,7 +202,7 @@ QImage SendButton::prepareRippleMask() const {
auto size = (_type == Type::Record)
? st::historyAttachEmoji.rippleAreaSize
: st::historyReplyCancel.rippleAreaSize;
return RippleAnimation::ellipseMask(QSize(size, size));
return RippleAnimation::EllipseMask(QSize(size, size));
}
QPoint SendButton::prepareRippleStartPosition() const {

View file

@ -444,7 +444,7 @@ QPoint Action::prepareRippleStartPosition() const {
}
QImage Action::prepareRippleMask() const {
return Ui::RippleAnimation::rectMask(size());
return Ui::RippleAnimation::RectMask(size());
}
int Action::contentHeight() const {

View file

@ -70,7 +70,8 @@ constexpr auto kIcons = std::array{
FilterIconPanel::FilterIconPanel(QWidget *parent)
: RpWidget(parent)
, _inner(Ui::CreateChild<Ui::RpWidget>(this)) {
, _inner(Ui::CreateChild<Ui::RpWidget>(this))
, _innerBg(ImageRoundRadius::Small, st::dialogsBg) {
setup();
}
@ -117,11 +118,7 @@ void FilterIconPanel::setupInner() {
_inner->paintRequest(
) | rpl::start_with_next([=](QRect clip) {
auto p = Painter(_inner);
Ui::FillRoundRect(
p,
_inner->rect(),
st::dialogsBg,
ImageRoundRadius::Small);
_innerBg.paint(p, _inner->rect());
p.setFont(st::emojiPanHeaderFont);
p.setPen(st::emojiPanHeaderFg);
p.drawTextLeft(

View file

@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/timer.h"
#include "ui/rp_widget.h"
#include "ui/effects/animations.h"
#include "ui/round_rect.h"
namespace Ui {
@ -69,6 +70,7 @@ private:
const not_null<Ui::RpWidget*> _inner;
rpl::event_stream<FilterIcon> _chosen;
Ui::RoundRect _innerBg;
int _selected = -1;
int _pressed = -1;

View file

@ -127,7 +127,7 @@ HistoryDownButton::HistoryDownButton(QWidget *parent, const style::TwoIconButton
}
QImage HistoryDownButton::prepareRippleMask() const {
return Ui::RippleAnimation::ellipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize));
return Ui::RippleAnimation::EllipseMask(QSize(_st.rippleAreaSize, _st.rippleAreaSize));
}
QPoint HistoryDownButton::prepareRippleStartPosition() const {
@ -502,7 +502,7 @@ QPoint UserpicButton::countPhotoPosition() const {
}
QImage UserpicButton::prepareRippleMask() const {
return Ui::RippleAnimation::ellipseMask(QSize(
return Ui::RippleAnimation::EllipseMask(QSize(
_st.photoSize,
_st.photoSize));
}
@ -896,7 +896,7 @@ QPoint SilentToggle::prepareRippleStartPosition() const {
}
QImage SilentToggle::prepareRippleMask() const {
return RippleAnimation::ellipseMask(
return RippleAnimation::EllipseMask(
QSize(_st.rippleAreaSize, _st.rippleAreaSize));
}

View file

@ -265,19 +265,32 @@ void SettingsSlider::startRipple(int sectionIndex) {
});
}
QImage SettingsSlider::prepareRippleMask(int sectionIndex, const Section &section) {
QImage SettingsSlider::prepareRippleMask(
int sectionIndex,
const Section &section) {
auto size = QSize(section.width, height() - _st.rippleBottomSkip);
if (!_rippleTopRoundRadius || (sectionIndex > 0 && sectionIndex + 1 < getSectionsCount())) {
return RippleAnimation::rectMask(size);
if (!_rippleTopRoundRadius
|| (sectionIndex > 0 && sectionIndex + 1 < getSectionsCount())) {
return RippleAnimation::RectMask(size);
}
return RippleAnimation::maskByDrawer(size, false, [this, sectionIndex, width = section.width](QPainter &p) {
return RippleAnimation::MaskByDrawer(size, false, [&](QPainter &p) {
auto plusRadius = _rippleTopRoundRadius + 1;
p.drawRoundedRect(0, 0, width, height() + plusRadius, _rippleTopRoundRadius, _rippleTopRoundRadius);
p.drawRoundedRect(
0,
0,
section.width,
height() + plusRadius,
_rippleTopRoundRadius,
_rippleTopRoundRadius);
if (sectionIndex > 0) {
p.fillRect(0, 0, plusRadius, plusRadius, p.brush());
}
if (sectionIndex + 1 < getSectionsCount()) {
p.fillRect(width - plusRadius, 0, plusRadius, plusRadius, p.brush());
p.fillRect(
section.width - plusRadius,
0,
plusRadius,
plusRadius, p.brush());
}
});
}

View file

@ -745,7 +745,7 @@ void EditorBlock::addRowRipple(int index) {
auto &row = rowAtIndex(index);
auto ripple = row.ripple();
if (!ripple) {
auto mask = Ui::RippleAnimation::rectMask(QSize(width(), row.height()));
auto mask = Ui::RippleAnimation::RectMask(QSize(width(), row.height()));
ripple = row.setRipple(std::make_unique<Ui::RippleAnimation>(st::defaultRippleAnimation, std::move(mask), [this, index = findRowIndex(&row)] {
updateRow(_data[index]);
}));

@ -1 +1 @@
Subproject commit 2c2a7887e644dff7130d764c5a7b04aaa0463056
Subproject commit 89ae115a878feb9e07fe7423fcf123397eba5966