Add QR code generation progress.

This commit is contained in:
John Preston 2019-11-26 16:17:19 +03:00
parent ba7762305e
commit f4bf79b067
2 changed files with 43 additions and 18 deletions

View File

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/wrap/fade_wrap.h" #include "ui/wrap/fade_wrap.h"
#include "ui/wrap/vertical_layout.h" #include "ui/wrap/vertical_layout.h"
#include "ui/effects/radial_animation.h"
#include "ui/text/text_utilities.h" #include "ui/text/text_utilities.h"
#include "ui/image/image_prepare.h" #include "ui/image/image_prepare.h"
#include "ui/painter.h" #include "ui/painter.h"
@ -61,6 +62,15 @@ namespace {
[[nodiscard]] not_null<Ui::RpWidget*> PrepareQrWidget( [[nodiscard]] not_null<Ui::RpWidget*> PrepareQrWidget(
not_null<QWidget*> parent, not_null<QWidget*> parent,
rpl::producer<QByteArray> codes) { rpl::producer<QByteArray> codes) {
struct State {
explicit State(Fn<void()> callback)
: waiting(callback, st::defaultInfiniteRadialAnimation) {
}
QImage qr;
QImage center;
Ui::InfiniteRadialAnimation waiting;
};
auto qrs = std::move( auto qrs = std::move(
codes codes
) | rpl::map([](const QByteArray &code) { ) | rpl::map([](const QByteArray &code) {
@ -72,8 +82,9 @@ namespace {
style::PaletteChanged() style::PaletteChanged()
); );
auto result = Ui::CreateChild<Ui::RpWidget>(parent.get()); auto result = Ui::CreateChild<Ui::RpWidget>(parent.get());
const auto current = result->lifetime().make_state<QImage>(); const auto state = result->lifetime().make_state<State>(
const auto center = result->lifetime().make_state<QImage>(); [=] { result->update(); });
state->waiting.start();
result->resize(st::introQrMaxSize, st::introQrMaxSize); result->resize(st::introQrMaxSize, st::introQrMaxSize);
rpl::combine( rpl::combine(
std::move(qrs), std::move(qrs),
@ -81,7 +92,8 @@ namespace {
) | rpl::map([](const Qr::Data &code, const auto &) { ) | rpl::map([](const Qr::Data &code, const auto &) {
return TelegramQr(code, st::introQrPixel, st::introQrMaxSize); return TelegramQr(code, st::introQrPixel, st::introQrMaxSize);
}) | rpl::start_with_next([=](QImage &&image) { }) | rpl::start_with_next([=](QImage &&image) {
*current = std::move(image); state->qr = std::move(image);
state->waiting.stop();
result->update(); result->update();
}, result->lifetime()); }, result->lifetime());
std::move( std::move(
@ -89,29 +101,41 @@ namespace {
) | rpl::map([] { ) | rpl::map([] {
return TelegramLogoImage(); return TelegramLogoImage();
}) | rpl::start_with_next([=](QImage &&image) { }) | rpl::start_with_next([=](QImage &&image) {
*center = std::move(image); state->center = std::move(image);
}, result->lifetime()); }, result->lifetime());
result->paintRequest( result->paintRequest(
) | rpl::filter([=] { ) | rpl::start_with_next([=](QRect clip) {
return !center->isNull();
}) | rpl::start_with_next([=](QRect clip) {
auto p = QPainter(result); auto p = QPainter(result);
p.drawImage( auto rect = QRect(
QRect( (result->width() - st::introQrCenterSize) / 2,
(result->width() - st::introQrCenterSize) / 2, (result->height() - st::introQrCenterSize) / 2,
(result->height() - st::introQrCenterSize) / 2, st::introQrCenterSize,
st::introQrCenterSize, st::introQrCenterSize);
st::introQrCenterSize), p.drawImage(rect, state->center);
*center); if (!anim::Disabled() && state->waiting.animating()) {
if (current) { auto hq = PainterHighQualityEnabler(p);
const auto size = current->size() / cIntRetinaFactor(); const auto line = st::radialLine;
const auto radial = state->waiting.computeState();
auto pen = st::activeButtonBg->p;
pen.setWidth(line);
pen.setCapStyle(Qt::RoundCap);
p.setOpacity(radial.shown);
p.setPen(pen);
p.drawArc(
rect.marginsAdded({ line, line, line, line }),
radial.arcFrom,
radial.arcLength);
p.setOpacity(1.);
}
if (!state->qr.isNull()) {
const auto size = state->qr.size() / cIntRetinaFactor();
p.drawImage( p.drawImage(
QRect( QRect(
(result->width() - size.width()) / 2, (result->width() - size.width()) / 2,
(result->height() - size.height()) / 2, (result->height() - size.height()) / 2,
size.width(), size.width(),
size.height()), size.height()),
*current); state->qr);
} }
}, result->lifetime()); }, result->lifetime());
return result; return result;

View File

@ -478,7 +478,8 @@ void Step::showFast() {
} }
bool Step::animating() const { bool Step::animating() const {
return (_slideAnimation && _slideAnimation->animating()) || _a_show.animating(); return (_slideAnimation && _slideAnimation->animating())
|| _a_show.animating();
} }
bool Step::hasCover() const { bool Step::hasCover() const {