some rework in UIWidget input

This commit is contained in:
Eduardo Bart 2012-03-26 10:34:43 -03:00
parent 532e8e3e39
commit 9309d6e7f3
13 changed files with 139 additions and 132 deletions

View File

@ -22,13 +22,14 @@ MainWindow
margin-bottom: 5 margin-bottom: 5
padding: 1 padding: 1
focusable: false focusable: false
vertical-scrollbar: characterListScrollBar
VerticalScrollBar VerticalScrollBar
attached-to: characterList id: characterListScrollBar
anchors.top: characterList.top anchors.top: characterList.top
anchors.bottom: characterList.bottom anchors.bottom: characterList.bottom
anchors.right: characterList.right anchors.right: characterList.right
maximum: 0 step: 14
Label Label
id: accountStatusLabel id: accountStatusLabel

View File

@ -17,7 +17,7 @@ function Mouse.restoreCursor()
end end
function Mouse.isPressed() function Mouse.isPressed()
return g_ui.getPressedWidget() == nil return g_ui.getPressedWidget() ~= nil
end end
function Mouse.bindAutoPress(widget, callback) function Mouse.bindAutoPress(widget, callback)

View File

@ -33,7 +33,9 @@ function UIScrollArea:updateScrollBars()
if scrollbar then if scrollbar then
if self.inverted then if self.inverted then
scrollbar:setMinimum(-scrollheight) scrollbar:setMinimum(-scrollheight)
scrollbar:setMaximum(0)
else else
scrollbar:setMinimum(0)
scrollbar:setMaximum(scrollheight) scrollbar:setMaximum(scrollheight)
end end
end end
@ -50,10 +52,8 @@ end
function UIScrollArea:setVerticalScrollBar(scrollbar) function UIScrollArea:setVerticalScrollBar(scrollbar)
self.verticalScrollBar = scrollbar self.verticalScrollBar = scrollbar
scrollbar:setMaximum(0)
self.verticalScrollBar.onValueChange = function(scrollbar, value) self.verticalScrollBar.onValueChange = function(scrollbar, value)
local virtualOffset = self:getVirtualOffset() local virtualOffset = self:getVirtualOffset()
if self.inverted then value = -value end
virtualOffset.y = value virtualOffset.y = value
self:setVirtualOffset(virtualOffset) self:setVirtualOffset(virtualOffset)
end end
@ -72,3 +72,14 @@ end
function UIScrollArea:onLayoutUpdate() function UIScrollArea:onLayoutUpdate()
self:updateScrollBars() self:updateScrollBars()
end end
function UIScrollArea:onMouseWheel(mousePos, mouseWheel)
if self.verticalScrollBar then
if mouseWheel == MouseWheelUp then
self.verticalScrollBar:decrement()
else
self.verticalScrollBar:increment()
end
end
return true
end

View File

@ -22,7 +22,7 @@ local function calcValues(self)
local px = math.max(math.floor(proportion * pxrange), 10) local px = math.max(math.floor(proportion * pxrange), 10)
local offset = 0 local offset = 0
if range > 1 then if range > 1 then
offset = (((self.value - self.minimum) / (range - 1)) - 0.5) * (pxrange - px) offset = math.ceil((((self.value - self.minimum) / (range - 1)) - 0.5) * (pxrange - px))
end end
return range, pxrange, px, offset, center return range, pxrange, px, offset, center
@ -153,6 +153,15 @@ function UIScrollBar:onGeometryChange()
updateSlider(self) updateSlider(self)
end end
function UIScrollBar:onMouseWheel(mousePos, mouseWheel)
if mouseWheel == MouseWheelUp then
self:decrement()
else
self:increment()
end
return true
end
function UIScrollBar:getMaximum() return self.maximum end function UIScrollBar:getMaximum() return self.maximum end
function UIScrollBar:getMinimum() return self.minimum end function UIScrollBar:getMinimum() return self.minimum end
function UIScrollBar:getValue() return self.value end function UIScrollBar:getValue() return self.value end

View File

@ -46,7 +46,6 @@ function UISplitter:onMouseRelease(mousePos, mouseButton)
if not self:isHovered() then if not self:isHovered() then
Mouse.restoreCursor() Mouse.restoreCursor()
end end
self:ungrabMouse()
end end
function UISplitter:onStyleApply(styleName, styleNode) function UISplitter:onStyleApply(styleName, styleNode)

View File

@ -215,10 +215,6 @@ function Console.terminate()
Console = nil Console = nil
end end
function Console.debug()
print(#channels)
end
function Console.clear() function Console.clear()
for channelid, channelname in pairs(channels) do for channelid, channelname in pairs(channels) do
if channelid ~= 0 then if channelid ~= 0 then

View File

@ -12,7 +12,6 @@ ConsoleTabBarPanel < TabBarPanel
ScrollablePanel ScrollablePanel
id: consoleBuffer id: consoleBuffer
// height = max lines * 14
anchors.fill: parent anchors.fill: parent
margin-right: 12 margin-right: 12
vertical-scrollbar: consoleScrollBar vertical-scrollbar: consoleScrollBar

View File

@ -70,7 +70,7 @@ void UIHorizontalLayout::internalUpdate()
pos.y = clippingRect.top() + (clippingRect.height() - size.height())/2; pos.y = clippingRect.top() + (clippingRect.height() - size.height())/2;
} }
widget->setRect(Rect(pos + parentWidget->getVirtualOffset(), size)); widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size));
gap = (m_alignRight) ? -widget->getMarginLeft() : (widget->getWidth() + widget->getMarginRight()); gap = (m_alignRight) ? -widget->getMarginLeft() : (widget->getWidth() + widget->getMarginRight());
gap += m_spacing; gap += m_spacing;

View File

@ -64,6 +64,7 @@ void UIManager::resize(const Size& size)
void UIManager::inputEvent(const InputEvent& event) void UIManager::inputEvent(const InputEvent& event)
{ {
m_isOnInputEvent = true; m_isOnInputEvent = true;
UIWidgetList widgetList;
switch(event.type) { switch(event.type) {
case Fw::KeyTextInputEvent: case Fw::KeyTextInputEvent:
m_keyboardReceiver->propagateOnKeyText(event.keyText); m_keyboardReceiver->propagateOnKeyText(event.keyText);
@ -78,41 +79,68 @@ void UIManager::inputEvent(const InputEvent& event)
m_keyboardReceiver->propagateOnKeyUp(event.keyCode, event.keyboardModifiers); m_keyboardReceiver->propagateOnKeyUp(event.keyCode, event.keyboardModifiers);
break; break;
case Fw::MousePressInputEvent: case Fw::MousePressInputEvent:
m_mouseReceiver->propagateOnMousePress(event.mousePos, event.mouseButton);
if(event.mouseButton == Fw::MouseLeftButton && m_mouseReceiver->isVisible()) { if(event.mouseButton == Fw::MouseLeftButton && m_mouseReceiver->isVisible()) {
UIWidgetPtr pressedWidget = m_mouseReceiver->recursiveGetChildByPos(event.mousePos); UIWidgetPtr pressedWidget = m_mouseReceiver->recursiveGetChildByPos(event.mousePos);
if(pressedWidget && !pressedWidget->isEnabled()) if(pressedWidget && !pressedWidget->isEnabled())
pressedWidget = nullptr; pressedWidget = nullptr;
updatePressedWidget(pressedWidget, event.mousePos); updatePressedWidget(pressedWidget, event.mousePos);
} }
m_mouseReceiver->propagateOnMousePress(event.mousePos, event.mouseButton);
break; break;
case Fw::MouseReleaseInputEvent: { case Fw::MouseReleaseInputEvent: {
m_mouseReceiver->propagateOnMouseRelease(event.mousePos, event.mouseButton); // release dragging widget
if(event.mouseButton == Fw::MouseLeftButton) { bool accepted = false;
// release pressed widget if(m_draggingWidget && event.mouseButton == Fw::MouseLeftButton)
if(m_pressedWidget) accepted = updateDraggingWidget(nullptr, event.mousePos);
updatePressedWidget(nullptr, event.mousePos);
// release dragging widget if(!accepted) {
if(m_draggingWidget) m_mouseReceiver->propagateOnMouseRelease(event.mousePos, event.mouseButton, widgetList);
updateDraggingWidget(nullptr, event.mousePos);
// mouse release is always fired first on the pressed widget
if(m_pressedWidget) {
auto it = std::find(widgetList.begin(), widgetList.end(), m_pressedWidget);
if(it != widgetList.end())
widgetList.erase(it);
widgetList.push_front(m_pressedWidget);
}
for(const UIWidgetPtr& widget : widgetList) {
if(widget->onMouseRelease(event.mousePos, event.mouseButton))
break;
}
} }
if(m_pressedWidget && event.mouseButton == Fw::MouseLeftButton)
updatePressedWidget(nullptr, event.mousePos);
break; break;
} }
case Fw::MouseMoveInputEvent: { case Fw::MouseMoveInputEvent: {
// start dragging when moves a pressed widget // start dragging when moving a pressed widget
if(m_pressedWidget && m_pressedWidget->isDragable() && m_draggingWidget != m_pressedWidget) if(m_pressedWidget && m_pressedWidget->isDragable() && m_draggingWidget != m_pressedWidget)
updateDraggingWidget(m_pressedWidget, event.mousePos - event.mouseMoved); updateDraggingWidget(m_pressedWidget, event.mousePos - event.mouseMoved);
if(m_draggingWidget) // mouse move can change hovered widgets
m_draggingWidget->onDragMove(event.mousePos, event.mouseMoved);
updateHoveredWidget(); updateHoveredWidget();
m_mouseReceiver->propagateOnMouseMove(event.mousePos, event.mouseMoved);
// first fire dragging move
if(m_draggingWidget) {
if(m_draggingWidget->onDragMove(event.mousePos, event.mouseMoved))
break;
}
m_mouseReceiver->propagateOnMouseMove(event.mousePos, event.mouseMoved, widgetList);
for(const UIWidgetPtr& widget : widgetList) {
if(widget->onMouseMove(event.mousePos, event.mouseMoved))
break;
}
break; break;
} }
case Fw::MouseWheelInputEvent: case Fw::MouseWheelInputEvent:
m_mouseReceiver->propagateOnMouseWheel(event.mousePos, event.wheelDirection); m_mouseReceiver->propagateOnMouseWheel(event.mousePos, event.wheelDirection, widgetList);
for(const UIWidgetPtr& widget : widgetList) {
if(widget->onMouseWheel(event.mousePos, event.wheelDirection))
break;
}
break; break;
default: default:
break; break;
@ -120,58 +148,20 @@ void UIManager::inputEvent(const InputEvent& event)
m_isOnInputEvent = false; m_isOnInputEvent = false;
} }
bool UIManager::updatePressedWidget(const UIWidgetPtr& newPressedWidget, const Point& clickedPos) void UIManager::updatePressedWidget(const UIWidgetPtr& newPressedWidget, const Point& clickedPos)
{ {
bool accepted = false;
UIWidgetPtr oldPressedWidget = m_pressedWidget; UIWidgetPtr oldPressedWidget = m_pressedWidget;
if(oldPressedWidget) {
if(oldPressedWidget->isEnabled()) {
// when releasing mouse inside pressed widget area send onClick event
if(!clickedPos.isNull() && oldPressedWidget->containsPoint(clickedPos)) {
// onMouseRelease will be already fired by mouseReceiver
accepted = oldPressedWidget->onClick(clickedPos);
// must send mouse events even if the mouse is outside widget area when releasing a pressed widget
} else
accepted = oldPressedWidget->onMouseRelease(clickedPos, Fw::MouseLeftButton);
}
}
m_pressedWidget = newPressedWidget; m_pressedWidget = newPressedWidget;
// when releasing mouse inside pressed widget area send onClick event
if(oldPressedWidget && oldPressedWidget->isEnabled() && oldPressedWidget->containsPoint(clickedPos))
oldPressedWidget->onClick(clickedPos);
if(newPressedWidget) if(newPressedWidget)
newPressedWidget->updateState(Fw::PressedState); newPressedWidget->updateState(Fw::PressedState);
if(oldPressedWidget) if(oldPressedWidget)
oldPressedWidget->updateState(Fw::PressedState); oldPressedWidget->updateState(Fw::PressedState);
return accepted;
}
void UIManager::updateHoveredWidget()
{
if(m_hoverUpdateScheduled)
return;
g_eventDispatcher.addEvent([this] {
if(!m_rootWidget)
return;
m_hoverUpdateScheduled = false;
UIWidgetPtr hoveredWidget = m_rootWidget->recursiveGetChildByPos(g_window.getMousePosition());
if(hoveredWidget && !hoveredWidget->isEnabled())
hoveredWidget = nullptr;
if(hoveredWidget != m_hoveredWidget) {
UIWidgetPtr oldHovered = m_hoveredWidget;
m_hoveredWidget = hoveredWidget;
if(oldHovered)
oldHovered->updateState(Fw::HoverState);
if(hoveredWidget)
hoveredWidget->updateState(Fw::HoverState);
}
});
m_hoverUpdateScheduled = true;
} }
bool UIManager::updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Point& clickedPos) bool UIManager::updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Point& clickedPos)
@ -200,20 +190,53 @@ bool UIManager::updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Po
if(draggingWidget->onDragEnter(clickedPos)) { if(draggingWidget->onDragEnter(clickedPos)) {
m_draggingWidget = draggingWidget; m_draggingWidget = draggingWidget;
draggingWidget->updateState(Fw::DraggingState); draggingWidget->updateState(Fw::DraggingState);
accepted = true;
} }
} }
return accepted; return accepted;
} }
void UIManager::updateHoveredWidget()
{
if(m_hoverUpdateScheduled)
return;
g_eventDispatcher.addEvent([this] {
if(!m_rootWidget)
return;
m_hoverUpdateScheduled = false;
UIWidgetPtr hoveredWidget = m_rootWidget->recursiveGetChildByPos(g_window.getMousePosition());
if(hoveredWidget && !hoveredWidget->isEnabled())
hoveredWidget = nullptr;
if(hoveredWidget != m_hoveredWidget) {
UIWidgetPtr oldHovered = m_hoveredWidget;
m_hoveredWidget = hoveredWidget;
if(oldHovered) {
oldHovered->updateState(Fw::HoverState);
oldHovered->onHoverChange(false);
}
if(hoveredWidget) {
hoveredWidget->updateState(Fw::HoverState);
hoveredWidget->onHoverChange(true);
}
}
});
m_hoverUpdateScheduled = true;
}
void UIManager::onWidgetAppear(const UIWidgetPtr& widget) void UIManager::onWidgetAppear(const UIWidgetPtr& widget)
{ {
updateHoveredWidget(); if(widget->containsPoint(g_window.getMousePosition()))
updateHoveredWidget();
} }
void UIManager::onWidgetDisappear(const UIWidgetPtr& widget) void UIManager::onWidgetDisappear(const UIWidgetPtr& widget)
{ {
updateHoveredWidget(); if(widget->containsPoint(g_window.getMousePosition()))
updateHoveredWidget();
} }
void UIManager::onWidgetDestroy(const UIWidgetPtr& widget) void UIManager::onWidgetDestroy(const UIWidgetPtr& widget)
@ -233,10 +256,8 @@ void UIManager::onWidgetDestroy(const UIWidgetPtr& widget)
if(m_draggingWidget == widget) if(m_draggingWidget == widget)
updateDraggingWidget(nullptr); updateDraggingWidget(nullptr);
}
void UIManager::addDestroyedWidget(const UIWidgetPtr& widget) #ifdef DEBUG
{
static UIWidgetList destroyedWidgets; static UIWidgetList destroyedWidgets;
static ScheduledEventPtr checkEvent; static ScheduledEventPtr checkEvent;
@ -258,6 +279,7 @@ void UIManager::addDestroyedWidget(const UIWidgetPtr& widget)
} }
}); });
}, 1000); }, 1000);
#endif
} }
bool UIManager::importStyle(const std::string& file) bool UIManager::importStyle(const std::string& file)

View File

@ -37,9 +37,9 @@ public:
void resize(const Size& size); void resize(const Size& size);
void inputEvent(const InputEvent& event); void inputEvent(const InputEvent& event);
bool updatePressedWidget(const UIWidgetPtr& newPressedWidget, const Point& clickedPos = Point()); void updatePressedWidget(const UIWidgetPtr& newPressedWidget, const Point& clickedPos = Point());
void updateHoveredWidget();
bool updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Point& clickedPos = Point()); bool updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Point& clickedPos = Point());
void updateHoveredWidget();
bool importStyle(const std::string& file); bool importStyle(const std::string& file);
void importStyleFromOTML(const OTMLNodePtr& styleNode); void importStyleFromOTML(const OTMLNodePtr& styleNode);
@ -69,7 +69,6 @@ protected:
void onWidgetAppear(const UIWidgetPtr& widget); void onWidgetAppear(const UIWidgetPtr& widget);
void onWidgetDisappear(const UIWidgetPtr& widget); void onWidgetDisappear(const UIWidgetPtr& widget);
void onWidgetDestroy(const UIWidgetPtr& widget); void onWidgetDestroy(const UIWidgetPtr& widget);
void addDestroyedWidget(const UIWidgetPtr& widget);
friend class UIWidget; friend class UIWidget;

View File

@ -70,7 +70,7 @@ void UIVerticalLayout::internalUpdate()
pos.x = clippingRect.left() + (clippingRect.width() - size.width())/2; pos.x = clippingRect.left() + (clippingRect.width() - size.width())/2;
} }
widget->setRect(Rect(pos + parentWidget->getVirtualOffset(), size)); widget->setRect(Rect(pos - parentWidget->getVirtualOffset(), size));
gap = (m_alignBottom) ? -widget->getMarginTop() : (widget->getHeight() + widget->getMarginBottom()); gap = (m_alignBottom) ? -widget->getMarginTop() : (widget->getHeight() + widget->getMarginBottom());
gap += m_spacing; gap += m_spacing;

View File

@ -244,12 +244,16 @@ void UIWidget::focusChild(const UIWidgetPtr& child, Fw::FocusReason reason)
child->setLastFocusReason(reason); child->setLastFocusReason(reason);
child->updateState(Fw::FocusState); child->updateState(Fw::FocusState);
child->updateState(Fw::ActiveState); child->updateState(Fw::ActiveState);
g_eventDispatcher.addEvent(std::bind(&UIWidget::onFocusChange, child, true, reason));
} }
if(oldFocused) { if(oldFocused) {
oldFocused->setLastFocusReason(reason); oldFocused->setLastFocusReason(reason);
oldFocused->updateState(Fw::FocusState); oldFocused->updateState(Fw::FocusState);
oldFocused->updateState(Fw::ActiveState); oldFocused->updateState(Fw::ActiveState);
g_eventDispatcher.addEvent(std::bind(&UIWidget::onFocusChange, oldFocused, false, reason));
} }
onChildFocusChange(child, oldFocused, reason); onChildFocusChange(child, oldFocused, reason);
@ -647,8 +651,6 @@ void UIWidget::destroy()
setVisible(false); setVisible(false);
setEnabled(false); setEnabled(false);
g_ui.onWidgetDestroy(asUIWidget());
// remove itself from parent // remove itself from parent
if(UIWidgetPtr parent = getParent()) if(UIWidgetPtr parent = getParent())
parent->removeChild(asUIWidget()); parent->removeChild(asUIWidget());
@ -660,9 +662,7 @@ void UIWidget::destroy()
releaseLuaFieldsTable(); releaseLuaFieldsTable();
#ifdef DEBUG g_ui.onWidgetDestroy(asUIWidget());
g_ui.addDestroyedWidget(asUIWidget());
#endif
} }
void UIWidget::destroyChildren() void UIWidget::destroyChildren()
@ -781,7 +781,6 @@ void UIWidget::setEnabled(bool enabled)
updateState(Fw::DisabledState); updateState(Fw::DisabledState);
updateState(Fw::ActiveState); updateState(Fw::ActiveState);
updateState(Fw::HoverState);
} }
} }
@ -1090,7 +1089,6 @@ void UIWidget::updateState(Fw::WidgetState state)
break; break;
} }
case Fw::HoverState: { case Fw::HoverState: {
updateChildren = true;
newStatus = (g_ui.getHoveredWidget() == asUIWidget() && isEnabled()); newStatus = (g_ui.getHoveredWidget() == asUIWidget() && isEnabled());
break; break;
} }
@ -1143,10 +1141,10 @@ void UIWidget::updateState(Fw::WidgetState state)
} }
if(setState(state, newStatus)) { if(setState(state, newStatus)) {
if(state == Fw::FocusState) { // disabled widgets cannot have hover state
g_eventDispatcher.addEvent(std::bind(&UIWidget::onFocusChange, asUIWidget(), newStatus, m_lastFocusReason)); if(state == Fw::DisabledState && !newStatus && isHovered()) {
} else if(state == Fw::HoverState) g_ui.updateHoveredWidget();
g_eventDispatcher.addEvent(std::bind(&UIWidget::onHoverChange, asUIWidget(), newStatus)); }
} }
} }
@ -1288,7 +1286,7 @@ bool UIWidget::onDragLeave(UIWidgetPtr droppedWidget, const Point& mousePos)
bool UIWidget::onDragMove(const Point& mousePos, const Point& mouseMoved) bool UIWidget::onDragMove(const Point& mousePos, const Point& mouseMoved)
{ {
return callLuaField("onDragMove", mousePos, mouseMoved); return callLuaField<bool>("onDragMove", mousePos, mouseMoved);
} }
bool UIWidget::onDrop(UIWidgetPtr draggedWidget, const Point& mousePos) bool UIWidget::onDrop(UIWidgetPtr draggedWidget, const Point& mousePos)
@ -1489,10 +1487,9 @@ bool UIWidget::propagateOnMousePress(const Point& mousePos, Fw::MouseButton butt
return false; return false;
} }
bool UIWidget::propagateOnMouseRelease(const Point& mousePos, Fw::MouseButton button) void UIWidget::propagateOnMouseRelease(const Point& mousePos, Fw::MouseButton button, UIWidgetList& widgetList)
{ {
// do a backup of children list, because it may change while looping it // do a backup of children list, because it may change while looping it
UIWidgetPtr clickedChild;
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded // events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
@ -1500,48 +1497,31 @@ bool UIWidget::propagateOnMouseRelease(const Point& mousePos, Fw::MouseButton bu
// mouse press events only go to children that contains the mouse position // mouse press events only go to children that contains the mouse position
if(child->containsPoint(mousePos) && child == getChildByPos(mousePos)) { if(child->containsPoint(mousePos) && child == getChildByPos(mousePos)) {
clickedChild = child; child->propagateOnMouseRelease(mousePos, button, widgetList);
break; break;
} }
} }
if(clickedChild) { // only non phatom widgets receives mouse release events
if(clickedChild->propagateOnMouseRelease(mousePos, button))
return true;
}
// only non phatom widgets receives mouse events
if(!isPhantom()) if(!isPhantom())
return onMouseRelease(mousePos, button); widgetList.push_back(asUIWidget());
return false;
} }
bool UIWidget::propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved) void UIWidget::propagateOnMouseMove(const Point& mousePos, const Point& mouseMoved, UIWidgetList& widgetList)
{ {
// do a backup of children list, because it may change while looping it
UIWidgetList children;
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded // events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
continue; continue;
// mouse move events go to all children // mouse move events go to all children
children.push_back(child); child->propagateOnMouseMove(mousePos, mouseMoved, widgetList);
} }
widgetList.push_back(asUIWidget());
for(const UIWidgetPtr& child : children) {
if(child->propagateOnMouseMove(mousePos, mouseMoved))
return true;
}
return onMouseMove(mousePos, mouseMoved);
} }
bool UIWidget::propagateOnMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction) void UIWidget::propagateOnMouseWheel(const Point& mousePos, Fw::MouseWheelDirection direction, UIWidgetList& widgetList)
{ {
// do a backup of children list, because it may change while looping it
UIWidgetList children;
for(const UIWidgetPtr& child : m_children) { for(const UIWidgetPtr& child : m_children) {
// events on hidden or disabled widgets are discarded // events on hidden or disabled widgets are discarded
if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible()) if(!child->isExplicitlyEnabled() || !child->isExplicitlyVisible())
@ -1549,17 +1529,8 @@ bool UIWidget::propagateOnMouseWheel(const Point& mousePos, Fw::MouseWheelDirect
// mouse wheel events only go to children that contains the mouse position // mouse wheel events only go to children that contains the mouse position
if(child->containsPoint(mousePos) && child == getChildByPos(mousePos)) if(child->containsPoint(mousePos) && child == getChildByPos(mousePos))
children.push_back(child); child->propagateOnMouseWheel(mousePos, direction, widgetList);
} }
for(const UIWidgetPtr& child : children) { widgetList.push_back(asUIWidget());
if(child->propagateOnMouseWheel(mousePos, direction))
return true;
}
// only non phatom widgets receives mouse events
if(!isPhantom())
return onMouseWheel(mousePos, direction);
else
return false;
} }

View File

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