From d7756fc09ff272c9369e68359b20ffc3e6fd8584 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Wed, 12 Jun 2019 05:57:26 +0200 Subject: [PATCH] LibGUI: Add an "exclusive" property to GAbstractButtons. This makes checkable buttons exclusive with other checkable buttons in the same parent widget. Basically like radio buttons. This should probably be used to implement GRadioButton once it's a bit more mature. --- LibGUI/GAbstractButton.cpp | 14 ++++++++++++++ LibGUI/GAbstractButton.h | 14 ++++++++++++++ LibGUI/GButton.cpp | 2 ++ LibGUI/GWidget.h | 1 + 4 files changed, 31 insertions(+) diff --git a/LibGUI/GAbstractButton.cpp b/LibGUI/GAbstractButton.cpp index e85404fc27..27b0fefb32 100644 --- a/LibGUI/GAbstractButton.cpp +++ b/LibGUI/GAbstractButton.cpp @@ -29,6 +29,20 @@ void GAbstractButton::set_checked(bool checked) if (m_checked == checked) return; m_checked = checked; + + if (is_exclusive() && checked) { + parent_widget()->for_each_child_of_type([&] (auto& sibling) { + if (!sibling.is_exclusive() || !sibling.is_checkable() || !sibling.is_checked()) + return IterationDecision::Continue; + sibling.m_checked = false; + sibling.update(); + if (sibling.on_checked) + sibling.on_checked(false); + return IterationDecision::Continue; + }); + m_checked = true; + } + update(); if (on_checked) on_checked(checked); diff --git a/LibGUI/GAbstractButton.h b/LibGUI/GAbstractButton.h index 4d96c2f00f..7ef205a209 100644 --- a/LibGUI/GAbstractButton.h +++ b/LibGUI/GAbstractButton.h @@ -14,6 +14,9 @@ public: void set_text(const StringView&); const String& text() const { return m_text; } + bool is_exclusive() const { return m_exclusive; } + void set_exclusive(bool b) { m_exclusive = b; } + bool is_checked() const { return m_checked; } void set_checked(bool); @@ -42,9 +45,20 @@ protected: void paint_text(GPainter&, const Rect&, const Font&, TextAlignment); private: + virtual bool is_abstract_button() const final { return true; } + String m_text; bool m_checked { false }; bool m_checkable { false }; bool m_hovered { false }; bool m_being_pressed { false }; + bool m_exclusive { false }; }; + +template<> +inline bool is(const CObject& object) +{ + if (!is(object)) + return false; + return to(object).is_abstract_button(); +} diff --git a/LibGUI/GButton.cpp b/LibGUI/GButton.cpp index 21b9f39043..6528131215 100644 --- a/LibGUI/GButton.cpp +++ b/LibGUI/GButton.cpp @@ -60,6 +60,8 @@ void GButton::click() { if (!is_enabled()) return; + if (is_checkable()) + set_checked(!is_checked()); if (on_click) on_click(*this); } diff --git a/LibGUI/GWidget.h b/LibGUI/GWidget.h index 5c729484cf..67e6522809 100644 --- a/LibGUI/GWidget.h +++ b/LibGUI/GWidget.h @@ -198,6 +198,7 @@ public: } virtual bool is_radio_button() const { return false; } + virtual bool is_abstract_button() const { return false; } private: virtual bool is_widget() const final { return true; }