|
|
//========= 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 ); }
|