]> git.tdb.fi Git - libs/gltk.git/blob - source/panel.h
43c0f41b64d91a0241d9211f761e5702f9d5a47e
[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                 Widget &get_last_widget();
40                 template<typename T>
41                 void arrangement();
42                 template<typename T>
43                 void child(const std::string &);
44                 void constraint(Layout::ConstraintType, const std::string &);
45                 void expand(bool, bool);
46                 void ghost(bool);
47                 void gravity(int, int);
48                 void grid(std::size_t);
49                 void layout();
50                 template<typename T>
51                 void unnamed_child();
52
53                 friend class Panel;
54         };
55
56 private:
57         template<typename T>
58         class ArrangedLoader: public DataFile::Loader
59         {
60         private:
61                 typename T::Loader arr_loader;
62
63         public:
64                 ArrangedLoader(Loader &, T &);
65         };
66
67 protected:
68         std::vector<Widget *> nav_order;
69         Layout *layout = nullptr;
70
71         static TypeRegistry<Loader::AddChildType, Loader &> widget_registry;
72         static bool widget_registry_init_done;
73
74 public:
75         Panel();
76         virtual ~Panel();
77
78         template<typename T>
79         static void register_child_type(const std::string &);
80
81         const char *get_class() const override { return "panel"; }
82
83         Layout &get_or_create_layout();
84
85 protected:
86         void autosize_special(const Part &, Geometry &) const override;
87         void render_special(const Part &, GL::Renderer &) const override;
88
89 public:
90         bool navigate(Navigation) override;
91 protected:
92         Widget *find_next_child(int, int, int, int, int) const;
93         static int compute_delta(int, int, int, int, int);
94
95         void on_size_change() override;
96         void on_child_added(Widget &) override;
97         void on_child_removed(Widget &) override;
98 };
99
100
101 template<typename T>
102 void Panel::register_child_type(const std::string &name)
103 {
104         widget_registry.register_type<T>(name);
105 }
106
107
108 template<typename T>
109 void Panel::Loader::child(const std::string &n)
110 {
111         unnamed_child<T>();
112         wdg_map[n] = last_widget;
113 }
114
115 template<typename T>
116 void Panel::Loader::unnamed_child()
117 {
118         RefPtr<T> chl = new T();
119         load_sub(*chl);
120         obj.add(*chl.get());
121         last_widget = chl.release();
122 }
123
124
125 template<typename T>
126 void Panel::Loader::AddChildType<T>::operator()(const std::string &kwd, Loader &ldr) const
127 {
128         ldr.add(kwd, &Loader::child<T>);
129         ldr.add(kwd, &Loader::unnamed_child<T>);
130 }
131
132 } // namespace GLtk
133 } // namespace Msp
134
135 #endif