]> git.tdb.fi Git - libs/gltk.git/blob - source/panel.h
e9744fd107a273c12365a86d11cec545228109d6
[libs/gltk.git] / source / panel.h
1 #ifndef MSP_GLTK_PANEL_H_
2 #define MSP_GLTK_PANEL_H_
3
4 #include <msp/core/typeregistry.h>
5 #include "container.h"
6 #include "layout.h"
7 #include "mspgltk_api.h"
8
9 namespace Msp {
10 namespace GLtk {
11
12 /**
13 Panels are containers for other widgets.  Panel styles should have a special
14 part "children" to render the child widgets.  All properties of this part are
15 ignored.
16 */
17 class MSPGLTK_API Panel: public Container
18 {
19 public:
20         class Loader: public DataFile::DerivedObjectLoader<Panel, Widget::Loader>
21         {
22         public:
23                 typedef std::map<std::string, Widget *> WidgetMap;
24
25         protected:
26                 template<typename T>
27                 struct AddChildType
28                 {
29                         void operator()(const std::string &, Loader &) const;
30                 };
31
32                 WidgetMap &wdg_map;
33                 Widget *last_widget;
34
35         public:
36                 Loader(Panel &, WidgetMap &);
37
38         private:
39                 Layout &get_layout();
40                 Widget &get_last_widget();
41                 template<typename T>
42                 void arrangement();
43                 template<typename T>
44                 void child(const std::string &);
45                 void constraint(Layout::ConstraintType, const std::string &);
46                 void expand(bool, bool);
47                 void ghost(bool);
48                 void gravity(int, int);
49                 void grid(std::size_t);
50                 void layout();
51                 template<typename T>
52                 void unnamed_child();
53
54                 friend class Panel;
55         };
56
57 private:
58         template<typename T>
59         class ArrangedLoader: public DataFile::Loader
60         {
61         private:
62                 typename T::Loader arr_loader;
63
64         public:
65                 ArrangedLoader(Loader &, T &);
66         };
67
68 protected:
69         std::vector<Widget *> nav_order;
70         Layout *layout = nullptr;
71
72         static TypeRegistry<Loader::AddChildType, Loader &> widget_registry;
73         static bool widget_registry_init_done;
74
75         Panel(const Panel &);
76         Panel &operator=(const Panel &);
77 public:
78         Panel();
79         virtual ~Panel();
80
81         template<typename T>
82         static void register_child_type(const std::string &);
83
84         const char *get_class() const override { return "panel"; }
85
86         void set_layout(Layout *);
87         Layout *get_layout() { return layout; }
88
89 protected:
90         void autosize_special(const Part &, Geometry &) const override;
91         void render_special(const Part &, GL::Renderer &) const override;
92
93 public:
94         bool navigate(Navigation) override;
95 protected:
96         Widget *find_next_child(int, int, int, int, int) const;
97         static int compute_delta(int, int, int, int, int);
98
99         void on_size_change() override;
100         void on_child_added(Widget &) override;
101         void on_child_removed(Widget &) override;
102 };
103
104
105 template<typename T>
106 void Panel::register_child_type(const std::string &name)
107 {
108         widget_registry.register_type<T>(name);
109 }
110
111
112 template<typename T>
113 void Panel::Loader::child(const std::string &n)
114 {
115         unnamed_child<T>();
116         wdg_map[n] = last_widget;
117 }
118
119 template<typename T>
120 void Panel::Loader::unnamed_child()
121 {
122         RefPtr<T> chl = new T();
123         load_sub(*chl);
124         obj.add(*chl.get());
125         last_widget = chl.release();
126 }
127
128
129 template<typename T>
130 void Panel::Loader::AddChildType<T>::operator()(const std::string &kwd, Loader &ldr) const
131 {
132         ldr.add(kwd, &Loader::child<T>);
133         ldr.add(kwd, &Loader::unnamed_child<T>);
134 }
135
136 } // namespace GLtk
137 } // namespace Msp
138
139 #endif