Counter Strike : Global Offensive Source Code
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

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