void EventDispatcher::DispatchMouseOverOut(Widget *target, const Point &mousePos) { // do over/out handling for wherever the mouse is right now if (target != m_lastMouseOverTarget.Get() || target->IsDisabled()) { if (m_lastMouseOverTarget) { // if we're switching from float to non-float then we need to force the out event, even if the mouse is still over the last target. // only the base widget of a floating stack is marked floating, so walk up to find it // XXX this is doing too much work. should we flag this on the widget somewhere? Widget *targetBase = target; while (!targetBase->IsFloating() && targetBase->GetContainer()) targetBase = targetBase->GetContainer(); Widget *lastTargetBase = m_lastMouseOverTarget.Get(); while (!lastTargetBase->IsFloating() && lastTargetBase->GetContainer()) lastTargetBase = lastTargetBase->GetContainer(); // if we're moving from float->non-float or non-float->float, // or the two targets don't have the same base (eg one just got // removed from the context in whole ui switch) // force the out event on the last target by reporting a position // that is by definition outside itself const Point outPos = (targetBase->IsFloating() != lastTargetBase->IsFloating() || targetBase != lastTargetBase) ? Point(-INT_MAX) : mousePos-m_lastMouseOverTarget->GetAbsolutePosition(); m_lastMouseOverTarget->TriggerMouseOut(outPos); } if (target->IsDisabled()) m_lastMouseOverTarget.Reset(0); else { m_lastMouseOverTarget.Reset(target); m_lastMouseOverTarget->TriggerMouseOver(mousePos-m_lastMouseOverTarget->GetAbsolutePosition()); } } }
bool Widget::IsOnTopLayer() const { const Layer *topLayer = GetContext()->GetTopLayer(); Widget *scan = GetContainer(); while (scan) { if (scan == topLayer) return true; scan = scan->GetContainer(); } return false; }