1.11
frame.h
1/*
2 * Copyright (C) 2018 Microchip Technology Inc. All rights reserved.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6#ifndef EGT_FRAME_H
7#define EGT_FRAME_H
8
14#include <cassert>
15#include <egt/detail/alignment.h>
16#include <egt/detail/meta.h>
17#include <egt/screen.h>
18#include <egt/widget.h>
19#include <exception>
20#include <memory>
21#include <string>
22#include <vector>
23
24namespace egt
25{
26inline namespace v1
27{
44class EGT_API Frame : public Widget
45{
46public:
47
52 explicit Frame(const Rect& rect = {},
53 const Flags& flags = {}) noexcept;
54
60 Frame(Frame& parent, const Rect& rect,
61 const Flags& flags = {}) noexcept;
62
67 : Frame(props, false)
68 {
69 }
70
71protected:
72
73 Frame(Serializer::Properties& props, bool is_derived) noexcept;
74
75public:
76
77 Frame(const Frame&) = delete;
78 Frame& operator=(const Frame&) = delete;
79 Frame(Frame&&) noexcept = default;
80 Frame& operator=(Frame&&) noexcept = default;
81
82 ~Frame() noexcept override;
83
101 virtual void add(const std::shared_ptr<Widget>& widget);
102
120 virtual void add_at(const std::shared_ptr<Widget>& widget, size_t pos);
121
127 template<class T>
128 void add(const std::shared_ptr<T>& widget)
129 {
130 auto p = std::dynamic_pointer_cast<Widget>(widget);
131 add(p);
132 }
133
140 template<class T>
141 void add_at(const std::shared_ptr<T>& widget, size_t pos)
142 {
143 auto p = std::dynamic_pointer_cast<Widget>(widget);
144 add_at(p, pos);
145 }
146
160 void add(Widget& widget)
161 {
162 // Nasty, but it gets the job done. If a widget is passed in as a
163 // reference, we don't own it, so create a "pointless" shared_ptr that
164 // will not delete it.
165 auto w = std::shared_ptr<Widget>(&widget, [](Widget*) {});
166 add(w);
167 }
168
183 void add_at(Widget& widget, size_t pos)
184 {
185 // Nasty, but it gets the job done. If a widget is passed in as a
186 // reference, we don't own it, so create a "pointless" shared_ptr that
187 // will not delete it.
188 auto w = std::shared_ptr<Widget>(&widget, [](Widget*) {});
189 add_at(w, pos);
190 }
191
195 bool is_child(Widget* widget) const;
196
197 EGT_NODISCARD virtual Point to_child(const Point& p) const
198 {
199 return Widget::to_subordinate(p);
200 }
201
202 EGT_NODISCARD Rect to_child(Rect rect) const
203 {
204 return Widget::to_subordinate(rect);
205 }
206
214 virtual void remove(Widget* widget);
215
225 virtual void remove_at(size_t pos);
226
231
232 using Widget::children;
233
237 EGT_NODISCARD size_t count_children() const { return children().size(); }
238
242 EGT_NODISCARD std::shared_ptr<Widget> child_at(size_t index) const
243 {
244 if (index >= children().size())
245 return nullptr;
246 else
247 return *std::next(children().begin(), index);
248 }
249
253 EGT_NODISCARD bool top_level() const override
254 {
255 return !m_parent;
256 }
257
267 template <class T>
268 std::shared_ptr<T> find_child(const std::string& name)
269 {
270 if (name.empty())
271 return nullptr;
272
273 auto i = std::find_if(children().begin(), children().end(),
274 [&name](const auto & obj)
275 {
276 return obj->name() == name;
277 });
278
279 // just return first one
280 if (i != children().end())
281 return std::dynamic_pointer_cast<T>(*i);
282
283 i = std::find_if(children().begin(), children().end(),
284 [](const auto & obj)
285 {
286 return obj->frame();
287 });
288
289 for (; i != children().end(); ++i)
290 {
291 auto frame = dynamic_cast<Frame*>((*i).get());
292 if (frame)
293 {
294 auto w = frame->find_child<T>(name);
295 if (w)
296 return w;
297 }
298 }
299
300 return nullptr;
301 }
302
303 void walk(const WalkCallback& callback, int level = 0) override;
304
309
310 using Widget::zorder;
311 using Widget::zorder_down;
312 using Widget::zorder_up;
313 using Widget::zorder_bottom;
314 using Widget::zorder_top;
315
316 void show() override
317 {
318 if (visible())
319 return;
320
321 Widget::show();
322 layout();
323 }
324
331
345 template<typename T, typename... Args>
346 std::shared_ptr<T> spawn(Args&& ... args)
347 {
348 auto w = std::make_shared<T>(std::forward<Args>(args)...);
349 add(w);
350 return w;
351 }
352
353 using Widget::special_child_draw_callback;
354
355 void serialize(Serializer& serializer) const override;
356
357 void serialize_children(Serializer& serializer) const override;
358
359 void deserialize_children(const Deserializer& deserializer) override;
360
362 void on_screen_resized() override;
363
364private:
365
366
367 void add_private(const std::shared_ptr<Widget>& widget, ssize_t pos = -1);
368 void remove_all_basic();
369};
370
371}
372}
373
374#endif
Definition serialize.h:200
Utility class for managing a set of flags with the ability to observe changes to the flags.
Definition flags.h:40
A Frame is a Widget that has children widgets.
Definition frame.h:45
Frame & operator=(const Frame &)=delete
EGT_NODISCARD bool top_level() const override
Return true if this is a top level frame, with no parent.
Definition frame.h:253
EGT_NODISCARD size_t count_children() const
Get the number of children widgets.
Definition frame.h:237
void serialize_children(Serializer &serializer) const override
Serialize the widget's children to the specified serializer.
void add_at(const std::shared_ptr< T > &widget, size_t pos)
Utility wrapper around add_at()
Definition frame.h:141
virtual EGT_NODISCARD Point to_child(const Point &p) const
Definition frame.h:197
Frame(Serializer::Properties &props) noexcept
Definition frame.h:66
virtual void remove_at(size_t pos)
Remove the child widget at the specified position.
void walk(const WalkCallback &callback, int level=0) override
Walk the Widget tree and call callback with each Widget.
void add(Widget &widget)
Add a child widget.
Definition frame.h:160
virtual void remove(Widget *widget)
Remove a child widget.
std::shared_ptr< T > find_child(const std::string &name)
Find a child Widget in the entire tree by name.
Definition frame.h:268
Frame(Frame &&) noexcept=default
void remove_all()
Remove all child widgets.
std::shared_ptr< T > spawn(Args &&... args)
Create a child widget of the specified type.
Definition frame.h:346
EGT_NODISCARD Rect to_child(Rect rect) const
Definition frame.h:202
void deserialize_children(const Deserializer &deserializer) override
Deserialize the children of this widget.
void serialize(Serializer &serializer) const override
Serialize the widget to the specified serializer.
Frame(const Frame &)=delete
void add_at(Widget &widget, size_t pos)
Add a child widget at the specified position.
Definition frame.h:183
Widget * hit_test(const DisplayPoint &point)
Get the widget under the given DisplayPoint.
void show() override
Show the Widget.
Definition frame.h:316
EGT_NODISCARD std::shared_ptr< Widget > child_at(size_t index) const
Get a child widget at a specific index.
Definition frame.h:242
Frame(Frame &parent, const Rect &rect, const Flags &flags={}) noexcept
Frame(Serializer::Properties &props, bool is_derived) noexcept
bool is_child(Widget *widget) const
Returns true if the child exists.
void on_screen_resized() override
Overridden to be called recursively on all children.
Frame(const Rect &rect={}, const Flags &flags={}) noexcept
void paint_children_to_file()
Paint individual children to file.
Abstract base serializer class.
Definition serialize.h:34
std::list< std::tuple< std::string, std::string, Serializer::Attributes > > Properties
Definition serialize.h:47
Base Widget class.
Definition widget.h:53
std::function< bool(Widget *widget, int level)> WalkCallback
Callback definition used by walk().
Definition widget.h:1161
EGT framework namespace.
Definition animation.h:24