Skip to content

Commit

Permalink
Add rpl interface to RadiobuttonGroup.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Feb 23, 2024
1 parent 1af6140 commit 0c6b2c6
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 41 deletions.
22 changes: 18 additions & 4 deletions ui/widgets/checkbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,11 +907,25 @@ void RadiobuttonGroup::setValue(int value) {
for (const auto button : _buttons) {
button->handleNewGroupValue(_value);
}
if (const auto callback = _changedCallback) {
callback(_value);
const auto guard = weak_from_this();
_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(
QWidget *parent,
const std::shared_ptr<RadiobuttonGroup> &group,
Expand All @@ -927,7 +941,7 @@ Radiobutton::Radiobutton(
st,
std::make_unique<RadioView>(
radioSt,
(group->hasValue() && group->value() == value))) {
(group->hasValue() && group->current() == value))) {
}

Radiobutton::Radiobutton(
Expand All @@ -946,7 +960,7 @@ Radiobutton::Radiobutton(
, _value(value) {
using namespace rpl::mappers;

checkbox()->setChecked(group->hasValue() && group->value() == value);
checkbox()->setChecked(group->hasValue() && group->current() == value);
_group->registerButton(this);
checkbox()->checkedChanges(
) | rpl::filter(
Expand Down
85 changes: 48 additions & 37 deletions ui/widgets/checkbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ class Checkbox : public RippleButton, public ClickHandlerHost {
using ClickHandlerFilter = Fn<bool(const ClickHandlerPtr&, Qt::MouseButton)>;
void setClickHandlerFilter(ClickHandlerFilter &&filter);

bool checked() const;
rpl::producer<bool> checkedChanges() const;
rpl::producer<bool> checkedValue() const;
[[nodiscard]] bool checked() const;
[[nodiscard]] rpl::producer<bool> checkedChanges() const;
[[nodiscard]] rpl::producer<bool> checkedValue() const;
enum class NotifyAboutChange {
Notify,
DontNotify,
Expand All @@ -204,17 +204,17 @@ class Checkbox : public RippleButton, public ClickHandlerHost {

void finishAnimating();

QMargins getMargins() const override {
[[nodiscard]] QMargins getMargins() const override {
return _st.margin;
}
int naturalWidth() const override;
[[nodiscard]] int naturalWidth() const override;

void updateCheck() {
rtlupdate(checkRect());
}
QRect checkRect() const;
[[nodiscard]] QRect checkRect() const;

not_null<AbstractCheckView*> checkView() const {
[[nodiscard]] not_null<AbstractCheckView*> checkView() const {
return _check.get();
}

Expand Down Expand Up @@ -257,7 +257,8 @@ class Checkbox : public RippleButton, public ClickHandlerHost {

class Radiobutton;

class RadiobuttonGroup {
class RadiobuttonGroup
: public std::enable_shared_from_this<RadiobuttonGroup> {
public:
RadiobuttonGroup() = default;
RadiobuttonGroup(int value) : _value(value), _hasValue(true) {
Expand All @@ -266,29 +267,32 @@ class RadiobuttonGroup {
void setChangedCallback(Fn<void(int value)> 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;
}
int value() const {
[[nodiscard]] int current() const {
return _value;
}
void setValue(int value);

private:
friend class Radiobutton;
void registerButton(Radiobutton *button) {
if (!base::contains(_buttons, button)) {
_buttons.push_back(button);
}
}
void unregisterButton(Radiobutton *button) {
_buttons.erase(std::remove(_buttons.begin(), _buttons.end(), button), _buttons.end());
}
void registerButton(Radiobutton *button);
void unregisterButton(Radiobutton *button);

int _value = 0;
bool _hasValue = false;
Fn<void(int value)> _changedCallback;
rpl::event_stream<int> _changes;
std::vector<Radiobutton*> _buttons;

};
Expand Down Expand Up @@ -340,35 +344,42 @@ template <typename Enum>
class Radioenum;

template <typename Enum>
class RadioenumGroup {
class RadioenumGroup : public RadiobuttonGroup {
using Parent = RadiobuttonGroup;

[[nodiscard]] static Enum Cast(int value) {
return static_cast<Enum>(value);
}

public:
RadioenumGroup() = default;
RadioenumGroup(Enum value) : _group(static_cast<int>(value)) {
RadioenumGroup(Enum value) : Parent(static_cast<int>(value)) {
}

template <typename Callback>
void setChangedCallback(Callback &&callback) {
_group.setChangedCallback([callback](int value) {
callback(static_cast<Enum>(value));
Parent::setChangedCallback([copy = std::move(callback)](int value) {
copy(Cast(value));
});
}

bool hasValue() const {
return _group.hasValue();
[[nodiscard]] rpl::producer<Enum> changes() const {
return Parent::changes() | rpl::map(Cast);
}
[[nodiscard]] rpl::producer<Enum> value() const {
return Parent::value() | rpl::map(Cast);
}
Enum value() const {
return static_cast<Enum>(_group.value());
[[nodiscard]] Enum current() const {
return Cast(Parent::current());
}
void setValue(Enum value) {
_group.setValue(static_cast<int>(value));
Parent::setValue(static_cast<int>(value));
}

private:
template <typename OtherEnum>
friend class Radioenum;

RadiobuttonGroup _group;

};

template <typename Enum>
Expand All @@ -382,7 +393,7 @@ class Radioenum : public Radiobutton {
const style::Checkbox &st = st::defaultCheckbox)
: Radiobutton(
parent,
std::shared_ptr<RadiobuttonGroup>(group, &group->_group),
group->shared_from_this(),
static_cast<int>(value),
text,
st) {
Expand All @@ -394,13 +405,13 @@ class Radioenum : public Radiobutton {
const QString &text,
const style::Checkbox &st,
std::unique_ptr<AbstractCheckView> check)
: Radiobutton(
parent,
std::shared_ptr<RadiobuttonGroup>(group, &group->_group),
static_cast<int>(value),
text,
st,
std::move(check)) {
: Radiobutton(
parent,
group->shared_from_this(),
static_cast<int>(value),
text,
st,
std::move(check)) {
}

};
Expand Down

0 comments on commit 0c6b2c6

Please sign in to comment.