Container::~Container()
{
+ // Clear children here while members are still valid
while(!children.empty())
- delete children.front()->widget;
+ {
+ if(children.back()->own_widget)
+ /* Avoid destroying the unique_ptr for the widget from within its own
+ reset() function */
+ unique_ptr<Widget> w = move(children.back()->own_widget);
+ else
+ children.pop_back();
+ }
}
-void Container::add(Widget &wdg)
+void Container::add(unique_ptr<Widget> wdg)
{
- wdg.set_parent(this);
- children.push_back(new Child(*this, &wdg));
- if(wdg.get_animation_interval())
- check_animation_interval();
- children_rebuild_needed = true;
- signal_rebuild_needed.emit();
- on_child_added(wdg);
+ add_child(*wdg).own_widget = move(wdg);
}
void Container::remove(Widget &wdg)
{
- auto i = find_if(children, [&wdg](const Child *c){ return c->widget==&wdg; });
+ auto i = find_if(children, [&wdg](const unique_ptr<Child> &c){ return c->widget==&wdg; });
if(i==children.end())
throw hierarchy_error("widget not in container");
+ unique_ptr<Widget> owned = move((*i)->own_widget);
if(&wdg==saved_input_focus)
saved_input_focus = nullptr;
wdg.set_parent(nullptr);
- delete *i;
children.erase(i);
if(wdg.get_animation_interval())
check_animation_interval();
on_child_removed(wdg);
}
+Container::Child &Container::add_child(Widget &wdg)
+{
+ wdg.set_parent(this);
+ children.push_back(make_unique<Child>(*this, &wdg));
+ if(wdg.get_animation_interval())
+ check_animation_interval();
+ children_rebuild_needed = true;
+ signal_rebuild_needed.emit();
+ on_child_added(wdg);
+ return *children.back();
+}
+
Geometry Container::determine_child_geometry(const Widget &child, const Part &part) const
{
Geometry pgeom = part.get_geometry();
vector<Widget *> Container::get_children() const
{
vector<Widget *> result;
- for(const Child *c: children)
+ for(const unique_ptr<Child> &c: children)
result.push_back(c->widget);
return result;
}
void Container::raise(Widget &wdg)
{
- auto i = find_if(children, [&wdg](const Child *c){ return c->widget==&wdg; });
+ auto i = find_if(children, [&wdg](const unique_ptr<Child> &c){ return c->widget==&wdg; });
if(i==children.end())
throw hierarchy_error("widget not in container");
- Child *c = *i;
+ unique_ptr<Child> c = move(*i);
children.erase(i);
- children.push_back(c);
+ children.push_back(move(c));
}
void Container::set_pointer_focus(Widget *wdg, bool grab)
void Container::check_animation_interval()
{
Time::TimeDelta shortest;
- for(const Child *c: children)
+ for(const unique_ptr<Child> &c: children)
{
const Time::TimeDelta &child_iv = c->widget->get_animation_interval();
if(child_iv && (!shortest || child_iv<shortest))
if(children_rebuild_needed)
{
children_rebuild_needed = false;
- for(Child *c: children)
+ for(const unique_ptr<Child> &c: children)
c->widget->rebuild_hierarchy();
}
}
void Container::animate(const Time::TimeDelta &dt)
{
- for(Child *c: children)
+ for(const unique_ptr<Child> &c: children)
{
const Time::TimeDelta &child_iv = c->widget->get_animation_interval();
if(!child_iv)
void Container::on_reparent()
{
- for(const Child *c: children)
+ for(const unique_ptr<Child> &c: children)
{
if(Container *o = dynamic_cast<Container *>(c->widget))
o->on_reparent();
widget->signal_rebuild_needed.connect(sigc::mem_fun(this, &Child::rebuild_needed));
}
+Container::Child::Child(Container &c, unique_ptr<Widget> w):
+ Child(c, w.get())
+{
+ own_widget = move(w);
+}
+
Container::Child::~Child()
{
visibility_changed(false);