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