#pragma once #include #include #include namespace creeper::mutual_exclusion_group::internal { template concept switch_function_trait = std::invocable; template requires switch_function_trait struct MutualExclusionGroup : public Group { using Group::Group; public: auto switch_widgets(std::size_t index) const noexcept { for (auto [index_, w] : std::views::enumerate(this->widgets)) { switch_function(*w, index_ == index); } } auto switch_widgets(W* widget) const noexcept { for (auto w_ : this->widgets) { switch_function(*w_, w_ == widget); } } auto make_signal_injection(auto signal) const noexcept -> void { for (auto widget : this->widgets) { QObject::connect(widget, signal, [this, widget] { switch_widgets(widget); }); } } }; constexpr inline auto checked_switch_function = [](auto& w, bool on) { w.set_checked(on); }; constexpr inline auto opened_switch_function = [](auto& w, bool on) { w.set_opened(on); }; constexpr inline auto selected_switch_function = [](auto& w, bool on) { w.set_selected(on); }; constexpr inline auto no_action_as_token = [](auto& w, bool on) { }; } namespace creeper::mutual_exclusion_group::pro { struct TokenContext { }; using Token = common::Token; template struct SignalInjection : Token { Signal signal; explicit SignalInjection(Signal signal) noexcept : signal { signal } { } auto apply(auto& self) const noexcept -> void { self.make_signal_injection(signal); // } }; template concept trait = std::derived_from || group::pro::trait; CREEPER_DEFINE_CHECKER(trait); using namespace group::pro; } namespace creeper { template requires mutual_exclusion_group::internal::switch_function_trait using MutualExclusionGroup = mutual_exclusion_group::internal::MutualExclusionGroup; template using CheckGroup = Declarative< MutualExclusionGroup, CheckerOr>; namespace check_group = mutual_exclusion_group; template using OpenGroup = Declarative< MutualExclusionGroup, CheckerOr>; namespace open_group = mutual_exclusion_group; template using SelectGroup = Declarative< MutualExclusionGroup, CheckerOr>; namespace select_group = mutual_exclusion_group; namespace internal { inline auto use_mutual_exclusion_group_namespace() { std::ignore = check_group::pro::Token {}; std::ignore = open_group::pro::Token {}; std::ignore = select_group::pro::Token {}; } } }