Add rpl interface to RadiobuttonGroup.

This commit is contained in:
John Preston 2024-02-23 13:24:20 +04:00
parent 1af6140fa3
commit 0c6b2c611d
2 changed files with 66 additions and 41 deletions

View file

@ -907,11 +907,25 @@ void RadiobuttonGroup::setValue(int value) {
for (const auto button : _buttons) { for (const auto button : _buttons) {
button->handleNewGroupValue(_value); button->handleNewGroupValue(_value);
} }
if (const auto callback = _changedCallback) { const auto guard = weak_from_this();
callback(_value); _changes.fire_copy(value);
if (guard.lock()) {
if (const auto callback = _changedCallback) {
callback(_value);
}
} }
} }
void RadiobuttonGroup::registerButton(Radiobutton *button) {
if (!base::contains(_buttons, button)) {
_buttons.push_back(button);
}
}
void RadiobuttonGroup::unregisterButton(Radiobutton *button) {
_buttons.erase(ranges::remove(_buttons, button), _buttons.end());
}
Radiobutton::Radiobutton( Radiobutton::Radiobutton(
QWidget *parent, QWidget *parent,
const std::shared_ptr<RadiobuttonGroup> &group, const std::shared_ptr<RadiobuttonGroup> &group,
@ -927,7 +941,7 @@ Radiobutton::Radiobutton(
st, st,
std::make_unique<RadioView>( std::make_unique<RadioView>(
radioSt, radioSt,
(group->hasValue() && group->value() == value))) { (group->hasValue() && group->current() == value))) {
} }
Radiobutton::Radiobutton( Radiobutton::Radiobutton(
@ -946,7 +960,7 @@ Radiobutton::Radiobutton(
, _value(value) { , _value(value) {
using namespace rpl::mappers; using namespace rpl::mappers;
checkbox()->setChecked(group->hasValue() && group->value() == value); checkbox()->setChecked(group->hasValue() && group->current() == value);
_group->registerButton(this); _group->registerButton(this);
checkbox()->checkedChanges( checkbox()->checkedChanges(
) | rpl::filter( ) | rpl::filter(

View file

@ -191,9 +191,9 @@ public:
using ClickHandlerFilter = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>; using ClickHandlerFilter = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>;
void setClickHandlerFilter(ClickHandlerFilter &&filter); void setClickHandlerFilter(ClickHandlerFilter &&filter);
bool checked() const; [[nodiscard]] bool checked() const;
rpl::producer<bool> checkedChanges() const; [[nodiscard]] rpl::producer<bool> checkedChanges() const;
rpl::producer<bool> checkedValue() const; [[nodiscard]] rpl::producer<bool> checkedValue() const;
enum class NotifyAboutChange { enum class NotifyAboutChange {
Notify, Notify,
DontNotify, DontNotify,
@ -204,17 +204,17 @@ public:
void finishAnimating(); void finishAnimating();
QMargins getMargins() const override { [[nodiscard]] QMargins getMargins() const override {
return _st.margin; return _st.margin;
} }
int naturalWidth() const override; [[nodiscard]] int naturalWidth() const override;
void updateCheck() { void updateCheck() {
rtlupdate(checkRect()); rtlupdate(checkRect());
} }
QRect checkRect() const; [[nodiscard]] QRect checkRect() const;
not_null<AbstractCheckView*> checkView() const { [[nodiscard]] not_null<AbstractCheckView*> checkView() const {
return _check.get(); return _check.get();
} }
@ -257,7 +257,8 @@ private:
class Radiobutton; class Radiobutton;
class RadiobuttonGroup { class RadiobuttonGroup
: public std::enable_shared_from_this<RadiobuttonGroup> {
public: public:
RadiobuttonGroup() = default; RadiobuttonGroup() = default;
RadiobuttonGroup(int value) : _value(value), _hasValue(true) { RadiobuttonGroup(int value) : _value(value), _hasValue(true) {
@ -266,29 +267,32 @@ public:
void setChangedCallback(Fn<void(int value)> callback) { void setChangedCallback(Fn<void(int value)> callback) {
_changedCallback = std::move(callback); _changedCallback = std::move(callback);
} }
[[nodiscard]] rpl::producer<int> changes() const {
return _changes.events();
}
[[nodiscard]] rpl::producer<int> value() const {
return hasValue()
? _changes.events_starting_with_copy(_value)
: changes();
}
bool hasValue() const { [[nodiscard]] bool hasValue() const {
return _hasValue; return _hasValue;
} }
int value() const { [[nodiscard]] int current() const {
return _value; return _value;
} }
void setValue(int value); void setValue(int value);
private: private:
friend class Radiobutton; friend class Radiobutton;
void registerButton(Radiobutton *button) { void registerButton(Radiobutton *button);
if (!base::contains(_buttons, button)) { void unregisterButton(Radiobutton *button);
_buttons.push_back(button);
}
}
void unregisterButton(Radiobutton *button) {
_buttons.erase(std::remove(_buttons.begin(), _buttons.end(), button), _buttons.end());
}
int _value = 0; int _value = 0;
bool _hasValue = false; bool _hasValue = false;
Fn<void(int value)> _changedCallback; Fn<void(int value)> _changedCallback;
rpl::event_stream<int> _changes;
std::vector<Radiobutton*> _buttons; std::vector<Radiobutton*> _buttons;
}; };
@ -340,35 +344,42 @@ template <typename Enum>
class Radioenum; class Radioenum;
template <typename Enum> template <typename Enum>
class RadioenumGroup { class RadioenumGroup : public RadiobuttonGroup {
using Parent = RadiobuttonGroup;
[[nodiscard]] static Enum Cast(int value) {
return static_cast<Enum>(value);
}
public: public:
RadioenumGroup() = default; RadioenumGroup() = default;
RadioenumGroup(Enum value) : _group(static_cast<int>(value)) { RadioenumGroup(Enum value) : Parent(static_cast<int>(value)) {
} }
template <typename Callback> template <typename Callback>
void setChangedCallback(Callback &&callback) { void setChangedCallback(Callback &&callback) {
_group.setChangedCallback([callback](int value) { Parent::setChangedCallback([copy = std::move(callback)](int value) {
callback(static_cast<Enum>(value)); copy(Cast(value));
}); });
} }
bool hasValue() const { [[nodiscard]] rpl::producer<Enum> changes() const {
return _group.hasValue(); return Parent::changes() | rpl::map(Cast);
} }
Enum value() const { [[nodiscard]] rpl::producer<Enum> value() const {
return static_cast<Enum>(_group.value()); return Parent::value() | rpl::map(Cast);
}
[[nodiscard]] Enum current() const {
return Cast(Parent::current());
} }
void setValue(Enum value) { void setValue(Enum value) {
_group.setValue(static_cast<int>(value)); Parent::setValue(static_cast<int>(value));
} }
private: private:
template <typename OtherEnum> template <typename OtherEnum>
friend class Radioenum; friend class Radioenum;
RadiobuttonGroup _group;
}; };
template <typename Enum> template <typename Enum>
@ -382,7 +393,7 @@ public:
const style::Checkbox &st = st::defaultCheckbox) const style::Checkbox &st = st::defaultCheckbox)
: Radiobutton( : Radiobutton(
parent, parent,
std::shared_ptr<RadiobuttonGroup>(group, &group->_group), group->shared_from_this(),
static_cast<int>(value), static_cast<int>(value),
text, text,
st) { st) {
@ -394,13 +405,13 @@ public:
const QString &text, const QString &text,
const style::Checkbox &st, const style::Checkbox &st,
std::unique_ptr<AbstractCheckView> check) std::unique_ptr<AbstractCheckView> check)
: Radiobutton( : Radiobutton(
parent, parent,
std::shared_ptr<RadiobuttonGroup>(group, &group->_group), group->shared_from_this(),
static_cast<int>(value), static_cast<int>(value),
text, text,
st, st,
std::move(check)) { std::move(check)) {
} }
}; };