]> git.tdb.fi Git - libs/gltk.git/blob - source/panel.cpp
c90c83b970d757dff2404331376ee777b09a2ef1
[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("list",      &Loader::child<List>);
99         add("panel",     &Loader::panel);
100         add("row",       &Loader::arrangement<Row>);
101         add("toggle",    &Loader::child<Toggle>);
102         add("vslider",   &Loader::child<VSlider>);
103 }
104
105 Layout &Panel::Loader::get_layout()
106 {
107         if(!obj.layout)
108                 obj.set_layout(new Layout);
109
110         return *obj.layout;
111 }
112
113 Widget &Panel::Loader::get_last_widget()
114 {
115         if(!last_widget)
116                 throw logic_error("no widget loaded");
117
118         return *last_widget;
119 }
120
121 template<typename T>
122 void Panel::Loader::arrangement()
123 {
124         T arr(get_layout());
125         ArrangedLoader<T> ldr(*this, arr);
126         load_sub_with(ldr);
127 }
128
129 template<typename T>
130 void Panel::Loader::child(const string &n)
131 {
132         RefPtr<T> chl = new T();
133         load_sub(*chl);
134         obj.add(*chl.get());
135         last_widget = wdg_map[n] = chl.release();
136 }
137
138 void Panel::Loader::constraint(Layout::ConstraintType type, const string &n)
139 {
140         Widget &src = get_last_widget();
141         Widget &tgt = *get_item(wdg_map, n);
142         get_layout().add_constraint(src, type, tgt);
143 }
144
145 void Panel::Loader::expand(bool h, bool v)
146 {
147         get_layout().set_expand(get_last_widget(), h, v);
148 }
149
150 void Panel::Loader::gravity(int h, int v)
151 {
152         get_layout().set_gravity(get_last_widget(), h, v);
153 }
154
155 void Panel::Loader::grid(unsigned cols)
156 {
157         Grid grd(get_layout(), cols);
158         ArrangedLoader<Grid> ldr(*this, grd);
159         load_sub_with(ldr);
160 }
161
162 void Panel::Loader::panel(const string &n)
163 {
164         RefPtr<Panel> p = new Panel();
165         load_sub(*p, wdg_map);
166         obj.add(*p.get());
167         last_widget = wdg_map[n] = p.release();
168 }
169
170
171 template<typename T>
172 Panel::ArrangedLoader<T>::ArrangedLoader(Loader &ldr, T &arr):
173         arr_loader(arr)
174 {
175         add_auxiliary_loader(ldr);
176         add_auxiliary_loader(arr_loader);
177 }
178
179 } // namespace GLtk
180 } // namespace Msp