mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-22 09:07:05 +02:00
Support new rounding for albums.
This commit is contained in:
parent
8268e9f872
commit
9cab06e17d
10 changed files with 80 additions and 93 deletions
|
@ -421,13 +421,7 @@ QSize Document::countCurrentSize(int newWidth) {
|
|||
}
|
||||
|
||||
void Document::draw(Painter &p, const PaintContext &context) const {
|
||||
const auto corners = (isBubbleTop()
|
||||
? (RectPart::TopLeft | RectPart::TopRight)
|
||||
: RectParts())
|
||||
| ((isRoundedInBubbleBottom() && !Has<HistoryDocumentCaptioned>())
|
||||
? (RectPart::BottomLeft | RectPart::BottomRight)
|
||||
: RectParts());
|
||||
draw(p, context, width(), LayoutMode::Full, corners);
|
||||
draw(p, context, width(), LayoutMode::Full, adjustedBubbleRounding());
|
||||
}
|
||||
|
||||
void Document::draw(
|
||||
|
@ -435,7 +429,7 @@ void Document::draw(
|
|||
const PaintContext &context,
|
||||
int width,
|
||||
LayoutMode mode,
|
||||
RectParts corners) const {
|
||||
Ui::BubbleRounding outsideRounding) const {
|
||||
if (width < st::msgPadding.left() + st::msgPadding.right() + 1) return;
|
||||
|
||||
ensureDataMediaCreated();
|
||||
|
@ -476,7 +470,7 @@ void Document::draw(
|
|||
const auto inner = QRect(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize);
|
||||
const auto radialOpacity = radial ? _animation->radial.opacity() : 1.;
|
||||
if (thumbed) {
|
||||
const auto rounding = thumbRounding(mode, corners);
|
||||
const auto rounding = thumbRounding(mode, outsideRounding);
|
||||
validateThumbnail(thumbed, st.thumbSize, rounding);
|
||||
p.drawImage(rthumb, thumbed->thumbnail);
|
||||
if (context.selected()) {
|
||||
|
@ -703,19 +697,20 @@ void Document::draw(
|
|||
|
||||
Ui::BubbleRounding Document::thumbRounding(
|
||||
LayoutMode mode,
|
||||
RectParts corners) const {
|
||||
auto result = bubbleRounding();
|
||||
Ui::BubbleRounding outsideRounding) const {
|
||||
using Corner = Ui::BubbleCornerRounding;
|
||||
if (mode != LayoutMode::Grouped && _parent->media() != this) {
|
||||
return {}; // In a WebPage preview.
|
||||
}
|
||||
const auto adjust = [&](RectPart corner, Corner already) {
|
||||
return (already == Corner::Large && (corners & corner))
|
||||
const auto hasCaption = Has<HistoryDocumentCaptioned>();
|
||||
const auto adjust = [&](Corner already, bool skip = false) {
|
||||
return (already == Corner::Large && !skip)
|
||||
? Corner::Large
|
||||
: Corner::Small;
|
||||
};
|
||||
result.topLeft = adjust(RectPart::TopLeft, result.topLeft);
|
||||
result.bottomLeft = adjust(RectPart::BottomLeft, result.bottomLeft);
|
||||
auto result = Ui::BubbleRounding();
|
||||
result.topLeft = adjust(outsideRounding.topLeft);
|
||||
result.bottomLeft = adjust(outsideRounding.bottomLeft, hasCaption);
|
||||
result.topRight = result.bottomRight = Corner::Small;
|
||||
return result;
|
||||
}
|
||||
|
@ -1280,7 +1275,7 @@ void Document::drawGrouped(
|
|||
const PaintContext &context,
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
float64 highlightOpacity,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const {
|
||||
|
@ -1290,7 +1285,7 @@ void Document::drawGrouped(
|
|||
context.translated(-geometry.topLeft()),
|
||||
geometry.width(),
|
||||
LayoutMode::Grouped,
|
||||
corners);
|
||||
rounding);
|
||||
p.translate(-geometry.topLeft());
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ public:
|
|||
const PaintContext &context,
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
float64 highlightOpacity,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const override;
|
||||
|
@ -110,7 +110,7 @@ private:
|
|||
const PaintContext &context,
|
||||
int width,
|
||||
LayoutMode mode,
|
||||
RectParts corners) const;
|
||||
Ui::BubbleRounding outsideRounding) const;
|
||||
[[nodiscard]] TextState textState(
|
||||
QPoint point,
|
||||
QSize layout,
|
||||
|
@ -128,7 +128,7 @@ private:
|
|||
|
||||
[[nodiscard]] Ui::BubbleRounding thumbRounding(
|
||||
LayoutMode mode,
|
||||
RectParts corners) const;
|
||||
Ui::BubbleRounding outsideRounding) const;
|
||||
void validateThumbnail(
|
||||
not_null<const HistoryDocumentThumbed*> thumbed,
|
||||
int size,
|
||||
|
|
|
@ -281,25 +281,6 @@ void Gif::validateRoundingMask(QSize size) const {
|
|||
}
|
||||
}
|
||||
|
||||
Images::CornersMaskRef Gif::prepareRoundingRef(
|
||||
std::optional<Ui::BubbleRounding> rounding) const {
|
||||
using namespace Ui;
|
||||
using namespace Images;
|
||||
if (!rounding) {
|
||||
return CornersMaskRef(CachedCornersMasks(CachedCornerRadius::Small));
|
||||
}
|
||||
auto result = CornersMaskRef();
|
||||
for (auto i = 0; i != 4; ++i) {
|
||||
const auto corner = (*rounding)[i];
|
||||
result.p[i] = (corner == BubbleCornerRounding::Large)
|
||||
? &CachedCornersMasks(CachedCornerRadius::BubbleLarge)[i]
|
||||
: (corner == BubbleCornerRounding::Small)
|
||||
? &CachedCornersMasks(CachedCornerRadius::BubbleSmall)[i]
|
||||
: nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Gif::downloadInCorner() const {
|
||||
return _data->isVideoFile()
|
||||
&& (_data->loading() || !autoplayEnabled())
|
||||
|
@ -429,7 +410,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
validateRoundingMask(request.outer);
|
||||
request.mask = _roundingMask;
|
||||
} else {
|
||||
request.rounding = prepareRoundingRef(rounding);
|
||||
request.rounding = MediaRoundingMask(rounding);
|
||||
}
|
||||
if (!activeRoundPlaying && activeOwnPlaying->instance.playerLocked()) {
|
||||
if (activeOwnPlaying->frozenFrame.isNull()) {
|
||||
|
@ -1020,7 +1001,7 @@ void Gif::drawGrouped(
|
|||
const PaintContext &context,
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
float64 highlightOpacity,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const {
|
||||
|
@ -1081,8 +1062,7 @@ void Gif::drawGrouped(
|
|||
auto request = ::Media::Streaming::FrameRequest{
|
||||
.resize = pixSize * cIntRetinaFactor(),
|
||||
.outer = geometry.size() * cIntRetinaFactor(),
|
||||
//.radius = roundRadius, // #TODO rounding
|
||||
//.corners = corners,
|
||||
.rounding = MediaRoundingMask(rounding),
|
||||
};
|
||||
if (activeOwnPlaying->instance.playerLocked()) {
|
||||
if (activeOwnPlaying->frozenFrame.isNull()) {
|
||||
|
@ -1105,7 +1085,7 @@ void Gif::drawGrouped(
|
|||
}
|
||||
}
|
||||
} else {
|
||||
validateGroupedCache(geometry, corners, cacheKey, cache);
|
||||
validateGroupedCache(geometry, rounding, cacheKey, cache);
|
||||
p.drawPixmap(geometry, *cache);
|
||||
}
|
||||
|
||||
|
@ -1114,11 +1094,10 @@ void Gif::drawGrouped(
|
|||
: highlightOpacity;
|
||||
if (overlayOpacity > 0.) {
|
||||
p.setOpacity(overlayOpacity);
|
||||
// #TODO rounding
|
||||
//Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//if (!context.selected()) {
|
||||
// Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//}
|
||||
fillImageOverlay(p, geometry, rounding, context);
|
||||
if (!context.selected()) {
|
||||
fillImageOverlay(p, geometry, rounding, context);
|
||||
}
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
|
@ -1355,7 +1334,7 @@ bool Gif::isUnwrapped() const {
|
|||
|
||||
void Gif::validateGroupedCache(
|
||||
const QRect &geometry,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const {
|
||||
using Option = Images::Option;
|
||||
|
@ -1377,18 +1356,11 @@ void Gif::validateGroupedCache(
|
|||
const auto loadLevel = good ? 3 : thumb ? 2 : image ? 1 : 0;
|
||||
const auto width = geometry.width();
|
||||
const auto height = geometry.height();
|
||||
const auto corner = [&](RectPart part, Option skip) {
|
||||
return !(corners & part) ? skip : Option();
|
||||
};
|
||||
const auto options = Option::RoundLarge
|
||||
| (blur ? Option::Blur : Option(0))
|
||||
| corner(RectPart::TopLeft, Option::RoundSkipTopLeft)
|
||||
| corner(RectPart::TopRight, Option::RoundSkipTopRight)
|
||||
| corner(RectPart::BottomLeft, Option::RoundSkipBottomLeft)
|
||||
| corner(RectPart::BottomRight, Option::RoundSkipBottomRight);
|
||||
const auto options = (blur ? Option::Blur : Option(0));
|
||||
const auto key = (uint64(width) << 48)
|
||||
| (uint64(height) << 32)
|
||||
| (uint64(options) << 16)
|
||||
| (uint64(rounding.key()) << 8)
|
||||
| (uint64(loadLevel));
|
||||
if (*cacheKey == key) {
|
||||
return;
|
||||
|
@ -1403,9 +1375,14 @@ void Gif::validateGroupedCache(
|
|||
const auto ratio = style::DevicePixelRatio();
|
||||
|
||||
*cacheKey = key;
|
||||
*cache = (image ? image : Image::BlankMedia().get())->pixNoCache(
|
||||
auto scaled = Images::Prepare(
|
||||
(image ? image : Image::BlankMedia().get())->original(),
|
||||
pixSize * ratio,
|
||||
{ .options = options, .outer = { width, height } });
|
||||
auto rounded = Images::Round(
|
||||
std::move(scaled),
|
||||
MediaRoundingMask(rounding));
|
||||
*cache = Ui::PixmapFromImage(std::move(rounded));
|
||||
}
|
||||
|
||||
void Gif::setStatusSize(int64 newSize) const {
|
||||
|
|
|
@ -76,7 +76,7 @@ public:
|
|||
const PaintContext &context,
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
float64 highlightOpacity,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const override;
|
||||
|
@ -169,7 +169,7 @@ private:
|
|||
|
||||
void validateGroupedCache(
|
||||
const QRect &geometry,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const;
|
||||
void setStatusSize(int64 newSize) const;
|
||||
|
@ -177,8 +177,6 @@ private:
|
|||
[[nodiscard]] QSize sizeForAspectRatio() const;
|
||||
|
||||
void validateRoundingMask(QSize size) const;
|
||||
[[nodiscard]] Images::CornersMaskRef prepareRoundingRef(
|
||||
std::optional<Ui::BubbleRounding> rounding) const;
|
||||
|
||||
[[nodiscard]] bool downloadInCorner() const;
|
||||
void drawCornerStatus(
|
||||
|
|
|
@ -189,7 +189,7 @@ public:
|
|||
const PaintContext &context,
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
float64 highlightOpacity,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const {
|
||||
|
|
|
@ -245,15 +245,23 @@ void GroupedMedia::refreshParentId(
|
|||
}
|
||||
}
|
||||
|
||||
RectParts GroupedMedia::cornersFromSides(RectParts sides) const {
|
||||
Ui::BubbleRounding GroupedMedia::applyRoundingSides(
|
||||
Ui::BubbleRounding already,
|
||||
RectParts sides) const {
|
||||
auto result = Ui::GetCornersFromSides(sides);
|
||||
if (!isBubbleTop()) {
|
||||
result &= ~(RectPart::TopLeft | RectPart::TopRight);
|
||||
if (!(result & RectPart::TopLeft)) {
|
||||
already.topLeft = Ui::BubbleCornerRounding::None;
|
||||
}
|
||||
if (!isRoundedInBubbleBottom() || !_caption.isEmpty()) {
|
||||
result &= ~(RectPart::BottomLeft | RectPart::BottomRight);
|
||||
if (!(result & RectPart::TopRight)) {
|
||||
already.topRight = Ui::BubbleCornerRounding::None;
|
||||
}
|
||||
return result;
|
||||
if (!(result & RectPart::BottomLeft)) {
|
||||
already.bottomLeft = Ui::BubbleCornerRounding::None;
|
||||
}
|
||||
if (!(result & RectPart::BottomRight)) {
|
||||
already.bottomRight = Ui::BubbleCornerRounding::None;
|
||||
}
|
||||
return already;
|
||||
}
|
||||
|
||||
QMargins GroupedMedia::groupedPadding() const {
|
||||
|
@ -302,6 +310,11 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
|||
const auto textSelection = (_mode == Mode::Column)
|
||||
&& !fullSelection
|
||||
&& !IsSubGroupSelection(selection);
|
||||
const auto inWebPage = (_parent->media() != this);
|
||||
constexpr auto kSmall = Ui::BubbleCornerRounding::Small;
|
||||
const auto rounding = inWebPage
|
||||
? Ui::BubbleRounding{ kSmall, kSmall, kSmall, kSmall }
|
||||
: adjustedBubbleRoundingWithCaption(_caption);
|
||||
for (auto i = 0, count = int(_parts.size()); i != count; ++i) {
|
||||
const auto &part = _parts[i];
|
||||
const auto partContext = context.withSelection(fullSelection
|
||||
|
@ -325,7 +338,7 @@ void GroupedMedia::draw(Painter &p, const PaintContext &context) const {
|
|||
partContext,
|
||||
part.geometry.translated(0, groupPadding.top()),
|
||||
part.sides,
|
||||
cornersFromSides(part.sides),
|
||||
applyRoundingSides(rounding, part.sides),
|
||||
highlightOpacity,
|
||||
&part.cacheKey,
|
||||
&part.cache);
|
||||
|
|
|
@ -141,7 +141,9 @@ private:
|
|||
|
||||
void refreshCaption();
|
||||
|
||||
[[nodiscard]] RectParts cornersFromSides(RectParts sides) const;
|
||||
[[nodiscard]] Ui::BubbleRounding applyRoundingSides(
|
||||
Ui::BubbleRounding already,
|
||||
RectParts sides) const;
|
||||
[[nodiscard]] QMargins groupedPadding() const;
|
||||
|
||||
Ui::Text::String _caption;
|
||||
|
|
|
@ -543,14 +543,14 @@ void Photo::drawGrouped(
|
|||
const PaintContext &context,
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
float64 highlightOpacity,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const {
|
||||
ensureDataMediaCreated();
|
||||
_dataMedia->automaticLoad(_realParent->fullId(), _parent->data());
|
||||
|
||||
validateGroupedCache(geometry, corners, cacheKey, cache);
|
||||
validateGroupedCache(geometry, rounding, cacheKey, cache);
|
||||
|
||||
const auto st = context.st;
|
||||
const auto sti = context.imageStyle();
|
||||
|
@ -573,11 +573,10 @@ void Photo::drawGrouped(
|
|||
if (overlayOpacity > 0.) {
|
||||
p.setOpacity(overlayOpacity);
|
||||
const auto roundRadius = ImageRoundRadius::Large;
|
||||
// #TODO rounding
|
||||
//Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//if (!context.selected()) {
|
||||
// Ui::FillComplexOverlayRect(p, st, geometry, roundRadius, corners);
|
||||
//}
|
||||
fillImageOverlay(p, geometry, rounding, context);
|
||||
if (!context.selected()) {
|
||||
fillImageOverlay(p, geometry, rounding, context);
|
||||
}
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
|
@ -680,7 +679,7 @@ bool Photo::needInfoDisplay() const {
|
|||
|
||||
void Photo::validateGroupedCache(
|
||||
const QRect &geometry,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const {
|
||||
using Option = Images::Option;
|
||||
|
@ -697,18 +696,11 @@ void Photo::validateGroupedCache(
|
|||
: 0;
|
||||
const auto width = geometry.width();
|
||||
const auto height = geometry.height();
|
||||
const auto corner = [&](RectPart part, Option skip) {
|
||||
return !(corners & part) ? skip : Option();
|
||||
};
|
||||
const auto options = Option::RoundLarge
|
||||
| (loaded ? Option() : Option::Blur)
|
||||
| corner(RectPart::TopLeft, Option::RoundSkipTopLeft)
|
||||
| corner(RectPart::TopRight, Option::RoundSkipTopRight)
|
||||
| corner(RectPart::BottomLeft, Option::RoundSkipBottomLeft)
|
||||
| corner(RectPart::BottomRight, Option::RoundSkipBottomRight);
|
||||
const auto options = (loaded ? Option() : Option::Blur);
|
||||
const auto key = (uint64(width) << 48)
|
||||
| (uint64(height) << 32)
|
||||
| (uint64(options) << 16)
|
||||
| (uint64(rounding.key()) << 8)
|
||||
| (uint64(loadLevel));
|
||||
if (*cacheKey == key) {
|
||||
return;
|
||||
|
@ -731,9 +723,14 @@ void Photo::validateGroupedCache(
|
|||
: Image::BlankMedia().get();
|
||||
|
||||
*cacheKey = key;
|
||||
*cache = image->pixNoCache(
|
||||
auto scaled = Images::Prepare(
|
||||
image->original(),
|
||||
pixSize * ratio,
|
||||
{ .options = options, .outer = { width, height } });
|
||||
auto rounded = Images::Round(
|
||||
std::move(scaled),
|
||||
MediaRoundingMask(rounding));
|
||||
*cache = Ui::PixmapFromImage(std::move(rounded));
|
||||
}
|
||||
|
||||
bool Photo::createStreamingObjects() {
|
||||
|
|
|
@ -67,7 +67,7 @@ public:
|
|||
const PaintContext &context,
|
||||
const QRect &geometry,
|
||||
RectParts sides,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
float64 highlightOpacity,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const override;
|
||||
|
@ -123,7 +123,7 @@ private:
|
|||
bool needInfoDisplay() const;
|
||||
void validateGroupedCache(
|
||||
const QRect &geometry,
|
||||
RectParts corners,
|
||||
Ui::BubbleRounding rounding,
|
||||
not_null<uint64*> cacheKey,
|
||||
not_null<QPixmap*> cache) const;
|
||||
void validateImageCache(
|
||||
|
|
|
@ -72,6 +72,11 @@ struct BubbleRounding {
|
|||
return { this, index };
|
||||
}
|
||||
|
||||
[[nodiscard]] uchar key() const {
|
||||
static_assert(sizeof(*this) == sizeof(uchar));
|
||||
return uchar(*reinterpret_cast<const std::byte*>(this));
|
||||
}
|
||||
|
||||
inline friend constexpr auto operator<=>(
|
||||
BubbleRounding,
|
||||
BubbleRounding) = default;
|
||||
|
|
Loading…
Add table
Reference in a new issue