+ if(focus_index<0 || items[focus_index]->is_visible())
+ return;
+
+ if(static_cast<unsigned>(focus_index)<first)
+ slider.set_value(max_scroll-focus_index);
+ else
+ slider.set_value(max_scroll-last_to_first(focus_index));
+}
+
+void List::slider_value_changed(double value)
+{
+ if(max_scroll>0 && !ignore_slider_change)
+ {
+ first = max_scroll-static_cast<unsigned>(value);
+ rebuild();
+ }
+}
+
+void List::adjust_index(int &index, int pos, int change)
+{
+ if(index>pos)
+ index += change;
+ else if(index==pos)
+ index = (change>0 ? index+change : -1);
+}
+
+
+List::DataObserver::DataObserver(List &l):
+ list(l)
+{
+ list.data->signal_item_added.connect(sigc::mem_fun(this, &DataObserver::item_added));
+ list.data->signal_item_removed.connect(sigc::mem_fun(this, &DataObserver::item_removed));
+ list.data->signal_cleared.connect(sigc::mem_fun(this, &DataObserver::cleared));
+ list.data->signal_refresh_item.connect(sigc::mem_fun(this, &DataObserver::refresh_item));
+}
+
+void List::DataObserver::item_added(unsigned i)
+{
+ adjust_index(list.sel_index, i, 1);
+ adjust_index(list.focus_index, i, 1);
+
+ Item *item = list.create_item(i);
+ list.items.insert(list.items.begin()+i, item);
+ list.items_changed();
+}
+
+void List::DataObserver::item_removed(unsigned i)
+{
+ bool had_selection = (list.sel_index>=0);
+ adjust_index(list.sel_index, i, -1);
+ adjust_index(list.focus_index, i, -1);
+
+ delete list.items[i];
+ list.items.erase(list.items.begin()+i);
+ list.items_changed();
+
+ if(had_selection && list.sel_index<0)
+ list.signal_selection_cleared.emit();
+}
+
+void List::DataObserver::cleared()
+{
+ list.sel_index = -1;
+ list.focus_index = -1;
+ for(vector<Item *>::iterator i=list.items.begin(); i!=list.items.end(); ++i)
+ delete *i;
+ list.items.clear();
+ list.items_changed();
+
+ list.signal_selection_cleared.emit();
+}
+
+void List::DataObserver::refresh_item(unsigned i)
+{
+ delete list.items[i];
+ // Avoid stale pointer while create_item is executing
+ list.items[i] = 0;
+ list.items[i] = list.create_item(i);
+ list.items_changed();
+}
+
+
+void List::Item::autosize_special(const Part &part, Geometry &ageom) const
+{
+ if(part.get_name()=="children")
+ {
+ const Sides &margin = part.get_margin();
+ for(list<Child *>::const_iterator i=children.begin(); i!=children.end(); ++i)