Beispiel #1
0
//-----------------------------------------------------------------------------
// Purpose: Called whenever a panel is constructed
//-----------------------------------------------------------------------------
void CVGui::PanelCreated(VPanel *panel)
{
	UtlHandle_t h = m_HandleTable.AddHandle();
	m_HandleTable.SetHandle( h, panel );

#if DUMP_PANEL_LIST
	int nCount = m_HandleTable.GetHandleCount();
	int nActualCount = 0;
	for ( int i = 0; i < nCount; ++i )
	{
		UtlHandle_t h = m_HandleTable.GetHandleFromIndex( i );
		if ( m_HandleTable.IsHandleValid( h ) )
		{
			++nActualCount;
		}
	}

	if ( nActualCount >= WARN_PANEL_NUMBER )
	{
		FILE *file1 = fopen("panellist.txt", "w");
		if (file1 != NULL)
		{
			fprintf(file1, "Too many panels...listing them all.\n");
			int panelIndex;
			for (panelIndex = 0; panelIndex < nCount; ++panelIndex)
			{
				UtlHandle_t h = m_HandleTable.GetHandleFromIndex( i );
				VPanel *pPanel = m_HandleTable.GetHandle( h );
				IClientPanel *ipanel = ( pPanel ) ? pPanel->Client() : NULL;
				if ( ipanel )
					fprintf(file1, "panel %d: name: %s   classname: %s\n", panelIndex, ipanel->GetName(), ipanel->GetClassName());
				else
					fprintf(file1, "panel %d: can't get ipanel\n", panelIndex);
			}

			fclose(file1);
		}
	}

	Assert( nActualCount < WARN_PANEL_NUMBER );
#endif // DUMP_PANEL_LIST

	((VPanel *)panel)->SetHPanel( h );

	g_pSurface->AddPanel((VPANEL)panel);
}
//-----------------------------------------------------------------------------
// Purpose: Calculate the new key focus
//-----------------------------------------------------------------------------
VPanel *CInputWin32::CalculateNewKeyFocus()
{
	InputContext_t *pContext = GetInputContext(m_hContext);

	// get the top-order panel
	VPanel *top = NULL;
	VPanel *wantedKeyFocus = NULL;

	if (!pContext->_rootPanel)
	{
		if (surface()->GetPopupCount() > 0)
		{
			// find the highest-level window that is both visible and a popup
			int index = surface()->GetPopupCount();
			
			while (index)
			{
				
				top = (VPanel *)surface()->GetPopup(--index);

				// traverse the heirachy and check if the popup really is visible
				if (top->IsPopup() && top->IsVisible() && top->IsKeyBoardInputEnabled() && !surface()->IsMinimized((VPANEL)top))
				{
					bool IsVisible = top->IsVisible();
					VPanel *p = top->GetParent();
					// drill down the heirachy checking that everything is visible
					while(p && IsVisible)
					{
						if( p->IsVisible()==false)
						{
							IsVisible=false;
							break;
						}
						p=p->GetParent();
					}

					if (IsVisible && !surface()->IsMinimized((VPANEL)top) )
					{
						break;
					}
				}
				
				top = NULL;
			} 
		}
	}
	else
	{
		top = (VPanel *)pContext->_rootPanel;
	}

	if (top)
	{
		// ask the top-level panel for what it considers to be the current focus
		wantedKeyFocus = (VPanel *)top->Client()->GetCurrentKeyFocus();
		if (!wantedKeyFocus)
		{
			wantedKeyFocus = top;

		}
	}

	// check to see if any of this surfaces panels have the focus
	if (!surface()->HasFocus())
	{
		wantedKeyFocus=NULL;
	}

	// check if we are in modal state, 
	// and if we are make sure this panel is a child of us.
	if (!IsChildOfModalPanel((VPANEL)wantedKeyFocus))
	{	
		wantedKeyFocus=NULL;
	}

	return wantedKeyFocus;
}
//-----------------------------------------------------------------------------
// 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: 
//-----------------------------------------------------------------------------
void CInputWin32::RunFrame()
{
	InputContext_t *pContext = GetInputContext(m_hContext);

	if (m_hContext == DEFAULT_INPUT_CONTEXT)
	{
		_updateToggleButtonState = true;

	/*	FIXME: add the set cursor call?
		// make sure the cursor looks like it is supposed to
		if (pContext->_mouseFocus)
		{
			pContext->_mouseFocus->Client()->InternalSetCursor();
		}*/
	}


	// tick whoever has the focus
	if (pContext->_keyFocus)
	{
		// when modal dialogs are up messages only get sent to the dialogs children.
		if (IsChildOfModalPanel((VPANEL)pContext->_keyFocus))
		{	
			ivgui()->PostMessage((VPANEL)pContext->_keyFocus, new KeyValues("KeyFocusTicked"), NULL);
		}
	}

	// tick whoever has the focus
	if (pContext->_mouseFocus)
	{
		// when modal dialogs are up messages only get sent to the dialogs children.
		if (IsChildOfModalPanel((VPANEL)pContext->_mouseFocus))
		{	
			ivgui()->PostMessage((VPANEL)pContext->_mouseFocus, new KeyValues("MouseFocusTicked"), NULL);
		}
	}

	//clear mouse and key states
	for (int i = 0; i < MOUSE_LAST; i++)
	{
		pContext->_mousePressed[i] = 0;
		pContext->_mouseDoublePressed[i] = 0;
		pContext->_mouseReleased[i] = 0;
	}
	for (i = 0; i < KEY_LAST; i++)
	{
		pContext->_keyPressed[i] = 0;
		pContext->_keyTyped[i] = 0;
		pContext->_keyReleased[i] = 0;
	}

	VPanel *wantedKeyFocus = CalculateNewKeyFocus();

	// make sure old and new focus get painted
	if (pContext->_keyFocus != wantedKeyFocus)
	{
		if (pContext->_keyFocus != NULL)
		{
			pContext->_keyFocus->Client()->InternalFocusChanged(true);

			// send a message to the window saying that it's losing focus
			ivgui()->PostMessage((VPANEL)pContext->_keyFocus, new KeyValues("KillFocus"), NULL);

			pContext->_keyFocus->Client()->Repaint();

			// repaint the nearest popup as well, since it will need to redraw after losing focus
			VPanel *dlg = pContext->_keyFocus;
			while (dlg && !dlg->IsPopup())
			{
				dlg = dlg->GetParent();
			}
			if (dlg)
			{
				dlg->Client()->Repaint();
			}
		}
		if (wantedKeyFocus != NULL)
		{
			wantedKeyFocus->Client()->InternalFocusChanged(false);

			// send a message to the window saying that it's gaining focus
			ivgui()->PostMessage((VPANEL)wantedKeyFocus, new KeyValues("SetFocus"), NULL);
			wantedKeyFocus->Client()->Repaint();

			// repaint the nearest popup as well, since it will need to redraw after gaining focus
			VPanel *dlg = wantedKeyFocus;
			while (dlg && !dlg->IsPopup())
			{
				dlg = dlg->GetParent();
			}
			if (dlg)
			{
				dlg->Client()->Repaint();
			}
		}

		// accept the focus request
		pContext->_keyFocus = wantedKeyFocus;
		if (pContext->_keyFocus)
		{
			pContext->_keyFocus->MoveToFront();
		}
	}
}