Fix crash in radiobutton destruction.

It crashed if the button was destroyed from group _changedCallback.
This commit is contained in:
John Preston 2018-12-05 13:55:56 +04:00
parent b10ccce44a
commit efe3dfad5c
13 changed files with 165 additions and 119 deletions

View File

@ -569,17 +569,20 @@ void ProxiesBox::setupContent() {
}
refreshProxyForCalls();
});
subscribe(_tryIPv6->checkedChanged, [=](bool checked) {
_tryIPv6->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
_controller->setTryIPv6(checked);
});
}, _tryIPv6->lifetime());
_controller->proxySettingsValue(
) | rpl::start_with_next([=](ProxyData::Settings value) {
_proxySettings->setValue(value);
}, inner->lifetime());
subscribe(_proxyForCalls->entity()->checkedChanged, [=](bool checked) {
_proxyForCalls->entity()->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
_controller->setProxyForCalls(checked);
});
}, _proxyForCalls->lifetime());
if (_rows.empty()) {
createNoRowsLabel();

View File

@ -236,9 +236,12 @@ void EditAdminBox::prepare() {
auto addCheckbox = [&](Flags flags, const QString &text) {
const auto checked = (prepareFlags & flags) != 0;
auto control = addControl(object_ptr<Ui::Checkbox>(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin);
subscribe(control->checkedChanged, [this, control](bool checked) {
InvokeQueued(this, [this, control] { applyDependencies(control); });
});
control->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
InvokeQueued(this, [=] {
applyDependencies(control);
});
}, control->lifetime());
if (!channel()->amCreator()) {
if (!(channel()->adminRights() & flags)) {
control->setDisabled(true); // Grey out options that we don't have ourselves.
@ -267,11 +270,14 @@ void EditAdminBox::prepare() {
auto addAdmins = _checkboxes.find(Flag::f_add_admins);
if (addAdmins != _checkboxes.end()) {
_aboutAddAdmins = addControl(object_ptr<Ui::FlatLabel>(this, st::boxLabel), st::rightsAboutMargin);
_aboutAddAdmins = addControl(
object_ptr<Ui::FlatLabel>(this, st::boxLabel),
st::rightsAboutMargin);
Assert(addAdmins != _checkboxes.end());
subscribe(addAdmins->second->checkedChanged, [this](bool checked) {
addAdmins->second->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
refreshAboutAddAdminsText();
});
}, addAdmins->second->lifetime());
refreshAboutAddAdminsText();
}
@ -354,12 +360,15 @@ void EditRestrictedBox::prepare() {
auto prepareRights = (_oldRights.c_channelBannedRights().vflags.v ? _oldRights : DefaultRights(channel()));
_until = prepareRights.c_channelBannedRights().vuntil_date.v;
auto addCheckbox = [this, &prepareRights](Flags flags, const QString &text) {
auto addCheckbox = [&](Flags flags, const QString &text) {
auto checked = (prepareRights.c_channelBannedRights().vflags.v & flags) == 0;
auto control = addControl(object_ptr<Ui::Checkbox>(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin);
subscribe(control->checkedChanged, [this, control](bool checked) {
InvokeQueued(this, [this, control] { applyDependencies(control); });
});
control->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
InvokeQueued(this, [=] {
applyDependencies(control);
});
}, control->lifetime());
if (!canSave()) {
control->setDisabled(true);
}

View File

@ -127,15 +127,24 @@ void AddBotToGroup(not_null<UserData*> bot, not_null<PeerData*> chat) {
// return mapFromGlobal(QCursor::pos()) - _st.rippleAreaPosition;
//}
class EditChatAdminsBoxController::LabeledCheckbox : public TWidget, private base::Subscriber {
class EditChatAdminsBoxController::LabeledCheckbox : public Ui::RpWidget {
public:
LabeledCheckbox(QWidget *parent, const QString &text, bool checked = false, const style::Checkbox &st = st::defaultCheckbox, const style::Check &checkSt = st::defaultCheck);
base::Observable<bool> checkedChanged;
LabeledCheckbox(
QWidget *parent,
const QString &text,
bool checked = false,
const style::Checkbox &st = st::defaultCheckbox,
const style::Check &checkSt = st::defaultCheck);
bool checked() const {
return _checkbox->checked();
}
rpl::producer<bool> checkedChanges() const {
return _checkbox->checkedChanges();
}
rpl::producer<bool> checkedValue() const {
return _checkbox->checkedValue();
}
void setLabelText(
bool checked,
@ -605,9 +614,8 @@ EditChatAdminsBoxController::LabeledCheckbox::LabeledCheckbox(
bool checked,
const style::Checkbox &st,
const style::Check &checkSt)
: TWidget(parent)
: RpWidget(parent)
, _checkbox(this, text, checked, st, checkSt) {
subscribe(_checkbox->checkedChanged, [this](bool value) { checkedChanged.notify(value, true); });
}
void EditChatAdminsBoxController::LabeledCheckbox::setLabelText(
@ -676,7 +684,8 @@ void EditChatAdminsBoxController::prepare() {
}));
}
subscribe(_allAdmins->checkedChanged, [this](bool checked) {
_allAdmins->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
delegate()->peerListSetSearchMode(checked ? PeerListSearchMode::Disabled : PeerListSearchMode::Enabled);
for (auto i = 0, count = delegate()->peerListFullRowsCount(); i != count; ++i) {
auto row = delegate()->peerListRowAt(i);
@ -687,7 +696,7 @@ void EditChatAdminsBoxController::prepare() {
row->setDisabledState(PeerListRow::State::Active);
}
}
});
}, _allAdmins->lifetime());
}
void EditChatAdminsBoxController::createAllAdminsCheckbox() {

View File

@ -464,8 +464,7 @@ not_null<Ui::Checkbox*> SettingsWidget::addOption(
((readData().types & types) == types),
st::defaultBoxCheckbox),
st::exportSettingPadding);
base::ObservableViewer(
checkbox->checkedChanged
checkbox->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
changeData([&](Settings &data) {
if (checked) {
@ -474,7 +473,7 @@ not_null<Ui::Checkbox*> SettingsWidget::addOption(
data.types &= ~types;
}
});
}, lifetime());
}, checkbox->lifetime());
return checkbox;
}
@ -509,8 +508,7 @@ void SettingsWidget::addChatOption(
st::defaultBoxCheckbox),
st::exportSubSettingPadding));
base::ObservableViewer(
onlyMy->entity()->checkedChanged
onlyMy->entity()->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
changeData([&](Settings &data) {
if (checked) {
@ -519,13 +517,9 @@ void SettingsWidget::addChatOption(
data.fullChats |= types;
}
});
}, checkbox->lifetime());
}, onlyMy->lifetime());
onlyMy->toggleOn(base::ObservableViewer(
checkbox->checkedChanged
));
onlyMy->toggle(checkbox->checked(), anim::type::instant);
onlyMy->toggleOn(checkbox->checkedValue());
if (types & (Type::PublicGroups | Type::PublicChannels)) {
onlyMy->entity()->setChecked(true);
@ -568,8 +562,7 @@ void SettingsWidget::addMediaOption(
((readData().media.types & type) == type),
st::defaultBoxCheckbox),
st::exportSettingPadding);
base::ObservableViewer(
checkbox->checkedChanged
checkbox->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
changeData([&](Settings &data) {
if (checked) {
@ -578,7 +571,7 @@ void SettingsWidget::addMediaOption(
data.media.types &= ~type;
}
});
}, lifetime());
}, checkbox->lifetime());
}
void SettingsWidget::addSizeSlider(

View File

@ -23,13 +23,16 @@ public:
bool checked() const {
return _check->checked();
}
base::Observable<bool> checkedChanged;
rpl::producer<bool> checkedChanges() const;
rpl::producer<bool> checkedValue() const;
enum class NotifyAboutChange {
Notify,
DontNotify,
};
void setChecked(bool checked, NotifyAboutChange notify = NotifyAboutChange::Notify);
void setChecked(
bool checked,
NotifyAboutChange notify = NotifyAboutChange::Notify);
void finishAnimating();
@ -48,6 +51,7 @@ protected:
private:
const style::Checkbox &_st;
std::unique_ptr<Ui::AbstractCheckView> _check;
rpl::event_stream<bool> _checkedChanges;
QRect _checkRect;
@ -73,11 +77,19 @@ UserCheckbox::UserCheckbox(QWidget *parent, not_null<UserData*> user, bool check
_checkRect = { QPoint(_st.margin.left(), (st::contactsPhotoSize - checkSize.height()) / 2), checkSize };
}
rpl::producer<bool> UserCheckbox::checkedChanges() const {
return _checkedChanges.events();
}
rpl::producer<bool> UserCheckbox::checkedValue() const {
return _checkedChanges.events_starting_with(checked());
}
void UserCheckbox::setChecked(bool checked, NotifyAboutChange notify) {
if (_check->checked() != checked) {
_check->setChecked(checked, anim::type::normal);
if (notify == NotifyAboutChange::Notify) {
checkedChanged.notify(checked, true);
_checkedChanges.fire_copy(checked);
}
}
}
@ -132,9 +144,14 @@ QPoint UserCheckbox::prepareRippleStartPosition() const {
} // namespace
class FilterBox::Inner : public TWidget, private base::Subscriber {
class FilterBox::Inner : public Ui::RpWidget {
public:
Inner(QWidget *parent, not_null<ChannelData*> channel, const std::vector<not_null<UserData*>> &admins, const FilterValue &filter, Fn<void()> changedCallback);
Inner(
QWidget *parent,
not_null<ChannelData*> channel,
const std::vector<not_null<UserData*>> &admins,
const FilterValue &filter,
Fn<void()> changedCallback);
template <typename Widget>
QPointer<Widget> addRow(object_ptr<Widget> widget, int marginTop) {
@ -155,11 +172,15 @@ protected:
void resizeEvent(QResizeEvent *e) override;
private:
void createControls(const std::vector<not_null<UserData*>> &admins, const FilterValue &filter);
void createControls(
const std::vector<not_null<UserData*>> &admins,
const FilterValue &filter);
void createAllActionsCheckbox(const FilterValue &filter);
void createActionsCheckboxes(const FilterValue &filter);
void createAllUsersCheckbox(const FilterValue &filter);
void createAdminsCheckboxes(const std::vector<not_null<UserData*>> &admins, const FilterValue &filter);
void createAdminsCheckboxes(
const std::vector<not_null<UserData*>> &admins,
const FilterValue &filter);
not_null<ChannelData*> _channel;
@ -180,7 +201,13 @@ private:
};
FilterBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> channel, const std::vector<not_null<UserData*>> &admins, const FilterValue &filter, Fn<void()> changedCallback) : TWidget(parent)
FilterBox::Inner::Inner(
QWidget *parent,
not_null<ChannelData*> channel,
const std::vector<not_null<UserData*>> &admins,
const FilterValue &filter,
Fn<void()> changedCallback)
: RpWidget(parent)
, _channel(channel)
, _changedCallback(std::move(changedCallback)) {
createControls(admins, filter);
@ -196,7 +223,8 @@ void FilterBox::Inner::createControls(const std::vector<not_null<UserData*>> &ad
void FilterBox::Inner::createAllActionsCheckbox(const FilterValue &filter) {
auto checked = (filter.flags == 0);
_allFlags = addRow(object_ptr<Ui::Checkbox>(this, lang(lng_admin_log_filter_all_actions), checked, st::adminLogFilterCheckbox), st::adminLogFilterCheckbox.margin.top());
subscribe(_allFlags->checkedChanged, [this](bool checked) {
_allFlags->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
if (!std::exchange(_restoringInvariant, true)) {
auto allChecked = _allFlags->checked();
for_const (auto &&checkbox, _filterFlags) {
@ -207,7 +235,7 @@ void FilterBox::Inner::createAllActionsCheckbox(const FilterValue &filter) {
_changedCallback();
}
}
});
}, _allFlags->lifetime());
}
void FilterBox::Inner::createActionsCheckboxes(const FilterValue &filter) {
@ -217,7 +245,8 @@ void FilterBox::Inner::createActionsCheckboxes(const FilterValue &filter) {
auto checked = (filter.flags == 0) || (filter.flags & flag);
auto checkbox = addRow(object_ptr<Ui::Checkbox>(this, std::move(text), checked, st::defaultBoxCheckbox), st::adminLogFilterLittleSkip);
_filterFlags.insert(flag, checkbox);
subscribe(checkbox->checkedChanged, [this](bool checked) {
checkbox->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
if (!std::exchange(_restoringInvariant, true)) {
auto allChecked = true;
for_const (auto &&checkbox, _filterFlags) {
@ -232,7 +261,7 @@ void FilterBox::Inner::createActionsCheckboxes(const FilterValue &filter) {
_changedCallback();
}
}
});
}, checkbox->lifetime());
};
auto isGroup = _channel->isMegagroup();
if (isGroup) {
@ -251,7 +280,8 @@ void FilterBox::Inner::createActionsCheckboxes(const FilterValue &filter) {
void FilterBox::Inner::createAllUsersCheckbox(const FilterValue &filter) {
_allUsers = addRow(object_ptr<Ui::Checkbox>(this, lang(lng_admin_log_filter_all_admins), filter.allUsers, st::adminLogFilterCheckbox), st::adminLogFilterSkip);
subscribe(_allUsers->checkedChanged, [this](bool checked) {
_allUsers->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
if (checked && !std::exchange(_restoringInvariant, true)) {
for_const (auto &&checkbox, _admins) {
checkbox->setChecked(true);
@ -261,14 +291,15 @@ void FilterBox::Inner::createAllUsersCheckbox(const FilterValue &filter) {
_changedCallback();
}
}
});
}, _allUsers->lifetime());
}
void FilterBox::Inner::createAdminsCheckboxes(const std::vector<not_null<UserData*>> &admins, const FilterValue &filter) {
for (auto user : admins) {
auto checked = filter.allUsers || base::contains(filter.admins, user);
auto checkbox = addRow(object_ptr<UserCheckbox>(this, user, checked), st::adminLogFilterLittleSkip);
subscribe(checkbox->checkedChanged, [this](bool checked) {
checkbox->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
if (!std::exchange(_restoringInvariant, true)) {
auto allChecked = true;
for_const (auto &&checkbox, _admins) {
@ -285,7 +316,7 @@ void FilterBox::Inner::createAdminsCheckboxes(const std::vector<not_null<UserDat
_changedCallback();
}
}
});
}, checkbox->lifetime());
_admins.insert(user, checkbox);
}
}

View File

@ -191,9 +191,7 @@ bool SectionWithToggle::toggled() const {
rpl::producer<bool> SectionWithToggle::toggledValue() const {
if (_toggle) {
return rpl::single(
_toggle->checked()
) | rpl::then(base::ObservableViewer(_toggle->checkedChanged));
return _toggle->checkedValue();
}
return rpl::never<bool>();
}

View File

@ -296,8 +296,7 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
Local::writeSettings();
};
base::ObservableViewer(
tray->checkedChanged
tray->checkedChanges(
) | rpl::filter([=](bool checked) {
return (checked != trayEnabled());
}) | rpl::start_with_next([=](bool checked) {
@ -309,8 +308,7 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
}, tray->lifetime());
if (taskbar) {
base::ObservableViewer(
taskbar->checkedChanged
taskbar->checkedChanges(
) | rpl::filter([=](bool checked) {
return (checked != taskbarEnabled());
}) | rpl::start_with_next([=](bool checked) {
@ -338,8 +336,7 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
lng_settings_add_sendto,
cSendToMenu());
base::ObservableViewer(
autostart->checkedChanged
autostart->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != cAutoStart());
}) | rpl::start_with_next([=](bool checked) {
@ -354,13 +351,8 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
}
}, autostart->lifetime());
minimized->toggleOn(rpl::single(
autostart->checked()
) | rpl::then(base::ObservableViewer(
autostart->checkedChanged
)));
base::ObservableViewer(
minimized->entity()->checkedChanged
minimized->toggleOn(autostart->checkedValue());
minimized->entity()->checkedChanges(
) | rpl::filter([=](bool checked) {
return (checked != minimizedToggled());
}) | rpl::start_with_next([=](bool checked) {
@ -380,8 +372,7 @@ void SetupTrayContent(not_null<Ui::VerticalLayout*> container) {
minimized->entity()->setChecked(minimizedToggled());
}, minimized->lifetime());
base::ObservableViewer(
sendto->checkedChanged
sendto->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != cSendToMenu());
}) | rpl::start_with_next([](bool checked) {

View File

@ -441,11 +441,10 @@ void SetupStickersEmoji(not_null<Ui::VerticalLayout*> container) {
st::settingsCheckbox);
};
const auto add = [&](LangKey label, bool checked, auto &&handle) {
base::ObservableViewer(
inner->add(
checkbox(label, checked),
st::settingsCheckboxPadding
)->checkedChanged
inner->add(
checkbox(label, checked),
st::settingsCheckboxPadding
)->checkedChanges(
) | rpl::start_with_next(
std::move(handle),
inner->lifetime());
@ -670,8 +669,7 @@ void SetupChatBackground(not_null<Ui::VerticalLayout*> container) {
st::settingsCheckbox),
st::settingsSendTypePadding));
base::ObservableViewer(
tile->checkedChanged
tile->checkedChanges(
) | rpl::start_with_next([](bool checked) {
Window::Theme::Background()->setTile(checked);
}, tile->lifetime());
@ -695,8 +693,7 @@ void SetupChatBackground(not_null<Ui::VerticalLayout*> container) {
return (Global::AdaptiveChatLayout() == Adaptive::ChatLayout::Wide);
}));
base::ObservableViewer(
adaptive->entity()->checkedChanged
adaptive->entity()->checkedChanges(
) | rpl::start_with_next([](bool checked) {
Global::SetAdaptiveForWide(checked);
Adaptive::Changed().notify();
@ -986,15 +983,14 @@ void SetupSupport(not_null<Ui::VerticalLayout*> container) {
AddSkip(inner, st::settingsCheckboxesSkip);
base::ObservableViewer(
inner->add(
object_ptr<Ui::Checkbox>(
inner,
"Enable templates autocomplete",
Auth().settings().supportTemplatesAutocomplete(),
st::settingsCheckbox),
st::settingsSendTypePadding
)->checkedChanged
inner->add(
object_ptr<Ui::Checkbox>(
inner,
"Enable templates autocomplete",
Auth().settings().supportTemplatesAutocomplete(),
st::settingsCheckbox),
st::settingsSendTypePadding
)->checkedChanges(
) | rpl::start_with_next([=](bool checked) {
Auth().settings().setSupportTemplatesAutocomplete(checked);
Local::writeUserSettings();

View File

@ -594,8 +594,7 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
Local::writeUserSettings();
Auth().notifications().settingsChanged().notify(change);
};
base::ObservableViewer(
desktop->checkedChanged
desktop->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != Global::DesktopNotify());
}) | rpl::start_with_next([=](bool checked) {
@ -603,8 +602,7 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
changed(Change::DesktopEnabled);
}, desktop->lifetime());
base::ObservableViewer(
name->entity()->checkedChanged
name->entity()->checkedChanges(
) | rpl::map([=](bool checked) {
if (!checked) {
return dbinvShowNothing;
@ -619,8 +617,7 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
changed(Change::ViewParams);
}, name->lifetime());
base::ObservableViewer(
preview->entity()->checkedChanged
preview->entity()->checkedChanges(
) | rpl::map([=](bool checked) {
if (checked) {
return dbinvShowPreview;
@ -635,8 +632,7 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
changed(Change::ViewParams);
}, preview->lifetime());
base::ObservableViewer(
sound->checkedChanged
sound->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != Global::SoundNotify());
}) | rpl::start_with_next([=](bool checked) {
@ -644,8 +640,7 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
changed(Change::SoundEnabled);
}, sound->lifetime());
base::ObservableViewer(
muted->checkedChanged
muted->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != Auth().settings().includeMutedCounter());
}) | rpl::start_with_next([=](bool checked) {
@ -653,14 +648,13 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
changed(Change::IncludeMuted);
}, muted->lifetime());
base::ObservableViewer(
count->checkedChanged
count->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != Auth().settings().countUnreadMessages());
}) | rpl::start_with_next([=](bool checked) {
Auth().settings().setCountUnreadMessages(checked);
changed(Change::CountMessages);
}, muted->lifetime());
}, count->lifetime());
base::ObservableViewer(
Auth().notifications().settingsChanged()
@ -679,8 +673,7 @@ void SetupNotificationsContent(not_null<Ui::VerticalLayout*> container) {
}, desktop->lifetime());
if (native) {
base::ObservableViewer(
native->checkedChanged
native->checkedChanges(
) | rpl::filter([](bool checked) {
return (checked != Global::NativeNotifications());
}) | rpl::start_with_next([=](bool checked) {

View File

@ -66,12 +66,17 @@ void AbstractButton::mouseMoveEvent(QMouseEvent *e) {
void AbstractButton::mouseReleaseEvent(QMouseEvent *e) {
if (_state & StateFlag::Down) {
auto was = _state;
const auto was = _state;
_state &= ~State(StateFlag::Down);
auto weak = make_weak(this);
onStateChanged(was, StateChangeSource::ByPress);
if (!weak) {
return;
}
if (was & StateFlag::Over) {
_modifiers = e->modifiers();
auto weak = make_weak(this);
if (const auto callback = _clickedCallback) {
callback();
} else {

View File

@ -428,6 +428,14 @@ bool Checkbox::checked() const {
return _check->checked();
}
rpl::producer<bool> Checkbox::checkedChanges() const {
return _checkedChanges.events();
}
rpl::producer<bool> Checkbox::checkedValue() const {
return _checkedChanges.events_starting_with(checked());
}
void Checkbox::resizeToText() {
if (_st.width <= 0) {
resizeToWidth(_text.maxWidth() - _st.width);
@ -440,7 +448,7 @@ void Checkbox::setChecked(bool checked, NotifyAboutChange notify) {
if (_check->checked() != checked) {
_check->setChecked(checked, anim::type::normal);
if (notify == NotifyAboutChange::Notify) {
checkedChanged.notify(checked, true);
_checkedChanges.fire_copy(checked);
}
}
}
@ -635,19 +643,24 @@ Radiobutton::Radiobutton(
std::move(check))
, _group(group)
, _value(value) {
using namespace rpl::mappers;
checkbox()->setChecked(group->hasValue() && group->value() == value);
_group->registerButton(this);
subscribe(checkbox()->checkedChanged, [this](bool checked) {
if (checked) {
_group->setValue(_value);
}
});
checkbox()->checkedChanges(
) | rpl::filter(
_1
) | rpl::start_with_next([=] {
_group->setValue(_value);
}, lifetime());
}
void Radiobutton::handleNewGroupValue(int value) {
auto checked = (value == _value);
if (checkbox()->checked() != checked) {
checkbox()->setChecked(checked, Ui::Checkbox::NotifyAboutChange::DontNotify);
checkbox()->setChecked(
checked,
Ui::Checkbox::NotifyAboutChange::DontNotify);
}
}

View File

@ -156,12 +156,15 @@ public:
void setCheckAlignment(style::align alignment);
bool checked() const;
rpl::producer<bool> checkedChanges() const;
rpl::producer<bool> checkedValue() const;
enum class NotifyAboutChange {
Notify,
DontNotify,
};
void setChecked(bool checked, NotifyAboutChange notify = NotifyAboutChange::Notify);
base::Observable<bool> checkedChanged;
void setChecked(
bool checked,
NotifyAboutChange notify = NotifyAboutChange::Notify);
void finishAnimating();
@ -192,6 +195,7 @@ private:
const style::Checkbox &_st;
std::unique_ptr<AbstractCheckView> _check;
rpl::event_stream<bool> _checkedChanges;
QPixmap _checkCache;
Text _text;
@ -237,7 +241,7 @@ private:
};
class Radiobutton : public Checkbox, private base::Subscriber {
class Radiobutton : public Checkbox {
public:
Radiobutton(
QWidget *parent,
@ -261,8 +265,10 @@ protected:
private:
// Hide the names from Checkbox.
bool checked() const;
void checkedChanges() const;
void checkedValue() const;
void setChecked(bool checked, NotifyAboutChange notify);
void checkedChanged();
Checkbox *checkbox() {
return this;
}

View File

@ -305,11 +305,10 @@ void TermsBox::prepare() {
}
if (age) {
base::ObservableViewer(
age->entity()->checkedChanged
age->entity()->checkedChanges(
) | rpl::start_with_next([=] {
toggleAgeError(false);
}, lifetime());
}, age->lifetime());
heightValue(
) | rpl::start_with_next([=](int height) {