2 #include <msp/core/maputils.h>
3 #include <msp/core/refptr.h>
6 #include "draghandle.h"
12 #include "indicator.h"
30 input_type = INPUT_NAVIGATION;
39 void Panel::set_layout(Layout *l)
41 l->set_container(*this);
46 void Panel::autosize_special(const Part &part, Geometry &ageom) const
48 if(part.get_name()=="children" && layout)
49 layout->autosize(ageom);
52 void Panel::render_special(const Part &part, GL::Renderer &renderer) const
54 if(part.get_name()=="children")
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);
62 bool Panel::navigate(Navigation nav)
64 if(Container::navigate(nav))
67 if(nav==NAV_UP || nav==NAV_DOWN || nav==NAV_LEFT || nav==NAV_RIGHT)
73 const Geometry &fgeom = input_focus->get_geometry();
74 x = fgeom.x+fgeom.w/2;
75 y = fgeom.y+fgeom.h/2;
79 else if(nav==NAV_DOWN)
81 else if(nav==NAV_RIGHT)
83 else if(nav==NAV_LEFT)
88 for(list<Child *>::const_iterator i=children.begin(); i!=children.end(); ++i)
90 if((*i)->widget==input_focus || !(*i)->widget->is_focusable())
93 const Geometry &cgeom = (*i)->widget->get_geometry();
94 int dx = cgeom.x+cgeom.w/2-x;
95 int dy = cgeom.y+cgeom.h/2-y;
98 if(nav==NAV_UP && dy>0)
100 else if(nav==NAV_DOWN && dy<0)
101 score = -dy+abs(dx)*4;
102 else if(nav==NAV_RIGHT && dx>0)
103 score = dx+abs(dy)*4;
104 else if(nav==NAV_LEFT && dx<0)
105 score = -dx+abs(dy)*4;
107 if(score>0 && (!sibling || score<best_score))
109 sibling = (*i)->widget;
116 set_input_focus(sibling);
117 if(Panel *panel = dynamic_cast<Panel *>(sibling))
118 panel->navigate(nav);
126 void Panel::on_geometry_change()
132 void Panel::on_child_added(Widget &wdg)
136 layout->add_widget(wdg);
137 signal_autosize_changed.emit();
141 void Panel::on_child_removed(Widget &wdg)
145 layout->remove_widget(wdg);
146 signal_autosize_changed.emit();
151 Panel::Loader::Loader(Panel &p, map<string, Widget *> &m):
152 DataFile::DerivedObjectLoader<Panel, Widget::Loader>(p),
156 add("button", &Loader::child<Button>);
157 add("column", &Loader::arrangement<Column>);
158 add("constraint",&Loader::constraint);
159 add("draghandle",&Loader::child<DragHandle>);
160 add("dropdown", &Loader::child<Dropdown>);
161 add("entry", &Loader::child<Entry>);
162 add("expand", &Loader::expand);
163 add("ghost", &Loader::ghost);
164 add("gravity", &Loader::gravity);
165 add("grid", &Loader::grid);
166 add("hslider", &Loader::child<HSlider>);
167 add("image", &Loader::child<Image>);
168 add("indicator", &Loader::child<Indicator>);
169 add("label", &Loader::child<Label>);
170 add("layout", &Loader::layout);
171 add("list", &Loader::child<List>);
172 add("panel", &Loader::panel);
173 add("row", &Loader::arrangement<Row>);
174 add("stack", &Loader::arrangement<Stack>);
175 add("toggle", &Loader::child<Toggle>);
176 add("vslider", &Loader::child<VSlider>);
179 Layout &Panel::Loader::get_layout()
182 obj.set_layout(new Layout);
187 Widget &Panel::Loader::get_last_widget()
190 throw logic_error("no widget loaded");
196 void Panel::Loader::arrangement()
199 ArrangedLoader<T> ldr(*this, arr);
204 void Panel::Loader::child(const string &n)
206 RefPtr<T> chl = new T();
209 last_widget = wdg_map[n] = chl.release();
212 void Panel::Loader::constraint(Layout::ConstraintType type, const string &n)
214 Widget &src = get_last_widget();
215 Widget &tgt = *get_item(wdg_map, n);
216 get_layout().add_constraint(src, type, tgt);
219 void Panel::Loader::expand(bool h, bool v)
221 get_layout().set_expand(get_last_widget(), h, v);
224 void Panel::Loader::ghost(bool g)
226 get_layout().set_ghost(get_last_widget(), g);
229 void Panel::Loader::gravity(int h, int v)
231 get_layout().set_gravity(get_last_widget(), h, v);
234 void Panel::Loader::grid(unsigned cols)
236 Grid grd(get_layout(), cols);
237 ArrangedLoader<Grid> ldr(*this, grd);
241 void Panel::Loader::layout()
243 Layout::Loader ldr(get_layout(), wdg_map);
247 void Panel::Loader::panel(const string &n)
249 RefPtr<Panel> p = new Panel();
250 load_sub(*p, wdg_map);
252 last_widget = wdg_map[n] = p.release();
257 Panel::ArrangedLoader<T>::ArrangedLoader(Loader &ldr, T &arr):
260 add_auxiliary_loader(ldr);
261 add_auxiliary_loader(arr_loader);