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.

301 lines
8.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #if defined(WIN32) && !defined( _X360 )
  7. #include <windows.h>
  8. #endif
  9. #undef PropertySheet
  10. #include "matsys_controls/gamefiletreeview.h"
  11. #include "filesystem.h"
  12. #include "tier1/KeyValues.h"
  13. #include "vgui/ISurface.h"
  14. #include "vgui/Cursor.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include "tier0/memdbgon.h"
  17. using namespace vgui;
  18. //-----------------------------------------------------------------------------
  19. // list of all tree view icons
  20. //-----------------------------------------------------------------------------
  21. enum
  22. {
  23. IMAGE_FOLDER = 1,
  24. IMAGE_OPENFOLDER,
  25. IMAGE_FILE,
  26. };
  27. //-----------------------------------------------------------------------------
  28. // Constructor
  29. //-----------------------------------------------------------------------------
  30. CGameFileTreeView::CGameFileTreeView( Panel *parent, const char *name, const char *pRootFolderName, const char *pRootDir, const char *pExtension ) : BaseClass(parent, name), m_Images( false )
  31. {
  32. m_RootDir = pRootDir;
  33. m_Ext = pExtension;
  34. m_bUseExt = ( pExtension != NULL );
  35. m_RootFolderName = pRootFolderName;
  36. // build our list of images
  37. m_Images.AddImage( scheme()->GetImage( "resource/icon_folder", false ) );
  38. m_Images.AddImage( scheme()->GetImage( "resource/icon_folder_selected", false ) );
  39. m_Images.AddImage( scheme()->GetImage( "resource/icon_file", false ) );
  40. SetImageList( &m_Images, false );
  41. }
  42. //-----------------------------------------------------------------------------
  43. // Purpose: Refreshes the active file list
  44. //-----------------------------------------------------------------------------
  45. void CGameFileTreeView::RefreshFileList()
  46. {
  47. RemoveAll();
  48. SetFgColor(Color(216, 222, 211, 255));
  49. // add the base node
  50. KeyValues *pkv = new KeyValues( "root" );
  51. pkv->SetString( "text", m_RootFolderName );
  52. pkv->SetInt( "root", 1 );
  53. pkv->SetInt( "expand", 1 );
  54. int iRoot = AddItem( pkv, GetRootItemIndex() );
  55. pkv->deleteThis();
  56. ExpandItem( iRoot, true );
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Selects the root folder
  60. //-----------------------------------------------------------------------------
  61. void CGameFileTreeView::SelectRoot()
  62. {
  63. AddSelectedItem( GetRootItemIndex(), true );
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Gets the number of root directories
  67. //-----------------------------------------------------------------------------
  68. int CGameFileTreeView::GetRootDirectoryCount()
  69. {
  70. return GetNumChildren( GetRootItemIndex() );
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Gets the ith root directory
  74. //-----------------------------------------------------------------------------
  75. const char *CGameFileTreeView::GetRootDirectory( int nIndex )
  76. {
  77. int nItemIndex = GetChild( GetRootItemIndex(), nIndex );
  78. KeyValues *kv = GetItemData( nItemIndex );
  79. if ( !kv )
  80. return NULL;
  81. return kv->GetString( "path", NULL );
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Populate the root node (necessary since tree view can't have multiple roots)
  85. //-----------------------------------------------------------------------------
  86. void CGameFileTreeView::PopulateRootNode( int itemIndex )
  87. {
  88. AddDirectoriesOfNode( itemIndex, m_RootDir );
  89. if ( m_bUseExt )
  90. {
  91. AddFilesOfNode( itemIndex, m_RootDir, m_Ext );
  92. }
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Populate the root node with directories
  96. //-----------------------------------------------------------------------------
  97. bool CGameFileTreeView::DoesDirectoryHaveSubdirectories( const char *pFilePath )
  98. {
  99. char pSearchString[MAX_PATH];
  100. Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
  101. // get the list of files
  102. FileFindHandle_t findHandle;
  103. // generate children
  104. // add all the items
  105. const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
  106. while ( pszFileName )
  107. {
  108. bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
  109. if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
  110. return true;
  111. pszFileName = g_pFullFileSystem->FindNext( findHandle );
  112. }
  113. g_pFullFileSystem->FindClose( findHandle );
  114. return false;
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Populate the root node with directories
  118. //-----------------------------------------------------------------------------
  119. void CGameFileTreeView::AddDirectoriesOfNode( int itemIndex, const char *pFilePath )
  120. {
  121. char pSearchString[MAX_PATH];
  122. Q_snprintf( pSearchString, MAX_PATH, "%s\\*", pFilePath );
  123. // get the list of files
  124. FileFindHandle_t findHandle;
  125. // generate children
  126. // add all the items
  127. const char *pszFileName = g_pFullFileSystem->FindFirstEx( pSearchString, "GAME", &findHandle );
  128. while ( pszFileName )
  129. {
  130. bool bIsDirectory = g_pFullFileSystem->FindIsDirectory( findHandle );
  131. if ( bIsDirectory && Q_strnicmp( pszFileName, ".", 2 ) && Q_strnicmp( pszFileName, "..", 3 ) )
  132. {
  133. KeyValues *kv = new KeyValues( "node", "text", pszFileName );
  134. char pFullPath[MAX_PATH];
  135. Q_snprintf( pFullPath, sizeof(pFullPath), "%s/%s", pFilePath, pszFileName );
  136. Q_FixSlashes( pFullPath );
  137. Q_strlower( pFullPath );
  138. bool bHasSubdirectories = DoesDirectoryHaveSubdirectories( pFullPath );
  139. kv->SetString( "path", pFullPath );
  140. kv->SetInt( "expand", bHasSubdirectories );
  141. kv->SetInt( "dir", 1 );
  142. kv->SetInt( "image", IMAGE_FOLDER );
  143. int itemID = AddItem(kv, itemIndex);
  144. kv->deleteThis();
  145. // mark directories in orange
  146. SetItemColorForDirectories( itemID );
  147. }
  148. pszFileName = g_pFullFileSystem->FindNext( findHandle );
  149. }
  150. g_pFullFileSystem->FindClose( findHandle );
  151. }
  152. //-----------------------------------------------------------------------------
  153. // Populate the root node with files
  154. //-----------------------------------------------------------------------------
  155. void CGameFileTreeView::AddFilesOfNode( int itemIndex, const char *pFilePath, const char *pExt )
  156. {
  157. char pSearchString[MAX_PATH];
  158. Q_snprintf( pSearchString, MAX_PATH, "%s\\*.%s", pFilePath, pExt );
  159. // get the list of files
  160. FileFindHandle_t findHandle;
  161. // generate children
  162. // add all the items
  163. const char *pszFileName = g_pFullFileSystem->FindFirst( pSearchString, &findHandle );
  164. while ( pszFileName )
  165. {
  166. if ( !g_pFullFileSystem->FindIsDirectory( findHandle ) )
  167. {
  168. KeyValues *kv = new KeyValues( "node", "text", pszFileName );
  169. char pFullPath[MAX_PATH];
  170. Q_snprintf( pFullPath, MAX_PATH, "%s\\%s", pFilePath, pszFileName );
  171. kv->SetString( "path", pFullPath );
  172. kv->SetInt( "image", IMAGE_FILE );
  173. AddItem(kv, itemIndex);
  174. kv->deleteThis();
  175. }
  176. pszFileName = g_pFullFileSystem->FindNext( findHandle );
  177. }
  178. g_pFullFileSystem->FindClose( findHandle );
  179. }
  180. //-----------------------------------------------------------------------------
  181. // override to incremental request and show p4 directories
  182. //-----------------------------------------------------------------------------
  183. void CGameFileTreeView::GenerateChildrenOfNode(int itemIndex)
  184. {
  185. KeyValues *pkv = GetItemData(itemIndex);
  186. if ( pkv->GetInt("root") )
  187. {
  188. PopulateRootNode( itemIndex );
  189. return;
  190. }
  191. if (!pkv->GetInt("dir"))
  192. return;
  193. const char *pFilePath = pkv->GetString("path", "");
  194. if (!pFilePath[0])
  195. return;
  196. surface()->SetCursor(dc_waitarrow);
  197. AddDirectoriesOfNode( itemIndex, pFilePath );
  198. if ( m_bUseExt )
  199. {
  200. AddFilesOfNode( itemIndex, pFilePath, m_Ext );
  201. }
  202. }
  203. //-----------------------------------------------------------------------------
  204. // setup a context menu whenever a directory is clicked on
  205. //-----------------------------------------------------------------------------
  206. void CGameFileTreeView::GenerateContextMenu( int itemIndex, int x, int y )
  207. {
  208. return;
  209. /*
  210. KeyValues *pkv = GetItemData(itemIndex);
  211. const char *pFilePath = pkv->GetString("path", "");
  212. if (!pFilePath[0])
  213. return;
  214. Menu *pContext = new Menu(this, "FileContext");
  215. pContext->AddMenuItem("Cloak folder", new KeyValues("CloakFolder", "item", itemIndex), GetParent(), NULL);
  216. // show the context menu
  217. pContext->SetPos(x, y);
  218. pContext->SetVisible(true);
  219. */
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Sets an item to be colored as if its a menu
  223. //-----------------------------------------------------------------------------
  224. void CGameFileTreeView::SetItemColorForDirectories( int itemID )
  225. {
  226. // mark directories in orange
  227. SetItemFgColor( itemID, Color(224, 192, 0, 255) );
  228. }
  229. //-----------------------------------------------------------------------------
  230. // setup a smaller font
  231. //-----------------------------------------------------------------------------
  232. void CGameFileTreeView::ApplySchemeSettings(IScheme *pScheme)
  233. {
  234. BaseClass::ApplySchemeSettings(pScheme);
  235. SetFont( pScheme->GetFont("DefaultSmall") );
  236. }