rework mouse events propagation

This commit is contained in:
Eduardo Bart
2012-03-28 08:46:15 -03:00
parent 92d535f981
commit e2ea267703
11 changed files with 66 additions and 108 deletions

View File

@@ -85,7 +85,16 @@ void UIManager::inputEvent(const InputEvent& event)
pressedWidget = nullptr;
updatePressedWidget(pressedWidget, event.mousePos);
}
m_mouseReceiver->propagateOnMousePress(event.mousePos, event.mouseButton);
m_mouseReceiver->propagateOnMouseEvent(event.mousePos, widgetList);
for(const UIWidgetPtr& widget : widgetList) {
if(widget->isFocusable()) {
if(UIWidgetPtr parent = widget->getParent())
parent->focusChild(widget, Fw::MouseFocusReason);
}
widget->onMousePress(event.mousePos, event.mouseButton);
}
break;
case Fw::MouseReleaseInputEvent: {
// release dragging widget
@@ -94,7 +103,7 @@ void UIManager::inputEvent(const InputEvent& event)
accepted = updateDraggingWidget(nullptr, event.mousePos);
if(!accepted) {
m_mouseReceiver->propagateOnMouseRelease(event.mousePos, event.mouseButton, widgetList);
m_mouseReceiver->propagateOnMouseEvent(event.mousePos, widgetList);
// mouse release is always fired first on the pressed widget
if(m_pressedWidget) {
@@ -139,7 +148,7 @@ void UIManager::inputEvent(const InputEvent& event)
break;
}
case Fw::MouseWheelInputEvent:
m_mouseReceiver->propagateOnMouseWheel(event.mousePos, event.wheelDirection, widgetList);
m_mouseReceiver->propagateOnMouseEvent(event.mousePos, widgetList);
for(const UIWidgetPtr& widget : widgetList) {
if(widget->onMouseWheel(event.mousePos, event.wheelDirection))
break;

View File

@@ -1483,83 +1483,36 @@ bool UIWidget::propagateOnKeyUp(uchar keyCode, int keyboardModifiers)
return onKeyUp(keyCode, keyboardModifiers);
}
bool UIWidget::propagateOnMousePress(const Point& mousePos, Fw::MouseButton button)
bool UIWidget::propagateOnMouseEvent(const Point& mousePos, UIWidgetList& widgetList)
{
// do a backup of children list, because it may change while looping it
UIWidgetPtr clickedChild;
for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
continue;
// mouse press events only go to children that contains the mouse position
if(child->containsPoint(mousePos) && child == getChildByPos(mousePos)) {
clickedChild = child;
break;
bool ret = false;
if(containsChildPoint(mousePos)) {
for(auto it = m_children.rbegin(); it != m_children.rend(); ++it) {
const UIWidgetPtr& child = *it;
if(child->isExplicitlyEnabled() && child->isExplicitlyVisible() && child->containsPoint(mousePos)) {
if(child->propagateOnMouseEvent(mousePos, widgetList)) {
ret = true;
break;
}
}
}
}
if(clickedChild) {
// focusable child gains focus when clicked
if(clickedChild->isFocusable())
focusChild(clickedChild, Fw::MouseFocusReason);
// stop propagating if the child accept the event
if(clickedChild->propagateOnMousePress(mousePos, button))
return true;
}
// only non phatom widgets receives mouse events
if(!isPhantom())
return onMousePress(mousePos, button);
return false;
}
void UIWidget::propagateOnMouseRelease(const Point& mousePos, Fw::MouseButton button, UIWidgetList& widgetList)
{
// do a backup of children list, because it may change while looping it
for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
continue;
// mouse press events only go to children that contains the mouse position
if(child->containsPoint(mousePos) && child == getChildByPos(mousePos)) {
child->propagateOnMouseRelease(mousePos, button, widgetList);
break;
}
}
// only non phatom widgets receives mouse release events
if(!isPhantom())
widgetList.push_back(asUIWidget());
}
void UIWidget::propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved, UIWidgetList& widgetList)
{
for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
continue;
// mouse move events go to all children
child->propagateOnMouseMove(mousePos, mouseMoved, widgetList);
}
widgetList.push_back(asUIWidget());
if(!isPhantom())
ret = true;
return ret;
}
void UIWidget::propagateOnMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction, UIWidgetList& widgetList)
bool UIWidget::propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved, UIWidgetList& widgetList)
{
for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
continue;
// mouse wheel events only go to children that contains the mouse position
if(child->containsPoint(mousePos) && child == getChildByPos(mousePos))
child->propagateOnMouseWheel(mousePos, direction, widgetList);
for(auto it = m_children.begin(); it != m_children.end(); ++it) {
const UIWidgetPtr& child = *it;
if(child->isExplicitlyVisible() && child->isExplicitlyEnabled())
child->propagateOnMouseMove(mousePos, mouseMoved, widgetList);
}
widgetList.push_back(asUIWidget());
return true;
}

View File

@@ -201,10 +201,8 @@ protected:
bool propagateOnKeyDown(uchar keyCode, int keyboardModifiers);
bool propagateOnKeyPress(uchar keyCode, int keyboardModifiers, int autoRepeatTicks);
bool propagateOnKeyUp(uchar keyCode, int keyboardModifiers);
bool propagateOnMousePress(const Point& mousePos, Fw::MouseButton button);
void propagateOnMouseRelease(const Point& mousePos, Fw::MouseButton button, UIWidgetList& widgetList);
void propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved, UIWidgetList& widgetList);
void propagateOnMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction, UIWidgetList& widgetList);
bool propagateOnMouseEvent(const Point& mousePos, UIWidgetList& widgetList);
bool propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved, UIWidgetList& widgetList);
// function shortcuts