TermOx
cycle_stack.hpp
1 #ifndef TERMOX_WIDGET_WIDGETS_CYCLE_STACK_HPP
2 #define TERMOX_WIDGET_WIDGETS_CYCLE_STACK_HPP
3 #include <memory>
4 #include <type_traits>
5 #include <utility>
6 
7 #include <termox/painter/glyph_string.hpp>
8 #include <termox/widget/layouts/stack.hpp>
9 #include <termox/widget/pair.hpp>
10 #include <termox/widget/tuple.hpp>
11 #include <termox/widget/widget.hpp>
12 #include <termox/widget/widgets/button.hpp>
13 #include <termox/widget/widgets/cycle_box.hpp>
14 
15 namespace ox::detail {
16 
18 class CS_top_row : public HTuple<Button, Cycle_box, Button> {
19  public:
20  Button& left_btn = this->get<0>();
21  Cycle_box& cycle_box = this->get<1>();
22  Button& right_btn = this->get<2>();
23 
24  public:
25  CS_top_row();
26 };
27 
28 } // namespace ox::detail
29 namespace ox {
30 
32 template <typename Child = Widget>
33 class Cycle_stack : public VPair<detail::CS_top_row, layout::Stack<Child>> {
34  public:
35  // TODO Parameters needs to take titles for each child as well.
36  using Parameters = typename layout::Stack<Child>::Parameters;
37 
38  public:
39  detail::CS_top_row& top_row = this->first;
40  layout::Stack<Child>& stack = this->second;
41 
42  public:
43  explicit Cycle_stack(Parameters parameters)
45  std::move(parameters)}
46  {}
47 
48  template <typename... Widget_t>
49  explicit Cycle_stack(
50  std::pair<Glyph_string, std::unique_ptr<Widget_t>>... children)
51  {
52  // Can't move unique_ptrs out of a std::initializer_list... So can't
53  // forward to Layout's constructor.
54  (this->append_page(std::move(children.first),
55  std::move(children.second)),
56  ...);
57  }
58 
59  public:
61 
63  template <typename Widget_t = Child, typename... Args>
64  auto make_page(Glyph_string title, Args&&... args) -> Widget_t&
65  {
66  static_assert(std::is_base_of<Child, Widget_t>::value,
67  "Cycle_stack::make_page: Widget_t must be a Child type");
68  auto child = std::make_unique<Widget_t>(std::forward<Args>(args)...);
69  return static_cast<Widget_t&>(
70  this->append_page(std::move(title), std::move(child)));
71  }
72 
74 
75  auto append_page(Glyph_string title, std::unique_ptr<Child> widget)
76  -> Child&
77  {
78  auto& signal = top_row.cycle_box.add_option(std::move(title));
79  signal.connect(slot::set_active_page(stack, stack.size()));
80  auto& child = stack.append_page(std::move(widget));
81  if (stack.size() == 1)
82  stack.set_active_page(0);
83  return child;
84  }
85 };
86 
88 template <typename Child = Widget>
89 [[nodiscard]] auto cycle_stack(
90  typename Cycle_stack<Child>::Parameters parameters)
91  -> std::unique_ptr<Cycle_stack<Child>>
92 {
93  return std::make_unique<Cycle_stack<Child>>(std::move(parameters));
94 }
95 
97 template <typename Child = Widget, typename... Widget_t>
98 [[nodiscard]] auto cycle_stack(
99  std::pair<Glyph_string, std::unique_ptr<Widget_t>>... children)
100  -> std::unique_ptr<Cycle_stack<Child>>
101 {
102  return std::make_unique<Cycle_stack<Child>>(std::move(children)...);
103 }
104 
105 } // namespace ox
106 #endif // TERMOX_WIDGET_WIDGETS_CYCLE_STACK_HPP
Button widget that emits Signal on a left mouse button press.
Definition: button.hpp:18
A rotating set of labels, emitting a Signal when the label is changed.
Definition: cycle_box.hpp:27
auto add_option(Glyph_string label) -> sl::Signal< void()> &
Add an option/label to the Cycle_box using Label constructor parameters.
Definition: cycle_box.cpp:55
A layout::Stack with an interface to cycle through each Widget in the stack.
Definition: cycle_stack.hpp:33
auto make_page(Glyph_string title, Args &&... args) -> Widget_t &
Construct a new Widget_t object and add it to the end of the Stack.
Definition: cycle_stack.hpp:64
auto append_page(Glyph_string title, std::unique_ptr< Child > widget) -> Child &
Append a page to the Stack.
Definition: cycle_stack.hpp:75
Holds a collection of Glyphs with a similar interface to std::string.
Definition: glyph_string.hpp:19
Heterogeneous collection of Widgets within a Layout_t.
Definition: tuple.hpp:17
User interface to cycle through the pages of the Stack.
Definition: cycle_stack.hpp:18
A Layout enabling only a single Widget at a time.
Definition: stack.hpp:29
Heterogeneous pair of Widgets within a Layout.
Definition: pair.hpp:14
Definition: widget.hpp:33