first commit
This commit is contained in:
98
modern-qt/layout/mutual-exclusion-group.hh
Normal file
98
modern-qt/layout/mutual-exclusion-group.hh
Normal file
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
#include <modern-qt/layout/group.hh>
|
||||
#include <modern-qt/utility/wrapper/layout.hh>
|
||||
#include <ranges>
|
||||
|
||||
namespace creeper::mutual_exclusion_group::internal {
|
||||
|
||||
template <auto f, typename W>
|
||||
concept switch_function_trait = std::invocable<decltype(f), W&, bool>;
|
||||
|
||||
template <layout_trait T, widget_trait W, auto switch_function>
|
||||
requires switch_function_trait<switch_function, W>
|
||||
struct MutualExclusionGroup : public Group<T, W> {
|
||||
using Group<T, W>::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<TokenContext>;
|
||||
|
||||
template <typename Signal>
|
||||
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 <typename T>
|
||||
concept trait = std::derived_from<T, Token> || group::pro::trait<T>;
|
||||
|
||||
CREEPER_DEFINE_CHECKER(trait);
|
||||
using namespace group::pro;
|
||||
}
|
||||
namespace creeper {
|
||||
|
||||
template <layout_trait T, widget_trait W, auto switch_function>
|
||||
requires mutual_exclusion_group::internal::switch_function_trait<switch_function, W>
|
||||
using MutualExclusionGroup =
|
||||
mutual_exclusion_group::internal::MutualExclusionGroup<T, W, switch_function>;
|
||||
|
||||
template <layout_trait T, widget_trait W>
|
||||
using CheckGroup = Declarative<
|
||||
MutualExclusionGroup<T, W, mutual_exclusion_group::internal::checked_switch_function>,
|
||||
CheckerOr<mutual_exclusion_group::pro::checker, typename T::Checker>>;
|
||||
namespace check_group = mutual_exclusion_group;
|
||||
|
||||
template <layout_trait T, widget_trait W>
|
||||
using OpenGroup = Declarative<
|
||||
MutualExclusionGroup<T, W, mutual_exclusion_group::internal::opened_switch_function>,
|
||||
CheckerOr<mutual_exclusion_group::pro::checker, typename T::Checker>>;
|
||||
namespace open_group = mutual_exclusion_group;
|
||||
|
||||
template <layout_trait T, widget_trait W>
|
||||
using SelectGroup = Declarative<
|
||||
MutualExclusionGroup<T, W, mutual_exclusion_group::internal::selected_switch_function>,
|
||||
CheckerOr<mutual_exclusion_group::pro::checker, typename T::Checker>>;
|
||||
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 {};
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user