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