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.

788 lines
23 KiB

  1. //====== Copyright 1996-2005, Valve Corporation, All rights reserved. =======
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================
  6. #include "matsys_controls/mdlpicker.h"
  7. #include "tier1/keyvalues.h"
  8. #include "tier1/utldict.h"
  9. #include "filesystem.h"
  10. #include "studio.h"
  11. #include "matsys_controls/matsyscontrols.h"
  12. #include "matsys_controls/mdlpanel.h"
  13. #include "vgui_controls/Splitter.h"
  14. #include "vgui_controls/ComboBox.h"
  15. #include "vgui_controls/Button.h"
  16. #include "vgui_controls/PropertySheet.h"
  17. #include "vgui_controls/MessageBox.h"
  18. #include "vgui_controls/PropertyPage.h"
  19. #include "vgui_controls/CheckButton.h"
  20. #include "vgui_controls/DirectorySelectDialog.h"
  21. #include "vgui/IVGui.h"
  22. #include "vgui/IInput.h"
  23. #include "vgui/ISurface.h"
  24. #include "vgui/Cursor.h"
  25. #include "matsys_controls/assetpicker.h"
  26. #include "matsys_controls/colorpickerpanel.h"
  27. #include "dmxloader/dmxloader.h"
  28. #include "utlbuffer.h"
  29. #include "bitmap/tgawriter.h"
  30. #include "tier3/tier3.h"
  31. #include "istudiorender.h"
  32. #include "../vgui2/src/VPanel.h"
  33. // memdbgon must be the last include file in a .cpp file!!!
  34. #include "tier0/memdbgon.h"
  35. using namespace vgui;
  36. //-----------------------------------------------------------------------------
  37. //
  38. // MDL Picker
  39. //
  40. //-----------------------------------------------------------------------------
  41. //-----------------------------------------------------------------------------
  42. // Sort by MDL name
  43. //-----------------------------------------------------------------------------
  44. static int __cdecl MDLBrowserSortFunc( vgui::ListPanel *pPanel, const ListPanelItem &item1, const ListPanelItem &item2 )
  45. {
  46. const char *string1 = item1.kv->GetString("mdl");
  47. const char *string2 = item2.kv->GetString("mdl");
  48. return stricmp( string1, string2 );
  49. }
  50. //-----------------------------------------------------------------------------
  51. // Purpose: Constructor
  52. //-----------------------------------------------------------------------------
  53. CMDLPicker::CMDLPicker( vgui::Panel *pParent, int nFlags ) :
  54. BaseClass( pParent, "MDL Files", "mdl", "models", "mdlName" )
  55. {
  56. m_hSelectedMDL = MDLHANDLE_INVALID;
  57. m_nFlags = nFlags; // remember what we show and what not
  58. m_pRenderPage = NULL;
  59. m_pSequencesPage = NULL;
  60. m_pActivitiesPage = NULL;
  61. m_pSkinsPage = NULL;
  62. m_pInfoPage = NULL;
  63. m_pSequencesList = NULL;
  64. m_pActivitiesList = NULL;
  65. // Horizontal splitter for mdls
  66. m_pFileBrowserSplitter = new Splitter( this, "FileBrowserSplitter", SPLITTER_MODE_VERTICAL, 1 );
  67. float flFractions[] = { 0.33f, 0.67f };
  68. m_pFileBrowserSplitter->RespaceSplitters( flFractions );
  69. vgui::Panel *pSplitterLeftSide = m_pFileBrowserSplitter->GetChild( 0 );
  70. vgui::Panel *pSplitterRightSide = m_pFileBrowserSplitter->GetChild( 1 );
  71. // Standard browser controls
  72. pSplitterLeftSide->RequestFocus();
  73. CreateStandardControls( pSplitterLeftSide, false );
  74. // property sheet - revisions, changes, etc.
  75. m_pPreviewSplitter = new Splitter( pSplitterRightSide, "PreviewSplitter", SPLITTER_MODE_HORIZONTAL, 1 );
  76. vgui::Panel *pSplitterTopSide = m_pPreviewSplitter->GetChild( 0 );
  77. vgui::Panel *pSplitterBottomSide = m_pPreviewSplitter->GetChild( 1 );
  78. // MDL preview
  79. m_pMDLPreview = new CMDLPanel( pSplitterTopSide, "MDLPreview" );
  80. SetSkipChildDuringPainting( m_pMDLPreview );
  81. m_pViewsSheet = new vgui::PropertySheet( pSplitterBottomSide, "ViewsSheet" );
  82. m_pViewsSheet->AddActionSignalTarget( this );
  83. // now add wanted features
  84. if ( nFlags & PAGE_RENDER )
  85. {
  86. m_pRenderPage = new vgui::PropertyPage( m_pViewsSheet, "RenderPage" );
  87. m_pRenderPage->AddActionSignalTarget( this );
  88. m_pRenderPage->LoadControlSettingsAndUserConfig( "resource/mdlpickerrender.res" );
  89. RefreshRenderSettings();
  90. // ground
  91. Button *pSelectProbe = (Button*)m_pRenderPage->FindChildByName( "ChooseLightProbe" );
  92. pSelectProbe->AddActionSignalTarget( this );
  93. }
  94. if ( nFlags & PAGE_SEQUENCES )
  95. {
  96. m_pSequencesPage = new vgui::PropertyPage( m_pViewsSheet, "SequencesPage" );
  97. m_pSequencesList = new vgui::ListPanel( m_pSequencesPage, "SequencesList" );
  98. m_pSequencesList->AddColumnHeader( 0, "sequence", "sequence", 52, 0 );
  99. m_pSequencesList->AddActionSignalTarget( this );
  100. m_pSequencesList->SetSelectIndividualCells( true );
  101. m_pSequencesList->SetEmptyListText("No .MDL file currently selected.");
  102. m_pSequencesList->SetDragEnabled( true );
  103. m_pSequencesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 6, -6, -6 );
  104. }
  105. if ( nFlags & PAGE_ACTIVITIES )
  106. {
  107. m_pActivitiesPage = new vgui::PropertyPage( m_pViewsSheet, "ActivitiesPage" );
  108. m_pActivitiesList = new vgui::ListPanel( m_pActivitiesPage, "ActivitiesList" );
  109. m_pActivitiesList->AddColumnHeader( 0, "activity", "activity", 52, 0 );
  110. m_pActivitiesList->AddActionSignalTarget( this );
  111. m_pActivitiesList->SetSelectIndividualCells( true );
  112. m_pActivitiesList->SetEmptyListText( "No .MDL file currently selected." );
  113. m_pActivitiesList->SetDragEnabled( true );
  114. m_pActivitiesList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 6, -6, -6 );
  115. }
  116. if ( nFlags & PAGE_SKINS )
  117. {
  118. m_pSkinsPage = new vgui::PropertyPage( m_pViewsSheet, "SkinsPage" );
  119. m_pSkinsList = new vgui::ListPanel( m_pSkinsPage, "SkinsList" );
  120. m_pSkinsList->AddColumnHeader( 0, "skin", "skin", 52, 0 );
  121. m_pSkinsList->AddActionSignalTarget( this );
  122. m_pSkinsList->SetSelectIndividualCells( true );
  123. m_pSkinsList->SetEmptyListText( "No .MDL file currently selected." );
  124. m_pSkinsList->SetDragEnabled( true );
  125. m_pSkinsList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 6, -6, -6 );
  126. }
  127. if ( nFlags & PAGE_INFO )
  128. {
  129. m_pInfoPage = new vgui::PropertyPage( m_pViewsSheet, "InfoPage" );
  130. m_pInfoPage->AddActionSignalTarget( this );
  131. m_pInfoPage->LoadControlSettingsAndUserConfig( "resource/mdlpickerinfo.res" );
  132. CheckButton * pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName( "PhysicsObject" );
  133. pTempCheck->SetDisabledFgColor1( pTempCheck->GetFgColor());
  134. pTempCheck->SetDisabledFgColor2( pTempCheck->GetFgColor());
  135. pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName( "StaticObject" );
  136. pTempCheck->SetDisabledFgColor1( pTempCheck->GetFgColor());
  137. pTempCheck->SetDisabledFgColor2( pTempCheck->GetFgColor());
  138. pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName( "DynamicObject" );
  139. pTempCheck->SetDisabledFgColor1( pTempCheck->GetFgColor());
  140. pTempCheck->SetDisabledFgColor2( pTempCheck->GetFgColor());
  141. m_pPropDataList = new vgui::ListPanel( m_pInfoPage, "PropData" );
  142. m_pPropDataList->AddColumnHeader( 0, "key", "key", 250, ListPanel::COLUMN_FIXEDSIZE );
  143. m_pPropDataList->AddColumnHeader( 1, "value", "value", 52, 0 );
  144. m_pPropDataList->AddActionSignalTarget( this );
  145. m_pPropDataList->SetSelectIndividualCells( false );
  146. m_pPropDataList->SetEmptyListText( "No prop_data available." );
  147. m_pPropDataList->SetDragEnabled( true );
  148. m_pPropDataList->SetAutoResize( Panel::PIN_TOPLEFT, Panel::AUTORESIZE_DOWNANDRIGHT, 6, 72, -6, -6 );
  149. RefreshRenderSettings();
  150. }
  151. // Load layout settings; has to happen before pinning occurs in code
  152. LoadControlSettingsAndUserConfig( "resource/mdlpicker.res" );
  153. // Pages must be added after control settings are set up
  154. if ( m_pRenderPage )
  155. {
  156. m_pViewsSheet->AddPage( m_pRenderPage, "Render" );
  157. }
  158. if ( m_pSequencesPage )
  159. {
  160. m_pViewsSheet->AddPage( m_pSequencesPage, "Sequences" );
  161. }
  162. if ( m_pActivitiesPage )
  163. {
  164. m_pViewsSheet->AddPage( m_pActivitiesPage, "Activities" );
  165. }
  166. if ( m_pSkinsPage )
  167. {
  168. m_pViewsSheet->AddPage( m_pSkinsPage, "Skins" );
  169. }
  170. if ( m_pInfoPage )
  171. {
  172. m_pViewsSheet->AddPage( m_pInfoPage, "Info" );
  173. }
  174. }
  175. void CMDLPicker::RefreshRenderSettings()
  176. {
  177. vgui::CheckButton *pToggle;
  178. if ( !m_pRenderPage )
  179. return;
  180. // ground
  181. pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("NoGround");
  182. pToggle->AddActionSignalTarget( this );
  183. m_pMDLPreview->SetGroundGrid( !pToggle->IsSelected() );
  184. // collision
  185. pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("Collision");
  186. pToggle->AddActionSignalTarget( this );
  187. m_pMDLPreview->SetCollsionModel( pToggle->IsSelected() );
  188. // wireframe
  189. pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("Wireframe");
  190. pToggle->AddActionSignalTarget( this );
  191. m_pMDLPreview->SetWireFrame( pToggle->IsSelected() );
  192. // lockview
  193. pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("LockView");
  194. pToggle->AddActionSignalTarget( this );
  195. m_pMDLPreview->SetLockView( pToggle->IsSelected() );
  196. // look at camera
  197. pToggle = (vgui::CheckButton*)m_pRenderPage->FindChildByName("LookAtCamera");
  198. pToggle->AddActionSignalTarget( this );
  199. m_pMDLPreview->SetLookAtCamera( pToggle->IsSelected() );
  200. }
  201. //-----------------------------------------------------------------------------
  202. // Purpose: Destructor
  203. //-----------------------------------------------------------------------------
  204. CMDLPicker::~CMDLPicker()
  205. {
  206. }
  207. //-----------------------------------------------------------------------------
  208. // Performs layout
  209. //-----------------------------------------------------------------------------
  210. void CMDLPicker::PerformLayout()
  211. {
  212. // NOTE: This call should cause auto-resize to occur
  213. // which should fix up the width of the panels
  214. BaseClass::PerformLayout();
  215. int w, h;
  216. GetSize( w, h );
  217. // Layout the mdl splitter
  218. m_pFileBrowserSplitter->SetBounds( 0, 0, w, h );
  219. }
  220. //-----------------------------------------------------------------------------
  221. // Buttons on various pages
  222. //-----------------------------------------------------------------------------
  223. void CMDLPicker::OnAssetSelected( KeyValues *pParams )
  224. {
  225. const char *pAsset = pParams->GetString( "asset" );
  226. char pProbeBuf[MAX_PATH];
  227. Q_snprintf( pProbeBuf, sizeof(pProbeBuf), "materials/lightprobes/%s", pAsset );
  228. BeginDMXContext();
  229. CDmxElement *pLightProbe = NULL;
  230. bool bOk = UnserializeDMX( pProbeBuf, "GAME", true, &pLightProbe );
  231. if ( !pLightProbe || !bOk )
  232. {
  233. char pBuf[1024];
  234. Q_snprintf( pBuf, sizeof(pBuf), "Error loading lightprobe file '%s'!\n", pProbeBuf );
  235. vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Error Loading File!\n", pBuf, GetParent() );
  236. pMessageBox->DoModal( );
  237. EndDMXContext( true );
  238. return;
  239. }
  240. m_pMDLPreview->SetLightProbe( pLightProbe );
  241. EndDMXContext( true );
  242. }
  243. //-----------------------------------------------------------------------------
  244. // Buttons on various pages
  245. //-----------------------------------------------------------------------------
  246. void CMDLPicker::OnCommand( const char *pCommand )
  247. {
  248. if ( !Q_stricmp( pCommand, "ChooseLightProbe" ) )
  249. {
  250. CAssetPickerFrame *pPicker = new CAssetPickerFrame( this, "Select Light Probe (.prb) File",
  251. "Light Probe", "prb", "materials/lightprobes", "lightprobe" );
  252. pPicker->DoModal();
  253. return;
  254. }
  255. BaseClass::OnCommand( pCommand );
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Purpose: rebuilds the list of activities
  259. //-----------------------------------------------------------------------------
  260. void CMDLPicker::RefreshActivitiesAndSequencesList()
  261. {
  262. m_pActivitiesList->RemoveAll();
  263. m_pSequencesList->RemoveAll();
  264. m_pMDLPreview->SetSequence( 0, false );
  265. if ( m_hSelectedMDL == MDLHANDLE_INVALID )
  266. {
  267. m_pActivitiesList->SetEmptyListText("No .MDL file currently selected");
  268. m_pSequencesList->SetEmptyListText("No .MDL file currently selected");
  269. return;
  270. }
  271. m_pActivitiesList->SetEmptyListText(".MDL file contains no activities");
  272. m_pSequencesList->SetEmptyListText(".MDL file contains no sequences");
  273. studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
  274. CUtlDict<int, unsigned short> activityNames( true, 0, hdr->GetNumSeq() );
  275. for (int j = 0; j < hdr->GetNumSeq(); j++)
  276. {
  277. if ( /*g_viewerSettings.showHidden ||*/ !(hdr->pSeqdesc(j).flags & STUDIO_HIDDEN))
  278. {
  279. const char *pActivityName = hdr->pSeqdesc(j).pszActivityName();
  280. if ( pActivityName && pActivityName[0] )
  281. {
  282. // Multiple sequences can have the same activity name; only add unique activity names
  283. if ( activityNames.Find( pActivityName ) == activityNames.InvalidIndex() )
  284. {
  285. KeyValues *pkv = new KeyValues("node", "activity", pActivityName );
  286. int nItemID = m_pActivitiesList->AddItem( pkv, 0, false, false );
  287. KeyValues *pDrag = new KeyValues( "drag", "text", pActivityName );
  288. pDrag->SetString( "texttype", "activityName" );
  289. pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
  290. m_pActivitiesList->SetItemDragData( nItemID, pDrag );
  291. activityNames.Insert( pActivityName, j );
  292. }
  293. }
  294. const char *pSequenceName = hdr->pSeqdesc(j).pszLabel();
  295. if ( pSequenceName && pSequenceName[0] )
  296. {
  297. KeyValues *pkv = new KeyValues("node", "sequence", pSequenceName);
  298. int nItemID = m_pSequencesList->AddItem( pkv, 0, false, false );
  299. KeyValues *pDrag = new KeyValues( "drag", "text", pSequenceName );
  300. pDrag->SetString( "texttype", "sequenceName" );
  301. pDrag->SetString( "mdl", vgui::MDLCache()->GetModelName( m_hSelectedMDL ) );
  302. m_pSequencesList->SetItemDragData( nItemID, pDrag );
  303. }
  304. }
  305. }
  306. }
  307. //-----------------------------------------------------------------------------
  308. // A MDL was selected
  309. //-----------------------------------------------------------------------------
  310. void CMDLPicker::OnSelectedAssetPicked( const char *pMDLName )
  311. {
  312. char pRelativePath[MAX_PATH];
  313. if ( pMDLName )
  314. {
  315. Q_snprintf( pRelativePath, sizeof(pRelativePath), "models\\%s", pMDLName );
  316. SelectMDL( pRelativePath );
  317. }
  318. else
  319. {
  320. SelectMDL( NULL );
  321. }
  322. }
  323. //-----------------------------------------------------------------------------
  324. // Allows external apps to select a MDL
  325. //-----------------------------------------------------------------------------
  326. void CMDLPicker::SelectMDL( const char *pRelativePath )
  327. {
  328. MDLHandle_t hSelectedMDL = pRelativePath ? vgui::MDLCache()->FindMDL( pRelativePath ) : MDLHANDLE_INVALID;
  329. // We didn't change models after all...
  330. if ( hSelectedMDL == m_hSelectedMDL )
  331. {
  332. // vgui::MDLCache()->FindMDL adds a reference by default we don't use, release it again
  333. if ( hSelectedMDL != MDLHANDLE_INVALID )
  334. {
  335. vgui::MDLCache()->Release( hSelectedMDL );
  336. }
  337. return;
  338. }
  339. m_hSelectedMDL = hSelectedMDL;
  340. if ( vgui::MDLCache()->IsErrorModel( m_hSelectedMDL ) )
  341. {
  342. m_hSelectedMDL = MDLHANDLE_INVALID;
  343. }
  344. m_pMDLPreview->SetMDL( m_hSelectedMDL );
  345. m_pMDLPreview->LookAtMDL();
  346. if ( m_nFlags & ( PAGE_SKINS ) )
  347. {
  348. UpdateSkinsList();
  349. }
  350. if ( m_nFlags & ( PAGE_INFO ) )
  351. {
  352. UpdateInfoTab();
  353. }
  354. if ( m_nFlags & (PAGE_ACTIVITIES|PAGE_SEQUENCES) )
  355. {
  356. RefreshActivitiesAndSequencesList();
  357. }
  358. // vgui::MDLCache()->FindMDL adds a reference by default we don't use, release it again
  359. if ( hSelectedMDL != MDLHANDLE_INVALID )
  360. {
  361. vgui::MDLCache()->Release( hSelectedMDL );
  362. }
  363. PostActionSignal( new KeyValues( "MDLPreviewChanged", "mdl", pRelativePath ? pRelativePath : "" ) );
  364. }
  365. //-----------------------------------------------------------------------------
  366. // Purpose: updates revision view on a file being selected
  367. //-----------------------------------------------------------------------------
  368. void CMDLPicker::OnCheckButtonChecked(KeyValues *kv)
  369. {
  370. // RefreshMDLList();
  371. BaseClass::OnCheckButtonChecked( kv );
  372. RefreshRenderSettings();
  373. }
  374. void CMDLPicker::GetSelectedMDLName( char *pBuffer, int nMaxLen )
  375. {
  376. Assert( nMaxLen > 0 );
  377. if ( GetSelectedAssetCount() > 0 )
  378. {
  379. Q_snprintf( pBuffer, nMaxLen, "models\\%s", GetSelectedAsset( ) );
  380. }
  381. else
  382. {
  383. pBuffer[0] = 0;
  384. }
  385. }
  386. //-----------------------------------------------------------------------------
  387. // Gets the selected activity/sequence
  388. //-----------------------------------------------------------------------------
  389. int CMDLPicker::GetSelectedPage( )
  390. {
  391. if ( m_pSequencesPage && ( m_pViewsSheet->GetActivePage() == m_pSequencesPage ) )
  392. return PAGE_SEQUENCES;
  393. if ( m_pActivitiesPage && ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage ) )
  394. return PAGE_ACTIVITIES;
  395. return PAGE_NONE;
  396. }
  397. const char *CMDLPicker::GetSelectedSequenceName()
  398. {
  399. if ( !m_pSequencesPage )
  400. return NULL;
  401. int nIndex = m_pSequencesList->GetSelectedItem( 0 );
  402. if ( nIndex >= 0 )
  403. {
  404. KeyValues *pkv = m_pSequencesList->GetItem( nIndex );
  405. return pkv->GetString( "sequence", NULL );
  406. }
  407. return NULL;
  408. }
  409. const char *CMDLPicker::GetSelectedActivityName()
  410. {
  411. if ( !m_pActivitiesPage )
  412. return NULL;
  413. int nIndex = m_pActivitiesList->GetSelectedItem( 0 );
  414. if ( nIndex >= 0 )
  415. {
  416. KeyValues *pkv = m_pActivitiesList->GetItem( nIndex );
  417. return pkv->GetString( "activity", NULL );
  418. }
  419. return NULL;
  420. }
  421. int CMDLPicker::GetSelectedSkin()
  422. {
  423. if ( !m_pSkinsPage )
  424. return NULL;
  425. int nIndex = m_pSkinsList->GetSelectedItem( 0 );
  426. if ( nIndex >= 0 )
  427. {
  428. return nIndex;
  429. }
  430. return NULL;
  431. }
  432. //-----------------------------------------------------------------------------
  433. // Plays the selected activity
  434. //-----------------------------------------------------------------------------
  435. void CMDLPicker::SelectActivity( const char *pActivityName )
  436. {
  437. studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
  438. for ( int i = 0; i < pstudiohdr->GetNumSeq(); i++ )
  439. {
  440. mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
  441. if ( stricmp( seqdesc.pszActivityName(), pActivityName ) == 0 )
  442. {
  443. // FIXME: Add weighted sequence selection logic?
  444. m_pMDLPreview->SetSequence( i, false );
  445. break;
  446. }
  447. }
  448. PostActionSignal( new KeyValues( "SequenceSelectionChanged", "activity", pActivityName ) );
  449. }
  450. //-----------------------------------------------------------------------------
  451. // Plays the selected sequence
  452. //-----------------------------------------------------------------------------
  453. void CMDLPicker::SelectSequence( const char *pSequenceName )
  454. {
  455. studiohdr_t *pstudiohdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
  456. for (int i = 0; i < pstudiohdr->GetNumSeq(); i++)
  457. {
  458. mstudioseqdesc_t &seqdesc = pstudiohdr->pSeqdesc( i );
  459. if ( !Q_stricmp( seqdesc.pszLabel(), pSequenceName ) )
  460. {
  461. m_pMDLPreview->SetSequence( i, false );
  462. break;
  463. }
  464. }
  465. PostActionSignal( new KeyValues( "SequenceSelectionChanged", "sequence", pSequenceName ) );
  466. }
  467. void CMDLPicker::SelectSkin( int nSkin )
  468. {
  469. m_pMDLPreview->SetSkin( nSkin );
  470. PostActionSignal( new KeyValues( "SkinSelectionChanged", "skin", nSkin));
  471. }
  472. //-----------------------------------------------------------------------------
  473. // Purpose: Updates preview when an item is selected
  474. //-----------------------------------------------------------------------------
  475. void CMDLPicker::OnItemSelected( KeyValues *kv )
  476. {
  477. Panel *pPanel = (Panel *)kv->GetPtr("panel", NULL);
  478. if ( m_pSequencesList && (pPanel == m_pSequencesList ) )
  479. {
  480. const char *pSequenceName = GetSelectedSequenceName();
  481. if ( pSequenceName )
  482. {
  483. SelectSequence( pSequenceName );
  484. }
  485. return;
  486. }
  487. if ( m_pActivitiesList && ( pPanel == m_pActivitiesList ) )
  488. {
  489. const char *pActivityName = GetSelectedActivityName();
  490. if ( pActivityName )
  491. {
  492. SelectActivity( pActivityName );
  493. }
  494. return;
  495. }
  496. if ( m_pSkinsList && ( pPanel == m_pSkinsList ) )
  497. {
  498. int nSelectedSkin = GetSelectedSkin();
  499. SelectSkin( nSelectedSkin );
  500. return;
  501. }
  502. BaseClass::OnItemSelected( kv );
  503. }
  504. //-----------------------------------------------------------------------------
  505. // Purpose: Called when a page is shown
  506. //-----------------------------------------------------------------------------
  507. void CMDLPicker::OnPageChanged( )
  508. {
  509. if ( m_pSequencesPage && ( m_pViewsSheet->GetActivePage() == m_pSequencesPage ) )
  510. {
  511. m_pSequencesList->RequestFocus();
  512. const char *pSequenceName = GetSelectedSequenceName();
  513. if ( pSequenceName )
  514. {
  515. SelectSequence( pSequenceName );
  516. }
  517. return;
  518. }
  519. if ( m_pActivitiesPage && ( m_pViewsSheet->GetActivePage() == m_pActivitiesPage ) )
  520. {
  521. m_pActivitiesList->RequestFocus();
  522. const char *pActivityName = GetSelectedActivityName();
  523. if ( pActivityName )
  524. {
  525. SelectActivity( pActivityName );
  526. }
  527. return;
  528. }
  529. }
  530. //-----------------------------------------------------------------------------
  531. //
  532. // Purpose: Modal picker frame
  533. //
  534. //-----------------------------------------------------------------------------
  535. CMDLPickerFrame::CMDLPickerFrame( vgui::Panel *pParent, const char *pTitle, int nFlags ) :
  536. BaseClass( pParent )
  537. {
  538. SetAssetPicker( new CMDLPicker( this, nFlags ) );
  539. LoadControlSettingsAndUserConfig( "resource/mdlpickerframe.res" );
  540. SetTitle( pTitle, false );
  541. }
  542. CMDLPickerFrame::~CMDLPickerFrame()
  543. {
  544. }
  545. //-----------------------------------------------------------------------------
  546. // Allows external apps to select a MDL
  547. //-----------------------------------------------------------------------------
  548. void CMDLPickerFrame::SelectMDL( const char *pRelativePath )
  549. {
  550. static_cast<CMDLPicker*>( GetAssetPicker() )->SelectMDL( pRelativePath );
  551. }
  552. int CMDLPicker::UpdateSkinsList()
  553. {
  554. int nNumSkins = 0;
  555. if ( m_pSkinsList )
  556. {
  557. m_pSkinsList->RemoveAll();
  558. studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
  559. if ( hdr )
  560. {
  561. nNumSkins = hdr->numskinfamilies;
  562. for ( int i = 0; i < nNumSkins; i++ )
  563. {
  564. char skinText[25] = "";
  565. sprintf( skinText, "skin%i", i );
  566. KeyValues *pkv = new KeyValues("node", "skin", skinText );
  567. m_pSkinsList->AddItem( pkv, 0, false, false );
  568. }
  569. }
  570. }
  571. return nNumSkins;
  572. }
  573. void CMDLPicker::UpdateInfoTab()
  574. {
  575. studiohdr_t *hdr = vgui::MDLCache()->GetStudioHdr( m_hSelectedMDL );
  576. if ( !hdr )
  577. return;
  578. int nMass = hdr->mass;
  579. Panel *pTempPanel = m_pInfoPage->FindChildByName("MassValue");
  580. char massBuff[10];
  581. Q_snprintf( massBuff, 10, "%d", nMass );
  582. ((vgui::Label *)pTempPanel)->SetText( massBuff );
  583. bool bIsStatic = ( hdr->flags & STUDIOHDR_FLAGS_STATIC_PROP ) ? true : false;
  584. bool bIsPhysics = false;
  585. Label *pTempLabel = (Label *)m_pInfoPage->FindChildByName("StaticText");
  586. pTempLabel->SetVisible( false );
  587. KeyValues *pkvModelKeys = new KeyValues( "modelkeys" );
  588. pkvModelKeys->LoadFromBuffer( "modelkeys", hdr->KeyValueText() );
  589. KeyValues *kvPropData = pkvModelKeys->FindKey( "prop_data" );
  590. if ( kvPropData )
  591. {
  592. int iPropDataCount = UpdatePropDataList( kvPropData, bIsStatic );
  593. if( iPropDataCount )
  594. {
  595. bIsPhysics = true;
  596. }
  597. }
  598. else
  599. {
  600. m_pPropDataList->RemoveAll();
  601. }
  602. pkvModelKeys->deleteThis();
  603. CheckButton * pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName("StaticObject");
  604. pTempCheck->SetCheckButtonCheckable( true );
  605. pTempCheck->SetSelected( bIsStatic );
  606. pTempCheck->SetCheckButtonCheckable( false );
  607. pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName("PhysicsObject");
  608. pTempCheck->SetCheckButtonCheckable( true );
  609. pTempCheck->SetSelected( bIsPhysics );
  610. pTempCheck->SetCheckButtonCheckable( false );
  611. pTempCheck = (CheckButton *)m_pInfoPage->FindChildByName("DynamicObject");
  612. pTempCheck->SetCheckButtonCheckable( true );
  613. pTempCheck->SetSelected( !bIsPhysics );
  614. pTempCheck->SetCheckButtonCheckable( false );
  615. }
  616. int CMDLPicker::UpdatePropDataList( KeyValues *pkvPropData, bool &bIsStatic )
  617. {
  618. int iCount = 0;
  619. if ( m_pPropDataList )
  620. {
  621. m_pPropDataList->RemoveAll();
  622. KeyValues *kvItem = pkvPropData->GetFirstSubKey();
  623. while ( kvItem )
  624. {
  625. if ( kvItem->GetDataType() != KeyValues::TYPE_NONE )
  626. {
  627. // Special handling for some keys
  628. if ( !Q_strcmp( kvItem->GetName(), "allowstatic" ) && !Q_strcmp( kvItem->GetString() , "1" ) )
  629. {
  630. if ( !bIsStatic )
  631. {
  632. Label *pTempLabel = (Label *)m_pInfoPage->FindChildByName( "StaticText" );
  633. pTempLabel->SetVisible( true );
  634. }
  635. bIsStatic &= true;
  636. }
  637. KeyValues *pkv = new KeyValues("node", "key", kvItem->GetName(), "value", kvItem->GetString() );
  638. m_pPropDataList->AddItem( pkv, 0, false, false );
  639. iCount++;
  640. }
  641. kvItem = kvItem->GetNextKey();
  642. }
  643. }
  644. return iCount;
  645. }