mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Support new rounding in bot inline keyboards.
This commit is contained in:
parent
9cab06e17d
commit
e5f2d83548
58 changed files with 498 additions and 305 deletions
|
@ -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),
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -50,7 +50,7 @@ private:
|
|||
};
|
||||
|
||||
QImage SourceButton::prepareRippleMask() const {
|
||||
return RippleAnimation::roundRectMask(size(), st::roundRadiusLarge);
|
||||
return RippleAnimation::RoundRectMask(size(), st::roundRadiusLarge);
|
||||
}
|
||||
|
||||
class Source final {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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)];
|
||||
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -265,19 +265,32 @@ void SettingsSlider::startRipple(int sectionIndex) {
|
|||
});
|
||||
}
|
||||
|
||||
QImage SettingsSlider::prepareRippleMask(int sectionIndex, const Section §ion) {
|
||||
QImage SettingsSlider::prepareRippleMask(
|
||||
int sectionIndex,
|
||||
const Section §ion) {
|
||||
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());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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
|
Loading…
Add table
Reference in a new issue