]> git.tdb.fi Git - libs/gltk.git/blob - source/panel.cpp
Allow loading generic layout properties from datafiles
[libs/gltk.git] / source / panel.cpp
1 #include <algorithm>
2 #include <msp/core/maputils.h>
3 #include <msp/core/refptr.h>
4 #include "button.h"
5 #include "column.h"
6 #include "dropdown.h"
7 #include "entry.h"
8 #include "grid.h"
9 #include "hslider.h"
10 #include "indicator.h"
11 #include "label.h"
12 #include "list.h"
13 #include "panel.h"
14 #include "part.h"
15 #include "row.h"
16 #include "toggle.h"
17 #include "vslider.h"
18
19 using namespace std;
20
21 namespace Msp {
22 namespace GLtk {
23
24 Panel::Panel():
25         layout(0)
26 { }
27
28 Panel::~Panel()
29 {
30         delete layout;
31         layout = 0;
32 }
33
34 void Panel::set_layout(Layout *l)
35 {
36         l->set_container(*this);
37         delete layout;
38         layout = l;
39 }
40
41 void Panel::autosize()
42 {
43         if(layout)
44                 layout->autosize();
45 }
46
47 void Panel::render_special(const Part &part, GL::Renderer &renderer) const
48 {
49         if(part.get_name()=="children")
50         {
51                 for(list<Container::Child *>::const_iterator i=children.begin(); i!=children.end(); ++i)
52                         if((*i)->widget->is_visible())
53                                 (*i)->widget->render(renderer);
54         }
55 }
56
57 void Panel::on_geometry_change()
58 {
59         if(layout)
60                 layout->update();
61 }
62
63 void Panel::on_child_added(Widget &wdg)
64 {
65         if(layout)
66         {
67                 layout->add_widget(wdg);
68                 signal_autosize_changed.emit();
69         }
70 }
71
72 void Panel::on_child_removed(Widget &wdg)
73 {
74         if(layout)
75         {
76                 layout->remove_widget(wdg);
77                 signal_autosize_changed.emit();
78         }
79 }
80
81
82 Panel::Loader::Loader(Panel &p, map<string, Widget *> &m):
83         DataFile::DerivedObjectLoader<Panel, Widget::Loader>(p),
84         wdg_map(m),
85         last_widget(0)
86 {
87         add("button",    &Loader::child<Button>);
88         add("column",    &Loader::arrangement<Column>);
89         add("constraint",&Loader::constraint);
90         add("dropdown",  &Loader::child<Dropdown>);
91         add("entry",     &Loader::child<Entry>);
92         add("expand",    &Loader::expand);
93         add("gravity",   &Loader::gravity);
94         add("grid",      &Loader::grid);
95         add("hslider",   &Loader::child<HSlider>);
96         add("indicator", &Loader::child<Indicator>);
97         add("label",     &Loader::child<Label>);
98         add("layout",    &Loader::layout);
99         add("list",      &Loader::child<List>);
100         add("panel",     &Loader::panel);
101         add("row",       &Loader::arrangement<Row>);
102         add("toggle",    &Loader::child<Toggle>);
103         add("vslider",   &Loader::child<VSlider>);
104 }
105
106 Layout &Panel::Loader::get_layout()
107 {
108         if(!obj.layout)
109                 obj.set_layout(new Layout);
110
111         return *obj.layout;
112 }
113
114 Widget &Panel::Loader::get_last_widget()
115 {
116         if(!last_widget)
117                 throw logic_error("no widget loaded");
118
119         return *last_widget;
120 }
121
122 template<typename T>
123 void Panel::Loader::arrangement()
124 {
125         T arr(get_layout());
126         ArrangedLoader<T> ldr(*this, arr);
127         load_sub_with(ldr);
128 }
129
130 template<typename T>
131 void Panel::Loader::child(const string &n)
132 {
133         RefPtr<T> chl = new T();
134         load_sub(*chl);
135         obj.add(*chl.get());
136         last_widget = wdg_map[n] = chl.release();
137 }
138
139 void Panel::Loader::constraint(Layout::ConstraintType type, const string &n)
140 {
141         Widget &src = get_last_widget();
142         Widget &tgt = *get_item(wdg_map, n);
143         get_layout().add_constraint(src, type, tgt);
144 }
145
146 void Panel::Loader::expand(bool h, bool v)
147 {
148         get_layout().set_expand(get_last_widget(), h, v);
149 }
150
151 void Panel::Loader::gravity(int h, int v)
152 {
153         get_layout().set_gravity(get_last_widget(), h, v);
154 }
155
156 void Panel::Loader::grid(unsigned cols)
157 {
158         Grid grd(get_layout(), cols);
159         ArrangedLoader<Grid> ldr(*this, grd);
160         load_sub_with(ldr);
161 }
162
163 void Panel::Loader::layout()
164 {
165         Layout::Loader ldr(get_layout(), wdg_map);
166         load_sub_with(ldr);
167 }
168
169 void Panel::Loader::panel(const string &n)
170 {
171         RefPtr<Panel> p = new Panel();
172         load_sub(*p, wdg_map);
173         obj.add(*p.get());
174         last_widget = wdg_map[n] = p.release();
175 }
176
177
178 template<typename T>
179 Panel::ArrangedLoader<T>::ArrangedLoader(Loader &ldr, T &arr):
180         arr_loader(arr)
181 {
182         add_auxiliary_loader(ldr);
183         add_auxiliary_loader(arr_loader);
184 }
185
186 } // namespace GLtk
187 } // namespace Msp