Skip to content

Commit

Permalink
libdeng|Widget: Added generic event routing mechanism
Browse files Browse the repository at this point in the history
A Widget can now be configured to route specific types of events
to a particular widget. This is for the purpose of redirecting, say,
all mouse events temporarily to some widget.
  • Loading branch information
skyjake committed May 31, 2013
1 parent 1249164 commit fd039bb
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
2 changes: 2 additions & 0 deletions doomsday/libdeng2/include/de/core/event.h
Expand Up @@ -54,6 +54,8 @@ class DENG2_PUBLIC Event
int type() const { return _type; }

bool isKeyDown() const { return _type == KeyPress || _type == KeyRepeat; }
bool isMouse() const { return _type == MouseButton || _type == MouseMotion ||
_type == MousePosition || _type == MouseWheel; }

template <typename Type>
Type &as() {
Expand Down
3 changes: 2 additions & 1 deletion doomsday/libdeng2/include/de/widgets/rootwidget.h
Expand Up @@ -64,7 +64,8 @@ class DENG2_PUBLIC RootWidget : public Widget

/**
* Sets the focus widget. It is the first widget to be offered input
* events.
* events. As focus changes from widget to widget, they will be notified of
* this via the focusGained() and focusLost() methods.
*
* @param widget Widget to have focus. Set to @c NULL to clear focus.
*/
Expand Down
17 changes: 17 additions & 0 deletions doomsday/libdeng2/include/de/widgets/widget.h
Expand Up @@ -25,6 +25,8 @@
#include "../Event"
#include "../Id"

#include <QList>

namespace de {

class Widget;
Expand Down Expand Up @@ -116,6 +118,21 @@ class DENG2_PUBLIC Widget
String focusNext() const;
String focusPrev() const;

/**
* Routines specific types of events to another widget. It will be
* the only one offered those events.
*
* @param types List of event types.
* @param routeTo Widget to route events to. Caller must ensure
* that the widget is not destroyed while the
* routing is in effect.
*/
void setEventRouting(QList<int> const &types, Widget *routeTo);

void clearEventRouting();

bool isEventRouted(int type, Widget *to) const;

// Tree organization.
void clear();
Widget &add(Widget *child);
Expand Down
34 changes: 34 additions & 0 deletions doomsday/libdeng2/src/widgets/widget.cpp
Expand Up @@ -33,6 +33,9 @@ DENG2_PIMPL(Widget)
String focusNext;
String focusPrev;

typedef QMap<int, Widget *> Routing;
Routing routing;

typedef QList<Widget *> Children;
typedef QMap<String, Widget *> NamedChildren;
Children children;
Expand Down Expand Up @@ -173,6 +176,31 @@ String Widget::focusPrev() const
return d->focusPrev;
}

void Widget::setEventRouting(QList<int> const &types, Widget *routeTo)
{
foreach(int type, types)
{
if(routeTo)
{
d->routing.insert(type, routeTo);
}
else
{
d->routing.remove(type);
}
}
}

void Widget::clearEventRouting()
{
d->routing.clear();
}

bool Widget::isEventRouted(int type, Widget *to) const
{
return d->routing.contains(type) && d->routing[type] == to;
}

void Widget::clear()
{
d->clear();
Expand Down Expand Up @@ -279,6 +307,12 @@ bool Widget::dispatchEvent(Event const &event, bool (Widget::*memberFunc)(Event
return false;
}

// Routing has priority.
if(d->routing.contains(event.type()))
{
return d->routing[event.type()]->dispatchEvent(event, memberFunc);
}

// Tree is traversed in reverse order.
for(int i = d->children.size() - 1; i >= 0; --i)
{
Expand Down

0 comments on commit fd039bb

Please sign in to comment.