init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Close stale issues and PRs / stale (push) Successful in 13s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
This commit is contained in:
612
Telegram/SourceFiles/payments/ui/payments_form_summary.cpp
Normal file
612
Telegram/SourceFiles/payments/ui/payments_form_summary.cpp
Normal file
@@ -0,0 +1,612 @@
|
||||
/*
|
||||
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 "payments/ui/payments_form_summary.h"
|
||||
|
||||
#include "payments/ui/payments_panel_delegate.h"
|
||||
#include "settings/settings_common.h" // AddButtonWithLabel.
|
||||
#include "ui/widgets/scroll_area.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/vertical_list.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/text/format_values.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "countries/countries_instance.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "styles/style_payments.h"
|
||||
#include "styles/style_passport.h"
|
||||
|
||||
namespace Payments::Ui {
|
||||
namespace {
|
||||
|
||||
constexpr auto kLightOpacity = 0.1;
|
||||
constexpr auto kLightRippleOpacity = 0.11;
|
||||
constexpr auto kChosenOpacity = 0.8;
|
||||
constexpr auto kChosenRippleOpacity = 0.5;
|
||||
|
||||
[[nodiscard]] Fn<QColor()> TransparentColor(
|
||||
const style::color &c,
|
||||
float64 opacity) {
|
||||
return [&c, opacity] {
|
||||
return QColor(
|
||||
c->c.red(),
|
||||
c->c.green(),
|
||||
c->c.blue(),
|
||||
c->c.alpha() * opacity);
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] style::RoundButton TipButtonStyle(
|
||||
const style::RoundButton &original,
|
||||
const style::color &light,
|
||||
const style::color &ripple) {
|
||||
auto result = original;
|
||||
result.textBg = light;
|
||||
result.ripple.color = ripple;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
using namespace ::Ui;
|
||||
|
||||
class PanelDelegate;
|
||||
|
||||
FormSummary::FormSummary(
|
||||
QWidget *parent,
|
||||
const Invoice &invoice,
|
||||
const RequestedInformation ¤t,
|
||||
const PaymentMethodDetails &method,
|
||||
const ShippingOptions &options,
|
||||
not_null<PanelDelegate*> delegate,
|
||||
int scrollTop)
|
||||
: _delegate(delegate)
|
||||
, _invoice(invoice)
|
||||
, _method(method)
|
||||
, _options(options)
|
||||
, _information(current)
|
||||
, _scroll(this, st::passportPanelScroll)
|
||||
, _layout(_scroll->setOwnedWidget(object_ptr<VerticalLayout>(this)))
|
||||
, _topShadow(this)
|
||||
, _bottomShadow(this)
|
||||
, _submit(_invoice.receipt.paid
|
||||
? object_ptr<RoundButton>(nullptr)
|
||||
: object_ptr<RoundButton>(
|
||||
this,
|
||||
tr::lng_payments_pay_amount(
|
||||
lt_amount,
|
||||
rpl::single(formatAmount(computeTotalAmount()))),
|
||||
st::paymentsPanelSubmit))
|
||||
, _cancel(
|
||||
this,
|
||||
(_invoice.receipt.paid
|
||||
? tr::lng_about_done()
|
||||
: tr::lng_cancel()),
|
||||
st::paymentsPanelButton)
|
||||
, _tipLightBg(TransparentColor(st::paymentsTipActive, kLightOpacity))
|
||||
, _tipLightRipple(
|
||||
TransparentColor(st::paymentsTipActive, kLightRippleOpacity))
|
||||
, _tipChosenBg(TransparentColor(st::paymentsTipActive, kChosenOpacity))
|
||||
, _tipChosenRipple(
|
||||
TransparentColor(st::paymentsTipActive, kChosenRippleOpacity))
|
||||
, _tipButton(TipButtonStyle(
|
||||
st::paymentsTipButton,
|
||||
_tipLightBg.color(),
|
||||
_tipLightRipple.color()))
|
||||
, _tipChosen(TipButtonStyle(
|
||||
st::paymentsTipChosen,
|
||||
_tipChosenBg.color(),
|
||||
_tipChosenRipple.color()))
|
||||
, _initialScrollTop(scrollTop) {
|
||||
setupControls();
|
||||
}
|
||||
|
||||
rpl::producer<int> FormSummary::scrollTopValue() const {
|
||||
return _scroll->scrollTopValue();
|
||||
}
|
||||
|
||||
bool FormSummary::showCriticalError(const TextWithEntities &text) {
|
||||
if (_invoice
|
||||
|| (_scroll->height() - _layout->height()
|
||||
< st::paymentsPanelSize.height() / 2)) {
|
||||
return false;
|
||||
}
|
||||
Ui::AddSkip(_layout.get(), st::paymentsPricesTopSkip);
|
||||
_layout->add(
|
||||
object_ptr<FlatLabel>(
|
||||
_layout.get(),
|
||||
rpl::single(text),
|
||||
st::paymentsCriticalError),
|
||||
style::al_top);
|
||||
return true;
|
||||
}
|
||||
|
||||
int FormSummary::contentHeight() const {
|
||||
return _invoice ? _scroll->height() : _layout->height();
|
||||
}
|
||||
|
||||
void FormSummary::updateThumbnail(const QImage &thumbnail) {
|
||||
_invoice.cover.thumbnail = thumbnail;
|
||||
_thumbnails.fire_copy(thumbnail);
|
||||
}
|
||||
|
||||
QString FormSummary::formatAmount(
|
||||
int64 amount,
|
||||
bool forceStripDotZero) const {
|
||||
return FillAmountAndCurrency(
|
||||
amount,
|
||||
_invoice.currency,
|
||||
forceStripDotZero);
|
||||
}
|
||||
|
||||
int64 FormSummary::computeTotalAmount() const {
|
||||
const auto total = ranges::accumulate(
|
||||
_invoice.prices,
|
||||
int64(0),
|
||||
std::plus<>(),
|
||||
&LabeledPrice::price);
|
||||
const auto selected = ranges::find(
|
||||
_options.list,
|
||||
_options.selectedId,
|
||||
&ShippingOption::id);
|
||||
const auto shipping = (selected != end(_options.list))
|
||||
? ranges::accumulate(
|
||||
selected->prices,
|
||||
int64(0),
|
||||
std::plus<>(),
|
||||
&LabeledPrice::price)
|
||||
: int64(0);
|
||||
return total + shipping + _invoice.tipsSelected;
|
||||
}
|
||||
|
||||
void FormSummary::setupControls() {
|
||||
setupContent(_layout.get());
|
||||
|
||||
if (_submit) {
|
||||
_submit->setTextTransform(
|
||||
Ui::RoundButton::TextTransform::NoTransform);
|
||||
_submit->addClickHandler([=] {
|
||||
_delegate->panelSubmit();
|
||||
});
|
||||
}
|
||||
_cancel->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||
_cancel->addClickHandler([=] {
|
||||
_delegate->panelRequestClose();
|
||||
});
|
||||
if (!_invoice) {
|
||||
if (_submit) {
|
||||
_submit->hide();
|
||||
}
|
||||
_cancel->hide();
|
||||
}
|
||||
|
||||
using namespace rpl::mappers;
|
||||
|
||||
_topShadow->toggleOn(
|
||||
_scroll->scrollTopValue() | rpl::map(_1 > 0));
|
||||
_bottomShadow->toggleOn(rpl::combine(
|
||||
_scroll->scrollTopValue(),
|
||||
_scroll->heightValue(),
|
||||
_layout->heightValue(),
|
||||
_1 + _2 < _3));
|
||||
|
||||
rpl::merge(
|
||||
(_submit ? _submit->widthValue() : rpl::single(0)),
|
||||
_cancel->widthValue()
|
||||
) | rpl::skip(2) | rpl::on_next([=] {
|
||||
updateControlsGeometry();
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void FormSummary::setupCover(not_null<VerticalLayout*> layout) {
|
||||
struct State {
|
||||
QImage thumbnail;
|
||||
FlatLabel *title = nullptr;
|
||||
FlatLabel *description = nullptr;
|
||||
FlatLabel *seller = nullptr;
|
||||
};
|
||||
const auto cover = layout->add(object_ptr<RpWidget>(layout));
|
||||
const auto state = cover->lifetime().make_state<State>();
|
||||
state->title = CreateChild<FlatLabel>(
|
||||
cover,
|
||||
_invoice.cover.title,
|
||||
st::paymentsTitle);
|
||||
state->description = CreateChild<FlatLabel>(
|
||||
cover,
|
||||
rpl::single(_invoice.cover.description),
|
||||
st::paymentsDescription);
|
||||
state->seller = CreateChild<FlatLabel>(
|
||||
cover,
|
||||
_invoice.cover.seller,
|
||||
st::paymentsSeller);
|
||||
cover->paintRequest(
|
||||
) | rpl::on_next([=](QRect clip) {
|
||||
if (state->thumbnail.isNull()) {
|
||||
return;
|
||||
}
|
||||
const auto &padding = st::paymentsCoverPadding;
|
||||
const auto left = padding.left();
|
||||
const auto top = padding.top();
|
||||
const auto rect = QRect(
|
||||
QPoint(left, top),
|
||||
state->thumbnail.size() / state->thumbnail.devicePixelRatio());
|
||||
if (rect.intersects(clip)) {
|
||||
QPainter(cover).drawImage(rect, state->thumbnail);
|
||||
}
|
||||
}, cover->lifetime());
|
||||
rpl::combine(
|
||||
cover->widthValue(),
|
||||
_thumbnails.events_starting_with_copy(_invoice.cover.thumbnail)
|
||||
) | rpl::on_next([=](int width, QImage &&thumbnail) {
|
||||
const auto &padding = st::paymentsCoverPadding;
|
||||
const auto thumbnailSkip = st::paymentsThumbnailSize.width()
|
||||
+ st::paymentsThumbnailSkip;
|
||||
const auto left = padding.left()
|
||||
+ (thumbnail.isNull() ? 0 : thumbnailSkip);
|
||||
const auto available = width
|
||||
- padding.left()
|
||||
- padding.right()
|
||||
- (thumbnail.isNull() ? 0 : thumbnailSkip);
|
||||
state->title->resizeToNaturalWidth(available);
|
||||
state->title->moveToLeft(
|
||||
left,
|
||||
padding.top() + st::paymentsTitleTop);
|
||||
state->description->resizeToNaturalWidth(available);
|
||||
state->description->moveToLeft(
|
||||
left,
|
||||
(state->title->y()
|
||||
+ state->title->height()
|
||||
+ st::paymentsDescriptionTop));
|
||||
state->seller->resizeToNaturalWidth(available);
|
||||
state->seller->moveToLeft(
|
||||
left,
|
||||
(state->description->y()
|
||||
+ state->description->height()
|
||||
+ st::paymentsSellerTop));
|
||||
const auto thumbnailHeight = padding.top()
|
||||
+ (thumbnail.isNull()
|
||||
? 0
|
||||
: int(thumbnail.height() / thumbnail.devicePixelRatio()))
|
||||
+ padding.bottom();
|
||||
const auto height = state->seller->y()
|
||||
+ state->seller->height()
|
||||
+ padding.bottom();
|
||||
cover->resize(width, std::max(thumbnailHeight, height));
|
||||
state->thumbnail = std::move(thumbnail);
|
||||
cover->update();
|
||||
}, cover->lifetime());
|
||||
}
|
||||
|
||||
void FormSummary::setupPrices(not_null<VerticalLayout*> layout) {
|
||||
const auto addRow = [&](
|
||||
const QString &label,
|
||||
const TextWithEntities &value,
|
||||
bool full = false) {
|
||||
const auto &st = full
|
||||
? st::paymentsFullPriceAmount
|
||||
: st::paymentsPriceAmount;
|
||||
const auto right = CreateChild<FlatLabel>(
|
||||
layout.get(),
|
||||
rpl::single(value),
|
||||
st);
|
||||
const auto &padding = st::paymentsPricePadding;
|
||||
const auto left = layout->add(
|
||||
object_ptr<FlatLabel>(
|
||||
layout,
|
||||
label,
|
||||
(full
|
||||
? st::paymentsFullPriceLabel
|
||||
: st::paymentsPriceLabel)),
|
||||
style::margins(
|
||||
padding.left(),
|
||||
padding.top(),
|
||||
(padding.right()
|
||||
+ right->textMaxWidth()
|
||||
+ 2 * st.style.font->spacew),
|
||||
padding.bottom()));
|
||||
rpl::combine(
|
||||
left->topValue(),
|
||||
layout->widthValue()
|
||||
) | rpl::on_next([=](int top, int width) {
|
||||
right->moveToRight(st::paymentsPricePadding.right(), top, width);
|
||||
}, right->lifetime());
|
||||
return right;
|
||||
};
|
||||
|
||||
Ui::AddSkip(layout, st::paymentsPricesTopSkip);
|
||||
if (_invoice.receipt) {
|
||||
addRow(
|
||||
tr::lng_payments_date_label(tr::now),
|
||||
{ langDateTime(base::unixtime::parse(_invoice.receipt.date)) },
|
||||
true);
|
||||
Ui::AddSkip(layout, st::paymentsPricesBottomSkip);
|
||||
Ui::AddDivider(layout);
|
||||
Ui::AddSkip(layout, st::paymentsPricesBottomSkip);
|
||||
}
|
||||
|
||||
const auto add = [&](
|
||||
const QString &label,
|
||||
int64 amount,
|
||||
bool full = false) {
|
||||
addRow(label, { formatAmount(amount) }, full);
|
||||
};
|
||||
for (const auto &price : _invoice.prices) {
|
||||
add(price.label, price.price);
|
||||
}
|
||||
const auto selected = ranges::find(
|
||||
_options.list,
|
||||
_options.selectedId,
|
||||
&ShippingOption::id);
|
||||
if (selected != end(_options.list)) {
|
||||
for (const auto &price : selected->prices) {
|
||||
add(price.label, price.price);
|
||||
}
|
||||
}
|
||||
|
||||
const auto computedTotal = computeTotalAmount();
|
||||
const auto total = _invoice.receipt.paid
|
||||
? _invoice.receipt.totalAmount
|
||||
: computedTotal;
|
||||
if (_invoice.receipt.paid) {
|
||||
if (const auto tips = total - computedTotal) {
|
||||
add(tr::lng_payments_tips_label(tr::now), tips);
|
||||
}
|
||||
} else if (_invoice.tipsMax > 0) {
|
||||
const auto text = formatAmount(_invoice.tipsSelected);
|
||||
const auto label = addRow(
|
||||
tr::lng_payments_tips_label(tr::now),
|
||||
tr::link(text));
|
||||
label->overrideLinkClickHandler([=] {
|
||||
_delegate->panelChooseTips();
|
||||
});
|
||||
setupSuggestedTips(layout);
|
||||
}
|
||||
|
||||
add(tr::lng_payments_total_label(tr::now), total, true);
|
||||
Ui::AddSkip(layout, st::paymentsPricesBottomSkip);
|
||||
}
|
||||
|
||||
void FormSummary::setupSuggestedTips(not_null<VerticalLayout*> layout) {
|
||||
if (_invoice.suggestedTips.empty()) {
|
||||
return;
|
||||
}
|
||||
struct Button {
|
||||
RoundButton *widget = nullptr;
|
||||
int minWidth = 0;
|
||||
};
|
||||
struct State {
|
||||
std::vector<Button> buttons;
|
||||
int maxWidth = 0;
|
||||
};
|
||||
const auto outer = layout->add(
|
||||
object_ptr<RpWidget>(layout),
|
||||
st::paymentsTipButtonsPadding);
|
||||
const auto state = outer->lifetime().make_state<State>();
|
||||
for (const auto amount : _invoice.suggestedTips) {
|
||||
const auto selected = (amount == _invoice.tipsSelected);
|
||||
const auto &st = selected
|
||||
? _tipChosen
|
||||
: _tipButton;
|
||||
state->buttons.push_back(Button{
|
||||
.widget = CreateChild<RoundButton>(
|
||||
outer,
|
||||
rpl::single(formatAmount(amount, true)),
|
||||
st),
|
||||
});
|
||||
auto &button = state->buttons.back();
|
||||
button.widget->show();
|
||||
button.widget->setClickedCallback([=] {
|
||||
_delegate->panelChangeTips(selected ? 0 : amount);
|
||||
});
|
||||
button.minWidth = button.widget->width();
|
||||
state->maxWidth = std::max(state->maxWidth, button.minWidth);
|
||||
}
|
||||
outer->widthValue(
|
||||
) | rpl::filter([=](int outerWidth) {
|
||||
return outerWidth >= state->maxWidth;
|
||||
}) | rpl::on_next([=](int outerWidth) {
|
||||
const auto skip = st::paymentsTipSkip;
|
||||
const auto &buttons = state->buttons;
|
||||
auto left = outerWidth;
|
||||
auto height = 0;
|
||||
auto rowStart = 0;
|
||||
auto rowEnd = 0;
|
||||
auto buttonWidths = std::vector<float64>();
|
||||
const auto layoutRow = [&] {
|
||||
const auto count = rowEnd - rowStart;
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
buttonWidths.resize(count);
|
||||
ranges::fill(buttonWidths, 0.);
|
||||
auto available = float64(outerWidth - (count - 1) * skip);
|
||||
auto zeros = count;
|
||||
do {
|
||||
const auto started = zeros;
|
||||
const auto average = available / zeros;
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
if (buttonWidths[i] > 0.) {
|
||||
continue;
|
||||
}
|
||||
const auto min = buttons[rowStart + i].minWidth;
|
||||
if (min > average) {
|
||||
buttonWidths[i] = min;
|
||||
available -= min;
|
||||
--zeros;
|
||||
}
|
||||
}
|
||||
if (started == zeros) {
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
if (!buttonWidths[i]) {
|
||||
buttonWidths[i] = average;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (zeros > 0);
|
||||
auto x = 0.;
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
const auto button = buttons[rowStart + i].widget;
|
||||
auto right = x + buttonWidths[i];
|
||||
button->setFullWidth(
|
||||
int(base::SafeRound(right) - base::SafeRound(x)));
|
||||
button->moveToLeft(
|
||||
int(base::SafeRound(x)),
|
||||
height,
|
||||
outerWidth);
|
||||
x = right + skip;
|
||||
}
|
||||
height += buttons[0].widget->height() + skip;
|
||||
};
|
||||
for (const auto &button : buttons) {
|
||||
if (button.minWidth <= left) {
|
||||
left -= button.minWidth + skip;
|
||||
++rowEnd;
|
||||
continue;
|
||||
}
|
||||
layoutRow();
|
||||
rowStart = rowEnd++;
|
||||
left = outerWidth - button.minWidth - skip;
|
||||
}
|
||||
layoutRow();
|
||||
outer->resize(outerWidth, height - skip);
|
||||
}, outer->lifetime());
|
||||
}
|
||||
|
||||
void FormSummary::setupSections(not_null<VerticalLayout*> layout) {
|
||||
Ui::AddSkip(layout, st::paymentsSectionsTopSkip);
|
||||
|
||||
const auto add = [&](
|
||||
rpl::producer<QString> title,
|
||||
const QString &label,
|
||||
const style::icon *icon,
|
||||
Fn<void()> handler) {
|
||||
const auto button = Settings::AddButtonWithLabel(
|
||||
layout,
|
||||
std::move(title),
|
||||
rpl::single(label),
|
||||
st::paymentsSectionButton,
|
||||
{ .icon = icon });
|
||||
button->addClickHandler(std::move(handler));
|
||||
if (_invoice.receipt) {
|
||||
button->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
}
|
||||
};
|
||||
add(
|
||||
tr::lng_payments_payment_method(),
|
||||
(_method.savedMethods.empty()
|
||||
? QString()
|
||||
: _method.savedMethods[_method.savedMethodIndex].title),
|
||||
&st::paymentsIconPaymentMethod,
|
||||
[=] { _delegate->panelEditPaymentMethod(); });
|
||||
if (_invoice.isShippingAddressRequested) {
|
||||
auto list = QStringList();
|
||||
const auto push = [&](const QString &value) {
|
||||
if (!value.isEmpty()) {
|
||||
list.push_back(value);
|
||||
}
|
||||
};
|
||||
push(_information.shippingAddress.address1);
|
||||
push(_information.shippingAddress.address2);
|
||||
push(_information.shippingAddress.city);
|
||||
push(_information.shippingAddress.state);
|
||||
push(Countries::Instance().countryNameByISO2(
|
||||
_information.shippingAddress.countryIso2));
|
||||
push(_information.shippingAddress.postcode);
|
||||
add(
|
||||
tr::lng_payments_shipping_address(),
|
||||
list.join(", "),
|
||||
&st::paymentsIconShippingAddress,
|
||||
[=] { _delegate->panelEditShippingInformation(); });
|
||||
}
|
||||
if (!_options.list.empty()) {
|
||||
const auto selected = ranges::find(
|
||||
_options.list,
|
||||
_options.selectedId,
|
||||
&ShippingOption::id);
|
||||
add(
|
||||
tr::lng_payments_shipping_method(),
|
||||
(selected != end(_options.list)) ? selected->title : QString(),
|
||||
&st::paymentsIconShippingMethod,
|
||||
[=] { _delegate->panelChooseShippingOption(); });
|
||||
}
|
||||
if (_invoice.isNameRequested) {
|
||||
add(
|
||||
tr::lng_payments_info_name(),
|
||||
_information.name,
|
||||
&st::paymentsIconName,
|
||||
[=] { _delegate->panelEditName(); });
|
||||
}
|
||||
if (_invoice.isEmailRequested) {
|
||||
add(
|
||||
tr::lng_payments_info_email(),
|
||||
_information.email,
|
||||
&st::paymentsIconEmail,
|
||||
[=] { _delegate->panelEditEmail(); });
|
||||
}
|
||||
if (_invoice.isPhoneRequested) {
|
||||
add(
|
||||
tr::lng_payments_info_phone(),
|
||||
(_information.phone.isEmpty()
|
||||
? QString()
|
||||
: Ui::FormatPhone(_information.phone)),
|
||||
&st::paymentsIconPhone,
|
||||
[=] { _delegate->panelEditPhone(); });
|
||||
}
|
||||
Ui::AddSkip(layout, st::paymentsSectionsTopSkip);
|
||||
}
|
||||
|
||||
void FormSummary::setupContent(not_null<VerticalLayout*> layout) {
|
||||
_scroll->widthValue(
|
||||
) | rpl::on_next([=](int width) {
|
||||
layout->resizeToWidth(width);
|
||||
}, layout->lifetime());
|
||||
|
||||
setupCover(layout);
|
||||
if (_invoice) {
|
||||
Ui::AddDivider(layout);
|
||||
setupPrices(layout);
|
||||
Ui::AddDivider(layout);
|
||||
setupSections(layout);
|
||||
}
|
||||
}
|
||||
|
||||
void FormSummary::resizeEvent(QResizeEvent *e) {
|
||||
updateControlsGeometry();
|
||||
}
|
||||
|
||||
void FormSummary::updateControlsGeometry() {
|
||||
const auto &padding = st::paymentsPanelPadding;
|
||||
const auto buttonsHeight = padding.top()
|
||||
+ _cancel->height()
|
||||
+ padding.bottom();
|
||||
const auto buttonsTop = height() - buttonsHeight;
|
||||
_scroll->setGeometry(0, 0, width(), buttonsTop);
|
||||
_topShadow->resizeToWidth(width());
|
||||
_topShadow->moveToLeft(0, 0);
|
||||
_bottomShadow->resizeToWidth(width());
|
||||
_bottomShadow->moveToLeft(0, buttonsTop - st::lineWidth);
|
||||
auto right = padding.right();
|
||||
if (_submit) {
|
||||
_submit->moveToRight(right, buttonsTop + padding.top());
|
||||
right += _submit->width() + padding.left();
|
||||
}
|
||||
_cancel->moveToRight(right, buttonsTop + padding.top());
|
||||
|
||||
_scroll->updateBars();
|
||||
|
||||
if (buttonsTop > 0 && width() > 0) {
|
||||
if (const auto top = base::take(_initialScrollTop)) {
|
||||
_scroll->scrollToY(top);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Payments::Ui
|
||||
Reference in New Issue
Block a user