Adapted display of longest usernames in box for share of QR code.

This commit is contained in:
23rd 2024-09-07 11:21:38 +03:00
parent 29e97232d8
commit 8e1595eb29

View file

@ -79,7 +79,7 @@ using Colors = std::vector<QColor>;
[[nodiscard]] not_null<Ui::RpWidget*> PrepareQrWidget( [[nodiscard]] not_null<Ui::RpWidget*> PrepareQrWidget(
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
not_null<Ui::RpWidget*> topWidget, not_null<Ui::RpWidget*> topWidget,
rpl::producer<TextWithEntities> codes, rpl::producer<TextWithEntities> username,
rpl::producer<QString> links, rpl::producer<QString> links,
rpl::producer<std::vector<QColor>> bgs) { rpl::producer<std::vector<QColor>> bgs) {
const auto divider = container->add( const auto divider = container->add(
@ -92,7 +92,8 @@ using Colors = std::vector<QColor>;
Ui::Animations::Basic updating; Ui::Animations::Basic updating;
QImage qr; QImage qr;
std::vector<QColor> bgs; std::vector<QColor> bgs;
rpl::variable<TextWithEntities> code; rpl::variable<TextWithEntities> username;
int textMaxHeight = 0;
rpl::variable<QString> link; rpl::variable<QString> link;
}; };
auto palettes = rpl::single(rpl::empty) | rpl::then( auto palettes = rpl::single(rpl::empty) | rpl::then(
@ -103,7 +104,7 @@ using Colors = std::vector<QColor>;
topWidget->setAttribute(Qt::WA_TransparentForMouseEvents); topWidget->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto state = result->lifetime().make_state<State>( const auto state = result->lifetime().make_state<State>(
[=] { result->update(); }); [=] { result->update(); });
state->code = rpl::variable<TextWithEntities>(std::move(codes)); state->username = rpl::variable<TextWithEntities>(std::move(username));
state->link = rpl::variable<QString>(std::move(links)); state->link = rpl::variable<QString>(std::move(links));
std::move( std::move(
bgs bgs
@ -111,22 +112,32 @@ using Colors = std::vector<QColor>;
state->bgs = bgs; state->bgs = bgs;
}, container->lifetime()); }, container->lifetime());
const auto font = st::mainMenuResetScaleFont; const auto font = st::mainMenuResetScaleFont;
const auto textMaxHeight = font->height * 3; const auto backSkip = st::profileQrBackgroundSkip;
const auto qrMaxSize = st::boxWideWidth const auto qrMaxSize = st::boxWideWidth
- rect::m::sum::h(st::boxRowPadding) - rect::m::sum::h(st::boxRowPadding)
- 2 * st::profileQrBackgroundSkip; - 2 * backSkip;
result->resize(
qrMaxSize + 2 * st::profileQrBackgroundSkip,
qrMaxSize + 2 * st::profileQrBackgroundSkip + textMaxHeight * 2);
rpl::combine( rpl::combine(
state->link.value() | rpl::map([](const QString &code) { state->username.value() | rpl::map([=](const TextWithEntities &u) {
return Qr::Encode(code.toUtf8(), Qr::Redundancy::Default); return font->width(u.text);
}), }),
rpl::duplicate(palettes) rpl::combine(
) | rpl::map([=](const Qr::Data &code, const auto &) { state->link.value() | rpl::map([](const QString &code) {
return TelegramQr(code, st::introQrPixel, qrMaxSize); return Qr::Encode(code.toUtf8(), Qr::Redundancy::Default);
}) | rpl::start_with_next([=](QImage &&image) { }),
rpl::duplicate(palettes)
) | rpl::map([=](const Qr::Data &code, const auto &) {
return TelegramQr(code, st::introQrPixel, qrMaxSize);
})
) | rpl::start_with_next([=](int usernameW, QImage &&image) {
state->qr = std::move(image); state->qr = std::move(image);
const auto qrWidth = state->qr.size().width()
/ style::DevicePixelRatio();
const auto lines = int(usernameW / qrWidth) + 1;
state->textMaxHeight = font->height * lines;
const auto heightSkip = (font->height * 3);
result->resize(
qrMaxSize + 2 * backSkip,
qrMaxSize + 2 * backSkip + state->textMaxHeight + heightSkip);
}, result->lifetime()); }, result->lifetime());
result->paintRequest( result->paintRequest(
) | rpl::start_with_next([=](QRect clip) { ) | rpl::start_with_next([=](QRect clip) {
@ -138,17 +149,21 @@ using Colors = std::vector<QColor>;
st::introQrPixel); st::introQrPixel);
const auto size = (state->qr.size() / style::DevicePixelRatio()); const auto size = (state->qr.size() / style::DevicePixelRatio());
const auto radius = st::profileQrBackgroundRadius; const auto radius = st::profileQrBackgroundRadius;
const auto skip = st::profileQrBackgroundSkip;
const auto qr = QRect( const auto qr = QRect(
(result->width() - size.width()) / 2, (result->width() - size.width()) / 2,
skip * 3, backSkip * 3,
size.width(), size.width(),
size.height()); size.height());
auto hq = PainterHighQualityEnabler(p); auto hq = PainterHighQualityEnabler(p);
p.setPen(Qt::NoPen); p.setPen(Qt::NoPen);
p.setBrush(Qt::white); p.setBrush(Qt::white);
p.drawRoundedRect( p.drawRoundedRect(
qr + QMargins(skip, skip + skip / 2, skip, skip + textMaxHeight), qr
+ QMargins(
backSkip,
backSkip + backSkip / 2,
backSkip,
backSkip + state->textMaxHeight),
radius, radius,
radius); radius);
if (!state->qr.isNull() && !state->bgs.empty()) { if (!state->qr.isNull() && !state->bgs.empty()) {
@ -167,7 +182,9 @@ using Colors = std::vector<QColor>;
gradientRotation, gradientRotation,
1. - (gradientRotationAdd / 45.)); 1. - (gradientRotationAdd / 45.));
p.drawImage(qr, back); p.drawImage(qr, back);
const auto coloredSize = QSize(back.width(), textMaxHeight); const auto coloredSize = QSize(
back.width(),
state->textMaxHeight);
auto colored = QImage( auto colored = QImage(
coloredSize * style::DevicePixelRatio(), coloredSize * style::DevicePixelRatio(),
QImage::Format_ARGB32_Premultiplied); QImage::Format_ARGB32_Premultiplied);
@ -183,13 +200,13 @@ using Colors = std::vector<QColor>;
option.setWrapMode(QTextOption::WrapAnywhere); option.setWrapMode(QTextOption::WrapAnywhere);
p.drawText( p.drawText(
Rect(coloredSize), Rect(coloredSize),
state->code.current().text.toUpper(), state->username.current().text.toUpper(),
option); option);
p.setCompositionMode(QPainter::CompositionMode_SourceIn); p.setCompositionMode(QPainter::CompositionMode_SourceIn);
p.drawImage(0, -back.height() + textMaxHeight, back); p.drawImage(0, -back.height() + state->textMaxHeight, back);
} }
p.drawImage(qr, state->qr); p.drawImage(qr, state->qr);
p.drawImage(qr.x(), qr.y() + qr.height() + skip / 2, colored); p.drawImage(qr.x(), qr.y() + qr.height() + backSkip / 2, colored);
} }
}, result->lifetime()); }, result->lifetime());
result->sizeValue( result->sizeValue(
@ -200,7 +217,7 @@ using Colors = std::vector<QColor>;
const auto qrHeight = state->qr.height() / style::DevicePixelRatio(); const auto qrHeight = state->qr.height() / style::DevicePixelRatio();
topWidget->moveToLeft( topWidget->moveToLeft(
(result->width() - topWidget->width()) / 2, (result->width() - topWidget->width()) / 2,
(st::profileQrBackgroundSkip (backSkip
+ st::profileQrBackgroundSkip / 2 + st::profileQrBackgroundSkip / 2
- topWidget->height() / 2)); - topWidget->height() / 2));
topWidget->raise(); topWidget->raise();