1 #ifndef TERMOX_WIDGET_LAYOUTS_PASSIVE_HPP
2 #define TERMOX_WIDGET_LAYOUTS_PASSIVE_HPP
8 #include <termox/widget/bordered.hpp>
9 #include <termox/widget/layouts/horizontal.hpp>
10 #include <termox/widget/layouts/vertical.hpp>
11 #include <termox/widget/pipe.hpp>
12 #include <termox/widget/size_policy.hpp>
13 #include <termox/widget/widget.hpp>
15 namespace ox::detail {
18 inline auto constexpr is_horizontal_or_vertical_v =
19 ::ox::layout::is_horizontal_v<W> || ::ox::layout::is_vertical_v<W>;
33 template <
typename Layout_t,
typename SFINAE =
void>
39 template <
typename Layout_t>
41 std::enable_if_t<detail::is_horizontal_or_vertical_v<Layout_t> &&
42 !detail::is_bordered_v<Layout_t>,
43 void>> :
public Layout_t {
45 using Base_t = Layout_t;
47 static auto constexpr is_vertical = layout::is_vertical_v<Base_t>;
50 using Parameters =
typename Base_t::Parameters;
53 template <
typename... Args>
54 Passive(Args&&... args) : Base_t{std::forward<Args>(args)...}
57 sum_hints(this->get_children(), this->get_child_offset()));
60 Passive(Parameters p) : Base_t{std::move(p)}
63 sum_hints(this->get_children(), this->get_child_offset()));
67 auto child_added_event(
ox::Widget& child) ->
bool override
70 sum_hints(this->get_children(), this->get_child_offset()));
71 return Base_t::child_added_event(child);
74 auto child_removed_event(
ox::Widget& child) ->
bool override
77 sum_hints(this->get_children(), this->get_child_offset()));
78 return Base_t::child_removed_event(child);
81 auto child_polished_event(
ox::Widget& child) ->
bool override
84 sum_hints(this->get_children(), this->get_child_offset()));
85 return Base_t::child_polished_event(child);
90 static auto sum_hints(decltype(std::declval<Layout_t>().get_children())
92 std::size_t begin_offset) ->
int
94 auto get_hint = [](
Widget const& child) {
95 if constexpr (is_vertical)
102 for (
auto i = begin_offset; i < children.size(); ++i)
103 sum += get_hint(children[i]);
107 void set_length(
int length)
109 if constexpr (is_vertical)
110 *
this | pipe::fixed_height(length);
112 *
this | pipe::fixed_width(length);
116 template <
typename W
idget_t>
125 template <
typename... Args>
126 Passive(Args&&... args) :
Base_t{std::forward<Args>(args)...}
131 Passive(Parameters p) :
Base_t{std::move(p)} { this->initialize(); }
136 this->height_policy = height;
137 this->width_policy = width;
141 [[nodiscard]]
static auto adjust_size_policies(Widget_t
const& wrapped,
143 -> std::array<ox::Size_policy, 2>
145 auto const border_height = b.north.has_value() + b.south.has_value();
146 auto const border_width = b.west.has_value() + b.east.has_value();
148 auto hp = wrapped.height_policy;
149 auto wp = wrapped.width_policy;
153 hp.max(hp.max() + border_height);
154 hp.min(hp.min() + border_height);
155 hp.hint(hp.hint() + border_height);
159 wp.max(wp.max() + border_width);
160 wp.min(wp.min() + border_width);
161 wp.hint(wp.hint() + border_width);
169 adjust_size_policies(Base_t::wrapped, this->Base_t::border());
170 this->set_policies(h, w);
172 Base_t::wrapped.width_policy.policy_updated.connect([
this] {
174 adjust_size_policies(Base_t::wrapped, this->Base_t::border());
175 this->set_policies(h, w);
177 Base_t::wrapped.height_policy.policy_updated.connect([
this] {
179 adjust_size_policies(Base_t::wrapped, this->Base_t::border());
180 this->set_policies(h, w);
182 this->border_set.connect([
this] {
184 adjust_size_policies(Base_t::wrapped, this->Base_t::border());
185 this->set_policies(h, w);
191 template <
typename Widget_t,
typename... Args>
192 [[nodiscard]]
auto passive(Args&&... args) -> std::unique_ptr<Passive<Widget_t>>
194 return std::make_unique<Passive<Widget_t>>(std::forward<Args>(args)...);
198 template <
typename W
idget_t>
199 [[nodiscard]]
auto passive(
typename Passive<Widget_t>::Parameters p)
200 -> std::unique_ptr<Passive<Widget_t>>
202 return std::make_unique<Passive<Widget_t>>(std::move(p));
Creates a Bordered widget, which wraps the template type in a Border.
Definition: bordered.hpp:233
Definition: passive.hpp:34
Defines how a Layout should resize a Widget in one length Dimension.
Definition: size_policy.hpp:11
void hint(int value)
Set the size hint, used as the initial value in calculations.
Definition: size_policy.cpp:16
static constexpr auto maximum_max
Largest possible value for max().
Definition: size_policy.hpp:26
Provided as a uniform interface for arranging child Widgets.
Definition: layout.hpp:23
Defines which border walls are enabled and how they are displayed.
Definition: bordered.hpp:21
Definition: passive.hpp:22
Definition: layout.hpp:27