1 #ifndef TERMOX_WIDGET_WIDGETS_ACCORDION_HPP
2 #define TERMOX_WIDGET_WIDGETS_ACCORDION_HPP
6 #include <signals_light/signal.hpp>
8 #include <termox/painter/color.hpp>
9 #include <termox/painter/glyph_string.hpp>
10 #include <termox/painter/painter.hpp>
11 #include <termox/painter/trait.hpp>
12 #include <termox/widget/layouts/detail/linear_layout.hpp>
13 #include <termox/widget/layouts/horizontal.hpp>
14 #include <termox/widget/layouts/opposite.hpp>
15 #include <termox/widget/layouts/passive.hpp>
16 #include <termox/widget/layouts/vertical.hpp>
17 #include <termox/widget/pipe.hpp>
18 #include <termox/widget/widgets/label.hpp>
19 #include <termox/widget/widgets/text_view.hpp>
24 template <
template <
typename>
typename Layout_t>
25 class Bar :
public Layout_t<Widget> {
27 class Indicator :
public Widget {
32 if constexpr (layout::is_vertical_v<Layout_t<Widget>>)
33 *
this | fixed_height(1);
35 *
this | fixed_width(3);
52 auto paint_event(
Painter& p) ->
bool override
62 class Title :
public layout::Opposite_t<Layout_t<Widget>> {
66 Align alignment = is_vertical ? Align::Left : Align::Top;
67 Glyph wallpaper = is_vertical ? U
'─' : U
'│';
71 sl::Signal<void()> clicked;
75 : centered_text_{this->template make_child<
Label<Layout_t>>(
77 .
append(std::move(p.title))
80 p.alignment, extra_left})}
82 using namespace ox::pipe;
83 if constexpr (is_vertical)
84 centered_text_ | fixed_height(1);
86 this->insert_child(widget(), 0);
87 this->insert_child(widget(), 2);
88 *
this | children() | fixed_width(1);
91 on_mouse_press([
this](
auto const&) { this->clicked(); });
92 centered_text_.set_wallpaper(p.wallpaper);
96 Label<Layout_t>& centered_text_;
98 static auto constexpr is_vertical =
99 layout::is_vertical_v<layout::Opposite_t<Layout_t<Widget>>>;
101 static auto constexpr extra_left = is_vertical ? 3 : 1;
105 static auto constexpr is_vertical = layout::is_vertical_v<Layout_t<Widget>>;
108 using Parameters =
typename Title::Parameters;
111 sl::Signal<void()> toggle_request;
114 Bar(Parameters p) : text_{this->template make_child<Title>(std::move(p))}
116 using namespace pipe;
117 if constexpr (is_vertical)
118 *
this | fixed_width(3);
120 *
this | fixed_height(1);
124 indicator_.mouse_pressed.connect(
125 [
this](
auto const&) { this->toggle_request(); });
126 text_.clicked.connect([
this] { this->toggle_request(); });
130 void expand() { indicator_.minus(); }
132 void collapse() { indicator_.plus(); }
134 auto indicator_widget() -> Indicator& {
return indicator_; }
136 auto title_widget() -> Title& {
return text_; }
139 Indicator& indicator_ = this->
template make_child<Indicator>();
143 enum class Bar_position { First, Last };
145 template <
template <
typename>
typename Layout_t,
147 Bar_position position = Bar_position::First>
150 static_assert(layout::is_vertical_v<Layout_t<Widget>> ||
151 layout::is_horizontal_v<Layout_t<Widget>>);
158 using Parameters =
typename Bar_t::Parameters;
165 template <
typename... Args>
167 : bar_{this->template make_child<
Bar_t>(std::move(p))},
169 this->template make_child<Widget_t>(std::forward<Args>(args)...)}
171 if constexpr (wrapped_index_ == 0)
172 this->swap_children(0, 1);
174 bar_.toggle_request.connect([
this] { this->toggle_expansion(); });
185 this->reinsert_wrapped();
186 this->enable(this->is_enabled());
194 this->extract_wrapped();
195 this->enable(this->is_enabled());
198 void toggle_expansion()
207 [[nodiscard]]
auto wrapped() -> Widget_t& {
return wrapped_; }
210 [[nodiscard]]
auto wrapped() const -> Widget_t const& {
return wrapped_; }
213 [[nodiscard]]
auto bar() ->
Bar_t& {
return bar_; }
216 [[nodiscard]]
auto bar() const ->
Bar_t const& {
return bar_; }
222 bool expanded_ =
true;
223 std::unique_ptr<Widget> w_storage_ =
nullptr;
225 static auto constexpr wrapped_index_ =
226 position == Bar_position::First ? 1 : 0;
228 static auto constexpr is_vertical = layout::is_vertical_v<Layout_t<Widget>>;
231 void reinsert_wrapped()
233 if (w_storage_ ==
nullptr)
235 this->insert_child(std::move(w_storage_), wrapped_index_);
236 w_storage_ =
nullptr;
239 void extract_wrapped()
241 if (w_storage_ ==
nullptr)
242 w_storage_ = this->remove_child_at(wrapped_index_);
246 template <
template <
typename>
typename Layout_t,
248 Bar_position position = Bar_position::First,
250 [[nodiscard]]
auto accordion(Args&&... args)
251 -> std::unique_ptr<Accordion<Layout_t, Widget_t, position>>
253 return std::make_unique<Accordion<Layout_t, Widget_t, position>>(
254 std::forward<Args>(args)...);
257 template <
typename W
idget_t, Bar_position position = Bar_position::First>
258 using HAccordion = Accordion<layout::Horizontal, Widget_t, position>;
260 template <
typename Widget_t,
261 Bar_position position = Bar_position::First,
263 [[nodiscard]]
auto haccordion(Args&&... args)
264 -> std::unique_ptr<HAccordion<Widget_t, position>>
266 return std::make_unique<HAccordion<Widget_t, position>>(
267 std::forward<Args>(args)...);
270 template <
typename W
idget_t, Bar_position position = Bar_position::First>
271 using VAccordion = Accordion<layout::Vertical, Widget_t, position>;
273 template <
typename Widget_t,
274 Bar_position position = Bar_position::First,
276 [[nodiscard]]
auto vaccordion(Args&&... args)
277 -> std::unique_ptr<VAccordion<Widget_t, position>>
279 return std::make_unique<VAccordion<Widget_t, position>>(
280 std::forward<Args>(args)...);
Definition: accordion.hpp:148
void expand()
Enable the wrapped Widget.
Definition: accordion.hpp:181
auto bar() const -> Bar_t const &
Return the titled Bar widget.
Definition: accordion.hpp:216
auto bar() -> Bar_t &
Return the titled Bar widget.
Definition: accordion.hpp:213
Accordion(Parameters p, Args &&... args)
Create an Accordion with args... going to Widget_t constructor.
Definition: accordion.hpp:166
auto wrapped() const -> Widget_t const &
Return the wrapped widget.
Definition: accordion.hpp:210
void collapse()
Disable the wrapped Widget.
Definition: accordion.hpp:190
auto wrapped() -> Widget_t &
Return the wrapped widget.
Definition: accordion.hpp:207
Layout_t is the Layout to use for the Bar, not Accordion.
Definition: accordion.hpp:25
Holds a collection of Glyphs with a similar interface to std::string.
Definition: glyph_string.hpp:19
auto append(Glyph g) -> Glyph_string &
Append a single Glyph to the end of *this.
Definition: glyph_string.cpp:21
A single line of text with alignment, non-editable.
Definition: label.hpp:22
Contains functions to paint Glyphs to a Widget's screen area.
Definition: painter.hpp:21
auto put(Glyph tile, Point p) -> Painter &
Put single Glyph to local coordinates.
Definition: painter.cpp:18
Definition: passive.hpp:34
Definition: accordion.hpp:64
Holds a description of a paintable tile on the screen.
Definition: glyph.hpp:11