Improve EditPrivacyBox layout.

Also fix incorrect killTimer() calls in DiscreteSlider.
This commit is contained in:
John Preston 2017-03-19 11:29:05 +03:00
parent 5530172add
commit a5df46f381
7 changed files with 88 additions and 114 deletions

View File

@ -447,10 +447,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_edit_privacy_exceptions" = "Add exceptions";
"lng_edit_privacy_lastseen_title" = "Last seen privacy";
"lng_edit_privacy_lastseen_everyone" = "Anyone can see my Last Seen time";
"lng_edit_privacy_lastseen_contacts" = "Only contacts can see my Last Seen time";
"lng_edit_privacy_lastseen_nobody" = "Nobody can see my Last Seen time";
"lng_edit_privacy_lastseen_description" = "Important: you won't be able to see Last Seen times for people with whom you don't share your Last Seen time. Approximate last seen will be shown instead (recently, within a week, within a month).";
"lng_edit_privacy_lastseen_description" = "You can choose who can see your last seen time:";
"lng_edit_privacy_lastseen_warning" = "Important: you won't be able to see Last Seen times for people with whom you don't share your Last Seen time. Approximate last seen will be shown instead (recently, within a week, within a month).";
"lng_edit_privacy_lastseen_always" = "Always share with{count:| # user| # users}";
"lng_edit_privacy_lastseen_never" = "Never share with{count:| # user| # users}";
"lng_edit_privacy_lastseen_exceptions" = "These settings will override the values above.";
@ -458,9 +456,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
"lng_edit_privacy_lastseen_never_title" = "Never share with";
"lng_edit_privacy_groups_title" = "Group invite settings";
"lng_edit_privacy_groups_everyone" = "Anyone can invite me to groups and channels";
"lng_edit_privacy_groups_contacts" = "Only contacts can invite me to groups and channels";
"lng_edit_privacy_groups_description" = "You can restrict who can add you to groups and channels with granular precision.";
"lng_edit_privacy_groups_description" = "You can choose who can add you to groups and channels with granular precision:";
"lng_edit_privacy_groups_always" = "Always allow{count:| # user| # users}";
"lng_edit_privacy_groups_never" = "Never allow{count:| # user| # users}";
"lng_edit_privacy_groups_exceptions" = "These users will or will not be able to add you to groups and channels regardless of the settings above.";

View File

@ -585,13 +585,14 @@ colorValueInput: InputField(defaultInputField) {
colorResultInput: InputField(colorValueInput) {
}
editPrivacyOptionMargin: margins(23px, 8px, 21px, -3px);
editPrivacyOptionMargin: margins(23px, 14px, 21px, 0px);
editPrivacyPadding: margins(23px, 0px, 21px, 0px);
editPrivacyWarningPadding: margins(23px, 14px, 21px, 0px);
editPrivacyTitle: FlatLabel(defaultFlatLabel) {
width: 320px;
textFg: boxTitleFg;
maxHeight: 46px;
margin: margins(0px, 13px, 0px, 7px);
maxHeight: 56px;
margin: margins(0px, 20px, 0px, 13px);
style: TextStyle(defaultTextStyle) {
font: boxTitleFont;
linkFont: boxTitleFont;

View File

@ -88,37 +88,6 @@ std::unique_ptr<PrivacyExceptionsBoxController::Row> PrivacyExceptionsBoxControl
} // namespace
class EditPrivacyBox::OptionWidget : public TWidget {
public:
OptionWidget(QWidget *parent, const std::shared_ptr<Ui::RadioenumGroup<Option>> &group, Option value, const QString &text, const QString &description);
QMargins getMargins() const override {
return _option->getMargins();
}
protected:
int resizeGetHeight(int newWidth) override;
private:
object_ptr<Ui::Radioenum<Option>> _option;
object_ptr<Ui::FlatLabel> _description;
};
EditPrivacyBox::OptionWidget::OptionWidget(QWidget *parent, const std::shared_ptr<Ui::RadioenumGroup<Option>> &group, Option value, const QString &text, const QString &description) : TWidget(parent)
, _option(this, group, value, text, st::defaultBoxCheckbox)
, _description(this, description, Ui::FlatLabel::InitType::Simple, st::editPrivacyLabel) {
}
int EditPrivacyBox::OptionWidget::resizeGetHeight(int newWidth) {
_option->resizeToNaturalWidth(newWidth);
auto optionTextLeft = st::defaultBoxCheckbox.textPosition.x();
_description->resizeToWidth(newWidth - optionTextLeft);
_option->moveToLeft(getMargins().left(), getMargins().top());
_description->moveToLeft(optionTextLeft + getMargins().left(), _option->bottomNoMargins());
return _description->bottomNoMargins();
}
EditPrivacyBox::EditPrivacyBox(QWidget*, std::unique_ptr<Controller> controller) : BoxContent()
, _controller(std::move(controller))
, _loading(this, lang(lng_contacts_loading), Ui::FlatLabel::InitType::Simple, st::membersAbout) {
@ -142,9 +111,6 @@ void EditPrivacyBox::prepare() {
})));
setDimensions(st::boxWideWidth, countDefaultHeight(st::boxWideWidth));
_loading->resizeToWidth(width());
_loading->moveToLeft(0, height() / 3);
}
int EditPrivacyBox::resizeGetHeight(int newWidth) {
@ -156,10 +122,11 @@ int EditPrivacyBox::resizeGetHeight(int newWidth) {
top = widget->bottomNoMargins() + padding.bottom();
};
layoutRow(_description, st::editPrivacyPadding);
layoutRow(_everyone, st::editPrivacyOptionMargin);
layoutRow(_contacts, st::editPrivacyOptionMargin);
layoutRow(_nobody, st::editPrivacyOptionMargin);
layoutRow(_description, st::editPrivacyPadding);
layoutRow(_warning, st::editPrivacyWarningPadding);
layoutRow(_exceptionsTitle, st::editPrivacyPadding);
auto linksTop = top;
layoutRow(_alwaysLink, st::editPrivacyPadding);
@ -176,33 +143,42 @@ int EditPrivacyBox::resizeGetHeight(int newWidth) {
return top;
}
void EditPrivacyBox::resizeEvent(QResizeEvent *e) {
if (_loading) {
_loading->moveToLeft((width() - _loading->width()) / 2, height() / 3);
}
}
int EditPrivacyBox::countDefaultHeight(int newWidth) {
auto height = 0;
auto fakeGroup = std::make_shared<Ui::RadioenumGroup<Option>>(Option::Everyone);
auto optionHeight = [this, newWidth, &fakeGroup](Option option, const QString &label) {
auto description = _controller->optionDescription(option);
if (description.isEmpty()) {
auto optionHeight = [this](Option option) {
if (!_controller->hasOption(option)) {
return 0;
}
return st::editPrivacyOptionMargin.top() + st::defaultBoxCheckbox.height + st::editPrivacyOptionMargin.bottom();
};
auto labelHeight = [this, newWidth](const QString &text, const style::FlatLabel &st, style::margins padding) {
if (text.isEmpty()) {
return 0;
}
auto fake = object_ptr<OptionWidget>(nullptr, fakeGroup, Option::Everyone, label, description);
fake->resizeToNaturalWidth(newWidth - st::editPrivacyOptionMargin.left() - st::editPrivacyOptionMargin.right());
return st::editPrivacyOptionMargin.top() + fake->heightNoMargins() + st::editPrivacyOptionMargin.bottom();
};
auto labelHeight = [this, newWidth](const QString &text, const style::FlatLabel &st) {
auto fake = object_ptr<Ui::FlatLabel>(nullptr, text, Ui::FlatLabel::InitType::Simple, st);
fake->resizeToNaturalWidth(newWidth - st::editPrivacyPadding.left() - st::editPrivacyPadding.right());
return st::editPrivacyPadding.top() + fake->heightNoMargins() + st::editPrivacyPadding.bottom();
fake->resizeToNaturalWidth(newWidth - padding.left() - padding.right());
return padding.top() + fake->heightNoMargins() + padding.bottom();
};
auto linkMargins = exceptionLinkMargins();
height += optionHeight(Option::Everyone, lang(lng_edit_privacy_everyone));
height += optionHeight(Option::Contacts, lang(lng_edit_privacy_contacts));
height += optionHeight(Option::Nobody, lang(lng_edit_privacy_nobody));
height += labelHeight(_controller->description(), st::editPrivacyLabel);
height += labelHeight(lang(lng_edit_privacy_exceptions), st::editPrivacyTitle);
height += linkMargins.top() + st::boxLinkButton.font->height + linkMargins.bottom(); // linkHeight(_controller->alwaysLinkText(0))
height += linkMargins.top() + st::boxLinkButton.font->height + linkMargins.bottom(); // linkHeight(_controller->neverLinkText(0))
height += labelHeight(_controller->exceptionsDescription(), st::editPrivacyLabel);
auto linkHeight = [this]() {
auto linkMargins = exceptionLinkMargins();
return linkMargins.top() + st::boxLinkButton.font->height + linkMargins.bottom();
};
height += labelHeight(_controller->description(), st::editPrivacyLabel, st::editPrivacyPadding);
height += optionHeight(Option::Everyone);
height += optionHeight(Option::Contacts);
height += optionHeight(Option::Nobody);
height += labelHeight(_controller->warning(), st::editPrivacyLabel, st::editPrivacyWarningPadding);
height += labelHeight(lang(lng_edit_privacy_exceptions), st::editPrivacyTitle, st::editPrivacyPadding);
height += linkHeight();
height += linkHeight();
height += labelHeight(_controller->exceptionsDescription(), st::editPrivacyLabel, st::editPrivacyPadding);
return height;
}
@ -246,8 +222,9 @@ QVector<MTPInputPrivacyRule> EditPrivacyBox::collectResult() {
return result;
};
constexpr auto kMaxRules = 3; // allow users, disallow users, option
auto result = QVector<MTPInputPrivacyRule>();
result.reserve(3);
result.reserve(kMaxRules);
if (showExceptionLink(Exception::Always) && !_alwaysUsers.empty()) {
result.push_back(MTP_inputPrivacyValueAllowUsers(MTP_vector<MTPInputUser>(collectInputUsers(_alwaysUsers))));
}
@ -291,39 +268,37 @@ bool EditPrivacyBox::showExceptionLink(Exception exception) const {
Unexpected("Invalid exception value.");
}
void EditPrivacyBox::createOption(Option option, object_ptr<OptionWidget> &widget, const QString &label) {
auto description = _controller->optionDescription(option);
auto selected = (_option == option);
if (!description.isEmpty() || selected) {
widget.create(this, _optionGroup, option, label, description);
}
}
void EditPrivacyBox::createWidgets() {
_loading.destroy();
_optionGroup = std::make_shared<Ui::RadioenumGroup<Option>>(_option);
createOption(Option::Everyone, _everyone, lang(lng_edit_privacy_everyone));
createOption(Option::Contacts, _contacts, lang(lng_edit_privacy_contacts));
createOption(Option::Nobody, _nobody, lang(lng_edit_privacy_nobody));
_optionGroup->setChangedCallback([this](Option value) {
_option = value;
_alwaysLink->toggleAnimated(showExceptionLink(Exception::Always));
_neverLink->toggleAnimated(showExceptionLink(Exception::Never));
});
_description.create(this, _controller->description(), Ui::FlatLabel::InitType::Simple, st::editPrivacyLabel);
_exceptionsTitle.create(this, lang(lng_edit_privacy_exceptions), Ui::FlatLabel::InitType::Simple, st::editPrivacyTitle);
auto createOption = [this](object_ptr<Ui::Radioenum<Option>> &widget, Option option, const QString &label) {
if (_controller->hasOption(option) || (_option == option)) {
widget.create(this, _optionGroup, option, label, st::defaultBoxCheckbox);
}
};
auto createLabel = [this](object_ptr<Ui::FlatLabel> &widget, const QString &text, const style::FlatLabel &st) {
if (text.isEmpty()) {
return;
}
widget.create(this, text, Ui::FlatLabel::InitType::Simple, st);
};
auto createExceptionLink = [this](Exception exception) {
exceptionLink(exception).create(this, object_ptr<Ui::LinkButton>(this, exceptionLinkText(exception)), exceptionLinkMargins(), [this] {
resizeGetHeight(width());
});
exceptionLink(exception)->entity()->setClickedCallback([this, exception] { editExceptionUsers(exception); });
};
createLabel(_description, _controller->description(), st::editPrivacyLabel);
createOption(_everyone, Option::Everyone, lang(lng_edit_privacy_everyone));
createOption(_contacts, Option::Contacts, lang(lng_edit_privacy_contacts));
createOption(_nobody, Option::Nobody, lang(lng_edit_privacy_nobody));
createLabel(_warning, _controller->warning(), st::editPrivacyLabel);
createLabel(_exceptionsTitle, lang(lng_edit_privacy_exceptions), st::editPrivacyTitle);
createExceptionLink(Exception::Always);
createExceptionLink(Exception::Never);
_exceptionsDescription.create(this, _controller->exceptionsDescription(), Ui::FlatLabel::InitType::Simple, st::editPrivacyLabel);
createLabel(_exceptionsDescription, _controller->exceptionsDescription(), st::editPrivacyLabel);
clearButtons();
addButton(lang(lng_settings_save), [this] {
@ -335,6 +310,12 @@ void EditPrivacyBox::createWidgets() {
});
addButton(lang(lng_cancel), [this] { closeBox(); });
_optionGroup->setChangedCallback([this](Option value) {
_option = value;
_alwaysLink->toggleAnimated(showExceptionLink(Exception::Always));
_neverLink->toggleAnimated(showExceptionLink(Exception::Never));
});
showChildren();
_alwaysLink->toggleFast(showExceptionLink(Exception::Always));
_neverLink->toggleFast(showExceptionLink(Exception::Never));

View File

@ -27,6 +27,8 @@ class FlatLabel;
class LinkButton;
template <typename Enum>
class RadioenumGroup;
template <typename Enum>
class Radioenum;
template <typename Widget>
class WidgetSlideWrap;
} // namespace Ui
@ -48,10 +50,13 @@ public:
virtual MTPInputPrivacyKey key() = 0;
virtual QString title() = 0;
virtual QString optionDescription(Option option) {
return QString();
virtual bool hasOption(Option option) {
return true;
}
virtual QString description() = 0;
virtual QString warning() {
return QString();
}
virtual QString exceptionLinkText(Exception exception, int count) = 0;
virtual QString exceptionBoxTitle(Exception exception) = 0;
virtual QString exceptionsDescription() = 0;
@ -83,16 +88,14 @@ public:
protected:
void prepare() override;
int resizeGetHeight(int newWidth) override;
private:
class OptionWidget;
void resizeEvent(QResizeEvent *e) override;
private:
style::margins exceptionLinkMargins() const;
bool showExceptionLink(Exception exception) const;
void createWidgets();
void createOption(Option option, object_ptr<OptionWidget> &widget, const QString &label);
QVector<MTPInputPrivacyRule> collectResult();
void loadDone(const MTPaccount_PrivacyRules &result);
int countDefaultHeight(int newWidth);
@ -107,10 +110,11 @@ private:
std::shared_ptr<Ui::RadioenumGroup<Option>> _optionGroup;
object_ptr<Ui::FlatLabel> _loading;
object_ptr<OptionWidget> _everyone = { nullptr };
object_ptr<OptionWidget> _contacts = { nullptr };
object_ptr<OptionWidget> _nobody = { nullptr };
object_ptr<Ui::FlatLabel> _description = { nullptr };
object_ptr<Ui::Radioenum<Option>> _everyone = { nullptr };
object_ptr<Ui::Radioenum<Option>> _contacts = { nullptr };
object_ptr<Ui::Radioenum<Option>> _nobody = { nullptr };
object_ptr<Ui::FlatLabel> _warning = { nullptr };
object_ptr<Ui::FlatLabel> _exceptionsTitle = { nullptr };
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _alwaysLink = { nullptr };
object_ptr<Ui::WidgetSlideWrap<Ui::LinkButton>> _neverLink = { nullptr };

View File

@ -230,19 +230,14 @@ QString LastSeenPrivacyController::title() {
return lang(lng_edit_privacy_lastseen_title);
}
QString LastSeenPrivacyController::optionDescription(Option option) {
switch (option) {
case Option::Everyone: return lang(lng_edit_privacy_lastseen_everyone);
case Option::Contacts: return lang(lng_edit_privacy_lastseen_contacts);
case Option::Nobody: return lang(lng_edit_privacy_lastseen_nobody);
}
return QString();
}
QString LastSeenPrivacyController::description() {
return lang(lng_edit_privacy_lastseen_description);
}
QString LastSeenPrivacyController::warning() {
return lang(lng_edit_privacy_lastseen_warning);
}
QString LastSeenPrivacyController::exceptionLinkText(Exception exception, int count) {
switch (exception) {
case Exception::Always: return lng_edit_privacy_lastseen_always(lt_count, count);
@ -274,7 +269,7 @@ void LastSeenPrivacyController::confirmSave(bool someAreDisallowed, base::lambda
AuthSession::Current().data().setLastSeenWarningSeen(true);
Local::writeUserSettings();
};
auto box = Box<ConfirmBox>(lang(lng_edit_privacy_lastseen_description), lang(lng_continue), lang(lng_cancel), std::move(callback));
auto box = Box<ConfirmBox>(lang(lng_edit_privacy_lastseen_warning), lang(lng_continue), lang(lng_cancel), std::move(callback));
*weakBox = Ui::show(std::move(box), KeepOtherLayers);
} else {
saveCallback();
@ -289,12 +284,8 @@ QString GroupsInvitePrivacyController::title() {
return lang(lng_edit_privacy_groups_title);
}
QString GroupsInvitePrivacyController::optionDescription(Option option) {
switch (option) {
case Option::Everyone: return lang(lng_edit_privacy_groups_everyone);
case Option::Contacts: return lang(lng_edit_privacy_groups_contacts);
}
return QString();
bool GroupsInvitePrivacyController::hasOption(Option option) {
return (option != Option::Nobody);
}
QString GroupsInvitePrivacyController::description() {

View File

@ -55,8 +55,8 @@ public:
MTPInputPrivacyKey key() override;
QString title() override;
QString optionDescription(Option option) override;
QString description() override;
QString warning() override;
QString exceptionLinkText(Exception exception, int count) override;
QString exceptionBoxTitle(Exception exception) override;
QString exceptionsDescription() override;
@ -73,7 +73,7 @@ public:
MTPInputPrivacyKey key() override;
QString title() override;
QString optionDescription(Option option) override;
bool hasOption(Option option) override;
QString description() override;
QString exceptionLinkText(Exception exception, int count) override;
QString exceptionBoxTitle(Exception exception) override;

View File

@ -44,6 +44,7 @@ void DiscreteSlider::setActiveSection(int index) {
void DiscreteSlider::activateCallback() {
if (_timerId >= 0) {
killTimer(_timerId);
_timerId = -1;
}
auto ms = getms();
if (ms >= _callbackAfterMs) {