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