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

@@ -64,6 +64,7 @@ void UIManager::resize(const Size& size)
void UIManager::inputEvent(const InputEvent& event)
{
m_isOnInputEvent = true;
UIWidgetList widgetList;
switch(event.type) {
case Fw::KeyTextInputEvent:
m_keyboardReceiver->propagateOnKeyText(event.keyText);
@@ -78,41 +79,68 @@ void UIManager::inputEvent(const InputEvent& event)
m_keyboardReceiver->propagateOnKeyUp(event.keyCode, event.keyboardModifiers);
break;
case Fw::MousePressInputEvent:
m_mouseReceiver->propagateOnMousePress(event.mousePos, event.mouseButton);
if(event.mouseButton == Fw::MouseLeftButton && m_mouseReceiver->isVisible()) {
UIWidgetPtr pressedWidget = m_mouseReceiver->recursiveGetChildByPos(event.mousePos);
if(pressedWidget && !pressedWidget->isEnabled())
pressedWidget = nullptr;
updatePressedWidget(pressedWidget, event.mousePos);
}
m_mouseReceiver->propagateOnMousePress(event.mousePos, event.mouseButton);
break;
case Fw::MouseReleaseInputEvent: {
m_mouseReceiver->propagateOnMouseRelease(event.mousePos, event.mouseButton);
if(event.mouseButton == Fw::MouseLeftButton) {
// release pressed widget
if(m_pressedWidget)
updatePressedWidget(nullptr, event.mousePos);
// release dragging widget
bool accepted = false;
if(m_draggingWidget && event.mouseButton == Fw::MouseLeftButton)
accepted = updateDraggingWidget(nullptr, event.mousePos);
// release dragging widget
if(m_draggingWidget)
updateDraggingWidget(nullptr, event.mousePos);
if(!accepted) {
m_mouseReceiver->propagateOnMouseRelease(event.mousePos, event.mouseButton, widgetList);
// 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;
}
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)
updateDraggingWidget(m_pressedWidget, event.mousePos - event.mouseMoved);
if(m_draggingWidget)
m_draggingWidget->onDragMove(event.mousePos, event.mouseMoved);
// mouse move can change hovered widgets
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;
}
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;
default:
break;
@@ -120,58 +148,20 @@ void UIManager::inputEvent(const InputEvent& event)
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;
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;
// when releasing mouse inside pressed widget area send onClick event
if(oldPressedWidget && oldPressedWidget->isEnabled() && oldPressedWidget->containsPoint(clickedPos))
oldPressedWidget->onClick(clickedPos);
if(newPressedWidget)
newPressedWidget->updateState(Fw::PressedState);
if(oldPressedWidget)
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)
@@ -200,20 +190,53 @@ bool UIManager::updateDraggingWidget(const UIWidgetPtr& draggingWidget, const Po
if(draggingWidget->onDragEnter(clickedPos)) {
m_draggingWidget = draggingWidget;
draggingWidget->updateState(Fw::DraggingState);
accepted = true;
}
}
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)
{
updateHoveredWidget();
if(widget->containsPoint(g_window.getMousePosition()))
updateHoveredWidget();
}
void UIManager::onWidgetDisappear(const UIWidgetPtr& widget)
{
updateHoveredWidget();
if(widget->containsPoint(g_window.getMousePosition()))
updateHoveredWidget();
}
void UIManager::onWidgetDestroy(const UIWidgetPtr& widget)
@@ -233,10 +256,8 @@ void UIManager::onWidgetDestroy(const UIWidgetPtr& widget)
if(m_draggingWidget == widget)
updateDraggingWidget(nullptr);
}
void UIManager::addDestroyedWidget(const UIWidgetPtr& widget)
{
#ifdef DEBUG
static UIWidgetList destroyedWidgets;
static ScheduledEventPtr checkEvent;
@@ -258,6 +279,7 @@ void UIManager::addDestroyedWidget(const UIWidgetPtr& widget)
}
});
}, 1000);
#endif
}
bool UIManager::importStyle(const std::string& file)