]> git.tdb.fi Git - libs/gltk.git/blob - source/container.h
Rework how widget ownership works in Container
[libs/gltk.git] / source / container.h
1 #ifndef MSP_GLTK_CONTAINER_H_
2 #define MSP_GLTK_CONTAINER_H_
3
4 #include <memory>
5 #include <stdexcept>
6 #include <vector>
7 #include <sigc++/trackable.h>
8 #include "mspgltk_api.h"
9 #include "widget.h"
10
11 namespace Msp {
12 namespace GLtk {
13
14 class MSPGLTK_API hierarchy_error: public std::logic_error
15 {
16 public:
17         hierarchy_error(const std::string &);
18 };
19
20
21 class MSPGLTK_API Container: virtual public Widget
22 {
23 protected:
24         struct Child: public sigc::trackable
25         {
26                 Container &container;
27                 std::unique_ptr<Widget> own_widget;
28                 Widget *widget = nullptr;
29                 Time::TimeDelta time_since_animate;
30
31                 Child(Container &, Widget *);
32                 Child(Container &, std::unique_ptr<Widget>);
33                 virtual ~Child();
34
35                 void visibility_changed(bool);
36                 void request_focus();
37                 void grab_pointer();
38                 void ungrab_pointer();
39                 void request_animation(const Time::TimeDelta &);
40                 void rebuild_needed();
41         };
42
43         std::vector<std::unique_ptr<Child>> children;
44         Widget *click_focus = nullptr;
45         unsigned click_button = 0;
46         Widget *pointer_focus = nullptr;
47         bool pointer_grabbed = false;
48         Widget *input_focus = nullptr;
49         Widget *saved_input_focus = nullptr;
50         Widget *touch_focus = nullptr;
51         bool children_rebuild_needed = false;
52
53         Container() = default;
54 public:
55         virtual ~Container();
56
57         void add(Widget &w) { add_child(w); }
58         void add(std::unique_ptr<Widget>);
59
60         template<typename T, typename... Args>
61         T &add_new(Args &&...);
62
63         void remove(Widget &);
64 protected:
65         Child &add_child(Widget &);
66         Geometry determine_child_geometry(const Widget &, const Part &) const;
67         void autosize_child(const Widget &, const Part &, Geometry &) const;
68         void reposition_child(Widget &, const Part &) const;
69 public:
70         std::vector<Widget *> get_children() const;
71         Widget *find_child_at(int, int) const;
72         Widget *find_descendant_at(int, int) const;
73         void raise(Widget &);
74
75 protected:
76         void set_pointer_focus(Widget *, bool = false);
77         void set_input_focus(Widget *);
78 public:
79         Widget *get_input_focus() const { return input_focus; }
80         Widget *get_final_input_focus() const;
81
82 private:
83         void check_animation_interval();
84
85 protected:
86         void rebuild_hierarchy() override;
87
88 public:
89         void button_press(int, int, unsigned) override;
90         void button_release(int, int, unsigned) override;
91         void pointer_motion(int, int) override;
92 private:
93         Widget *get_pointer_target(int, int, bool) const;
94 public:
95         void pointer_leave() override;
96         void touch_press(int, int, unsigned) override;
97         void touch_release(int, int, unsigned) override;
98         void touch_motion(int, int, unsigned) override;
99         bool key_press(unsigned, unsigned) override;
100         bool key_release(unsigned, unsigned) override;
101         bool character(wchar_t) override;
102         void focus_in() override;
103         void focus_out() override;
104         bool navigate(Navigation) override;
105         void animate(const Time::TimeDelta &) override;
106 protected:
107         void on_reparent() override;
108         virtual void on_child_added(Widget &) { }
109         virtual void on_child_removed(Widget &) { }
110         virtual void on_input_focus_changed(Widget *);
111 };
112
113
114 template<typename T, typename... Args>
115 T &Container::add_new(Args &&... args)
116 {
117         std::unique_ptr<T> wdg = std::make_unique<T>(std::forward<Args>(args)...);
118         T *ptr = wdg.get();
119         add(move(wdg));
120         return *ptr;
121 }
122
123 } // namespace GLtk
124 } // namespace Msp
125
126 #endif