tdesktop/Telegram/SourceFiles/passport/passport_form_box.cpp

265 lines
5.9 KiB
C++

/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "passport/passport_form_box.h"
#include "passport/passport_form_view_separate.h"
#include "passport/passport_form_row.h"
#include "lang/lang_keys.h"
#include "ui/widgets/input_fields.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/text_options.h"
#include "styles/style_boxes.h"
#include "styles/style_widgets.h"
#include "styles/style_passport.h"
namespace Passport {
class FormBox::CheckWidget : public Ui::RpWidget {
public:
CheckWidget(QWidget *parent, not_null<ViewSeparate*> controller);
void setInnerFocus();
void submit();
protected:
int resizeGetHeight(int newWidth) override;
private:
void showError(const QString &error);
void hideError();
not_null<ViewSeparate*> _controller;
object_ptr<Ui::PasswordInput> _password;
object_ptr<Ui::FlatLabel> _hint = { nullptr };
object_ptr<Ui::FlatLabel> _error = { nullptr };
object_ptr<Ui::LinkButton> _forgot;
object_ptr<Ui::FlatLabel> _about;
};
class FormBox::Inner : public Ui::RpWidget {
public:
Inner(QWidget *parent, not_null<ViewSeparate*> controller);
void refresh();
protected:
int resizeGetHeight(int newWidth) override;
void paintEvent(QPaintEvent *e) override;
private:
not_null<ViewSeparate*> _controller;
std::vector<object_ptr<FormRow>> _rows;
};
FormBox::CheckWidget::CheckWidget(
QWidget *parent,
not_null<ViewSeparate*> controller)
: RpWidget(parent)
, _controller(controller)
, _password(
this,
st::defaultInputField,
langFactory(lng_passport_password_placeholder))
, _forgot(this, lang(lng_signin_recover), st::boxLinkButton)
, _about(
this,
lang(lng_passport_password_request),
Ui::FlatLabel::InitType::Simple,
st::passportPasswordLabel) {
connect(_password, &Ui::PasswordInput::submitted, this, [=] {
submit();
});
connect(_password, &Ui::PasswordInput::changed, this, [=] {
hideError();
});
if (const auto hint = _controller->passwordHint(); !hint.isEmpty()) {
_hint.create(
this,
hint,
Ui::FlatLabel::InitType::Simple,
st::passportPasswordHintLabel);
}
_controller->passwordError(
) | rpl::start_with_next([=](const QString &error) {
showError(error);
}, lifetime());
}
void FormBox::CheckWidget::showError(const QString &error) {
_password->showError();
_error.create(
this,
error,
Ui::FlatLabel::InitType::Simple,
st::passportErrorLabel);
_error->show();
if (_hint) {
_hint->hide();
}
resizeToWidth(width());
}
void FormBox::CheckWidget::hideError() {
_error.destroy();
if (_hint) {
_hint->show();
}
}
void FormBox::CheckWidget::submit() {
_controller->submitPassword(_password->getLastText());
}
void FormBox::CheckWidget::setInnerFocus() {
_password->setFocusFast();
}
int FormBox::CheckWidget::resizeGetHeight(int newWidth) {
const auto padding = st::passportPasswordPadding;
const auto availableWidth = newWidth
- st::boxPadding.left()
- st::boxPadding.right();
auto top = padding.top();
_about->resizeToWidth(availableWidth);
_about->moveToLeft(padding.left(), top);
top += _about->height();
_password->resize(availableWidth, _password->height());
_password->moveToLeft(padding.left(), top);
top += _password->height();
if (_error) {
_error->resizeToWidth(availableWidth);
_error->moveToLeft(padding.left(), top);
}
if (_hint) {
_hint->resizeToWidth(availableWidth);
_hint->moveToLeft(padding.left(), top);
top += _hint->height();
} else {
top += st::passportPasswordHintLabel.style.font->height;
}
_forgot->moveToLeft(padding.left(), top);
top += _forgot->height();
return top + padding.bottom();
}
FormBox::Inner::Inner(
QWidget *parent,
not_null<ViewSeparate*> controller)
: RpWidget(parent)
, _controller(controller) {
refresh();
}
void FormBox::Inner::refresh() {
auto index = 0;
_controller->fillRows([&](
QString title,
QString description,
bool ready) {
if (_rows.size() <= index) {
_rows.push_back(object_ptr<FormRow>(this, title, description));
_rows[index]->addClickHandler([=] {
_controller->editValue(index);
});
}
_rows[index++]->setReady(ready);
});
while (_rows.size() > index) {
_rows.pop_back();
}
resizeToWidth(width());
}
int FormBox::Inner::resizeGetHeight(int newWidth) {
auto result = 0;
for (auto &row : _rows) {
row->resizeToWidth(newWidth);
row->moveToLeft(0, result);
result += row->height();
}
return result;
}
void FormBox::Inner::paintEvent(QPaintEvent *e) {
Painter p(this);
}
FormBox::FormBox(QWidget*, not_null<ViewSeparate*> controller)
: _controller(controller) {
}
void FormBox::prepare() {
setTitle(langFactory(lng_passport_title));
addButton(langFactory(lng_create_group_next), [=] {
submitPassword();
});
addButton(langFactory(lng_cancel), [=] {
closeBox();
});
_passwordCheck = setInnerWidget(
object_ptr<CheckWidget>(this, _controller));
_passwordCheck->resizeToWidth(st::boxWideWidth);
_innerCached.create(this, _controller);
_innerCached->resizeToWidth(st::boxWideWidth);
const auto desiredHeight = std::min(
std::max(_innerCached->height(), _passwordCheck->height()),
st::boxMaxListHeight);
setDimensions(st::boxWideWidth, desiredHeight);
_innerCached->hide();
_controller->secretReadyEvents(
) | rpl::start_with_next([=] {
showForm();
}, lifetime());
}
void FormBox::setInnerFocus() {
if (_passwordCheck) {
_passwordCheck->setInnerFocus();
} else {
_inner->setFocus();
}
}
void FormBox::submitPassword() {
Expects(_passwordCheck != nullptr);
_passwordCheck->submit();
}
void FormBox::showForm() {
clearButtons();
addButton(langFactory(lng_passport_authorize), [=] {
submitForm();
});
addButton(langFactory(lng_cancel), [=] {
closeBox();
});
_inner = setInnerWidget(std::move(_innerCached));
_inner->show();
}
void FormBox::submitForm() {
}
} // namespace Passport