TermOx
widget.hpp
1 #ifndef TERMOX_WIDGET_WIDGET_HPP
2 #define TERMOX_WIDGET_WIDGET_HPP
3 #include <chrono>
4 #include <cstddef>
5 #include <cstdint>
6 #include <memory>
7 #include <set>
8 #include <string>
9 #include <type_traits>
10 #include <utility>
11 #include <vector>
12 
13 #include <signals_light/signal.hpp>
14 
15 #include <termox/common/fps.hpp>
16 #include <termox/common/transform_view.hpp>
17 #include <termox/painter/brush.hpp>
18 #include <termox/painter/color.hpp>
19 #include <termox/painter/glyph.hpp>
20 #include <termox/painter/painter.hpp>
21 #include <termox/system/key.hpp>
22 #include <termox/system/mouse.hpp>
23 #include <termox/widget/area.hpp>
24 #include <termox/widget/cursor.hpp>
25 #include <termox/widget/focus_policy.hpp>
26 #include <termox/widget/point.hpp>
27 #include <termox/widget/size_policy.hpp>
28 
29 namespace ox {
30 
31 class Widget {
32  public:
33  struct Parameters {
34  std::string name = std::string{};
35  Focus_policy focus_policy = Focus_policy::None;
36  Size_policy width_policy = Size_policy{};
37  Size_policy height_policy = Size_policy{};
38  Brush brush = Brush{};
39  Glyph wallpaper = Glyph{U' '};
40  bool brush_paints_wallpaper = true;
41  Cursor cursor = Cursor{};
42  };
43 
44  private:
45  template <typename Signature>
46  using Signal = sl::Signal<Signature>;
47 
48  public:
49  // Event Signals - Alternatives to overriding virtual event handlers.
50  /* Called after event handlers are invoked. Parameters are in same order as
51  * matching event handler function's parameters. */
52  Signal<void()> enabled;
53  Signal<void()> disabled;
54  Signal<void(Widget&)> child_added;
55  Signal<void(Widget&)> child_removed;
56  Signal<void(Widget&)> child_polished;
57  Signal<void(Point, Point)> moved;
58  Signal<void(Area, Area)> resized;
59  Signal<void(Mouse const&)> mouse_pressed;
60  Signal<void(Mouse const&)> mouse_released;
61  Signal<void(Mouse const&)> mouse_wheel_scrolled;
62  Signal<void(Mouse const&)> mouse_moved;
63  Signal<void(Key)> key_pressed;
64  Signal<void(Key)> key_released;
65  Signal<void()> focused_in;
66  Signal<void()> focused_out;
67  Signal<void()> deleted;
68  Signal<void(Painter&)> painted;
69  Signal<void()> timer;
70 
71  // Event filter Signals. The first parameter is the original receiver.
72  Signal<bool(Widget&)> enabled_filter;
73  Signal<bool(Widget&)> disabled_filter;
74  Signal<bool(Widget&, Widget&)> child_added_filter;
75  Signal<bool(Widget&, Widget&)> child_removed_filter;
76  Signal<bool(Widget&, Widget&)> child_polished_filter;
77  Signal<bool(Widget&, Point, Point)> moved_filter;
78  Signal<bool(Widget&, Area, Area)> resized_filter;
79  Signal<bool(Widget&, Mouse const&)> mouse_pressed_filter;
80  Signal<bool(Widget&, Mouse const&)> mouse_released_filter;
81  Signal<bool(Widget&, Mouse const&)> mouse_wheel_scrolled_filter;
82  Signal<bool(Widget&, Mouse const&)> mouse_moved_filter;
83  Signal<bool(Widget&, Key)> key_pressed_filter;
84  Signal<bool(Widget&, Key)> key_released_filter;
85  Signal<bool(Widget&)> focused_in_filter;
86  Signal<bool(Widget&)> focused_out_filter;
87  Signal<bool(Widget&)> deleted_filter;
88  Signal<bool(Widget&, Painter&)> painted_filter;
89  Signal<bool(Widget&)> timer_filter;
90 
91  public:
93  Focus_policy focus_policy;
94 
97 
100 
103 
106 
108  sl::Lifetime lifetime;
109 
110  public:
112  explicit Widget(std::string name = "",
113  Focus_policy focus_policy_ = Focus_policy::None,
114  Size_policy width_policy_ = Size_policy{},
115  Size_policy height_policy_ = Size_policy{},
116  Brush brush_ = Brush{},
117  Glyph wallpaper = U' ',
118  bool brush_paints_wallpaper = true,
119  Cursor cursor = Cursor{});
120 
122  explicit Widget(Parameters p);
123 
124  virtual ~Widget() = default;
125 
126  // Widgets are exclusively owned by std::unique_ptrs and sl::Slots often
127  // depend on Widget references to remain valid, copying and moving would
128  // invalidate those references.
129  Widget(Widget const&) = delete;
130  Widget(Widget&&) = delete;
131  Widget& operator=(Widget const&) = delete;
132  Widget& operator=(Widget&&) = delete;
133 
134  public:
136  void set_name(std::string name);
137 
139  [[nodiscard]] auto name() const -> std::string const&;
140 
142  [[nodiscard]] auto unique_id() const -> std::uint16_t;
143 
145  void set_wallpaper(Glyph g);
146 
148  [[nodiscard]] auto get_wallpaper() const -> Glyph;
149 
151 
152  void enable(bool enable = true);
153 
155 
156  void disable(bool disable = true);
157 
159  [[nodiscard]] auto is_enabled() const -> bool;
160 
162 
164  [[nodiscard]] auto parent() const -> Widget*;
165 
167  [[nodiscard]] auto top_left() const -> Point;
168 
170  [[nodiscard]] auto area() const -> Area;
171 
173  virtual void update();
174 
177  [[nodiscard]] virtual auto is_layout_type() const -> bool;
178 
180 
185  void install_event_filter(Widget& filter);
186 
188 
189  void remove_event_filter(Widget& filter);
190 
192  [[nodiscard]] auto get_event_filters() const -> std::set<Widget*> const&;
193 
195 
200  void enable_animation(std::chrono::milliseconds interval);
201 
203  void enable_animation(FPS fps);
204 
206 
208  void disable_animation();
209 
211  [[nodiscard]] auto is_animated() const -> bool;
212 
214  [[nodiscard]] auto get_children()
215  {
216  auto constexpr dereference = [](auto& widg_ptr) -> Widget& {
217  return *widg_ptr;
218  };
219  return Transform_view(children_, dereference);
220  }
221 
223  [[nodiscard]] auto get_children() const
224  {
225  auto constexpr dereference = [](auto const& widg_ptr) -> Widget const& {
226  return *widg_ptr;
227  };
228  return Transform_view(children_, dereference);
229  }
230 
232  [[nodiscard]] auto get_descendants() const -> std::vector<Widget*>;
233 
235  void paint_wallpaper_with_brush(bool paints = true);
236 
238  [[nodiscard]] auto paints_wallpaper_with_brush() const -> bool;
239 
241 
243  [[nodiscard]] auto generate_wallpaper() const -> Glyph;
244 
246  [[nodiscard]] auto get_child_offset() const -> std::size_t;
247 
249  [[nodiscard]] auto child_count() const -> std::size_t;
250 
251  // - - - - - - - - - - - - - Event Handlers - - - - - - - - - - - - - - - -
253  virtual auto enable_event() -> bool;
254 
256  virtual auto disable_event() -> bool;
257 
259  virtual auto child_added_event(Widget& child) -> bool;
260 
262  virtual auto child_removed_event(Widget& child) -> bool;
263 
265  virtual auto child_polished_event(Widget& child) -> bool;
266 
268  virtual auto move_event(Point new_position, Point old_position) -> bool;
269 
271  virtual auto resize_event(Area new_size, Area old_size) -> bool;
272 
274  virtual auto mouse_press_event(Mouse const& m) -> bool;
275 
277  virtual auto mouse_release_event(Mouse const& m) -> bool;
278 
280  virtual auto mouse_wheel_event(Mouse const& m) -> bool;
281 
283  virtual auto mouse_move_event(Mouse const& m) -> bool;
284 
286  virtual auto key_press_event(Key k) -> bool;
287 
289 
290  virtual auto key_release_event(Key k) -> bool;
291 
293  virtual auto focus_in_event() -> bool;
294 
296  virtual auto focus_out_event() -> bool;
297 
299  virtual auto delete_event() -> bool;
300 
302  virtual auto paint_event(Painter& p) -> bool;
303 
305  virtual auto timer_event() -> bool;
306 
307  // - - - - - - - - - - - Event Filter Handlers - - - - - - - - - - - - - - -
309  virtual auto enable_event_filter(Widget& receiver) -> bool;
310 
312  virtual auto disable_event_filter(Widget& receiver) -> bool;
313 
315  virtual auto child_added_event_filter(Widget& receiver, Widget& child)
316  -> bool;
317 
319  virtual auto child_removed_event_filter(Widget& receiver, Widget& child)
320  -> bool;
321 
323  virtual auto child_polished_event_filter(Widget& receiver, Widget& child)
324  -> bool;
325 
327  virtual auto move_event_filter(Widget& receiver,
328  Point new_position,
329  Point old_position) -> bool;
330 
332  virtual auto resize_event_filter(Widget& receiver,
333  Area new_size,
334  Area old_size) -> bool;
335 
337  virtual auto mouse_press_event_filter(Widget& receiver, Mouse const& m)
338  -> bool;
339 
341  virtual auto mouse_release_event_filter(Widget& receiver, Mouse const& m)
342  -> bool;
343 
345  virtual auto mouse_wheel_event_filter(Widget& receiver, Mouse const& m)
346  -> bool;
347 
349  virtual auto mouse_move_event_filter(Widget& receiver, Mouse const& m)
350  -> bool;
351 
353  virtual auto key_press_event_filter(Widget& receiver, Key k) -> bool;
354 
356  virtual auto key_release_event_filter(Widget& receiver, Key k) -> bool;
357 
359  virtual auto focus_in_event_filter(Widget& receiver) -> bool;
360 
362  virtual auto focus_out_event_filter(Widget& receiver) -> bool;
363 
365  virtual auto delete_event_filter(Widget& receiver) -> bool;
366 
368  virtual auto paint_event_filter(Widget& receiver, Painter& p) -> bool;
369 
371  virtual auto timer_event_filter(Widget& receiver) -> bool;
372 
373  private:
374  bool enabled_ = false;
375  bool brush_paints_wallpaper_;
376  bool is_animated_ = false;
377 
378  protected:
379  using Children_t = std::vector<std::unique_ptr<Widget>>;
380  Children_t children_;
381  std::size_t child_offset_ = 0;
382 
383  private:
384  std::string name_;
385  Widget* parent_ = nullptr;
386  Glyph wallpaper_;
387  std::set<Widget*> event_filters_;
388 
389  // Top left point of *this, relative to the top left of the screen.
390  Point top_left_position_ = {0, 0};
391 
392  // The entire area of the widget.
393  Area area_ = {0, 0};
394 
395  std::uint16_t const unique_id_;
396 
397  public:
399  void set_top_left(Point p);
400 
402  void set_area(Area a);
403 
405  void set_parent(Widget* parent);
406 };
407 
409 [[nodiscard]] auto widget(std::string name = "",
410  Focus_policy focus_policy = Focus_policy::None,
411  Size_policy width_policy = Size_policy{},
412  Size_policy height_policy = Size_policy{},
413  Brush brush = Brush{},
414  Glyph wallpaper = U' ',
415  bool brush_paints_wallpaper = true,
416  Cursor cursor = Cursor{}) -> std::unique_ptr<Widget>;
417 
419 [[nodiscard]] auto widget(Widget::Parameters parameters)
420  -> std::unique_ptr<Widget>;
421 
423 template <typename Widget_t, typename... Args>
424 [[nodiscard]] auto make(Args&&... args) -> std::unique_ptr<Widget_t>
425 {
426  static_assert(std::is_base_of_v<Widget, Widget_t>,
427  "Must make a Widget derived type.");
428  return std::make_unique<Widget_t>(std::forward<Args>(args)...);
429 }
430 
431 } // namespace ox
432 #endif // TERMOX_WIDGET_WIDGET_HPP
Holds the look of any paintable object with Traits and Colors.
Definition: brush.hpp:13
Holds and provides access to all data relevant to a Widget's cursor.
Definition: cursor.hpp:10
Contains functions to paint Glyphs to a Widget's screen area.
Definition: painter.hpp:21
Defines how a Layout should resize a Widget in one length Dimension.
Definition: size_policy.hpp:11
Read only Container view that applies transformation to elements at access.
Definition: transform_view.hpp:16
Definition: widget.hpp:31
virtual auto mouse_press_event(Mouse const &m) -> bool
Handles Mouse_press_event objects.
Definition: widget.cpp:230
virtual auto focus_out_event_filter(Widget &receiver) -> bool
Handles Focus_out_event objects filtered from other Widgets.
Definition: widget.cpp:301
virtual auto paint_event(Painter &p) -> bool
Handles Paint_event objects.
Definition: widget.cpp:248
virtual auto child_removed_event_filter(Widget &receiver, Widget &child) -> bool
Handles Child_removed_event objects filtered from other Widgets.
Definition: widget.cpp:261
virtual auto resize_event(Area new_size, Area old_size) -> bool
Handles Resize_event objects.
Definition: widget.cpp:224
virtual auto disable_event_filter(Widget &receiver) -> bool
Handles Disable_event objects filtered from other Widgets.
Definition: widget.cpp:254
virtual auto mouse_wheel_event(Mouse const &m) -> bool
Handles Mouse_wheel_event objects.
Definition: widget.cpp:234
void set_parent(Widget *parent)
Should only be used by Layout.
Definition: widget.cpp:313
virtual auto move_event(Point new_position, Point old_position) -> bool
Handles Move_event objects.
Definition: widget.cpp:218
auto get_wallpaper() const -> Glyph
Return the currently in use wallpaper or std::nullopt if none.
Definition: widget.cpp:87
Cursor cursor
Provides information on where the cursor is and if it is enabled.
Definition: widget.hpp:96
auto top_left() const -> Point
Return the global top left corner of this widget.
Definition: widget.cpp:106
void set_wallpaper(Glyph g)
Used to fill in empty space that is not filled in by paint_event().
Definition: widget.cpp:81
virtual auto key_press_event(Key k) -> bool
Handles Key_press_event objects.
Definition: widget.cpp:238
void set_area(Area a)
Should only be used by Resize_event send() function.
Definition: widget.cpp:311
virtual auto child_added_event(Widget &child) -> bool
Handles Child_added_event objects.
Definition: widget.cpp:208
virtual auto child_removed_event(Widget &child) -> bool
Handles Child_removed_event objects.
Definition: widget.cpp:210
virtual auto child_added_event_filter(Widget &receiver, Widget &child) -> bool
Handles Child_added_event objects filtered from other Widgets.
Definition: widget.cpp:256
virtual auto mouse_press_event_filter(Widget &receiver, Mouse const &m) -> bool
Handles Mouse_press_event objects filtered from other Widgets.
Definition: widget.cpp:275
Widget(std::string name="", Focus_policy focus_policy_=Focus_policy::None, Size_policy width_policy_=Size_policy{}, Size_policy height_policy_=Size_policy{}, Brush brush_=Brush{}, Glyph wallpaper=U' ', bool brush_paints_wallpaper=true, Cursor cursor=Cursor{})
Create an empty Widget.
Definition: widget.cpp:40
auto get_children()
Get a range containing Widget& to each child.
Definition: widget.hpp:214
virtual auto enable_event() -> bool
Handles Enable_event objects.
Definition: widget.cpp:200
void remove_event_filter(Widget &filter)
Remove a Widget from the Event filter list.
Definition: widget.cpp:129
virtual auto child_polished_event_filter(Widget &receiver, Widget &child) -> bool
Handles Child_polished_event objects filtered from other Widgets.
Definition: widget.cpp:266
virtual auto resize_event_filter(Widget &receiver, Area new_size, Area old_size) -> bool
Handles Resize_event objects filtered from other Widgets.
Definition: widget.cpp:273
auto is_enabled() const -> bool
Check whether the Widget is enabled.
Definition: widget.cpp:102
virtual auto focus_in_event() -> bool
Handles Focus_in_event objects.
Definition: widget.cpp:242
void install_event_filter(Widget &filter)
Install another Widget as an Event filter.
Definition: widget.cpp:114
virtual auto mouse_release_event(Mouse const &m) -> bool
Handles Mouse_release_event objects.
Definition: widget.cpp:232
void paint_wallpaper_with_brush(bool paints=true)
Set if the brush is applied to the wallpaper Glyph.
Definition: widget.cpp:177
sl::Lifetime lifetime
Slots can track this object's lifetime to disable Slot invocations.
Definition: widget.hpp:108
auto get_descendants() const -> std::vector< Widget * >
Return container of all descendants of self_.
Definition: widget.cpp:165
virtual auto focus_in_event_filter(Widget &receiver) -> bool
Handles Focus_in_event objects filtered from other Widgets.
Definition: widget.cpp:299
void set_name(std::string name)
Set the identifying name of the Widget.
Definition: widget.cpp:75
void enable_animation(std::chrono::milliseconds interval)
Enable animation on this Widget.
Definition: widget.cpp:139
virtual auto mouse_wheel_event_filter(Widget &receiver, Mouse const &m) -> bool
Handles Mouse_wheel_event objects filtered from other Widgets.
Definition: widget.cpp:285
auto is_animated() const -> bool
Return true if this Widget has animation enabled.
Definition: widget.cpp:163
auto get_event_filters() const -> std::set< Widget * > const &
Return the list of Event filter Widgets.
Definition: widget.cpp:134
Brush brush
A Brush that is applied to every Glyph painted by this Widget.
Definition: widget.hpp:105
virtual auto mouse_move_event_filter(Widget &receiver, Mouse const &m) -> bool
Handles Mouse_move_event objects filtered from other Widgets.
Definition: widget.cpp:290
virtual auto key_press_event_filter(Widget &receiver, Key k) -> bool
Handles Key_press_event objects filtered from other Widgets.
Definition: widget.cpp:295
virtual auto key_release_event_filter(Widget &receiver, Key k) -> bool
Handles Key_release_event objects filtered from other Widgets.
Definition: widget.cpp:297
virtual auto delete_event_filter(Widget &receiver) -> bool
Handles Delete_event objects filtered from other Widgets.
Definition: widget.cpp:303
virtual auto mouse_move_event(Mouse const &m) -> bool
Handles Mouse_move_event objects.
Definition: widget.cpp:236
virtual auto timer_event() -> bool
Handles Timer_event objects.
Definition: widget.cpp:250
virtual auto key_release_event(Key k) -> bool
Handles Key_release_event objects.
Definition: widget.cpp:240
Size_policy height_policy
Describes how the height of this Widget should be modified by a Layout.
Definition: widget.hpp:102
virtual auto is_layout_type() const -> bool
Definition: widget.cpp:112
auto get_child_offset() const -> std::size_t
Return the index of the first child displayed by this Widget.
Definition: widget.cpp:196
auto parent() const -> Widget *
Return the Widget's parent pointer.
Definition: widget.cpp:104
virtual auto mouse_release_event_filter(Widget &receiver, Mouse const &m) -> bool
Handles Mouse_release_event objects filtered from other Widgets.
Definition: widget.cpp:280
virtual void update()
Post a paint event to this Widget.
Definition: widget.cpp:110
virtual auto timer_event_filter(Widget &receiver) -> bool
Handles Timer_event objects filtered from other Widgets.
Definition: widget.cpp:307
virtual auto child_polished_event(Widget &child) -> bool
Handles Child_polished_event objects.
Definition: widget.cpp:212
virtual auto disable_event() -> bool
Handles Disable_event objects.
Definition: widget.cpp:206
auto name() const -> std::string const &
Return the name of the Widget.
Definition: widget.cpp:77
void disable(bool disable=true)
Disable this Widget and send a Disable_event to itself.
Definition: widget.cpp:100
virtual auto paint_event_filter(Widget &receiver, Painter &p) -> bool
Handles Paint_event objects filtered from other Widgets.
Definition: widget.cpp:305
auto paints_wallpaper_with_brush() const -> bool
If true, the brush will apply to the wallpaper Glyph.
Definition: widget.cpp:183
void set_top_left(Point p)
Should only be used by Move_event send() function.
Definition: widget.cpp:309
virtual auto delete_event() -> bool
Handles Delete_event objects.
Definition: widget.cpp:246
void disable_animation()
Turn off animation, no more Timer_events will be sent to this Widget.
Definition: widget.cpp:155
virtual auto focus_out_event() -> bool
Handles Focus_out_event objects.
Definition: widget.cpp:244
Size_policy width_policy
Describes how the width of this Widget should be modified by a Layout.
Definition: widget.hpp:99
auto get_children() const
Get a const range containing Widget& to each child.
Definition: widget.hpp:223
virtual auto move_event_filter(Widget &receiver, Point new_position, Point old_position) -> bool
Handles Move_event objects filtered from other Widgets.
Definition: widget.cpp:271
void enable(bool enable=true)
Enable this Widget and send an Enable_event to itself.
Definition: widget.cpp:89
auto unique_id() const -> std::uint16_t
Return the ID number unique to this Widget.
Definition: widget.cpp:79
auto area() const -> Area
Return the area the widget occupies.
Definition: widget.cpp:108
auto generate_wallpaper() const -> Glyph
Return the wallpaper Glyph.
Definition: widget.cpp:188
auto child_count() const -> std::size_t
Return the number of children held by this Widget.
Definition: widget.cpp:198
virtual auto enable_event_filter(Widget &receiver) -> bool
Handles Enable_event objects filtered from other Widgets.
Definition: widget.cpp:252
Focus_policy focus_policy
Describes how focus is given to this Widget.
Definition: widget.hpp:93
Holds a description of a paintable tile on the screen.
Definition: glyph.hpp:11
Definition: widget.hpp:33