diff --git a/Telegram/SourceFiles/core/local_url_handlers.cpp b/Telegram/SourceFiles/core/local_url_handlers.cpp index c5f2f177fa..de59f999a4 100644 --- a/Telegram/SourceFiles/core/local_url_handlers.cpp +++ b/Telegram/SourceFiles/core/local_url_handlers.cpp @@ -234,11 +234,6 @@ bool ShowWallPaper( const auto bg = params.value("bg_color"); const auto color = params.value("color"); const auto gradient = params.value("gradient"); - if (gradient.contains('~') || bg.contains('~')) { - Ui::show(Box( - tr::lng_background_gradient_unsupported(tr::now))); - return false; - } return BackgroundPreviewBox::Start( controller, (!color.isEmpty() diff --git a/Telegram/SourceFiles/data/data_wall_paper.cpp b/Telegram/SourceFiles/data/data_wall_paper.cpp index 14c5537048..d224f85294 100644 --- a/Telegram/SourceFiles/data/data_wall_paper.cpp +++ b/Telegram/SourceFiles/data/data_wall_paper.cpp @@ -121,7 +121,7 @@ constexpr auto kVersion = 1; } [[nodiscard]] std::vector ColorsFromString(const QString &string) { - constexpr auto kMaxColors = 2; // #TODO themes gradients replace to 4 + constexpr auto kMaxColors = 4; const auto view = QStringView(string); const auto count = int(view.size() / 6); if (!count || count > kMaxColors || view.size() != count * 7 - 1) { @@ -247,7 +247,8 @@ float64 WallPaper::patternOpacity() const { } int WallPaper::gradientRotation() const { - return _rotation; + // In case of complex gradients rotation value is dynamic. + return (_backgroundColors.size() < 3) ? _rotation : 0; } bool WallPaper::hasShareUrl() const { @@ -442,14 +443,6 @@ std::optional WallPaper::Create( if (!document->checkWallPaperProperties()) { return std::nullopt; } - const auto unsupported = data.vsettings() - && data.vsettings()->match([&](const MTPDwallPaperSettings &data) { - return data.vthird_background_color() - || data.vfourth_background_color(); // #TODO themes gradients - }); - if (unsupported) { - return std::nullopt; - } auto result = WallPaper(data.vid().v); result._accessHash = data.vaccess_hash().v; result._ownerId = session->userId(); @@ -480,14 +473,6 @@ std::optional WallPaper::Create( } std::optional WallPaper::Create(const MTPDwallPaperNoFile &data) { - const auto unsupported = data.vsettings() - && data.vsettings()->match([&](const MTPDwallPaperSettings &data) { - return data.vthird_background_color() - || data.vfourth_background_color(); // #TODO themes gradients - }); - if (unsupported) { - return std::nullopt; - } auto result = WallPaper(data.vid().v); result._flags = (data.is_dark() ? WallPaperFlag::Dark : WallPaperFlag(0)) | (data.is_default() ? WallPaperFlag::Default : WallPaperFlag(0)); @@ -581,8 +566,7 @@ std::optional WallPaper::FromSerialized( >> slug >> blurred >> backgroundColorsCount; - // #TODO themes gradients replace with 4 - if (backgroundColorsCount < 0 || backgroundColorsCount > 2) { + if (backgroundColorsCount < 0 || backgroundColorsCount > 4) { return std::nullopt; } backgroundColors.reserve(backgroundColorsCount); @@ -729,59 +713,17 @@ bool IsCloudWallPaper(const WallPaper &paper) { && !details::IsTestingEditorWallPaper(paper); } -[[nodiscard]] QImage FillDitheredGradient( - QImage image, - const std::vector &colors, - int rotation) { - Expects(colors.size() > 1); - - image.setDevicePixelRatio(1.); - const auto width = image.width(); - const auto height = image.height(); - if (!width || !height) { - return image; - } - - auto p = QPainter(&image); - const auto [start, finalStop] = [&]() -> std::pair { - const auto type = std::clamp(rotation, 0, 315) / 45; - switch (type) { - case 0: return { { 0, 0 }, { 0, height } }; - case 1: return { { width, 0 }, { 0, height } }; - case 2: return { { width, 0 }, { 0, 0 } }; - case 3: return { { width, height }, { 0, 0 } }; - case 4: return { { 0, height }, { 0, 0 } }; - case 5: return { { 0, height }, { width, 0 } }; - case 6: return { { 0, 0 }, { width, 0 } }; - case 7: return { { 0, 0 }, { width, height } }; - } - Unexpected("Rotation value in GenerateDitheredGradient."); - }(); - auto gradient = QLinearGradient(start, finalStop); - gradient.setStops(QGradientStops{ - { 0.0, colors[0] }, - { 1.0, colors[1] } - }); - p.fillRect(0, 0, width, height, QBrush(std::move(gradient))); - p.end(); - - return Images::DitherImage(std::move(image)); -} - QImage GenerateWallPaper( QSize size, const std::vector &bg, int gradientRotation, float64 patternOpacity, Fn drawPattern) { - auto result = QImage(size, QImage::Format_ARGB32_Premultiplied); - if (bg.size() < 2) { - result.fill(bg.empty() ? DefaultBackgroundColor() : bg.front()); - } else { - result = FillDitheredGradient( - std::move(result), - bg, - gradientRotation); + auto result = bg.empty() + ? Images::GenerateGradient(size, { DefaultBackgroundColor() }) + : Images::GenerateGradient(size, bg, gradientRotation); + if (bg.size() > 1) { + result = Images::DitherImage(std::move(result)); } if (drawPattern) { auto p = QPainter(&result); @@ -829,10 +771,15 @@ QImage GenerateDitheredGradient( const std::vector &colors, int rotation) { constexpr auto kSize = 512; - return FillDitheredGradient( - QImage(kSize, kSize, QImage::Format_ARGB32_Premultiplied), - colors, - rotation); + const auto size = QSize(kSize, kSize); + if (colors.empty()) { + return Images::GenerateGradient(size, { DefaultBackgroundColor() }); + } + auto result = Images::GenerateGradient(size, colors, rotation); + if (colors.size() > 1) { + result = Images::DitherImage(std::move(result)); + } + return result; } QImage GenerateDitheredGradient(const Data::WallPaper &paper) { diff --git a/Telegram/SourceFiles/window/section_widget.cpp b/Telegram/SourceFiles/window/section_widget.cpp index f04897aee1..0d577fd4b8 100644 --- a/Telegram/SourceFiles/window/section_widget.cpp +++ b/Telegram/SourceFiles/window/section_widget.cpp @@ -138,9 +138,9 @@ void SectionWidget::PaintBackground( cache.pixmap); } }; - const auto goodNow = !state.now.pixmap.isNull() - && (state.now.area == fill); - const auto useCache = goodNow || !gradient.isNull(); + const auto hasNow = !state.now.pixmap.isNull(); + const auto goodNow = hasNow && (state.now.area == fill); + const auto useCache = goodNow || (hasNow && !gradient.isNull()); if (useCache) { if (state.shown < 1. && !gradient.isNull()) { paintCache(state.was); diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 3d5fcdb7dd..669767855a 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 3d5fcdb7ddab336ee2fadc3ceeced420e2c1f504 +Subproject commit 669767855a197976183684d25b2753899ee95e5c