diff --git a/doomsday/libdeng2/include/de/core/event.h b/doomsday/libdeng2/include/de/core/event.h index ea789fa515..a19a5529cf 100644 --- a/doomsday/libdeng2/include/de/core/event.h +++ b/doomsday/libdeng2/include/de/core/event.h @@ -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 Type &as() { diff --git a/doomsday/libdeng2/include/de/widgets/rootwidget.h b/doomsday/libdeng2/include/de/widgets/rootwidget.h index 2725f658da..16059cfdb2 100644 --- a/doomsday/libdeng2/include/de/widgets/rootwidget.h +++ b/doomsday/libdeng2/include/de/widgets/rootwidget.h @@ -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. */ diff --git a/doomsday/libdeng2/include/de/widgets/widget.h b/doomsday/libdeng2/include/de/widgets/widget.h index 1d250632f2..9bcbede00e 100644 --- a/doomsday/libdeng2/include/de/widgets/widget.h +++ b/doomsday/libdeng2/include/de/widgets/widget.h @@ -25,6 +25,8 @@ #include "../Event" #include "../Id" +#include + namespace de { class Widget; @@ -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 const &types, Widget *routeTo); + + void clearEventRouting(); + + bool isEventRouted(int type, Widget *to) const; + // Tree organization. void clear(); Widget &add(Widget *child); diff --git a/doomsday/libdeng2/src/widgets/widget.cpp b/doomsday/libdeng2/src/widgets/widget.cpp index e3599314ba..cddab1d1bc 100644 --- a/doomsday/libdeng2/src/widgets/widget.cpp +++ b/doomsday/libdeng2/src/widgets/widget.cpp @@ -33,6 +33,9 @@ DENG2_PIMPL(Widget) String focusNext; String focusPrev; + typedef QMap Routing; + Routing routing; + typedef QList Children; typedef QMap NamedChildren; Children children; @@ -173,6 +176,31 @@ String Widget::focusPrev() const return d->focusPrev; } +void Widget::setEventRouting(QList 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(); @@ -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) {