mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added ability to remove background from QR in share QR box.
This commit is contained in:
parent
9557f0c844
commit
8d9d7c4cea
2 changed files with 62 additions and 15 deletions
|
@ -5631,6 +5631,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_qr_box_quality1" = "Normal";
|
"lng_qr_box_quality1" = "Normal";
|
||||||
"lng_qr_box_quality2" = "High";
|
"lng_qr_box_quality2" = "High";
|
||||||
"lng_qr_box_quality3" = "Very High";
|
"lng_qr_box_quality3" = "Very High";
|
||||||
|
"lng_qr_box_transparent_background" = "Transparent Background";
|
||||||
|
|
||||||
// Wnd specific
|
// Wnd specific
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,11 @@ using Colors = std::vector<QColor>;
|
||||||
st::profileQrBackgroundMargins.bottom());
|
st::profileQrBackgroundMargins.bottom());
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] QImage TelegramQr(const Qr::Data &data, int pixel, int max) {
|
[[nodiscard]] QImage TelegramQr(
|
||||||
|
const Qr::Data &data,
|
||||||
|
int pixel,
|
||||||
|
int max,
|
||||||
|
bool hasWhiteBackground) {
|
||||||
Expects(data.size > 0);
|
Expects(data.size > 0);
|
||||||
|
|
||||||
constexpr auto kCenterRatio = 0.175;
|
constexpr auto kCenterRatio = 0.175;
|
||||||
|
@ -70,8 +74,8 @@ using Colors = std::vector<QColor>;
|
||||||
auto qr = Qr::Generate(
|
auto qr = Qr::Generate(
|
||||||
data,
|
data,
|
||||||
pixel * style::DevicePixelRatio(),
|
pixel * style::DevicePixelRatio(),
|
||||||
Qt::transparent,
|
hasWhiteBackground ? Qt::transparent : Qt::black,
|
||||||
Qt::white);
|
hasWhiteBackground ? Qt::white : Qt::transparent);
|
||||||
{
|
{
|
||||||
auto p = QPainter(&qr);
|
auto p = QPainter(&qr);
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
@ -81,10 +85,16 @@ using Colors = std::vector<QColor>;
|
||||||
- Margins((size.width() - (size.width() * kCenterRatio)) / 2);
|
- Margins((size.width() - (size.width() * kCenterRatio)) / 2);
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(Qt::white);
|
p.setBrush(Qt::white);
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Clear);
|
if (hasWhiteBackground) {
|
||||||
p.drawEllipse(centerRect);
|
p.setCompositionMode(QPainter::CompositionMode_Clear);
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
p.drawEllipse(centerRect);
|
||||||
svg.render(&p, centerRect);
|
p.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
|
svg.render(&p, centerRect);
|
||||||
|
} else {
|
||||||
|
p.drawEllipse(centerRect);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_Clear);
|
||||||
|
svg.render(&p, centerRect);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return qr;
|
return qr;
|
||||||
}
|
}
|
||||||
|
@ -112,10 +122,11 @@ void Paint(
|
||||||
int qrPixel,
|
int qrPixel,
|
||||||
int radius,
|
int radius,
|
||||||
int textMaxHeight,
|
int textMaxHeight,
|
||||||
int photoSize) {
|
int photoSize,
|
||||||
|
bool hasWhiteBackground) {
|
||||||
auto hq = PainterHighQualityEnabler(p);
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(Qt::white);
|
p.setBrush(hasWhiteBackground ? Qt::white : Qt::transparent);
|
||||||
const auto roundedRect = qrRect
|
const auto roundedRect = qrRect
|
||||||
+ RoundedMargins(backgroundMargins, photoSize, textMaxHeight);
|
+ RoundedMargins(backgroundMargins, photoSize, textMaxHeight);
|
||||||
p.drawRoundedRect(roundedRect, radius, radius);
|
p.drawRoundedRect(roundedRect, radius, radius);
|
||||||
|
@ -132,7 +143,9 @@ void Paint(
|
||||||
backgroundColors,
|
backgroundColors,
|
||||||
gradientRotation,
|
gradientRotation,
|
||||||
1. - (gradientRotationAdd / 45.));
|
1. - (gradientRotationAdd / 45.));
|
||||||
p.drawImage(qrRect, back);
|
if (hasWhiteBackground) {
|
||||||
|
p.drawImage(qrRect, back);
|
||||||
|
}
|
||||||
const auto coloredSize = QSize(back.width(), textMaxHeight);
|
const auto coloredSize = QSize(back.width(), textMaxHeight);
|
||||||
auto colored = QImage(
|
auto colored = QImage(
|
||||||
coloredSize * style::DevicePixelRatio(),
|
coloredSize * style::DevicePixelRatio(),
|
||||||
|
@ -151,7 +164,17 @@ void Paint(
|
||||||
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||||
p.drawImage(0, -back.height() + textMaxHeight, back);
|
p.drawImage(0, -back.height() + textMaxHeight, back);
|
||||||
}
|
}
|
||||||
p.drawImage(qrRect, qrImage);
|
if (!hasWhiteBackground) {
|
||||||
|
auto copy = qrImage;
|
||||||
|
{
|
||||||
|
auto p = QPainter(©);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||||
|
p.drawImage(Rect(copy.size()), back);
|
||||||
|
}
|
||||||
|
p.drawImage(qrRect, copy);
|
||||||
|
} else {
|
||||||
|
p.drawImage(qrRect, qrImage);
|
||||||
|
}
|
||||||
if (textMaxHeight) {
|
if (textMaxHeight) {
|
||||||
p.drawImage(
|
p.drawImage(
|
||||||
qrRect.x() - textAdditionalWidth / 2,
|
qrRect.x() - textAdditionalWidth / 2,
|
||||||
|
@ -168,6 +191,7 @@ not_null<Ui::RpWidget*> PrepareQrWidget(
|
||||||
not_null<Ui::RpWidget*> topWidget,
|
not_null<Ui::RpWidget*> topWidget,
|
||||||
const style::font &font,
|
const style::font &font,
|
||||||
rpl::producer<bool> userpicToggled,
|
rpl::producer<bool> userpicToggled,
|
||||||
|
rpl::producer<bool> backgroundToggled,
|
||||||
rpl::producer<QString> username,
|
rpl::producer<QString> username,
|
||||||
rpl::producer<QString> links,
|
rpl::producer<QString> links,
|
||||||
rpl::producer<Colors> bgs,
|
rpl::producer<Colors> bgs,
|
||||||
|
@ -187,6 +211,7 @@ not_null<Ui::RpWidget*> PrepareQrWidget(
|
||||||
int textWidth = 0;
|
int textWidth = 0;
|
||||||
int textMaxHeight = 0;
|
int textMaxHeight = 0;
|
||||||
int photoSize = 0;
|
int photoSize = 0;
|
||||||
|
bool backgroundToggled = false;
|
||||||
};
|
};
|
||||||
const auto result = Ui::CreateChild<Ui::RpWidget>(divider);
|
const auto result = Ui::CreateChild<Ui::RpWidget>(divider);
|
||||||
topWidget->setParent(result);
|
topWidget->setParent(result);
|
||||||
|
@ -201,6 +226,7 @@ not_null<Ui::RpWidget*> PrepareQrWidget(
|
||||||
st::creditsBoxAboutDivider);
|
st::creditsBoxAboutDivider);
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
std::move(userpicToggled),
|
std::move(userpicToggled),
|
||||||
|
std::move(backgroundToggled),
|
||||||
std::move(username),
|
std::move(username),
|
||||||
std::move(bgs),
|
std::move(bgs),
|
||||||
std::move(links),
|
std::move(links),
|
||||||
|
@ -208,11 +234,13 @@ not_null<Ui::RpWidget*> PrepareQrWidget(
|
||||||
rpl::single(rpl::empty) | rpl::then(style::PaletteChanged())
|
rpl::single(rpl::empty) | rpl::then(style::PaletteChanged())
|
||||||
) | rpl::start_with_next([=](
|
) | rpl::start_with_next([=](
|
||||||
bool userpicToggled,
|
bool userpicToggled,
|
||||||
|
bool backgroundToggled,
|
||||||
const QString &username,
|
const QString &username,
|
||||||
const Colors &backgroundColors,
|
const Colors &backgroundColors,
|
||||||
const QString &link,
|
const QString &link,
|
||||||
const QString &about,
|
const QString &about,
|
||||||
const auto &) {
|
const auto &) {
|
||||||
|
state->backgroundToggled = backgroundToggled;
|
||||||
state->backgroundMargins = userpicToggled
|
state->backgroundMargins = userpicToggled
|
||||||
? st::profileQrBackgroundMargins
|
? st::profileQrBackgroundMargins
|
||||||
: NoPhotoBackgroundMargins();
|
: NoPhotoBackgroundMargins();
|
||||||
|
@ -230,7 +258,8 @@ not_null<Ui::RpWidget*> PrepareQrWidget(
|
||||||
state->qrImage = TelegramQr(
|
state->qrImage = TelegramQr(
|
||||||
Qr::Encode(link.toUtf8(), Qr::Redundancy::Default),
|
Qr::Encode(link.toUtf8(), Qr::Redundancy::Default),
|
||||||
st::introQrPixel,
|
st::introQrPixel,
|
||||||
downTo).scaled(
|
downTo,
|
||||||
|
backgroundToggled).scaled(
|
||||||
Size(qrMaxSize * style::DevicePixelRatio()),
|
Size(qrMaxSize * style::DevicePixelRatio()),
|
||||||
Qt::IgnoreAspectRatio,
|
Qt::IgnoreAspectRatio,
|
||||||
Qt::SmoothTransformation);
|
Qt::SmoothTransformation);
|
||||||
|
@ -293,7 +322,8 @@ not_null<Ui::RpWidget*> PrepareQrWidget(
|
||||||
st::introQrPixel,
|
st::introQrPixel,
|
||||||
st::profileQrBackgroundRadius,
|
st::profileQrBackgroundRadius,
|
||||||
state->textMaxHeight,
|
state->textMaxHeight,
|
||||||
state->photoSize);
|
state->photoSize,
|
||||||
|
state->backgroundToggled);
|
||||||
if (!state->photoSize) {
|
if (!state->photoSize) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -395,6 +425,7 @@ void FillPeerQrBox(
|
||||||
Ui::RpWidget* saveButton = nullptr;
|
Ui::RpWidget* saveButton = nullptr;
|
||||||
rpl::variable<bool> saveButtonBusy = false;
|
rpl::variable<bool> saveButtonBusy = false;
|
||||||
rpl::variable<bool> userpicToggled = true;
|
rpl::variable<bool> userpicToggled = true;
|
||||||
|
rpl::variable<bool> backgroundToggled = true;
|
||||||
rpl::variable<Colors> bgs;
|
rpl::variable<Colors> bgs;
|
||||||
Ui::Animations::Simple animation;
|
Ui::Animations::Simple animation;
|
||||||
rpl::variable<int> chosen = 0;
|
rpl::variable<int> chosen = 0;
|
||||||
|
@ -445,6 +476,7 @@ void FillPeerQrBox(
|
||||||
userpic,
|
userpic,
|
||||||
state->font,
|
state->font,
|
||||||
state->userpicToggled.value(),
|
state->userpicToggled.value(),
|
||||||
|
state->backgroundToggled.value(),
|
||||||
usernameValue(),
|
usernameValue(),
|
||||||
linkValue(),
|
linkValue(),
|
||||||
state->bgs.value(),
|
state->bgs.value(),
|
||||||
|
@ -729,6 +761,17 @@ void FillPeerQrBox(
|
||||||
state->userpicToggled = !state->userpicToggled.current();
|
state->userpicToggled = !state->userpicToggled.current();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
const auto backgroundToggle = box->verticalLayout()->add(
|
||||||
|
object_ptr<Ui::SettingsButton>(
|
||||||
|
box->verticalLayout(),
|
||||||
|
tr::lng_qr_box_transparent_background(),
|
||||||
|
st::settingsButtonNoIcon));
|
||||||
|
backgroundToggle->toggleOn(state->backgroundToggled.value(), true);
|
||||||
|
backgroundToggle->setClickedCallback([=] {
|
||||||
|
state->backgroundToggled = !state->backgroundToggled.current();
|
||||||
|
});
|
||||||
|
}
|
||||||
Ui::AddSkip(box->verticalLayout());
|
Ui::AddSkip(box->verticalLayout());
|
||||||
Ui::AddSkip(box->verticalLayout());
|
Ui::AddSkip(box->verticalLayout());
|
||||||
|
|
||||||
|
@ -750,6 +793,7 @@ void FillPeerQrBox(
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto userpicToggled = state->userpicToggled.current();
|
const auto userpicToggled = state->userpicToggled.current();
|
||||||
|
const auto backgroundToggled = state->backgroundToggled.current();
|
||||||
const auto scale = style::kScaleDefault
|
const auto scale = style::kScaleDefault
|
||||||
* (kMaxQualities + int(state->scaleValue.current() * 2));
|
* (kMaxQualities + int(state->scaleValue.current() * 2));
|
||||||
const auto divider = std::max(1, style::Scale())
|
const auto divider = std::max(1, style::Scale())
|
||||||
|
@ -800,7 +844,8 @@ void FillPeerQrBox(
|
||||||
link.current().toUtf8(),
|
link.current().toUtf8(),
|
||||||
Qr::Redundancy::Default),
|
Qr::Redundancy::Default),
|
||||||
introQrPixel,
|
introQrPixel,
|
||||||
qrMaxSize);
|
qrMaxSize,
|
||||||
|
backgroundToggled);
|
||||||
const auto textMaxWidth = backgroundMargins.left()
|
const auto textMaxWidth = backgroundMargins.left()
|
||||||
+ (qrImage.width() / style::DevicePixelRatio());
|
+ (qrImage.width() / style::DevicePixelRatio());
|
||||||
const auto lines = int(textWidth / textMaxWidth) + 1;
|
const auto lines = int(textWidth / textMaxWidth) + 1;
|
||||||
|
@ -841,7 +886,8 @@ void FillPeerQrBox(
|
||||||
introQrPixel,
|
introQrPixel,
|
||||||
profileQrBackgroundRadius,
|
profileQrBackgroundRadius,
|
||||||
textMaxHeight,
|
textMaxHeight,
|
||||||
photoSize);
|
photoSize,
|
||||||
|
backgroundToggled);
|
||||||
|
|
||||||
if (userpicToggled) {
|
if (userpicToggled) {
|
||||||
p.drawImage((resultSize.width() - photoSize) / 2, 0, top);
|
p.drawImage((resultSize.width() - photoSize) / 2, 0, top);
|
||||||
|
|
Loading…
Add table
Reference in a new issue