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.

431 lines
9.9 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <time.h>
  8. #include "MultiplayerAdvancedDialog.h"
  9. #include <vgui/ILocalize.h>
  10. #include <vgui/ISurface.h>
  11. #include <vgui_controls/ListPanel.h>
  12. #include <KeyValues.h>
  13. #include <vgui_controls/Label.h>
  14. #include <vgui_controls/Button.h>
  15. #include <vgui_controls/MessageBox.h>
  16. #include <vgui_controls/CheckButton.h>
  17. #include <vgui_controls/ComboBox.h>
  18. #include <vgui_controls/TextEntry.h>
  19. #include "cvarslider.h"
  20. #include "PanelListPanel.h"
  21. #include <vgui/IInput.h>
  22. #include <steam/steam_api.h>
  23. #include "EngineInterface.h"
  24. #include "fmtstr.h"
  25. #include "filesystem.h"
  26. #include <tier0/vcrmode.h>
  27. // memdbgon must be the last include file in a .cpp file!!!
  28. #include "tier0/memdbgon.h"
  29. using namespace vgui;
  30. #define OPTIONS_DIR "cfg"
  31. #define DEFAULT_OPTIONS_FILE OPTIONS_DIR "/user_default.scr"
  32. #define OPTIONS_FILE OPTIONS_DIR "/user.scr"
  33. //-----------------------------------------------------------------------------
  34. // Purpose: Constructor
  35. //-----------------------------------------------------------------------------
  36. CMultiplayerAdvancedDialog::CMultiplayerAdvancedDialog(vgui::Panel *parent) : BaseClass(NULL, "MultiplayerAdvancedDialog")
  37. {
  38. SetBounds(0, 0, 372, 160);
  39. SetSizeable( false );
  40. SetTitle("#GameUI_MultiplayerAdvanced", true);
  41. Button *cancel = new Button( this, "Cancel", "#GameUI_Cancel" );
  42. cancel->SetCommand( "Close" );
  43. Button *ok = new Button( this, "OK", "#GameUI_OK" );
  44. ok->SetCommand( "Ok" );
  45. m_pListPanel = new CPanelListPanel( this, "PanelListPanel" );
  46. m_pList = NULL;
  47. m_pDescription = new CInfoDescription();
  48. m_pDescription->InitFromFile( DEFAULT_OPTIONS_FILE );
  49. m_pDescription->InitFromFile( OPTIONS_FILE );
  50. m_pDescription->TransferCurrentValues( NULL );
  51. LoadControlSettings("Resource\\MultiplayerAdvancedDialog.res");
  52. CreateControls();
  53. MoveToCenterOfScreen();
  54. SetSizeable( false );
  55. SetDeleteSelfOnClose( true );
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Purpose: Destructor
  59. //-----------------------------------------------------------------------------
  60. CMultiplayerAdvancedDialog::~CMultiplayerAdvancedDialog()
  61. {
  62. delete m_pDescription;
  63. }
  64. //-----------------------------------------------------------------------------
  65. // Purpose:
  66. //-----------------------------------------------------------------------------
  67. void CMultiplayerAdvancedDialog::Activate()
  68. {
  69. BaseClass::Activate();
  70. input()->SetAppModalSurface(GetVPanel());
  71. }
  72. //-----------------------------------------------------------------------------
  73. // Purpose:
  74. //-----------------------------------------------------------------------------
  75. void CMultiplayerAdvancedDialog::OnClose()
  76. {
  77. BaseClass::OnClose();
  78. MarkForDeletion();
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. // Input : *command -
  83. //-----------------------------------------------------------------------------
  84. void CMultiplayerAdvancedDialog::OnCommand( const char *command )
  85. {
  86. if ( !stricmp( command, "Ok" ) )
  87. {
  88. // OnApplyChanges();
  89. SaveValues();
  90. OnClose();
  91. return;
  92. }
  93. BaseClass::OnCommand( command );
  94. }
  95. void CMultiplayerAdvancedDialog::OnKeyCodeTyped(KeyCode code)
  96. {
  97. // force ourselves to be closed if the escape key it pressed
  98. if (code == KEY_ESCAPE)
  99. {
  100. Close();
  101. }
  102. else
  103. {
  104. BaseClass::OnKeyCodeTyped(code);
  105. }
  106. }
  107. //-----------------------------------------------------------------------------
  108. // Purpose:
  109. //-----------------------------------------------------------------------------
  110. void CMultiplayerAdvancedDialog::GatherCurrentValues()
  111. {
  112. if ( !m_pDescription )
  113. return;
  114. // OK
  115. CheckButton *pBox;
  116. TextEntry *pEdit;
  117. ComboBox *pCombo;
  118. CCvarSlider *pSlider;
  119. mpcontrol_t *pList;
  120. CScriptObject *pObj;
  121. CScriptListItem *pItem;
  122. char szValue[256];
  123. char strValue[ 256 ];
  124. pList = m_pList;
  125. while ( pList )
  126. {
  127. pObj = pList->pScrObj;
  128. if ( pObj->type == O_CATEGORY )
  129. {
  130. pList = pList->next;
  131. continue;
  132. }
  133. if ( !pList->pControl )
  134. {
  135. pObj->SetCurValue( pObj->defValue );
  136. pList = pList->next;
  137. continue;
  138. }
  139. switch ( pObj->type )
  140. {
  141. case O_BOOL:
  142. pBox = (CheckButton *)pList->pControl;
  143. sprintf( szValue, "%s", pBox->IsSelected() ? "1" : "0" );
  144. break;
  145. case O_NUMBER:
  146. pEdit = ( TextEntry * )pList->pControl;
  147. pEdit->GetText( strValue, sizeof( strValue ) );
  148. sprintf( szValue, "%s", strValue );
  149. break;
  150. case O_STRING:
  151. pEdit = ( TextEntry * )pList->pControl;
  152. pEdit->GetText( strValue, sizeof( strValue ) );
  153. sprintf( szValue, "%s", strValue );
  154. break;
  155. case O_LIST:
  156. {
  157. pCombo = (ComboBox *)pList->pControl;
  158. // pCombo->GetText( strValue, sizeof( strValue ) );
  159. int activeItem = pCombo->GetActiveItem();
  160. pItem = pObj->pListItems;
  161. // int n = (int)pObj->fdefValue;
  162. while ( pItem )
  163. {
  164. if (!activeItem--)
  165. break;
  166. pItem = pItem->pNext;
  167. }
  168. if ( pItem )
  169. {
  170. sprintf( szValue, "%s", pItem->szValue );
  171. }
  172. else // Couln't find index
  173. {
  174. //assert(!("Couldn't find string in list, using default value"));
  175. sprintf( szValue, "%s", pObj->defValue );
  176. }
  177. break;
  178. }
  179. case O_SLIDER:
  180. pSlider = ( CCvarSlider * )pList->pControl;
  181. sprintf( szValue, "%.2f", pSlider->GetSliderValue() );
  182. break;
  183. }
  184. // Remove double quotes and % characters
  185. UTIL_StripInvalidCharacters( szValue, sizeof(szValue) );
  186. strcpy( strValue, szValue );
  187. pObj->SetCurValue( strValue );
  188. pList = pList->next;
  189. }
  190. }
  191. //-----------------------------------------------------------------------------
  192. // Purpose:
  193. //-----------------------------------------------------------------------------
  194. void CMultiplayerAdvancedDialog::CreateControls()
  195. {
  196. DestroyControls();
  197. // Go through desciption creating controls
  198. CScriptObject *pObj;
  199. pObj = m_pDescription->pObjList;
  200. // Build out the clan dropdown
  201. CScriptObject *pClanObj = m_pDescription->FindObject( "cl_clanid" );
  202. ISteamFriends *pFriends = steamapicontext->SteamFriends();
  203. if ( pFriends && pClanObj )
  204. {
  205. pClanObj->RemoveAndDeleteAllItems();
  206. int iGroupCount = pFriends->GetClanCount();
  207. pClanObj->AddItem( new CScriptListItem( "#Cstrike_ClanTag_None", "0" ) );
  208. for ( int k = 0; k < iGroupCount; ++ k )
  209. {
  210. CSteamID clanID = pFriends->GetClanByIndex( k );
  211. const char *pName = pFriends->GetClanName( clanID );
  212. const char *pTag = pFriends->GetClanTag( clanID );
  213. char id[12];
  214. Q_snprintf( id, sizeof( id ), "%d", clanID.GetAccountID() );
  215. pClanObj->AddItem( new CScriptListItem( CFmtStr( "%s (%s)", pTag, pName ), id ) );
  216. }
  217. }
  218. mpcontrol_t *pCtrl;
  219. CheckButton *pBox;
  220. TextEntry *pEdit;
  221. ComboBox *pCombo;
  222. CCvarSlider *pSlider;
  223. CScriptListItem *pListItem;
  224. Panel *objParent = m_pListPanel;
  225. while ( pObj )
  226. {
  227. if ( pObj->type == O_OBSOLETE || pObj->type == O_CATEGORY )
  228. {
  229. pObj = pObj->pNext;
  230. continue;
  231. }
  232. pCtrl = new mpcontrol_t( objParent, "mpcontrol_t" );
  233. pCtrl->type = pObj->type;
  234. switch ( pCtrl->type )
  235. {
  236. case O_BOOL:
  237. pBox = new CheckButton( pCtrl, "DescCheckButton", pObj->prompt );
  238. pBox->SetSelected( pObj->fdefValue != 0.0f ? true : false );
  239. pCtrl->pControl = (Panel *)pBox;
  240. break;
  241. case O_STRING:
  242. case O_NUMBER:
  243. pEdit = new TextEntry( pCtrl, "DescTextEntry");
  244. pEdit->InsertString(pObj->defValue);
  245. pCtrl->pControl = (Panel *)pEdit;
  246. break;
  247. case O_LIST:
  248. {
  249. pCombo = new ComboBox( pCtrl, "DescComboBox", 5, false );
  250. // track which row matches the current value
  251. int iRow = -1;
  252. int iCount = 0;
  253. pListItem = pObj->pListItems;
  254. while ( pListItem )
  255. {
  256. if ( iRow == -1 && !Q_stricmp( pListItem->szValue, pObj->curValue ) )
  257. iRow = iCount;
  258. pCombo->AddItem( pListItem->szItemText, NULL );
  259. pListItem = pListItem->pNext;
  260. ++iCount;
  261. }
  262. pCombo->ActivateItemByRow( iRow );
  263. pCtrl->pControl = (Panel *)pCombo;
  264. }
  265. break;
  266. case O_SLIDER:
  267. pSlider = new CCvarSlider( pCtrl, "DescSlider", "Test", pObj->fMin, pObj->fMax, pObj->cvarname, false );
  268. pCtrl->pControl = (Panel *)pSlider;
  269. break;
  270. default:
  271. break;
  272. }
  273. if ( pCtrl->type != O_BOOL )
  274. {
  275. pCtrl->pPrompt = new vgui::Label( pCtrl, "DescLabel", "" );
  276. pCtrl->pPrompt->SetContentAlignment( vgui::Label::a_west );
  277. pCtrl->pPrompt->SetTextInset( 5, 0 );
  278. pCtrl->pPrompt->SetText( pObj->prompt );
  279. }
  280. pCtrl->pScrObj = pObj;
  281. switch ( pCtrl->type )
  282. {
  283. case O_BOOL:
  284. case O_STRING:
  285. case O_NUMBER:
  286. case O_LIST:
  287. pCtrl->SetSize( 100, 28 );
  288. break;
  289. case O_SLIDER:
  290. pCtrl->SetSize( 100, 40 );
  291. break;
  292. default:
  293. break;
  294. }
  295. //pCtrl->SetBorder( scheme()->GetBorder(1, "DepressedButtonBorder") );
  296. m_pListPanel->AddItem( pCtrl );
  297. // Link it in
  298. if ( !m_pList )
  299. {
  300. m_pList = pCtrl;
  301. pCtrl->next = NULL;
  302. }
  303. else
  304. {
  305. mpcontrol_t *p;
  306. p = m_pList;
  307. while ( p )
  308. {
  309. if ( !p->next )
  310. {
  311. p->next = pCtrl;
  312. pCtrl->next = NULL;
  313. break;
  314. }
  315. p = p->next;
  316. }
  317. }
  318. pObj = pObj->pNext;
  319. }
  320. }
  321. //-----------------------------------------------------------------------------
  322. // Purpose:
  323. //-----------------------------------------------------------------------------
  324. void CMultiplayerAdvancedDialog::DestroyControls()
  325. {
  326. mpcontrol_t *p, *n;
  327. p = m_pList;
  328. while ( p )
  329. {
  330. n = p->next;
  331. //
  332. delete p->pControl;
  333. delete p->pPrompt;
  334. delete p;
  335. p = n;
  336. }
  337. m_pList = NULL;
  338. }
  339. //-----------------------------------------------------------------------------
  340. // Purpose:
  341. //-----------------------------------------------------------------------------
  342. void CMultiplayerAdvancedDialog::SaveValues()
  343. {
  344. // Get the values from the controls:
  345. GatherCurrentValues();
  346. // Create the game.cfg file
  347. if ( m_pDescription )
  348. {
  349. FileHandle_t fp;
  350. // Add settings to config.cfg
  351. m_pDescription->WriteToConfig();
  352. g_pFullFileSystem->CreateDirHierarchy( OPTIONS_DIR );
  353. fp = g_pFullFileSystem->Open( OPTIONS_FILE, "wb" );
  354. if ( fp )
  355. {
  356. m_pDescription->WriteToScriptFile( fp );
  357. g_pFullFileSystem->Close( fp );
  358. }
  359. }
  360. }