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