1 #ifndef TERMOX_WIDGET_LAYOUTS_STACK_HPP
2 #define TERMOX_WIDGET_LAYOUTS_STACK_HPP
12 #include <signals_light/signal.hpp>
14 #include <termox/system/event.hpp>
15 #include <termox/system/system.hpp>
16 #include <termox/widget/area.hpp>
17 #include <termox/widget/detail/link_lifetimes.hpp>
18 #include <termox/widget/layout.hpp>
19 #include <termox/widget/point.hpp>
20 #include <termox/widget/widget.hpp>
22 namespace ox::layout {
28 template <
typename Child_t = W
idget>
43 throw std::out_of_range{
"Stack::set_active_page: index is invalid"};
44 auto* previous = active_page_;
45 active_page_ = std::addressof(this->
get_children()[index]);
46 if (active_page_ == previous)
48 if (previous !=
nullptr)
53 this->move_active_page();
54 this->resize_active_page();
64 sets_focus_ = sets_focus;
71 template <
typename Widget_t = Child_t,
typename... Args>
74 static_assert(std::is_base_of<Child_t, Widget_t>::value,
75 "Stack::make_page: Widget_t must be a Child_t type");
77 std::make_unique<Widget_t>(std::forward<Args>(args)...)));
82 template <
typename W
idget_t>
83 auto append_page(std::unique_ptr<Widget_t> w_ptr) -> Widget_t&
85 static_assert(std::is_base_of<Child_t, Widget_t>::value,
86 "Stack::append_page: Widget_t must be a Child_t type");
94 template <
typename W
idget_t>
98 std::make_unique<Widget_t>(std::forward<Widget_t>(w)));
105 auto insert_page(std::unique_ptr<Child_t> child, std::size_t index)
108 auto& result = this->
insert_child(std::move(child), index);
119 throw std::out_of_range{
"Stack::delete_page: index is invalid"};
120 auto const* page_to_delete =
123 active_page_ =
nullptr;
133 [[nodiscard]]
auto remove_page(std::size_t index) -> std::unique_ptr<Widget>
135 if (index >= this->
size())
136 throw std::out_of_range{
"Stack::remove_page: index is invalid."};
137 auto const* page_to_remove =
140 active_page_ =
nullptr;
153 [[nodiscard]]
auto size() const -> std::
size_t
168 if (active_page_ ==
nullptr)
173 for (; begin != end; ++begin) {
174 if (std::addressof(*begin) == active_page_)
188 if (active_page_ !=
nullptr)
195 if (active_page_ !=
nullptr)
200 auto move_event(Point new_position, Point old_position) ->
bool override
202 this->move_active_page();
208 this->resize_active_page();
214 if (active_page_ !=
nullptr)
220 Child_t* active_page_ =
nullptr;
221 bool sets_focus_ =
true;
224 void move_active_page()
226 if (active_page_ !=
nullptr)
230 void resize_active_page()
232 if (active_page_ !=
nullptr)
238 template <
typename Widget_t = Widget,
typename... Args>
239 [[nodiscard]]
auto stack(Args&&... args) -> std::unique_ptr<Stack<Widget_t>>
241 return std::make_unique<Stack<Widget_t>>(std::forward<Args>(args)...);
249 template <
typename Child_t>
250 [[nodiscard]]
auto set_active_page(layout::Stack<Child_t>& stack)
251 -> sl::Slot<void(std::size_t)>
253 return link_lifetimes(
254 [&stack](
auto index) { stack.set_active_page(index); }, stack);
257 template <
typename Child_t>
258 [[nodiscard]]
auto set_active_page(layout::Stack<Child_t>& stack,
259 std::size_t index) -> sl::Slot<void()>
261 return link_lifetimes([&stack, index] { stack.set_active_page(index); },
265 template <
typename Child_t>
266 [[nodiscard]]
auto delete_page(layout::Stack<Child_t>& stack)
267 -> sl::Slot<void(std::size_t)>
269 return link_lifetimes([&stack](
auto index) { stack.delete_page(index); },
273 template <
typename Child_t>
274 [[nodiscard]]
auto delete_page(layout::Stack<Child_t>& stack, std::size_t index)
277 return link_lifetimes([&stack, index] { stack.delete_page(index); }, stack);
280 template <
typename Child_t>
281 [[nodiscard]]
auto insert_page(layout::Stack<Child_t>& stack)
282 -> sl::Slot<void(std::size_t, std::unique_ptr<Widget>)>
284 return link_lifetimes(
285 [&stack](
auto index,
auto widget) {
286 stack.insert_page(index, std::move(widget));
291 template <
typename Child_t>
292 [[nodiscard]]
auto insert_page(layout::Stack<Child_t>& stack, std::size_t index)
293 -> sl::Slot<void(std::unique_ptr<Widget>)>
295 return link_lifetimes(
296 [&stack, index](
auto widget) {
297 stack.insert_page(index, std::move(widget));
static void set_focus(Widget &w)
Give program focus to w.
Definition: system.cpp:39
static void post_event(Event e)
Append the event to the Event_queue for the thread it was called on.
Definition: system.cpp:112
Provided as a uniform interface for arranging child Widgets.
Definition: layout.hpp:23
auto get_children()
Return a View of all children.
Definition: layout.hpp:56
auto remove_child(Child_t const *child) -> std::unique_ptr< Widget >
Removes and returns the child pointed to by child.
Definition: layout.hpp:118
auto remove_and_delete_child(Child_t const *child) -> bool
Removes the child with given pointer and sends a Delete_event to it.
Definition: layout.hpp:155
auto insert_child(std::unique_ptr< Widget_t > w, std::size_t index) -> Widget_t &
Inserts w at index, sending child added event to *this.
Definition: layout.hpp:78
auto append_child(std::unique_ptr< Widget_t > w) -> Widget_t &
Move w to the end of the child container. Forwards to insert_child()
Definition: layout.hpp:95
A Layout enabling only a single Widget at a time.
Definition: stack.hpp:29
auto get_active_page() const -> Child_t *
Return a pointer to the current active page, or nullptr if none.
Definition: stack.hpp:159
void set_active_page(std::size_t index)
Set child Widget to be enabled/visible via its index into child vector.
Definition: stack.hpp:40
auto append_page(std::unique_ptr< Widget_t > w_ptr) -> Widget_t &
Add an existing Widget as a page to the end of the Stack.
Definition: stack.hpp:83
auto append_page(Widget_t &&w) -> Child_t &
Add an existing Widget as a page to the end of the Stack.
Definition: stack.hpp:95
auto insert_page(std::unique_ptr< Child_t > child, std::size_t index) -> Child_t &
Insert an existing Widget child at index.
Definition: stack.hpp:105
auto resize_event(Area new_size, Area old_size) -> bool override
Handles Resize_event objects.
Definition: stack.hpp:206
auto focus_in_event() -> bool override
Handles Focus_in_event objects.
Definition: stack.hpp:212
auto remove_page(std::size_t index) -> std::unique_ptr< Widget >
Remove page at index from the list and return it.
Definition: stack.hpp:133
static constexpr auto invalid_index
Used to indicate an error on return values of index type.
Definition: stack.hpp:183
auto active_page_index() const -> std::size_t
Return the index of the current active page.
Definition: stack.hpp:166
auto disable_event() -> bool override
Handles Disable_event objects.
Definition: stack.hpp:193
void give_focus_on_change(bool sets_focus=true)
Set whether Focus is given to a child Widget when it becomes active.
Definition: stack.hpp:62
void delete_page(std::size_t index)
Remove a page from the list, by index value, and delete it.
Definition: stack.hpp:116
sl::Signal< void(std::size_t)> page_changed
Emitted when the active page is changed, sends the new index along.
Definition: stack.hpp:32
auto enable_event() -> bool override
Handles Enable_event objects.
Definition: stack.hpp:186
auto move_event(Point new_position, Point old_position) -> bool override
Handles Move_event objects.
Definition: stack.hpp:200
auto size() const -> std::size_t
Return number of pages in this Stack.
Definition: stack.hpp:153
void clear()
Remove and delete all pages.
Definition: stack.hpp:145
auto make_page(Args &&... args) -> Widget_t &
Construct and append a page to the Stack.
Definition: stack.hpp:72