//----------------------------------------------------------------------------- // Purpose: Calculates which panel the cursor is currently over and sets it up // as the current mouse focus. //----------------------------------------------------------------------------- void CInputWin32::UpdateMouseFocus(int x, int y) { // find the panel that has the focus VPanel *focus = NULL; InputContext_t *pContext = GetInputContext( m_hContext ); if (!pContext->_rootPanel) { if (surface()->IsCursorVisible() && surface()->IsWithin(x, y)) { // faster version of code below // checks through each popup in order, top to bottom windows for (int i = surface()->GetPopupCount() - 1; i >= 0; i--) { VPanel *popup = (VPanel *)surface()->GetPopup(i); VPanel *panel = popup; bool wantsMouse = panel->IsMouseInputEnabled(); bool isVisible; do { isVisible = panel->IsVisible(); panel = panel->GetParent(); } while ( isVisible && panel && panel->GetParent() ); // only consider panels that want mouse input if ( wantsMouse && isVisible ) { focus = (VPanel *)popup->Client()->IsWithinTraverse(x, y, false); if (focus) break; } } if (!focus) { focus = (VPanel *)((VPanel *)surface()->GetEmbeddedPanel())->Client()->IsWithinTraverse(x, y, false); } } } else { focus = (VPanel *)((VPanel *)(pContext->_rootPanel))->Client()->IsWithinTraverse(x, y, false); } // mouse focus debugging code /* static VPanel *oldFocus = (VPanel *)0x0001; if (oldFocus != focus) { oldFocus = focus; if (focus) { ivgui()->DPrintf2("mouse over: (%s, %s)\n", focus->GetName(), focus->GetClassName()); } else { ivgui()->DPrintf2("mouse over: (NULL)\n"); } } */ // check if we are in modal state, // and if we are make sure this panel is a child of us. if (!IsChildOfModalPanel((VPANEL)focus)) { // should this be _appModalPanel? focus = NULL; } SetMouseFocus((VPANEL)focus); }
//----------------------------------------------------------------------------- // Purpose: Sets the new mouse focus // won't override _mouseCapture settings // Input : newMouseFocus - //----------------------------------------------------------------------------- void CInputWin32::SetMouseFocus(VPANEL newMouseFocus) { // check if we are in modal state, // and if we are make sure this panel is a child of us. if (!IsChildOfModalPanel(newMouseFocus)) { return; } bool wantsMouse, isPopup; // = popup->GetMouseInput(); VPanel *panel = (VPanel *)newMouseFocus; InputContext_t *pContext = GetInputContext( m_hContext ); if ( newMouseFocus ) { do { wantsMouse = panel->IsMouseInputEnabled(); isPopup = panel->IsPopup(); panel = panel->GetParent(); } while ( wantsMouse && !isPopup && panel && panel->GetParent() ); // only consider panels that want mouse input } // if this panel doesn't want mouse input don't let it get focus if (newMouseFocus && !wantsMouse) { return; } if ((VPANEL)pContext->_mouseOver != newMouseFocus || (!pContext->_mouseCapture && (VPANEL)pContext->_mouseFocus != newMouseFocus) ) { pContext->_oldMouseFocus = pContext->_mouseOver; pContext->_mouseOver = (VPanel *)newMouseFocus; //tell the old panel with the mouseFocus that the cursor exited if (pContext->_oldMouseFocus != NULL) { // only notify of entry if the mouse is not captured or we're a child of the captured panel if ( !pContext->_mouseCapture || pContext->_oldMouseFocus->HasParent(pContext->_mouseCapture) ) { ivgui()->PostMessage((VPANEL)pContext->_oldMouseFocus, new KeyValues("CursorExited"), NULL); } } //tell the new panel with the mouseFocus that the cursor entered if (pContext->_mouseOver != NULL) { // only notify of entry if the mouse is not captured or we're a child of the captured panel if ( !pContext->_mouseCapture || pContext->_mouseOver->HasParent(pContext->_mouseCapture) ) { ivgui()->PostMessage((VPANEL)pContext->_mouseOver, new KeyValues("CursorEntered"), NULL); } } // set where the mouse is currently over // mouse capture overrides destination if ( pContext->_mouseCapture ) { pContext->_mouseFocus = pContext->_mouseCapture; } else { pContext->_mouseFocus = pContext->_mouseOver; } } }