diff options
Diffstat (limited to 'hammer/targetnamecombo.cpp')
| -rw-r--r-- | hammer/targetnamecombo.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/hammer/targetnamecombo.cpp b/hammer/targetnamecombo.cpp new file mode 100644 index 0000000..6420e7b --- /dev/null +++ b/hammer/targetnamecombo.cpp @@ -0,0 +1,199 @@ +//========= Copyright 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" + +// 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 = m_pEntityList->Element(pos); + const char *pszTargetName = pEntity->GetKeyValue("targetname"); + 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); + + SetEditControlFont( *pWantedFont ); + SetEditControlTextColor( clrWanted ); + + // Pass it through to the owner if they want notification. + if ( m_pPassThru ) + m_pPassThru->OnTextChanged( pText ); +} |