void UIWidget::updateState(Fw::WidgetState state) { bool newStatus = true; bool oldStatus = hasState(state); bool updateChildren = false; switch(state) { case Fw::ActiveState: { UIWidgetPtr widget = asUIWidget(); UIWidgetPtr parent; do { parent = widget->getParent(); if(!widget->isExplicitlyEnabled() || ((parent && parent->getFocusedChild() != widget))) { newStatus = false; break; } } while(widget = parent); updateChildren = true; break; } case Fw::FocusState: { newStatus = (getParent() && getParent()->getFocusedChild() == asUIWidget()); break; } case Fw::HoverState: { updateChildren = true; Point mousePos = g_window.getMousePos(); UIWidgetPtr widget = asUIWidget(); UIWidgetPtr parent; do { parent = widget->getParent(); if(!widget->isExplicitlyEnabled() || !widget->isExplicitlyVisible() || !widget->containsPoint(mousePos) || (parent && widget != parent->getChildByPos(mousePos))) { newStatus = false; break; } } while(widget = parent); break; } case Fw::PressedState: { newStatus = m_pressed; break; } case Fw::DisabledState: { bool enabled = true; updateChildren = true; UIWidgetPtr widget = asUIWidget(); do { if(!widget->isExplicitlyEnabled()) { enabled = false; break; } } while(widget = widget->getParent()); newStatus = !enabled; break; } case Fw::FirstState: { newStatus = (getParent() && getParent()->getFirstChild() == asUIWidget()); break; } case Fw::MiddleState: { newStatus = (getParent() && getParent()->getFirstChild() != asUIWidget() && getParent()->getLastChild() != asUIWidget()); break; } case Fw::LastState: { newStatus = (getParent() && getParent()->getLastChild() == asUIWidget()); break; } case Fw::AlternateState: { newStatus = (getParent() && (getParent()->getChildIndex(asUIWidget()) % 2) == 1); break; } default: return; } if(updateChildren) { // do a backup of children list, because it may change while looping it UIWidgetList children = m_children; for(const UIWidgetPtr& child : children) child->updateState(state); } if(setState(state, newStatus)) { if(state == Fw::FocusState) { g_dispatcher.addEvent(std::bind(&UIWidget::onFocusChange, asUIWidget(), newStatus, m_lastFocusReason)); } else if(state == Fw::HoverState) g_dispatcher.addEvent(std::bind(&UIWidget::onHoverChange, asUIWidget(), newStatus)); } }