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.

541 lines
15 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //===========================================================================//
  6. #include "dme_controls/dmelogeditpanel.h"
  7. #include "movieobjects/dmelog.h"
  8. #include "vgui_controls/button.h"
  9. #include "vgui_controls/combobox.h"
  10. #include "tier1/KeyValues.h"
  11. using namespace vgui;
  12. //-----------------------------------------------------------------------------
  13. // constructor, destructor
  14. //-----------------------------------------------------------------------------
  15. CDmeLogEditPanel::CDmeLogEditPanel( vgui::Panel *pParent, const char *pName ) : BaseClass( pParent, pName )
  16. {
  17. SetVisible( false );
  18. m_flMinVertical = 0;
  19. m_flMaxVertical = 256;
  20. }
  21. CDmeLogEditPanel::~CDmeLogEditPanel()
  22. {
  23. }
  24. //-----------------------------------------------------------------------------
  25. // Converts normalized values to int time
  26. //-----------------------------------------------------------------------------
  27. DmeTime_t CDmeLogEditPanel::NormalizedToTime( float flIn )
  28. {
  29. return m_minTime + NormalizedToDuration( flIn );
  30. }
  31. DmeTime_t CDmeLogEditPanel::NormalizedToDuration( float flDuration )
  32. {
  33. flDuration = clamp( flDuration, 0.0f, 1.0f );
  34. return flDuration * ( m_maxTime - m_minTime );
  35. }
  36. float CDmeLogEditPanel::TimeToNormalized( DmeTime_t time )
  37. {
  38. if ( m_maxTime == m_minTime )
  39. return 0.0f;
  40. return GetFractionOfTimeBetween( time, m_minTime, m_maxTime, true );
  41. }
  42. float CDmeLogEditPanel::NormalizedToValue( float flValue )
  43. {
  44. return Lerp( flValue, m_flMinVertical, m_flMaxVertical );
  45. }
  46. float CDmeLogEditPanel::ValueToNormalized( float flNormalized )
  47. {
  48. if ( m_flMaxVertical == m_flMinVertical )
  49. return 0.0f;
  50. return (flNormalized - m_flMinVertical) / ( m_flMaxVertical - m_flMinVertical );
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Control points + values...
  54. //-----------------------------------------------------------------------------
  55. int CDmeLogEditPanel::FindOrAddControlPoint( float flIn, float flTolerance, float flOut )
  56. {
  57. Assert( m_hLog.Get() );
  58. DmeTime_t time = NormalizedToTime( flIn );
  59. DmeTime_t tolerance = ( flTolerance >= 0 ) ? NormalizedToDuration( flTolerance ) : DmeTime_t( 0 );
  60. float flValue = NormalizedToValue( flOut );
  61. int nKeyIndex = -1;
  62. Assert( m_hLog.Get() );
  63. switch( m_hLog->GetDataType() )
  64. {
  65. case AT_BOOL:
  66. nKeyIndex = CastElement<CDmeBoolLog >( m_hLog )->FindOrAddKey( time, tolerance, (bool)(flValue >= 0.5f) );
  67. break;
  68. case AT_INT:
  69. nKeyIndex = CastElement<CDmeIntLog >( m_hLog )->FindOrAddKey( time, tolerance, (int)(flValue + 0.5f) );
  70. break;
  71. case AT_FLOAT:
  72. nKeyIndex = CastElement<CDmeFloatLog >( m_hLog )->FindOrAddKey( time, tolerance, flValue );
  73. break;
  74. case AT_COLOR:
  75. {
  76. Color c = CastElement<CDmeColorLog >( m_hLog )->GetValue( time );
  77. int nComp = (int)( flValue + 0.5f );
  78. nComp = clamp( nComp, 0, 255 );
  79. for ( int i = 0; i < 4; ++i )
  80. {
  81. if ( m_LogFieldMask & (1 << i) )
  82. {
  83. c[i] = (unsigned char)nComp;
  84. }
  85. }
  86. nKeyIndex = CastElement<CDmeColorLog >( m_hLog )->FindOrAddKey( time, tolerance, c );
  87. }
  88. break;
  89. case AT_VECTOR2:
  90. nKeyIndex = FindOrAddKey< Vector2D >( time, tolerance, 2, flValue );
  91. break;
  92. case AT_VECTOR3:
  93. nKeyIndex = FindOrAddKey< Vector >( time, tolerance, 3, flValue );
  94. break;
  95. case AT_VECTOR4:
  96. nKeyIndex = FindOrAddKey< Vector4D >( time, tolerance, 4, flValue );
  97. break;
  98. case AT_QANGLE:
  99. nKeyIndex = FindOrAddKey< QAngle >( time, tolerance, 3, flValue );
  100. break;
  101. case AT_QUATERNION:
  102. nKeyIndex = FindOrAddKey< Quaternion >( time, tolerance, 4, flValue );
  103. break;
  104. }
  105. return nKeyIndex;
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Finds a control point within tolerance
  109. //-----------------------------------------------------------------------------
  110. int CDmeLogEditPanel::FindControlPoint( float flIn, float flTolerance )
  111. {
  112. Assert( m_hLog.Get() );
  113. DmeTime_t time = NormalizedToTime( flIn );
  114. DmeTime_t tolerance = NormalizedToDuration( flTolerance );
  115. return m_hLog->FindKeyWithinTolerance( time, tolerance );
  116. }
  117. //-----------------------------------------------------------------------------
  118. // Modifies an existing control point
  119. //-----------------------------------------------------------------------------
  120. int CDmeLogEditPanel::ModifyControlPoint( int nPoint, float flIn, float flOut )
  121. {
  122. Assert( m_hLog.Get() );
  123. DmeTime_t time = NormalizedToTime( flIn );
  124. DmeTime_t initialTime = m_hLog->GetKeyTime( nPoint );
  125. float flValue = NormalizedToValue( flOut );
  126. int nKeyIndex = -1;
  127. Assert( m_hLog.Get() );
  128. switch( m_hLog->GetDataType() )
  129. {
  130. case AT_BOOL:
  131. RemoveControlPoint( nPoint );
  132. nKeyIndex = CastElement<CDmeBoolLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), (bool)(flValue >= 0.5f) );
  133. break;
  134. case AT_INT:
  135. RemoveControlPoint( nPoint );
  136. nKeyIndex = CastElement<CDmeIntLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), (int)(flValue + 0.5f) );
  137. break;
  138. case AT_FLOAT:
  139. RemoveControlPoint( nPoint );
  140. nKeyIndex = CastElement<CDmeFloatLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), flValue );
  141. break;
  142. case AT_COLOR:
  143. {
  144. Color c = CastElement<CDmeColorLog >( m_hLog )->GetValue( initialTime );
  145. int nComp = (int)( flValue + 0.5f );
  146. nComp = clamp( nComp, 0, 255 );
  147. for ( int i = 0; i < 4; ++i )
  148. {
  149. if ( m_LogFieldMask & (1 << i) )
  150. {
  151. c[i] = (unsigned char)nComp;
  152. }
  153. }
  154. RemoveControlPoint( nPoint );
  155. nKeyIndex = CastElement<CDmeColorLog >( m_hLog )->FindOrAddKey( time, DmeTime_t( 0 ), c );
  156. }
  157. break;
  158. case AT_VECTOR2:
  159. nKeyIndex = ModifyKey< Vector2D >( nPoint, initialTime, time, 2, flValue );
  160. break;
  161. case AT_VECTOR3:
  162. nKeyIndex = ModifyKey< Vector >( nPoint, initialTime, time, 3, flValue );
  163. break;
  164. case AT_VECTOR4:
  165. nKeyIndex = ModifyKey< Vector4D >( nPoint, initialTime, time, 4, flValue );
  166. break;
  167. case AT_QANGLE:
  168. nKeyIndex = ModifyKey< QAngle >( nPoint, initialTime, time, 3, flValue );
  169. break;
  170. case AT_QUATERNION:
  171. nKeyIndex = ModifyKey< Quaternion >( nPoint, initialTime, time, 4, flValue );
  172. break;
  173. }
  174. return nKeyIndex;
  175. }
  176. //-----------------------------------------------------------------------------
  177. // Removes a single control point
  178. //-----------------------------------------------------------------------------
  179. void CDmeLogEditPanel::RemoveControlPoint( int nPoint )
  180. {
  181. Assert( m_hLog.Get() );
  182. m_hLog->RemoveKey( nPoint );
  183. }
  184. //-----------------------------------------------------------------------------
  185. // Gets the interpolated value of the log based on normalized time
  186. //-----------------------------------------------------------------------------
  187. float CDmeLogEditPanel::GetValue( float flIn )
  188. {
  189. DmeTime_t time = NormalizedToTime( flIn );
  190. float flValue = 0.0f;
  191. Assert( m_hLog.Get() );
  192. switch( m_hLog->GetDataType() )
  193. {
  194. case AT_BOOL:
  195. flValue = CastElement<CDmeBoolLog >( m_hLog )->GetValue( time );
  196. break;
  197. case AT_INT:
  198. flValue = CastElement<CDmeIntLog >( m_hLog )->GetValue( time );
  199. break;
  200. case AT_FLOAT:
  201. flValue = CastElement<CDmeFloatLog >( m_hLog )->GetValue( time );
  202. break;
  203. case AT_COLOR:
  204. {
  205. Color c = CastElement<CDmeColorLog >( m_hLog )->GetValue( time );
  206. flValue = c[m_nFieldIndex];
  207. }
  208. break;
  209. case AT_VECTOR2:
  210. flValue = CastElement<CDmeVector2Log >( m_hLog )->GetValue( time )[m_nFieldIndex];
  211. break;
  212. case AT_VECTOR3:
  213. flValue = CastElement<CDmeVector3Log >( m_hLog )->GetValue( time )[m_nFieldIndex];
  214. break;
  215. case AT_VECTOR4:
  216. flValue = CastElement<CDmeVector2Log >( m_hLog )->GetValue( time )[m_nFieldIndex];
  217. break;
  218. case AT_QANGLE:
  219. flValue = CastElement<CDmeQAngleLog >( m_hLog )->GetValue( time )[m_nFieldIndex];
  220. break;
  221. case AT_QUATERNION:
  222. flValue = CastElement<CDmeQuaternionLog >( m_hLog )->GetValue( time )[m_nFieldIndex];
  223. break;
  224. }
  225. return ValueToNormalized( flValue );
  226. }
  227. int CDmeLogEditPanel::ControlPointCount()
  228. {
  229. Assert( m_hLog.Get() );
  230. return m_hLog->GetKeyCount( );
  231. }
  232. //-----------------------------------------------------------------------------
  233. // Gets a particular control point's value
  234. //-----------------------------------------------------------------------------
  235. void CDmeLogEditPanel::GetControlPoint( int nPoint, float *pIn, float *pOut )
  236. {
  237. Assert( m_hLog.Get() );
  238. DmeTime_t time = m_hLog->GetKeyTime( nPoint );
  239. *pIn = TimeToNormalized( time );
  240. float flValue = 0.0f;
  241. Assert( m_hLog.Get() );
  242. switch( m_hLog->GetDataType() )
  243. {
  244. case AT_BOOL:
  245. flValue = CastElement<CDmeBoolLog >( m_hLog )->GetKeyValue( nPoint );
  246. break;
  247. case AT_INT:
  248. flValue = CastElement<CDmeIntLog >( m_hLog )->GetKeyValue( nPoint );
  249. break;
  250. case AT_FLOAT:
  251. flValue = CastElement<CDmeFloatLog >( m_hLog )->GetKeyValue( nPoint );
  252. break;
  253. case AT_COLOR:
  254. {
  255. Color c = CastElement<CDmeColorLog >( m_hLog )->GetKeyValue( nPoint );
  256. flValue = c[m_nFieldIndex];
  257. }
  258. break;
  259. case AT_VECTOR2:
  260. flValue = CastElement<CDmeVector2Log >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
  261. break;
  262. case AT_VECTOR3:
  263. flValue = CastElement<CDmeVector3Log >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
  264. break;
  265. case AT_VECTOR4:
  266. flValue = CastElement<CDmeVector2Log >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
  267. break;
  268. case AT_QANGLE:
  269. flValue = CastElement<CDmeQAngleLog >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
  270. break;
  271. case AT_QUATERNION:
  272. flValue = CastElement<CDmeQuaternionLog >( m_hLog )->GetKeyValue( nPoint )[m_nFieldIndex];
  273. break;
  274. }
  275. *pOut = ValueToNormalized( flValue );
  276. }
  277. //-----------------------------------------------------------------------------
  278. // Sets the log to edit
  279. //-----------------------------------------------------------------------------
  280. void CDmeLogEditPanel::SetDmeLog( CDmeLog *pLog )
  281. {
  282. bool bValid = pLog && ( pLog->GetDataType() == AT_INT || pLog->GetDataType() == AT_FLOAT || pLog->GetDataType() == AT_COLOR );
  283. if ( bValid )
  284. {
  285. m_hLog = pLog;
  286. }
  287. else
  288. {
  289. m_minTime.SetSeconds( 0.0f );
  290. m_maxTime.SetSeconds( 0.0f );
  291. }
  292. SetVisible( bValid );
  293. }
  294. void CDmeLogEditPanel::SetMask( int nMask )
  295. {
  296. m_LogFieldMask = nMask;
  297. m_nFieldIndex = 0;
  298. for ( int i = 0; i < 4; ++i )
  299. {
  300. if ( m_LogFieldMask & (1 << i) )
  301. {
  302. m_nFieldIndex = i;
  303. break;
  304. }
  305. }
  306. }
  307. //-----------------------------------------------------------------------------
  308. // Sets the time range on the view in ms
  309. //-----------------------------------------------------------------------------
  310. void CDmeLogEditPanel::SetTimeRange( DmeTime_t startTime, DmeTime_t endTime )
  311. {
  312. m_minTime = startTime;
  313. m_maxTime = endTime;
  314. }
  315. //-----------------------------------------------------------------------------
  316. // Sets the vertical range on the view
  317. //-----------------------------------------------------------------------------
  318. void CDmeLogEditPanel::SetVerticalRange( float flMin, float flMax )
  319. {
  320. m_flMinVertical = flMin;
  321. m_flMaxVertical = flMax;
  322. }
  323. //-----------------------------------------------------------------------------
  324. //
  325. // Purpose: Modal picker frame
  326. //
  327. //-----------------------------------------------------------------------------
  328. CDmeLogEditFrame::CDmeLogEditFrame( vgui::Panel *pParent, const char *pTitle ) :
  329. BaseClass( pParent, "DmeLogEditFrame" )
  330. {
  331. m_pContextKeyValues = NULL;
  332. SetDeleteSelfOnClose( true );
  333. m_pCurveEditor = new CDmeLogEditPanel( this, "DmeLogEditPanel" );
  334. m_pOkButton = new Button( this, "OkButton", "#GameUI_OK", this, "Ok" );
  335. m_pCancelButton = new Button( this, "CancelButton", "#GameUI_Cancel", this, "Cancel" );
  336. m_pFilter = new ComboBox( this, "LogFilter", 5, false );
  337. SetBlockDragChaining( true );
  338. LoadControlSettingsAndUserConfig( "resource/dmelogeditframe.res" );
  339. SetTitle( pTitle, false );
  340. }
  341. CDmeLogEditFrame::~CDmeLogEditFrame()
  342. {
  343. CleanUpMessage();
  344. }
  345. //-----------------------------------------------------------------------------
  346. // Deletes the message
  347. //-----------------------------------------------------------------------------
  348. void CDmeLogEditFrame::CleanUpMessage()
  349. {
  350. if ( m_pContextKeyValues )
  351. {
  352. m_pContextKeyValues->deleteThis();
  353. m_pContextKeyValues = NULL;
  354. }
  355. }
  356. //-----------------------------------------------------------------------------
  357. // Purpose: Called when the combo box changes
  358. //-----------------------------------------------------------------------------
  359. void CDmeLogEditFrame::OnTextChanged( )
  360. {
  361. KeyValues *pKeyValues = m_pFilter->GetActiveItemUserData();
  362. int nMask = pKeyValues->GetInt( "Value", CDmeLogEditPanel::FIELD_ALL );
  363. m_pCurveEditor->SetMask( nMask );
  364. }
  365. //-----------------------------------------------------------------------------
  366. // Purpose: Activate the dialog
  367. //-----------------------------------------------------------------------------
  368. void CDmeLogEditFrame::DoModal( CDmeLog *pLog, DmeTime_t startTime, DmeTime_t endTime, KeyValues *pKeyValues )
  369. {
  370. CleanUpMessage();
  371. m_pContextKeyValues = pKeyValues;
  372. m_pCurveEditor->SetDmeLog( pLog );
  373. m_pCurveEditor->SetTimeRange( startTime, endTime );
  374. m_pFilter->SetVisible( true );
  375. m_pFilter->RemoveAll();
  376. switch( pLog->GetDataType() )
  377. {
  378. case AT_BOOL:
  379. case AT_INT:
  380. case AT_FLOAT:
  381. m_pFilter->SetVisible( false );
  382. break;
  383. case AT_COLOR:
  384. m_pFilter->AddItem( "RGB Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_R | CDmeLogEditPanel::FIELD_G | CDmeLogEditPanel::FIELD_B ) );
  385. m_pFilter->AddItem( "Red Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_R ) );
  386. m_pFilter->AddItem( "Green Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_G ) );
  387. m_pFilter->AddItem( "Blue Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_B ) );
  388. m_pFilter->AddItem( "Alpha Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_A ) );
  389. break;
  390. case AT_VECTOR2:
  391. m_pFilter->AddItem( "X Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_X ) );
  392. m_pFilter->AddItem( "Y Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Y ) );
  393. break;
  394. case AT_VECTOR3:
  395. case AT_QANGLE:
  396. m_pFilter->AddItem( "X Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_X ) );
  397. m_pFilter->AddItem( "Y Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Y ) );
  398. m_pFilter->AddItem( "Z Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Z ) );
  399. break;
  400. case AT_VECTOR4:
  401. case AT_QUATERNION:
  402. m_pFilter->AddItem( "X Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_X ) );
  403. m_pFilter->AddItem( "Y Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Y ) );
  404. m_pFilter->AddItem( "Z Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_Z ) );
  405. m_pFilter->AddItem( "W Channel", new KeyValues( "Mask", "Value", CDmeLogEditPanel::FIELD_W ) );
  406. break;
  407. }
  408. if ( m_pFilter->IsVisible() )
  409. {
  410. // Will cause the mask to be set
  411. m_pFilter->ActivateItemByRow( 0 );
  412. }
  413. else
  414. {
  415. m_pCurveEditor->SetMask( CDmeLogEditPanel::FIELD_ALL );
  416. }
  417. BaseClass::DoModal();
  418. }
  419. //-----------------------------------------------------------------------------
  420. // On command
  421. //-----------------------------------------------------------------------------
  422. void CDmeLogEditFrame::OnCommand( const char *pCommand )
  423. {
  424. if ( !Q_stricmp( pCommand, "Ok" ) )
  425. {
  426. KeyValues *pActionKeys = new KeyValues( "LogEdited" );
  427. if ( m_pContextKeyValues )
  428. {
  429. pActionKeys->AddSubKey( m_pContextKeyValues );
  430. // This prevents them from being deleted later
  431. m_pContextKeyValues = NULL;
  432. }
  433. PostActionSignal( pActionKeys );
  434. CloseModal();
  435. return;
  436. }
  437. if ( !Q_stricmp( pCommand, "Cancel" ) )
  438. {
  439. CloseModal();
  440. return;
  441. }
  442. BaseClass::OnCommand( pCommand );
  443. }