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.

242 lines
5.8 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include "resource.h"
  8. #include "ProgressDialog.h"
  9. #include "mxtk/mx.h"
  10. #include "mdlviewer.h"
  11. #include "tier1/utlstring.h"
  12. #include "tier1/strtools.h"
  13. #include "tier1/fmtstr.h"
  14. #include <CommCtrl.h>
  15. class CProgressDialog : public IProgressDialog
  16. {
  17. public:
  18. CProgressDialog();
  19. void Start( char const *pchTitle, char const *pchText, bool bShowCancel );
  20. void Update( float flZeroToOneFraction );
  21. void UpdateText( char const *pchFmt, ... );
  22. bool IsCancelled();
  23. void Finish();
  24. static BOOL CALLBACK ProgressDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
  25. private:
  26. BOOL ProgressDialogProcImpl( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam );
  27. CUtlString m_sTitle;
  28. CUtlString m_sStatus;
  29. float m_flFraction;
  30. bool m_bShowCancel;
  31. bool m_bWantsCancel;
  32. HWND m_hwndDlg;
  33. double m_flStartTime;
  34. };
  35. static CProgressDialog g_ProgressDialog;
  36. IProgressDialog *g_pProgressDialog = &g_ProgressDialog;
  37. CProgressDialog::CProgressDialog() :
  38. m_flFraction( 0.0f ), m_hwndDlg( 0 ), m_bShowCancel( false ), m_bWantsCancel( false ), m_flStartTime( 0.0f )
  39. {
  40. }
  41. bool CProgressDialog::IsCancelled()
  42. {
  43. return m_bShowCancel && m_bWantsCancel;
  44. }
  45. //-----------------------------------------------------------------------------
  46. // Purpose:
  47. // Input : hwndDlg -
  48. // uMsg -
  49. // wParam -
  50. // lParam -
  51. // Output : static BOOL CALLBACK
  52. //-----------------------------------------------------------------------------
  53. BOOL CALLBACK CProgressDialog::ProgressDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  54. {
  55. return g_ProgressDialog.ProgressDialogProcImpl( hwndDlg, uMsg, wParam, lParam );
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Purpose:
  59. // Input : *view -
  60. // *actor -
  61. // Output : int
  62. //-----------------------------------------------------------------------------
  63. void CProgressDialog::Start( char const *pchTitle, char const *pchText, bool bShowCancel )
  64. {
  65. if ( m_hwndDlg )
  66. {
  67. Finish();
  68. }
  69. Assert( NULL == m_hwndDlg );
  70. m_sTitle = pchTitle;
  71. m_sStatus = pchText;
  72. m_flFraction = 0.0f;
  73. m_bShowCancel = bShowCancel;
  74. m_bWantsCancel = false;
  75. m_flStartTime = Plat_FloatTime();
  76. m_hwndDlg = CreateDialog( (HINSTANCE)GetModuleHandle( 0 ),
  77. MAKEINTRESOURCE( IDD_PROGRESS ),
  78. (HWND)g_MDLViewer->getHandle(),
  79. (DLGPROC)ProgressDialogProc );
  80. }
  81. void CProgressDialog::Update( float flZeroToOneFraction )
  82. {
  83. m_flFraction = clamp( flZeroToOneFraction, 0.0f, 1.0f );
  84. // Update the progress bar
  85. HWND pb = GetDlgItem( m_hwndDlg, IDC_FP_PROGRESS );
  86. int pos = clamp( (int)( 1000.0f * flZeroToOneFraction ), 0, 1000 );
  87. SendMessage( pb, (UINT) PBM_SETPOS, pos, 0 );
  88. HWND btn = GetDlgItem( m_hwndDlg, IDCANCEL );
  89. LRESULT lr = SendMessage( btn, BM_GETSTATE, 0, 0 );
  90. if ( lr & BST_PUSHED )
  91. {
  92. m_bWantsCancel = true;
  93. }
  94. if ( GetAsyncKeyState( VK_ESCAPE ) )
  95. {
  96. m_bWantsCancel = true;
  97. }
  98. mx::check();
  99. }
  100. void CProgressDialog::UpdateText( char const *pchFmt, ... )
  101. {
  102. char buf[ 2048 ];
  103. va_list argptr;
  104. va_start( argptr, pchFmt );
  105. Q_vsnprintf( buf, sizeof( buf ), pchFmt, argptr );
  106. va_end( argptr );
  107. m_sStatus = buf;
  108. SetDlgItemText( m_hwndDlg, IDC_FP_PROGRESS_TEXT, CFmtStr( "%s", m_sStatus.String() ) );
  109. SetDlgItemText( m_hwndDlg, IDC_FP_PROGRESS_PERCENT, CFmtStr( "%.2f %%", m_flFraction * 100.0f ) );
  110. double elapsed = Plat_FloatTime() - m_flStartTime;
  111. double flPercentagePerSecond = 0.0f;
  112. if ( m_flFraction > 0.0f )
  113. {
  114. flPercentagePerSecond = elapsed / m_flFraction;
  115. }
  116. double flSecondsRemaining = flPercentagePerSecond * ( 1.0f - m_flFraction );
  117. int seconds = (int)flSecondsRemaining;
  118. CFmtStr string;
  119. int hours = 0;
  120. int minutes = seconds / 60;
  121. if ( minutes > 0 )
  122. {
  123. seconds -= (minutes * 60);
  124. hours = minutes / 60;
  125. if ( hours > 0 )
  126. {
  127. minutes -= (hours * 60);
  128. }
  129. }
  130. if ( hours > 0 )
  131. {
  132. string.sprintf( "Time Remaining: %2i:%02i:%02i", hours, minutes, seconds );
  133. }
  134. else
  135. {
  136. string.sprintf( "Time Remaining: %02i:%02i", minutes, seconds );
  137. }
  138. SetDlgItemText( m_hwndDlg, IDC_FP_PROGRESS_ETA, string.Access() );
  139. }
  140. void CProgressDialog::Finish()
  141. {
  142. if ( !m_hwndDlg )
  143. return;
  144. DestroyWindow( m_hwndDlg );
  145. m_hwndDlg = NULL;
  146. }
  147. BOOL CProgressDialog::ProgressDialogProcImpl( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  148. {
  149. switch(uMsg)
  150. {
  151. case WM_INITDIALOG:
  152. // Insert code here to put the string (to find and replace with)
  153. // into the edit controls.
  154. // ...
  155. {
  156. RECT rcDlg;
  157. GetWindowRect( hwndDlg, &rcDlg );
  158. // Get relative to primary monitor instead of actual window parent
  159. RECT rcParent;
  160. rcParent.left = 0;
  161. rcParent.right = rcParent.left + GetSystemMetrics( SM_CXFULLSCREEN );
  162. rcParent.top = 0;
  163. rcParent.bottom = rcParent.top + GetSystemMetrics( SM_CYFULLSCREEN );
  164. int dialogw, dialogh;
  165. int parentw, parenth;
  166. parentw = rcParent.right - rcParent.left;
  167. parenth = rcParent.bottom - rcParent.top;
  168. dialogw = rcDlg.right - rcDlg.left;
  169. dialogh = rcDlg.bottom - rcDlg.top;
  170. int dlgleft, dlgtop;
  171. dlgleft = ( parentw - dialogw ) / 2;
  172. dlgtop = ( parenth - dialogh ) / 2;
  173. MoveWindow( hwndDlg,
  174. dlgleft,
  175. dlgtop,
  176. dialogw,
  177. dialogh,
  178. TRUE
  179. );
  180. SetDlgItemText( hwndDlg, IDC_FP_PROGRESS_TITLE, m_sTitle.String() );
  181. SetDlgItemText( hwndDlg, IDC_FP_PROGRESS_TEXT, m_sStatus.String() );
  182. HWND pb = GetDlgItem( hwndDlg, IDC_FP_PROGRESS );
  183. SendMessage( pb, (UINT) PBM_SETRANGE, 0, MAKELPARAM( 0, 1000 ) );
  184. ShowWindow( GetDlgItem( hwndDlg, IDCANCEL ), m_bShowCancel ? SW_SHOW : SW_HIDE );
  185. Update( 0.0f );
  186. }
  187. return FALSE;
  188. case WM_COMMAND:
  189. switch (LOWORD(wParam))
  190. {
  191. case IDCANCEL:
  192. m_bWantsCancel = true;
  193. break;
  194. }
  195. return TRUE;
  196. }
  197. return FALSE;
  198. }