When adding a widget to a parent, you don't always want to append it to
the set of existing children, but instead insert it before one of them.
This patch makes that possible by adding CObject::insert_child_before()
which also produces a ChildAdded event with an additional before_child
pointer. This pointer is then used by GWidget to make sure that any
layout present maintains the correct order. (Without doing that, newly
added children would still be appended into the layout order, despite
having a different widget sibling order.)
Okay, I've spent a whole day on this now, and it finally kinda works!
With this patch, CObject and all of its derived classes are reference
counted instead of tree-owned.
The previous, Qt-like model was nice and familiar, but ultimately also
outdated and difficult to reason about.
CObject-derived types should now be stored in RefPtr/NonnullRefPtr and
each class can be constructed using the forwarding construct() helper:
auto widget = GWidget::construct(parent_widget);
Note that construct() simply forwards all arguments to an existing
constructor. It is inserted into each class by the C_OBJECT macro,
see CObject.h to understand how that works.
CObject::delete_later() disappears in this patch, as there is no longer
a single logical owner of a CObject.
With this patch, CEvents no longer stop at the target object, but will
bubble up the ancestor chain as long as CEvent::is_accepted() is false.
To the set accepted flag, call CEvent::accept().
To clear the accepted flag, call CEvent::ignore().
Events start out in the accepted state, so if you want them to bubble
up, you have to call ignore() on them.
Using this mechanism, we now ignore non-tabbing keydown events in
GWidget, causing them to bubble up through the widget's ancestors. :^)