You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
223 lines
5.8 KiB
223 lines
5.8 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: Implements an autoselection combo box that color codes the text
|
|
// based on whether the current selection represents a single entity,
|
|
// multiple entities, or an unresolved entity targetname.
|
|
//
|
|
// The fonts are as follows:
|
|
//
|
|
// Single entity black, normal weight
|
|
// Multiple entities black, bold
|
|
// Unresolved red, normal weight
|
|
//
|
|
//=============================================================================//
|
|
|
|
#include "stdafx.h"
|
|
#include "MapEntity.h"
|
|
#include "TargetNameCombo.h"
|
|
#include "hammer.h"
|
|
#include "mapdoc.h"
|
|
#include "mapworld.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include <tier0/memdbgon.h>
|
|
|
|
|
|
#pragma warning( disable : 4355 )
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTargetNameComboBox, CFilteredComboBox)
|
|
//{{AFX_MSG_MAP(CTargetNameComboBox)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
CTargetNameComboBox::CTargetNameComboBox( CFilteredComboBox::ICallbacks *pPassThru ) :
|
|
BaseClass( this )
|
|
{
|
|
m_pEntityList = NULL;
|
|
m_pPassThru = pPassThru;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Frees allocated memory.
|
|
//-----------------------------------------------------------------------------
|
|
CTargetNameComboBox::~CTargetNameComboBox(void)
|
|
{
|
|
FreeSubLists();
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose:
|
|
//-----------------------------------------------------------------------------
|
|
void CTargetNameComboBox::FreeSubLists(void)
|
|
{
|
|
POSITION pos = m_SubLists.GetHeadPosition();
|
|
while (pos != NULL)
|
|
{
|
|
CMapEntityList *pList = m_SubLists.GetNext(pos);
|
|
delete pList;
|
|
}
|
|
|
|
m_SubLists.RemoveAll();
|
|
}
|
|
|
|
|
|
void CTargetNameComboBox::CreateFonts()
|
|
{
|
|
//
|
|
// Create a normal and bold font.
|
|
//
|
|
if (!m_BoldFont.m_hObject)
|
|
{
|
|
CFont &nf = GetNormalFont();
|
|
|
|
if ( nf.m_hObject )
|
|
{
|
|
LOGFONT LogFont;
|
|
nf.GetLogFont(&LogFont);
|
|
LogFont.lfWeight = FW_BOLD;
|
|
m_BoldFont.CreateFontIndirect(&LogFont);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
CTargetNameComboBox* CTargetNameComboBox::Create( CFilteredComboBox::ICallbacks *pCallbacks, DWORD dwStyle, RECT rect, CWnd *pParentWnd, UINT nID )
|
|
{
|
|
CTargetNameComboBox *pRet = new CTargetNameComboBox( pCallbacks );
|
|
pRet->BaseClass::Create( dwStyle, rect, pParentWnd, nID );
|
|
return pRet;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Purpose: Attaches an entity list to the combo box. This list will be used
|
|
// for matching targetnames to entities in the world.
|
|
// Input : pEntityList - The beauty of Hungarian notation and meaningful naming
|
|
// makes this comment utterly unnecessary.
|
|
//-----------------------------------------------------------------------------
|
|
void CTargetNameComboBox::SetEntityList(const CMapEntityList *pEntityList)
|
|
{
|
|
// We want all notifications, even if the current text doesn't match an exact entity name.
|
|
SetOnlyProvideSuggestions( false );
|
|
|
|
// Setup the list.
|
|
m_pEntityList = pEntityList;
|
|
|
|
FreeSubLists();
|
|
|
|
m_EntityLists.RemoveAll();
|
|
|
|
if (m_pEntityList != NULL)
|
|
{
|
|
FOR_EACH_OBJ( *m_pEntityList, pos )
|
|
{
|
|
CMapEntity *pEntity = (CUtlReference<CMapEntity>)m_pEntityList->Element(pos);
|
|
const char *pszTargetName = pEntity ? pEntity->GetKeyValue("targetname") : NULL;
|
|
|
|
if (pszTargetName != NULL)
|
|
{
|
|
//
|
|
// If the targetname is not in the combo box, add it to the combo as the
|
|
// first entry in an entity list. The list is necessary because there
|
|
// may be several entities in the map with the same targetname.
|
|
//
|
|
int nIndex = m_EntityLists.Find( pszTargetName );
|
|
if (nIndex == m_EntityLists.InvalidIndex())
|
|
{
|
|
CMapEntityList *pList = new CMapEntityList;
|
|
pList->AddToTail( pEntity );
|
|
|
|
m_EntityLists.Insert( pszTargetName, pList );
|
|
|
|
//
|
|
// Keep track of all the sub lists so we can delete them later.
|
|
//
|
|
m_SubLists.AddTail(pList);
|
|
}
|
|
//
|
|
// Else append the entity to the given targetname's list.
|
|
//
|
|
else
|
|
{
|
|
CMapEntityList *pList = m_EntityLists[nIndex];
|
|
pList->AddToTail(pEntity);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Setup the suggestions.
|
|
CUtlVector<CString> suggestions;
|
|
for ( int i=m_EntityLists.First(); i != m_EntityLists.InvalidIndex(); i=m_EntityLists.Next( i ) )
|
|
{
|
|
suggestions.AddToTail( m_EntityLists.GetElementName( i ) );
|
|
}
|
|
SetSuggestions( suggestions );
|
|
}
|
|
|
|
|
|
CMapEntityList* CTargetNameComboBox::GetSubEntityList( const char *pName )
|
|
{
|
|
int testIndex = m_EntityLists.Find( pName );
|
|
if ( testIndex != m_EntityLists.InvalidIndex() )
|
|
{
|
|
return m_EntityLists[testIndex];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void CTargetNameComboBox::OnTextChanged( const char *pText )
|
|
{
|
|
// Make sure our fonts are created.
|
|
CreateFonts();
|
|
|
|
// Update the fonts.
|
|
int nCount = 0;
|
|
CMapEntityList *pList = GetSubEntityList( pText );
|
|
if ( pList )
|
|
nCount = pList->Count();
|
|
|
|
// Figure out the font and color that we want.
|
|
CFont *pWantedFont = &m_BoldFont;
|
|
if ( (nCount == 0) || (nCount == 1) )
|
|
pWantedFont = &GetNormalFont();
|
|
|
|
COLORREF clrWanted = RGB(255,0,0);
|
|
if ( nCount > 0 )
|
|
{
|
|
clrWanted = RGB(0,0,0);
|
|
}
|
|
else
|
|
{
|
|
POSITION pos = APP()->pMapDocTemplate->GetFirstDocPosition();
|
|
while( pos != NULL )
|
|
{
|
|
CDocument *pDoc = APP()->pMapDocTemplate->GetNextDoc( pos );
|
|
CMapDoc *pMapDoc = dynamic_cast< CMapDoc * >( pDoc );
|
|
|
|
if ( pMapDoc )
|
|
{
|
|
if ( pMapDoc->GetMapWorld()->FindEntityByName( pText ) != NULL )
|
|
{
|
|
clrWanted = RGB( 0, 192, 192 );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SetEditControlFont( *pWantedFont );
|
|
SetEditControlTextColor( clrWanted );
|
|
|
|
// Pass it through to the owner if they want notification.
|
|
if ( m_pPassThru )
|
|
m_pPassThru->OnTextChanged( pText );
|
|
}
|