]> git.tdb.fi Git - libs/gltk.git/blob - source/container.h
6311a411a57fb1b16e03dcdd24564242a2ac5902
[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                 Widget *widget = nullptr;
28                 Time::TimeDelta time_since_animate;
29
30                 Child(Container &, Widget *);
31                 virtual ~Child();
32
33                 void visibility_changed(bool);
34                 void request_focus();
35                 void grab_pointer();
36                 void ungrab_pointer();
37                 void request_animation(const Time::TimeDelta &);
38                 void rebuild_needed();
39         };
40
41         std::vector<std::unique_ptr<Child>> children;
42         Widget *click_focus = nullptr;
43         unsigned click_button = 0;
44         Widget *pointer_focus = nullptr;
45         bool pointer_grabbed = false;
46         Widget *input_focus = nullptr;
47         Widget *saved_input_focus = nullptr;
48         Widget *touch_focus = nullptr;
49         bool children_rebuild_needed = false;
50
51         Container() = default;
52 public:
53         virtual ~Container();
54
55         void add(Widget &);
56         void remove(Widget &);
57 protected:
58         Geometry determine_child_geometry(const Widget &, const Part &) const;
59         void autosize_child(const Widget &, const Part &, Geometry &) const;
60         void reposition_child(Widget &, const Part &) const;
61 public:
62         std::vector<Widget *> get_children() const;
63         Widget *find_child_at(int, int) const;
64         Widget *find_descendant_at(int, int) const;
65         void raise(Widget &);
66
67 protected:
68         void set_pointer_focus(Widget *, bool = false);
69         void set_input_focus(Widget *);
70 public:
71         Widget *get_input_focus() const { return input_focus; }
72         Widget *get_final_input_focus() const;
73
74 private:
75         void check_animation_interval();
76
77 protected:
78         void rebuild_hierarchy() override;
79
80 public:
81         void button_press(int, int, unsigned) override;
82         void button_release(int, int, unsigned) override;
83         void pointer_motion(int, int) override;
84 private:
85         Widget *get_pointer_target(int, int, bool) const;
86 public:
87         void pointer_leave() override;
88         void touch_press(int, int, unsigned) override;
89         void touch_release(int, int, unsigned) override;
90         void touch_motion(int, int, unsigned) override;
91         bool key_press(unsigned, unsigned) override;
92         bool key_release(unsigned, unsigned) override;
93         bool character(wchar_t) override;
94         void focus_in() override;
95         void focus_out() override;
96         bool navigate(Navigation) override;
97         void animate(const Time::TimeDelta &) override;
98 protected:
99         void on_reparent() override;
100         virtual void on_child_added(Widget &) { }
101         virtual void on_child_removed(Widget &) { }
102         virtual void on_input_focus_changed(Widget *);
103 };
104
105 } // namespace GLtk
106 } // namespace Msp
107
108 #endif