void UIWidget::updateState(Fw::WidgetState state) { if(m_destroyed) return; bool newStatus = true; bool oldStatus = hasState(state); bool updateChildren = false; switch(state) { case Fw::ActiveState: { UIWidgetPtr widget = static_self_cast<UIWidget>(); UIWidgetPtr parent; do { parent = widget->getParent(); if(!widget->isExplicitlyEnabled() || ((parent && parent->getFocusedChild() != widget))) { newStatus = false; break; } } while((widget = parent)); updateChildren = newStatus != oldStatus; break; } case Fw::FocusState: { newStatus = (getParent() && getParent()->getFocusedChild() == static_self_cast<UIWidget>()); break; } case Fw::HoverState: { newStatus = (g_ui.getHoveredWidget() == static_self_cast<UIWidget>() && isEnabled()); break; } case Fw::PressedState: { newStatus = (g_ui.getPressedWidget() == static_self_cast<UIWidget>()); break; } case Fw::DraggingState: { newStatus = (g_ui.getDraggingWidget() == static_self_cast<UIWidget>()); break; } case Fw::DisabledState: { bool enabled = true; UIWidgetPtr widget = static_self_cast<UIWidget>(); do { if(!widget->isExplicitlyEnabled()) { enabled = false; break; } } while((widget = widget->getParent())); newStatus = !enabled; updateChildren = newStatus != oldStatus; break; } case Fw::FirstState: { newStatus = (getParent() && getParent()->getFirstChild() == static_self_cast<UIWidget>()); break; } case Fw::MiddleState: { newStatus = (getParent() && getParent()->getFirstChild() != static_self_cast<UIWidget>() && getParent()->getLastChild() != static_self_cast<UIWidget>()); break; } case Fw::LastState: { newStatus = (getParent() && getParent()->getLastChild() == static_self_cast<UIWidget>()); break; } case Fw::AlternateState: { newStatus = (getParent() && (getParent()->getChildIndex(static_self_cast<UIWidget>()) % 2) == 1); break; } case Fw::HiddenState: { bool visible = true; UIWidgetPtr widget = static_self_cast<UIWidget>(); do { if(!widget->isExplicitlyVisible()) { visible = false; break; } } while((widget = widget->getParent())); newStatus = !visible; updateChildren = newStatus != oldStatus; 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)) { // disabled widgets cannot have hover state if(state == Fw::DisabledState && !newStatus && isHovered()) { g_ui.updateHoveredWidget(); } else if(state == Fw::HiddenState) { onVisibilityChange(!newStatus); } } }
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)); } }