Skip to content

Commit

Permalink
libdeng2|Widget: Added Deletion audience; children can be reordered
Browse files Browse the repository at this point in the history
  • Loading branch information
skyjake committed Aug 16, 2013
1 parent 4ddd2a3 commit 808711a
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
7 changes: 7 additions & 0 deletions doomsday/libdeng2/include/de/widgets/widget.h
Expand Up @@ -79,6 +79,11 @@ class DENG2_PUBLIC Widget

typedef WidgetList Children;

/**
* Notified when the widget is about to be deleted.
*/
DENG2_DEFINE_AUDIENCE(Deletion, void widgetBeingDeleted(Widget &widget))

/**
* Notified when the widget's parent changes.
*/
Expand Down Expand Up @@ -182,9 +187,11 @@ class DENG2_PUBLIC Widget
// Tree organization.
void clear();
Widget &add(Widget *child);
Widget &insertBefore(Widget *child, Widget const &otherChild);
Widget *remove(Widget &child);
Widget *find(String const &name);
Widget const *find(String const &name) const;
void moveChildBefore(Widget *child, Widget const &otherChild);
Children children() const;
dsize childCount() const;
Widget *parent() const;
Expand Down
41 changes: 41 additions & 0 deletions doomsday/libdeng2/src/widgets/widget.cpp
Expand Up @@ -75,6 +75,9 @@ Widget::~Widget()
{
d->parent->remove(*this);
}

// Notify everyone else.
DENG2_FOR_AUDIENCE(Deletion, i) i->widgetBeingDeleted(*this);
}

Id Widget::id() const
Expand Down Expand Up @@ -260,6 +263,15 @@ Widget &Widget::add(Widget *child)
return *child;
}

Widget &Widget::insertBefore(Widget *child, Widget const &otherChild)
{
DENG2_ASSERT(child != &otherChild);

add(child);
moveChildBefore(child, otherChild);
return *child;
}

Widget *Widget::remove(Widget &child)
{
DENG2_ASSERT(child.d->parent == this);
Expand Down Expand Up @@ -306,6 +318,35 @@ Widget const *Widget::find(String const &name) const
return const_cast<Widget *>(this)->find(name);
}

void Widget::moveChildBefore(Widget *child, Widget const &otherChild)
{
if(child == &otherChild) return; // invalid

int from = -1;
int to = -1;

// Note: O(n)
for(int i = 0; i < d->children.size() && (from < 0 || to < 0); ++i)
{
if(d->children[i] == child)
{
from = i;
}
if(d->children[i] == &otherChild)
{
to = i;
}
}

DENG2_ASSERT(from != -1);
DENG2_ASSERT(to != -1);

d->children.removeAt(from);
if(to > from) to--;

d->children.insert(to, child);
}

Widget *Widget::parent() const
{
return d->parent;
Expand Down

0 comments on commit 808711a

Please sign in to comment.