diff --git a/Telegram/Resources/icons/intro_qr_plane.png b/Telegram/Resources/icons/intro_qr_plane.png new file mode 100644 index 000000000..cdc309f9d Binary files /dev/null and b/Telegram/Resources/icons/intro_qr_plane.png differ diff --git a/Telegram/Resources/icons/intro_qr_plane@2x.png b/Telegram/Resources/icons/intro_qr_plane@2x.png new file mode 100644 index 000000000..3d0c2e9af Binary files /dev/null and b/Telegram/Resources/icons/intro_qr_plane@2x.png differ diff --git a/Telegram/Resources/icons/intro_qr_plane@3x.png b/Telegram/Resources/icons/intro_qr_plane@3x.png new file mode 100644 index 000000000..ae5c5442e Binary files /dev/null and b/Telegram/Resources/icons/intro_qr_plane@3x.png differ diff --git a/Telegram/SourceFiles/intro/intro.style b/Telegram/SourceFiles/intro/intro.style index 8491d5b14..c9d4be939 100644 --- a/Telegram/SourceFiles/intro/intro.style +++ b/Telegram/SourceFiles/intro/intro.style @@ -162,9 +162,9 @@ introBackButton: IconButton(defaultIconButton) { } } -introQrTop: 0px; +introQrTop: -6px; introQrPixel: 50px; // large enough -introQrMaxSize: 170px; +introQrMaxSize: 180px; introQrLabelsWidth: 292px; introQrTitle: FlatLabel(defaultFlatLabel) { textFg: introTitleFg; @@ -179,3 +179,5 @@ introQrStep: defaultFlatLabel; introQrStepsTop: 232px; introQrStepMargins: margins(0px, 8px, 0px, 0px); introQrSkipTop: 360px; +introQrCenterSize: 44px; +introQrPlane: icon {{ "intro_qr_plane", activeButtonFg }}; diff --git a/Telegram/SourceFiles/intro/intro_qr.cpp b/Telegram/SourceFiles/intro/intro_qr.cpp index fe6971903..3ee26130e 100644 --- a/Telegram/SourceFiles/intro/intro_qr.cpp +++ b/Telegram/SourceFiles/intro/intro_qr.cpp @@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/vertical_layout.h" #include "ui/text/text_utilities.h" #include "ui/image/image_prepare.h" +#include "ui/painter.h" #include "main/main_account.h" #include "boxes/confirm_box.h" #include "core/application.h" @@ -26,35 +27,26 @@ namespace Intro { namespace details { namespace { -[[nodiscard]] QImage TelegramLogoImage(int size) { - constexpr auto kScale = 0.8; - const auto used = int(size * kScale); - const auto adjusted = used + ((used % 2) + (size % 2)) % 2; - const auto image = Core::App().logo().scaled( - adjusted, - adjusted, - Qt::KeepAspectRatio, - Qt::SmoothTransformation); - auto result = QImage(size, size, QImage::Format_ARGB32_Premultiplied); +[[nodiscard]] QImage TelegramLogoImage() { + const auto size = QSize(st::introQrCenterSize, st::introQrCenterSize); + auto result = QImage( + size * style::DevicePixelRatio(), + QImage::Format_ARGB32_Premultiplied); result.fill(Qt::transparent); + result.setDevicePixelRatio(style::DevicePixelRatio()); { - QPainter p(&result); - p.drawImage( - QRect( - (size - adjusted) / 2, - (size - adjusted) / 2, - adjusted, - adjusted), - image); + auto p = QPainter(&result); + auto hq = PainterHighQualityEnabler(p); + p.setBrush(st::activeButtonBg); + p.setPen(Qt::NoPen); + p.drawEllipse(QRect(QPoint(), size)); + st::introQrPlane.paintInCenter(p, QRect(QPoint(), size)); } return result; } [[nodiscard]] QImage TelegramQrExact(const Qr::Data &data, int pixel) { return Qr::Generate(data, pixel, st::windowFg->c); - //Qr::ReplaceCenter( - // Qr::Generate(data, pixel), - // TelegramLogoImage(Qr::ReplaceSize(data, pixel))); } [[nodiscard]] QImage TelegramQr(const Qr::Data &data, int pixel, int max = 0) { @@ -74,25 +66,53 @@ namespace { ) | rpl::map([](const QByteArray &code) { return Qr::Encode(code, Qr::Redundancy::Quartile); }); + auto palettes = rpl::single( + rpl::empty_value() + ) | rpl::then( + style::PaletteChanged() + ); auto result = Ui::CreateChild(parent.get()); - auto current = result->lifetime().make_state(); + const auto current = result->lifetime().make_state(); + const auto center = result->lifetime().make_state(); + result->resize(st::introQrMaxSize, st::introQrMaxSize); rpl::combine( std::move(qrs), - rpl::single(rpl::empty_value()) | rpl::then(style::PaletteChanged()) + rpl::duplicate(palettes) ) | rpl::map([](const Qr::Data &code, const auto &) { return TelegramQr(code, st::introQrPixel, st::introQrMaxSize); }) | rpl::start_with_next([=](QImage &&image) { - result->resize(image.size() / cIntRetinaFactor()); *current = std::move(image); result->update(); }, result->lifetime()); + std::move( + palettes + ) | rpl::map([] { + return TelegramLogoImage(); + }) | rpl::start_with_next([=](QImage &&image) { + *center = std::move(image); + }, result->lifetime()); result->paintRequest( ) | rpl::filter([=] { - return !current->isNull(); + return !center->isNull(); }) | rpl::start_with_next([=](QRect clip) { - QPainter(result).drawImage( - QRect(QPoint(), current->size() / cIntRetinaFactor()), - *current); + auto p = QPainter(result); + p.drawImage( + QRect( + (result->width() - st::introQrCenterSize) / 2, + (result->height() - st::introQrCenterSize) / 2, + st::introQrCenterSize, + st::introQrCenterSize), + *center); + if (current) { + const auto size = current->size() / cIntRetinaFactor(); + p.drawImage( + QRect( + (result->width() - size.width()) / 2, + (result->height() - size.height()) / 2, + size.width(), + size.height()), + *current); + } }, result->lifetime()); return result; }