Team Fortress 2 Source Code as on 22/4/2020
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.

199 lines
5.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Implements an autoselection combo box that color codes the text
  4. // based on whether the current selection represents a single entity,
  5. // multiple entities, or an unresolved entity targetname.
  6. //
  7. // The fonts are as follows:
  8. //
  9. // Single entity black, normal weight
  10. // Multiple entities black, bold
  11. // Unresolved red, normal weight
  12. //
  13. //=============================================================================//
  14. #include "stdafx.h"
  15. #include "MapEntity.h"
  16. #include "TargetNameCombo.h"
  17. // memdbgon must be the last include file in a .cpp file!!!
  18. #include <tier0/memdbgon.h>
  19. #pragma warning( disable : 4355 )
  20. BEGIN_MESSAGE_MAP(CTargetNameComboBox, CFilteredComboBox)
  21. //{{AFX_MSG_MAP(CTargetNameComboBox)
  22. //}}AFX_MSG_MAP
  23. END_MESSAGE_MAP()
  24. //-----------------------------------------------------------------------------
  25. // Purpose:
  26. //-----------------------------------------------------------------------------
  27. CTargetNameComboBox::CTargetNameComboBox( CFilteredComboBox::ICallbacks *pPassThru ) :
  28. BaseClass( this )
  29. {
  30. m_pEntityList = NULL;
  31. m_pPassThru = pPassThru;
  32. }
  33. //-----------------------------------------------------------------------------
  34. // Purpose: Frees allocated memory.
  35. //-----------------------------------------------------------------------------
  36. CTargetNameComboBox::~CTargetNameComboBox(void)
  37. {
  38. FreeSubLists();
  39. }
  40. //-----------------------------------------------------------------------------
  41. // Purpose:
  42. //-----------------------------------------------------------------------------
  43. void CTargetNameComboBox::FreeSubLists(void)
  44. {
  45. POSITION pos = m_SubLists.GetHeadPosition();
  46. while (pos != NULL)
  47. {
  48. CMapEntityList *pList = m_SubLists.GetNext(pos);
  49. delete pList;
  50. }
  51. m_SubLists.RemoveAll();
  52. }
  53. void CTargetNameComboBox::CreateFonts()
  54. {
  55. //
  56. // Create a normal and bold font.
  57. //
  58. if (!m_BoldFont.m_hObject)
  59. {
  60. CFont &nf = GetNormalFont();
  61. if ( nf.m_hObject )
  62. {
  63. LOGFONT LogFont;
  64. nf.GetLogFont(&LogFont);
  65. LogFont.lfWeight = FW_BOLD;
  66. m_BoldFont.CreateFontIndirect(&LogFont);
  67. }
  68. }
  69. }
  70. CTargetNameComboBox* CTargetNameComboBox::Create( CFilteredComboBox::ICallbacks *pCallbacks, DWORD dwStyle, RECT rect, CWnd *pParentWnd, UINT nID )
  71. {
  72. CTargetNameComboBox *pRet = new CTargetNameComboBox( pCallbacks );
  73. pRet->BaseClass::Create( dwStyle, rect, pParentWnd, nID );
  74. return pRet;
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose: Attaches an entity list to the combo box. This list will be used
  78. // for matching targetnames to entities in the world.
  79. // Input : pEntityList - The beauty of Hungarian notation and meaningful naming
  80. // makes this comment utterly unnecessary.
  81. //-----------------------------------------------------------------------------
  82. void CTargetNameComboBox::SetEntityList(const CMapEntityList *pEntityList)
  83. {
  84. // We want all notifications, even if the current text doesn't match an exact entity name.
  85. SetOnlyProvideSuggestions( false );
  86. // Setup the list.
  87. m_pEntityList = pEntityList;
  88. FreeSubLists();
  89. m_EntityLists.RemoveAll();
  90. if (m_pEntityList != NULL)
  91. {
  92. FOR_EACH_OBJ( *m_pEntityList, pos )
  93. {
  94. CMapEntity *pEntity = m_pEntityList->Element(pos);
  95. const char *pszTargetName = pEntity->GetKeyValue("targetname");
  96. if (pszTargetName != NULL)
  97. {
  98. //
  99. // If the targetname is not in the combo box, add it to the combo as the
  100. // first entry in an entity list. The list is necessary because there
  101. // may be several entities in the map with the same targetname.
  102. //
  103. int nIndex = m_EntityLists.Find( pszTargetName );
  104. if (nIndex == m_EntityLists.InvalidIndex())
  105. {
  106. CMapEntityList *pList = new CMapEntityList;
  107. pList->AddToTail(pEntity);
  108. m_EntityLists.Insert( pszTargetName, pList );
  109. //
  110. // Keep track of all the sub lists so we can delete them later.
  111. //
  112. m_SubLists.AddTail(pList);
  113. }
  114. //
  115. // Else append the entity to the given targetname's list.
  116. //
  117. else
  118. {
  119. CMapEntityList *pList = m_EntityLists[nIndex];
  120. pList->AddToTail(pEntity);
  121. }
  122. }
  123. }
  124. }
  125. // Setup the suggestions.
  126. CUtlVector<CString> suggestions;
  127. for ( int i=m_EntityLists.First(); i != m_EntityLists.InvalidIndex(); i=m_EntityLists.Next( i ) )
  128. {
  129. suggestions.AddToTail( m_EntityLists.GetElementName( i ) );
  130. }
  131. SetSuggestions( suggestions );
  132. }
  133. CMapEntityList* CTargetNameComboBox::GetSubEntityList( const char *pName )
  134. {
  135. int testIndex = m_EntityLists.Find( pName );
  136. if ( testIndex != m_EntityLists.InvalidIndex() )
  137. {
  138. return m_EntityLists[testIndex];
  139. }
  140. return NULL;
  141. }
  142. void CTargetNameComboBox::OnTextChanged( const char *pText )
  143. {
  144. // Make sure our fonts are created.
  145. CreateFonts();
  146. // Update the fonts.
  147. int nCount = 0;
  148. CMapEntityList *pList = GetSubEntityList( pText );
  149. if ( pList )
  150. nCount = pList->Count();
  151. // Figure out the font and color that we want.
  152. CFont *pWantedFont = &m_BoldFont;
  153. if ( (nCount == 0) || (nCount == 1) )
  154. pWantedFont = &GetNormalFont();
  155. COLORREF clrWanted = RGB(255,0,0);
  156. if ( nCount > 0 )
  157. clrWanted = RGB(0,0,0);
  158. SetEditControlFont( *pWantedFont );
  159. SetEditControlTextColor( clrWanted );
  160. // Pass it through to the owner if they want notification.
  161. if ( m_pPassThru )
  162. m_pPassThru->OnTextChanged( pText );
  163. }