public:
struct Child
{
+ Pane* pane;
Gtk::Widget* w;
int32_t minsize;
- Child (Gtk::Widget* widget, uint32_t ms) : w (widget), minsize (ms) {}
+ Child (Pane* p, Gtk::Widget* widget, uint32_t ms) : pane (p), w (widget), minsize (ms) {}
};
typedef std::list<Child> Children;
void add_divider ();
void handle_child_visibility ();
bool fract_is_ok (Dividers::size_type, float fract);
+
+ static void* notify_child_destroyed (void*);
+ void* child_destroyed (Gtk::Widget*);
};
class LIBGTKMM2EXT_API HPane : public Pane
Pane::~Pane ()
{
for (Children::iterator c = children.begin(); c != children.end(); ++c) {
+ c->w->remove_destroy_notify_callback (&(*c));
c->w->unparent ();
}
}
void
Pane::on_add (Widget* w)
{
- children.push_back (Child (w, 0));
+ children.push_back (Child (this, w, 0));
w->set_parent (*this);
+ /* Gtkmm 2.4 does not correctly arrange for ::on_remove() to be called
+ for custom containers that derive from Gtk::Container. So ... we need
+ to ensure that we hear about child destruction ourselves.
+ */
+ w->add_destroy_notify_callback (&children.back(), &Pane::notify_child_destroyed);
w->signal_show().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility));
w->signal_hide().connect (sigc::mem_fun (*this, &Pane::handle_child_visibility));
}
}
+void*
+Pane::notify_child_destroyed (void* data)
+{
+ Child* child = reinterpret_cast<Child*> (data);
+ return child->pane->child_destroyed (child->w);
+}
+
+void*
+Pane::child_destroyed (Gtk::Widget* w)
+{
+ for (Children::iterator c = children.begin(); c != children.end(); ++c) {
+ if (c->w == w) {
+ children.erase (c);
+ break;
+ }
+ }
+ return 0;
+}
+
void
Pane::on_remove (Widget* w)
{
for (Children::iterator c = children.begin(); c != children.end(); ++c) {
if (c->w == w) {
+ w->remove_destroy_notify_callback (&(*c));
w->unparent ();
children.erase (c);
break;