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.

1443 lines
38 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <utlvector.h>
  10. #include <vgui/IInput.h>
  11. #include <vgui/ILocalize.h>
  12. #include <vgui/ISurface.h>
  13. #include <vgui/ISystem.h>
  14. #include <vgui/KeyCode.h>
  15. #include <keyvalues.h>
  16. #include <vgui/MouseCode.h>
  17. #include <vgui_controls/BuildModeDialog.h>
  18. #include <vgui_controls/Label.h>
  19. #include <vgui_controls/TextEntry.h>
  20. #include <vgui_controls/Button.h>
  21. #include <vgui_controls/CheckButton.h>
  22. #include <vgui_controls/RadioButton.h>
  23. #include <vgui_controls/MenuButton.h>
  24. #include <vgui_controls/ComboBox.h>
  25. #include <vgui_controls/BuildGroup.h>
  26. #include <vgui_controls/MessageBox.h>
  27. #include <vgui_controls/Menu.h>
  28. #include <vgui_controls/Divider.h>
  29. #include <vgui_controls/PanelListPanel.h>
  30. // memdbgon must be the last include file in a .cpp file!!!
  31. #include <tier0/memdbgon.h>
  32. using namespace vgui;
  33. struct PanelItem_t
  34. {
  35. PanelItem_t() : m_EditLabel(NULL) {}
  36. Panel *m_EditLabel;
  37. TextEntry *m_EditPanel;
  38. ComboBox *m_pCombo;
  39. Button *m_EditButton;
  40. char m_szName[64];
  41. int m_iType;
  42. };
  43. class CSmallTextEntry : public TextEntry
  44. {
  45. DECLARE_CLASS_SIMPLE( CSmallTextEntry, TextEntry );
  46. public:
  47. CSmallTextEntry( Panel *parent, char const *panelName ) :
  48. BaseClass( parent, panelName )
  49. {
  50. }
  51. virtual void ApplySchemeSettings( IScheme *scheme )
  52. {
  53. BaseClass::ApplySchemeSettings( scheme );
  54. SetFont( scheme->GetFont( "DefaultVerySmall" ) );
  55. }
  56. };
  57. //-----------------------------------------------------------------------------
  58. // Purpose: Holds a list of all the edit fields for the currently selected panel
  59. //-----------------------------------------------------------------------------
  60. class BuildModeDialog::PanelList
  61. {
  62. public:
  63. CUtlVector<PanelItem_t> m_PanelList;
  64. void AddItem( Panel *label, TextEntry *edit, ComboBox *combo, Button *button, const char *name, int type )
  65. {
  66. PanelItem_t item;
  67. item.m_EditLabel = label;
  68. item.m_EditPanel = edit;
  69. Q_strncpy(item.m_szName, name, sizeof(item.m_szName));
  70. item.m_iType = type;
  71. item.m_pCombo = combo;
  72. item.m_EditButton = button;
  73. m_PanelList.AddToTail( item );
  74. }
  75. void RemoveAll( void )
  76. {
  77. for ( int i = 0; i < m_PanelList.Count(); i++ )
  78. {
  79. PanelItem_t *item = &m_PanelList[i];
  80. delete item->m_EditLabel;
  81. delete item->m_EditPanel;
  82. delete item->m_EditButton;
  83. }
  84. m_PanelList.RemoveAll();
  85. m_pControls->RemoveAll();
  86. }
  87. KeyValues *m_pResourceData;
  88. PanelListPanel *m_pControls;
  89. };
  90. //-----------------------------------------------------------------------------
  91. // Purpose: Dialog for adding localized strings
  92. //-----------------------------------------------------------------------------
  93. class BuildModeLocalizedStringEditDialog : public Frame
  94. {
  95. DECLARE_CLASS_SIMPLE(BuildModeLocalizedStringEditDialog, Frame);
  96. public:
  97. #pragma warning( disable : 4355 )
  98. BuildModeLocalizedStringEditDialog() : Frame(this, NULL)
  99. {
  100. m_pTokenEntry = new TextEntry(this, NULL);
  101. m_pValueEntry = new TextEntry(this, NULL);
  102. m_pFileCombo = new ComboBox(this, NULL, 12, false);
  103. m_pOKButton = new Button(this, NULL, "OK");
  104. m_pCancelButton = new Button(this, NULL, "Cancel");
  105. m_pCancelButton->SetCommand("Close");
  106. m_pOKButton->SetCommand("OK");
  107. // add the files to the combo
  108. for (int i = 0; i < g_pVGuiLocalize->GetLocalizationFileCount(); i++)
  109. {
  110. m_pFileCombo->AddItem(g_pVGuiLocalize->GetLocalizationFileName(i), NULL);
  111. }
  112. }
  113. #pragma warning( default : 4355 )
  114. virtual void DoModal(const char *token)
  115. {
  116. input()->SetAppModalSurface(GetVPanel());
  117. // setup data
  118. m_pTokenEntry->SetText(token);
  119. // lookup the value
  120. StringIndex_t val = g_pVGuiLocalize->FindIndex(token);
  121. if (val != INVALID_STRING_INDEX)
  122. {
  123. m_pValueEntry->SetText(g_pVGuiLocalize->GetValueByIndex(val));
  124. // set the place in the file combo
  125. m_pFileCombo->SetText(g_pVGuiLocalize->GetFileNameByIndex(val));
  126. }
  127. else
  128. {
  129. m_pValueEntry->SetText("");
  130. }
  131. }
  132. private:
  133. virtual void PerformLayout()
  134. {
  135. }
  136. virtual void OnClose()
  137. {
  138. input()->SetAppModalSurface(NULL);
  139. BaseClass::OnClose();
  140. //PostActionSignal(new KeyValues("Command"
  141. }
  142. virtual void OnCommand(const char *command)
  143. {
  144. if (!stricmp(command, "OK"))
  145. {
  146. //!! apply changes
  147. }
  148. else
  149. {
  150. BaseClass::OnCommand(command);
  151. }
  152. }
  153. vgui::TextEntry *m_pTokenEntry;
  154. vgui::TextEntry *m_pValueEntry;
  155. vgui::ComboBox *m_pFileCombo;
  156. vgui::Button *m_pOKButton;
  157. vgui::Button *m_pCancelButton;
  158. };
  159. class CBuildModeDialogMgr
  160. {
  161. public:
  162. void Add( BuildModeDialog *pDlg );
  163. void Remove( BuildModeDialog *pDlg );
  164. int Count() const;
  165. private:
  166. CUtlVector< BuildModeDialog * > m_vecBuildDialogs;
  167. };
  168. static CBuildModeDialogMgr g_BuildModeDialogMgr;
  169. void CBuildModeDialogMgr::Add( BuildModeDialog *pDlg )
  170. {
  171. if ( m_vecBuildDialogs.Find( pDlg ) == m_vecBuildDialogs.InvalidIndex() )
  172. {
  173. m_vecBuildDialogs.AddToTail( pDlg );
  174. }
  175. }
  176. void CBuildModeDialogMgr::Remove( BuildModeDialog *pDlg )
  177. {
  178. m_vecBuildDialogs.FindAndRemove( pDlg );
  179. }
  180. int CBuildModeDialogMgr::Count() const
  181. {
  182. return m_vecBuildDialogs.Count();
  183. }
  184. int GetBuildModeDialogCount()
  185. {
  186. return g_BuildModeDialogMgr.Count();
  187. }
  188. //-----------------------------------------------------------------------------
  189. // Purpose: Constructor
  190. //-----------------------------------------------------------------------------
  191. BuildModeDialog::BuildModeDialog(BuildGroup *buildGroup) : Frame(buildGroup->GetContextPanel(), "BuildModeDialog")
  192. {
  193. SetMinimumSize(300, 256);
  194. SetSize(300, 420);
  195. m_pCurrentPanel = NULL;
  196. m_pEditableParents = NULL;
  197. m_pEditableChildren = NULL;
  198. m_pNextChild = NULL;
  199. m_pPrevChild = NULL;
  200. m_pBuildGroup = buildGroup;
  201. _undoSettings = NULL;
  202. _copySettings = NULL;
  203. _autoUpdate = false;
  204. MakePopup();
  205. SetTitle("VGUI Build Mode Editor", true);
  206. CreateControls();
  207. LoadUserConfig("BuildModeDialog");
  208. g_BuildModeDialogMgr.Add( this );
  209. }
  210. //-----------------------------------------------------------------------------
  211. // Purpose: Destructor
  212. //-----------------------------------------------------------------------------
  213. BuildModeDialog::~BuildModeDialog()
  214. {
  215. g_BuildModeDialogMgr.Remove( this );
  216. m_pPanelList->m_pResourceData->deleteThis();
  217. m_pPanelList->m_pControls->DeleteAllItems();
  218. if (_undoSettings)
  219. _undoSettings->deleteThis();
  220. if (_copySettings)
  221. _copySettings->deleteThis();
  222. }
  223. //-----------------------------------------------------------------------------
  224. // Purpose: makes sure build mode has been shut down properly
  225. //-----------------------------------------------------------------------------
  226. void BuildModeDialog::OnClose()
  227. {
  228. if (m_pBuildGroup->IsEnabled())
  229. {
  230. m_pBuildGroup->SetEnabled(false);
  231. }
  232. else
  233. {
  234. BaseClass::OnClose();
  235. MarkForDeletion();
  236. }
  237. }
  238. class CBuildModeNavCombo : public ComboBox
  239. {
  240. DECLARE_CLASS_SIMPLE( CBuildModeNavCombo, ComboBox );
  241. public:
  242. CBuildModeNavCombo(Panel *parent, const char *panelName, int numLines, bool allowEdit, bool getParents, Panel *context ) :
  243. BaseClass( parent, panelName, numLines, allowEdit ),
  244. m_bParents( getParents )
  245. {
  246. m_hContext = context;
  247. }
  248. virtual void OnShowMenu(Menu *menu)
  249. {
  250. menu->DeleteAllItems();
  251. if ( !m_hContext.Get() )
  252. return;
  253. if ( m_bParents )
  254. {
  255. Panel *p = m_hContext->GetParent();
  256. while ( p )
  257. {
  258. EditablePanel *ep = dynamic_cast < EditablePanel * >( p );
  259. if ( ep && ep->GetBuildGroup() )
  260. {
  261. KeyValues *kv = new KeyValues( "Panel" );
  262. kv->SetPtr( "ptr", p );
  263. char const *text = ep->GetName() ? ep->GetName() : "unnamed";
  264. menu->AddMenuItem( text, new KeyValues("SetText", "text", text), GetParent(), kv );
  265. }
  266. p = p->GetParent();
  267. }
  268. }
  269. else
  270. {
  271. int i;
  272. int c = m_hContext->GetChildCount();
  273. for ( i = 0; i < c; ++i )
  274. {
  275. EditablePanel *ep = dynamic_cast < EditablePanel * >( m_hContext->GetChild( i ) );
  276. if ( ep && ep->IsVisible() && ep->GetBuildGroup() )
  277. {
  278. KeyValues *kv = new KeyValues( "Panel" );
  279. kv->SetPtr( "ptr", ep );
  280. char const *text = ep->GetName() ? ep->GetName() : "unnamed";
  281. menu->AddMenuItem( text, new KeyValues("SetText", "text", text), GetParent(), kv );
  282. }
  283. }
  284. }
  285. }
  286. private:
  287. bool m_bParents;
  288. vgui::PHandle m_hContext;
  289. };
  290. //-----------------------------------------------------------------------------
  291. // Purpose: Creates the build mode editing controls
  292. //-----------------------------------------------------------------------------
  293. void BuildModeDialog::CreateControls()
  294. {
  295. int i;
  296. m_pPanelList = new PanelList;
  297. m_pPanelList->m_pResourceData = new KeyValues( "BuildDialog" );
  298. m_pPanelList->m_pControls = new PanelListPanel(this, "BuildModeControls");
  299. // file to edit combo box is first
  300. m_pFileSelectionCombo = new ComboBox(this, "FileSelectionCombo", 10, false);
  301. for ( i = 0; i < m_pBuildGroup->GetRegisteredControlSettingsFileCount(); i++)
  302. {
  303. m_pFileSelectionCombo->AddItem(m_pBuildGroup->GetRegisteredControlSettingsFileByIndex(i), NULL);
  304. }
  305. if (m_pFileSelectionCombo->GetItemCount() < 2)
  306. {
  307. m_pFileSelectionCombo->SetEnabled(false);
  308. }
  309. int buttonH = 18;
  310. // status info at top of dialog
  311. m_pStatusLabel = new Label(this, "StatusLabel", "[nothing currently selected]");
  312. m_pStatusLabel->SetTextColorState(Label::CS_DULL);
  313. m_pStatusLabel->SetTall( buttonH );
  314. m_pDivider = new Divider(this, "Divider");
  315. // drop-down combo box for adding new controls
  316. m_pAddNewControlCombo = new ComboBox(this, NULL, 30, false);
  317. m_pAddNewControlCombo->SetSize(116, buttonH);
  318. m_pAddNewControlCombo->SetOpenDirection(Menu::DOWN);
  319. m_pEditableParents = new CBuildModeNavCombo( this, NULL, 15, false, true, m_pBuildGroup->GetContextPanel() );
  320. m_pEditableParents->SetSize(116, buttonH);
  321. m_pEditableParents->SetOpenDirection(Menu::DOWN);
  322. m_pEditableChildren = new CBuildModeNavCombo( this, NULL, 15, false, false, m_pBuildGroup->GetContextPanel() );
  323. m_pEditableChildren->SetSize(116, buttonH);
  324. m_pEditableChildren->SetOpenDirection(Menu::DOWN);
  325. m_pNextChild = new Button( this, "NextChild", "Next", this );
  326. m_pNextChild->SetCommand( new KeyValues( "OnChangeChild", "direction", 1 ) );
  327. m_pPrevChild = new Button( this, "PrevChild", "Prev", this );
  328. m_pPrevChild->SetCommand( new KeyValues( "OnChangeChild", "direction", -1 ) );
  329. // controls that can be added
  330. // this list comes from controls EditablePanel can create by name.
  331. int defaultItem = m_pAddNewControlCombo->AddItem("None", NULL);
  332. CUtlVector< char const * > names;
  333. CBuildFactoryHelper::GetFactoryNames( names );
  334. // Sort the names
  335. CUtlRBTree< char const *, int > sorted( 0, 0, StringLessThan );
  336. for ( i = 0; i < names.Count(); ++i )
  337. {
  338. sorted.Insert( names[ i ] );
  339. }
  340. for ( i = sorted.FirstInorder(); i != sorted.InvalidIndex(); i = sorted.NextInorder( i ) )
  341. {
  342. m_pAddNewControlCombo->AddItem( sorted[ i ], NULL );
  343. }
  344. m_pAddNewControlCombo->ActivateItem(defaultItem);
  345. m_pExitButton = new Button(this, "ExitButton", "&Exit");
  346. m_pExitButton->SetSize(64, buttonH);
  347. m_pSaveButton = new Button(this, "SaveButton", "&Save");
  348. m_pSaveButton->SetSize(64, buttonH);
  349. m_pApplyButton = new Button(this, "ApplyButton", "&Apply");
  350. m_pApplyButton->SetSize(64, buttonH);
  351. m_pReloadLocalization = new Button( this, "Localization", "&Reload Localization" );
  352. m_pReloadLocalization->SetSize( 100, buttonH );
  353. m_pExitButton->SetCommand("Exit");
  354. m_pSaveButton->SetCommand("Save");
  355. m_pApplyButton->SetCommand("Apply");
  356. m_pReloadLocalization->SetCommand( new KeyValues( "ReloadLocalization" ) );
  357. m_pDeleteButton = new Button(this, "DeletePanelButton", "Delete");
  358. m_pDeleteButton->SetSize(64, buttonH);
  359. m_pDeleteButton->SetCommand("DeletePanel");
  360. m_pVarsButton = new MenuButton(this, "VarsButton", "Variables");
  361. m_pVarsButton->SetSize(72, buttonH);
  362. m_pVarsButton->SetOpenDirection(Menu::UP);
  363. // iterate the vars
  364. KeyValues *vars = m_pBuildGroup->GetDialogVariables();
  365. if (vars && vars->GetFirstSubKey())
  366. {
  367. // create the menu
  368. m_pVarsButton->SetEnabled(true);
  369. Menu *menu = new Menu(m_pVarsButton, "VarsMenu");
  370. // set all the variables to be copied to the clipboard when selected
  371. for (KeyValues *kv = vars->GetFirstSubKey(); kv != NULL; kv = kv->GetNextKey())
  372. {
  373. char buf[32];
  374. _snprintf(buf, sizeof(buf), "%%%s%%", kv->GetName());
  375. menu->AddMenuItem(kv->GetName(), new KeyValues("SetClipboardText", "text", buf), this);
  376. }
  377. m_pVarsButton->SetMenu(menu);
  378. }
  379. else
  380. {
  381. // no variables
  382. m_pVarsButton->SetEnabled(false);
  383. }
  384. m_pApplyButton->SetTabPosition(1);
  385. m_pPanelList->m_pControls->SetTabPosition(2);
  386. m_pVarsButton->SetTabPosition(3);
  387. m_pDeleteButton->SetTabPosition(4);
  388. m_pAddNewControlCombo->SetTabPosition(5);
  389. m_pSaveButton->SetTabPosition(6);
  390. m_pExitButton->SetTabPosition(7);
  391. m_pEditableParents->SetTabPosition( 8 );
  392. m_pEditableChildren->SetTabPosition( 9 );
  393. m_pPrevChild->SetTabPosition( 10 );
  394. m_pNextChild->SetTabPosition( 11 );
  395. m_pReloadLocalization->SetTabPosition( 12 );
  396. }
  397. void BuildModeDialog::ApplySchemeSettings( IScheme *pScheme )
  398. {
  399. BaseClass::ApplySchemeSettings( pScheme );
  400. HFont font = pScheme->GetFont( "DefaultVerySmall" );
  401. m_pStatusLabel->SetFont( font );
  402. m_pReloadLocalization->SetFont( font );
  403. m_pExitButton->SetFont( font );
  404. m_pSaveButton->SetFont( font );
  405. m_pApplyButton->SetFont( font );
  406. m_pAddNewControlCombo->SetFont( font );
  407. m_pEditableParents->SetFont( font );
  408. m_pEditableChildren->SetFont( font );
  409. m_pDeleteButton->SetFont( font );
  410. m_pVarsButton->SetFont( font );
  411. m_pPrevChild->SetFont( font );
  412. m_pNextChild->SetFont( font );
  413. }
  414. //-----------------------------------------------------------------------------
  415. // Purpose: lays out controls
  416. //-----------------------------------------------------------------------------
  417. void BuildModeDialog::PerformLayout()
  418. {
  419. BaseClass::PerformLayout();
  420. // layout parameters
  421. const int BORDER_GAP = 16, YGAP_SMALL = 4, YGAP_LARGE = 8, TITLE_HEIGHT = 24, BOTTOM_CONTROLS_HEIGHT = 145, XGAP = 6;
  422. int wide, tall;
  423. GetSize(wide, tall);
  424. int xpos = BORDER_GAP;
  425. int ypos = BORDER_GAP + TITLE_HEIGHT;
  426. // controls from top down
  427. // selection combo
  428. m_pFileSelectionCombo->SetBounds(xpos, ypos, wide - (BORDER_GAP * 2), m_pStatusLabel->GetTall());
  429. ypos += (m_pStatusLabel->GetTall() + YGAP_SMALL);
  430. // status
  431. m_pStatusLabel->SetBounds(xpos, ypos, wide - (BORDER_GAP * 2), m_pStatusLabel->GetTall());
  432. ypos += (m_pStatusLabel->GetTall() + YGAP_SMALL);
  433. // center control
  434. m_pPanelList->m_pControls->SetPos(xpos, ypos);
  435. m_pPanelList->m_pControls->SetSize(wide - (BORDER_GAP * 2), tall - (ypos + BOTTOM_CONTROLS_HEIGHT));
  436. // controls from bottom-right
  437. ypos = tall - BORDER_GAP;
  438. xpos = BORDER_GAP + m_pVarsButton->GetWide() + m_pDeleteButton->GetWide() + m_pAddNewControlCombo->GetWide() + (XGAP * 2);
  439. // bottom row of buttons
  440. ypos -= m_pApplyButton->GetTall();
  441. xpos -= m_pApplyButton->GetWide();
  442. m_pApplyButton->SetPos(xpos, ypos);
  443. xpos -= m_pExitButton->GetWide();
  444. xpos -= XGAP;
  445. m_pExitButton->SetPos(xpos, ypos);
  446. xpos -= m_pSaveButton->GetWide();
  447. xpos -= XGAP;
  448. m_pSaveButton->SetPos(xpos, ypos);
  449. // divider
  450. xpos = BORDER_GAP;
  451. ypos -= (YGAP_LARGE + m_pDivider->GetTall());
  452. m_pDivider->SetBounds(xpos, ypos, wide - (xpos + BORDER_GAP), 2);
  453. ypos -= (YGAP_LARGE + m_pVarsButton->GetTall());
  454. xpos = BORDER_GAP;
  455. m_pEditableParents->SetPos( xpos, ypos );
  456. m_pEditableChildren->SetPos( xpos + 150, ypos );
  457. ypos -= (YGAP_LARGE + 18 );
  458. xpos = BORDER_GAP;
  459. m_pReloadLocalization->SetPos( xpos, ypos );
  460. xpos += ( XGAP ) + m_pReloadLocalization->GetWide();
  461. m_pPrevChild->SetPos( xpos, ypos );
  462. m_pPrevChild->SetSize( 64, m_pReloadLocalization->GetTall() );
  463. xpos += ( XGAP ) + m_pPrevChild->GetWide();
  464. m_pNextChild->SetPos( xpos, ypos );
  465. m_pNextChild->SetSize( 64, m_pReloadLocalization->GetTall() );
  466. ypos -= (YGAP_LARGE + m_pVarsButton->GetTall());
  467. xpos = BORDER_GAP;
  468. // edit buttons
  469. m_pVarsButton->SetPos(xpos, ypos);
  470. xpos += (XGAP + m_pVarsButton->GetWide());
  471. m_pDeleteButton->SetPos(xpos, ypos);
  472. xpos += (XGAP + m_pDeleteButton->GetWide());
  473. m_pAddNewControlCombo->SetPos(xpos, ypos);
  474. }
  475. //-----------------------------------------------------------------------------
  476. // Purpose: Deletes all the controls from the panel
  477. //-----------------------------------------------------------------------------
  478. void BuildModeDialog::RemoveAllControls( void )
  479. {
  480. // free the array
  481. m_pPanelList->RemoveAll();
  482. }
  483. //-----------------------------------------------------------------------------
  484. // Purpose: simple helper function to get a token from a string
  485. // Input : char **string - pointer to the string pointer, which will be incremented
  486. // Output : const char * - pointer to the token
  487. //-----------------------------------------------------------------------------
  488. const char *ParseTokenFromString( const char **string )
  489. {
  490. static char buf[128];
  491. buf[0] = 0;
  492. // find the first alnum character
  493. const char *tok = *string;
  494. while ( !V_isalnum(*tok) && *tok != 0 )
  495. {
  496. tok++;
  497. }
  498. // read in all the alnum characters
  499. int pos = 0;
  500. while ( V_isalnum(tok[pos]) )
  501. {
  502. buf[pos] = tok[pos];
  503. pos++;
  504. }
  505. // null terminate the token
  506. buf[pos] = 0;
  507. // update the main string pointer
  508. *string = &(tok[pos]);
  509. // return a pointer to the static buffer
  510. return buf;
  511. }
  512. void BuildModeDialog::OnTextKillFocus()
  513. {
  514. if ( !m_pCurrentPanel )
  515. return;
  516. ApplyDataToControls();
  517. }
  518. //-----------------------------------------------------------------------------
  519. // Purpose: sets up the current control to edit
  520. //-----------------------------------------------------------------------------
  521. void BuildModeDialog::SetActiveControl(Panel *controlToEdit)
  522. {
  523. if (m_pCurrentPanel == controlToEdit)
  524. {
  525. // it's already set, so just update the property data and quit
  526. if (m_pCurrentPanel)
  527. {
  528. UpdateControlData(m_pCurrentPanel);
  529. }
  530. return;
  531. }
  532. // reset the data
  533. m_pCurrentPanel = controlToEdit;
  534. RemoveAllControls();
  535. m_pPanelList->m_pControls->MoveScrollBarToTop();
  536. if (!m_pCurrentPanel)
  537. {
  538. m_pStatusLabel->SetText("[nothing currently selected]");
  539. m_pStatusLabel->SetTextColorState(Label::CS_DULL);
  540. RemoveAllControls();
  541. return;
  542. }
  543. // get the control description string
  544. const char *controlDesc = m_pCurrentPanel->GetDescription();
  545. // parse out the control description
  546. int tabPosition = 1;
  547. while (1)
  548. {
  549. const char *dataType = ParseTokenFromString(&controlDesc);
  550. // finish when we have no more tokens
  551. if (*dataType == 0)
  552. break;
  553. // default the data type to a string
  554. int datat = TYPE_STRING;
  555. if (!stricmp(dataType, "int"))
  556. {
  557. datat = TYPE_STRING; //!! just for now
  558. }
  559. else if (!stricmp(dataType, "alignment"))
  560. {
  561. datat = TYPE_ALIGNMENT;
  562. }
  563. else if (!stricmp(dataType, "autoresize"))
  564. {
  565. datat = TYPE_AUTORESIZE;
  566. }
  567. else if (!stricmp(dataType, "corner"))
  568. {
  569. datat = TYPE_CORNER;
  570. }
  571. else if (!stricmp(dataType, "localize"))
  572. {
  573. datat = TYPE_LOCALIZEDSTRING;
  574. }
  575. // get the field name
  576. const char *fieldName = ParseTokenFromString(&controlDesc);
  577. int itemHeight = 18;
  578. // build a control & label
  579. Label *label = new Label(this, NULL, fieldName);
  580. label->SetSize(96, itemHeight);
  581. label->SetContentAlignment(Label::a_east);
  582. TextEntry *edit = NULL;
  583. ComboBox *editCombo = NULL;
  584. Button *editButton = NULL;
  585. if (datat == TYPE_ALIGNMENT)
  586. {
  587. // drop-down combo box
  588. editCombo = new ComboBox(this, NULL, 9, false);
  589. editCombo->AddItem("north-west", NULL);
  590. editCombo->AddItem("north", NULL);
  591. editCombo->AddItem("north-east", NULL);
  592. editCombo->AddItem("west", NULL);
  593. editCombo->AddItem("center", NULL);
  594. editCombo->AddItem("east", NULL);
  595. editCombo->AddItem("south-west", NULL);
  596. editCombo->AddItem("south", NULL);
  597. editCombo->AddItem("south-east", NULL);
  598. edit = editCombo;
  599. }
  600. else if (datat == TYPE_AUTORESIZE)
  601. {
  602. // drop-down combo box
  603. editCombo = new ComboBox(this, NULL, 4, false);
  604. editCombo->AddItem( "0 - no auto-resize", NULL);
  605. editCombo->AddItem( "1 - resize right", NULL);
  606. editCombo->AddItem( "2 - resize down", NULL);
  607. editCombo->AddItem( "3 - down & right", NULL);
  608. edit = editCombo;
  609. }
  610. else if (datat == TYPE_CORNER)
  611. {
  612. // drop-down combo box
  613. editCombo = new ComboBox(this, NULL, 5, false);
  614. editCombo->AddItem("0 - top-left", NULL);
  615. editCombo->AddItem("1 - top-right", NULL);
  616. editCombo->AddItem("2 - bottom-left", NULL);
  617. editCombo->AddItem("3 - bottom-right", NULL);
  618. editCombo->AddItem("4 - no pin", NULL);
  619. editCombo->ActivateItemByRow( 4 );
  620. edit = editCombo;
  621. }
  622. else if (datat == TYPE_LOCALIZEDSTRING)
  623. {
  624. editButton = new Button(this, NULL, "...");
  625. editButton->SetParent(this);
  626. editButton->AddActionSignalTarget(this);
  627. editButton->SetTabPosition(tabPosition++);
  628. editButton->SetTall( itemHeight );
  629. label->SetAssociatedControl(editButton);
  630. }
  631. else
  632. {
  633. // normal string edit
  634. edit = new CSmallTextEntry(this, NULL);
  635. }
  636. if (edit)
  637. {
  638. edit->SetTall( itemHeight );
  639. edit->SetParent(this);
  640. edit->AddActionSignalTarget(this);
  641. edit->SetTabPosition(tabPosition++);
  642. label->SetAssociatedControl(edit);
  643. }
  644. HFont smallFont = scheme()->GetIScheme( GetScheme() )->GetFont( "DefaultVerySmall" );
  645. if ( label )
  646. {
  647. label->SetFont( smallFont );
  648. }
  649. if ( edit )
  650. {
  651. edit->SetFont( smallFont );
  652. }
  653. if ( editCombo )
  654. {
  655. editCombo->SetFont( smallFont );
  656. }
  657. if ( editButton )
  658. {
  659. editButton->SetFont( smallFont );
  660. }
  661. // add to our control list
  662. m_pPanelList->AddItem(label, edit, editCombo, editButton, fieldName, datat);
  663. if ( edit )
  664. {
  665. m_pPanelList->m_pControls->AddItem(label, edit);
  666. }
  667. else
  668. {
  669. m_pPanelList->m_pControls->AddItem(label, editButton);
  670. }
  671. }
  672. // check and see if the current panel is a Label
  673. // iterate through the class hierarchy
  674. if ( controlToEdit->IsBuildModeDeletable() )
  675. {
  676. m_pDeleteButton->SetEnabled(true);
  677. }
  678. else
  679. {
  680. m_pDeleteButton->SetEnabled(false);
  681. }
  682. // update the property data in the dialog
  683. UpdateControlData(m_pCurrentPanel);
  684. // set our title
  685. if ( m_pBuildGroup->GetResourceName() )
  686. {
  687. m_pFileSelectionCombo->SetText(m_pBuildGroup->GetResourceName());
  688. }
  689. else
  690. {
  691. m_pFileSelectionCombo->SetText("[ no resource file associated with dialog ]");
  692. }
  693. m_pApplyButton->SetEnabled(false);
  694. InvalidateLayout();
  695. Repaint();
  696. }
  697. //-----------------------------------------------------------------------------
  698. // Purpose: Updates the edit fields with information about the control
  699. //-----------------------------------------------------------------------------
  700. void BuildModeDialog::UpdateControlData(Panel *control)
  701. {
  702. KeyValues *dat = m_pPanelList->m_pResourceData->FindKey( control->GetName(), true );
  703. control->GetSettings( dat );
  704. // apply the settings to the edit panels
  705. for ( int i = 0; i < m_pPanelList->m_PanelList.Count(); i++ )
  706. {
  707. const char *name = m_pPanelList->m_PanelList[i].m_szName;
  708. const char *datstring = dat->GetString( name, "" );
  709. UpdateEditControl(m_pPanelList->m_PanelList[i], datstring);
  710. }
  711. char statusText[512];
  712. Q_snprintf(statusText, sizeof(statusText), "%s: \'%s\'", control->GetClassName(), control->GetName());
  713. m_pStatusLabel->SetText(statusText);
  714. m_pStatusLabel->SetTextColorState(Label::CS_NORMAL);
  715. }
  716. //-----------------------------------------------------------------------------
  717. // Purpose: Updates the data in a single edit control
  718. //-----------------------------------------------------------------------------
  719. void BuildModeDialog::UpdateEditControl(PanelItem_t &panelItem, const char *datstring)
  720. {
  721. switch (panelItem.m_iType)
  722. {
  723. case TYPE_AUTORESIZE:
  724. case TYPE_CORNER:
  725. {
  726. int dat = atoi(datstring);
  727. panelItem.m_pCombo->ActivateItemByRow(dat);
  728. }
  729. break;
  730. case TYPE_LOCALIZEDSTRING:
  731. {
  732. panelItem.m_EditButton->SetText(datstring);
  733. }
  734. break;
  735. default:
  736. {
  737. wchar_t unicode[512];
  738. g_pVGuiLocalize->ConvertANSIToUnicode(datstring, unicode, sizeof(unicode));
  739. panelItem.m_EditPanel->SetText(unicode);
  740. }
  741. break;
  742. }
  743. }
  744. //-----------------------------------------------------------------------------
  745. // Purpose: Called when one of the buttons is pressed
  746. //-----------------------------------------------------------------------------
  747. void BuildModeDialog::OnCommand(const char *command)
  748. {
  749. if (!stricmp(command, "Save"))
  750. {
  751. // apply the current data and save it to disk
  752. ApplyDataToControls();
  753. if (m_pBuildGroup->SaveControlSettings())
  754. {
  755. // disable save button until another change has been made
  756. m_pSaveButton->SetEnabled(false);
  757. }
  758. }
  759. else if (!stricmp(command, "Exit"))
  760. {
  761. // exit build mode
  762. ExitBuildMode();
  763. }
  764. else if (!stricmp(command, "Apply"))
  765. {
  766. // apply data to controls
  767. ApplyDataToControls();
  768. }
  769. else if (!stricmp(command, "DeletePanel"))
  770. {
  771. OnDeletePanel();
  772. }
  773. else if (!stricmp(command, "RevertToSaved"))
  774. {
  775. RevertToSaved();
  776. }
  777. else if (!stricmp(command, "ShowHelp"))
  778. {
  779. ShowHelp();
  780. }
  781. else
  782. {
  783. BaseClass::OnCommand(command);
  784. }
  785. }
  786. //-----------------------------------------------------------------------------
  787. // Purpose: Deletes a panel from the buildgroup
  788. //-----------------------------------------------------------------------------
  789. void BuildModeDialog::OnDeletePanel()
  790. {
  791. if (!m_pCurrentPanel->IsBuildModeEditable())
  792. {
  793. return;
  794. }
  795. m_pBuildGroup->RemoveSettings();
  796. SetActiveControl(m_pBuildGroup->GetCurrentPanel());
  797. _undoSettings->deleteThis();
  798. _undoSettings = NULL;
  799. m_pSaveButton->SetEnabled(true);
  800. }
  801. //-----------------------------------------------------------------------------
  802. // Purpose: Applies the current settings to the build controls
  803. //-----------------------------------------------------------------------------
  804. void BuildModeDialog::ApplyDataToControls()
  805. {
  806. // don't apply if the panel is not editable
  807. if ( !m_pCurrentPanel->IsBuildModeEditable())
  808. {
  809. UpdateControlData( m_pCurrentPanel );
  810. return; // return success, since we are behaving as expected.
  811. }
  812. char fieldName[512];
  813. if (m_pPanelList->m_PanelList[0].m_EditPanel)
  814. {
  815. m_pPanelList->m_PanelList[0].m_EditPanel->GetText(fieldName, sizeof(fieldName));
  816. }
  817. else
  818. {
  819. m_pPanelList->m_PanelList[0].m_EditButton->GetText(fieldName, sizeof(fieldName));
  820. }
  821. // check to see if any buildgroup panels have this name
  822. Panel *panel = m_pBuildGroup->FieldNameTaken(fieldName);
  823. if (panel)
  824. {
  825. if (panel != m_pCurrentPanel)// make sure name is taken by some other panel not this one
  826. {
  827. char messageString[255];
  828. Q_snprintf(messageString, sizeof( messageString ), "Fieldname is not unique: %s\nRename it and try again.", fieldName);
  829. MessageBox *errorBox = new MessageBox("Cannot Apply", messageString );
  830. errorBox->DoModal();
  831. UpdateControlData(m_pCurrentPanel);
  832. m_pApplyButton->SetEnabled(false);
  833. return;
  834. }
  835. }
  836. // create a section to store settings
  837. // m_pPanelList->m_pResourceData->getSection( m_pCurrentPanel->GetName(), true );
  838. KeyValues *dat = new KeyValues( m_pCurrentPanel->GetName() );
  839. // loop through the textedit filling in settings
  840. for ( int i = 0; i < m_pPanelList->m_PanelList.Count(); i++ )
  841. {
  842. const char *name = m_pPanelList->m_PanelList[i].m_szName;
  843. char buf[512];
  844. if (m_pPanelList->m_PanelList[i].m_EditPanel)
  845. {
  846. m_pPanelList->m_PanelList[i].m_EditPanel->GetText(buf, sizeof(buf));
  847. }
  848. else
  849. {
  850. m_pPanelList->m_PanelList[i].m_EditButton->GetText(buf, sizeof(buf));
  851. }
  852. switch (m_pPanelList->m_PanelList[i].m_iType)
  853. {
  854. case TYPE_CORNER:
  855. case TYPE_AUTORESIZE:
  856. // the integer value is assumed to be the first part of the string for these items
  857. dat->SetInt(name, atoi(buf));
  858. break;
  859. default:
  860. dat->SetString(name, buf);
  861. break;
  862. }
  863. }
  864. // dat is built, hand it back to the control
  865. m_pCurrentPanel->ApplySettings( dat );
  866. if ( m_pBuildGroup->GetContextPanel() )
  867. {
  868. m_pBuildGroup->GetContextPanel()->Repaint();
  869. }
  870. m_pApplyButton->SetEnabled(false);
  871. m_pSaveButton->SetEnabled(true);
  872. }
  873. //-----------------------------------------------------------------------------
  874. // Purpose: Store the settings of the current panel in a KeyValues
  875. //-----------------------------------------------------------------------------
  876. void BuildModeDialog::StoreUndoSettings()
  877. {
  878. // don't save if the planel is not editable
  879. if ( !m_pCurrentPanel->IsBuildModeEditable())
  880. {
  881. if (_undoSettings)
  882. _undoSettings->deleteThis();
  883. _undoSettings = NULL;
  884. return;
  885. }
  886. if (_undoSettings)
  887. {
  888. _undoSettings->deleteThis();
  889. _undoSettings = NULL;
  890. }
  891. _undoSettings = StoreSettings();
  892. }
  893. //-----------------------------------------------------------------------------
  894. // Purpose: Revert to the stored the settings of the current panel in a keyValues
  895. //-----------------------------------------------------------------------------
  896. void BuildModeDialog::DoUndo()
  897. {
  898. if ( _undoSettings )
  899. {
  900. m_pCurrentPanel->ApplySettings( _undoSettings );
  901. UpdateControlData(m_pCurrentPanel);
  902. _undoSettings->deleteThis();
  903. _undoSettings = NULL;
  904. }
  905. m_pSaveButton->SetEnabled(true);
  906. }
  907. //-----------------------------------------------------------------------------
  908. // Purpose: Copy the settings of the current panel into a keyValues
  909. //-----------------------------------------------------------------------------
  910. void BuildModeDialog::DoCopy()
  911. {
  912. if (_copySettings)
  913. {
  914. _copySettings->deleteThis();
  915. _copySettings = NULL;
  916. }
  917. _copySettings = StoreSettings();
  918. Q_strncpy (_copyClassName, m_pCurrentPanel->GetClassName(), sizeof( _copyClassName ) );
  919. }
  920. //-----------------------------------------------------------------------------
  921. // Purpose: Create a new Panel with the _copySettings applied
  922. //-----------------------------------------------------------------------------
  923. void BuildModeDialog::DoPaste()
  924. {
  925. // Make a new control located where you had the mouse
  926. int x, y;
  927. input()->GetCursorPos(x, y);
  928. m_pBuildGroup->GetContextPanel()->ScreenToLocal(x,y);
  929. Panel *newPanel = OnNewControl(_copyClassName, x, y);
  930. if (newPanel)
  931. {
  932. newPanel->ApplySettings(_copySettings);
  933. newPanel->SetPos(x, y);
  934. char name[255];
  935. m_pBuildGroup->GetNewFieldName(name, sizeof(name), newPanel);
  936. newPanel->SetName(name);
  937. }
  938. }
  939. //-----------------------------------------------------------------------------
  940. // Purpose: Store the settings of the current panel in a keyValues
  941. //-----------------------------------------------------------------------------
  942. KeyValues *BuildModeDialog::StoreSettings()
  943. {
  944. KeyValues *storedSettings;
  945. storedSettings = new KeyValues( m_pCurrentPanel->GetName() );
  946. // loop through the textedit filling in settings
  947. for ( int i = 0; i < m_pPanelList->m_PanelList.Count(); i++ )
  948. {
  949. const char *name = m_pPanelList->m_PanelList[i].m_szName;
  950. char buf[512];
  951. if (m_pPanelList->m_PanelList[i].m_EditPanel)
  952. {
  953. m_pPanelList->m_PanelList[i].m_EditPanel->GetText(buf, sizeof(buf));
  954. }
  955. else
  956. {
  957. m_pPanelList->m_PanelList[i].m_EditButton->GetText(buf, sizeof(buf));
  958. }
  959. switch (m_pPanelList->m_PanelList[i].m_iType)
  960. {
  961. case TYPE_CORNER:
  962. case TYPE_AUTORESIZE:
  963. // the integer value is assumed to be the first part of the string for these items
  964. storedSettings->SetInt(name, atoi(buf));
  965. break;
  966. default:
  967. storedSettings->SetString(name, buf);
  968. break;
  969. }
  970. }
  971. return storedSettings;
  972. }
  973. //-----------------------------------------------------------------------------
  974. // Purpose:
  975. //-----------------------------------------------------------------------------
  976. void BuildModeDialog::OnKeyCodeTyped(KeyCode code)
  977. {
  978. if (code == KEY_ENTER) // if someone hits return apply the changes
  979. {
  980. ApplyDataToControls();
  981. }
  982. else
  983. {
  984. Frame::OnKeyCodeTyped(code);
  985. }
  986. }
  987. //-----------------------------------------------------------------------------
  988. // Purpose: Checks to see if any text has changed
  989. //-----------------------------------------------------------------------------
  990. void BuildModeDialog::OnTextChanged( Panel *panel )
  991. {
  992. if (panel == m_pFileSelectionCombo)
  993. {
  994. // reload file if it's changed
  995. char newFile[512];
  996. m_pFileSelectionCombo->GetText(newFile, sizeof(newFile));
  997. if (stricmp(newFile, m_pBuildGroup->GetResourceName()) != 0)
  998. {
  999. // file has changed, reload
  1000. SetActiveControl(NULL);
  1001. m_pBuildGroup->ChangeControlSettingsFile(newFile);
  1002. }
  1003. return;
  1004. }
  1005. if (panel == m_pAddNewControlCombo)
  1006. {
  1007. char buf[40];
  1008. m_pAddNewControlCombo->GetText(buf, 40);
  1009. if (stricmp(buf, "None") != 0)
  1010. {
  1011. OnNewControl(buf);
  1012. // reset box back to None
  1013. m_pAddNewControlCombo->ActivateItemByRow( 0 );
  1014. }
  1015. }
  1016. if ( panel == m_pEditableChildren )
  1017. {
  1018. KeyValues *kv = m_pEditableChildren->GetActiveItemUserData();
  1019. if ( kv )
  1020. {
  1021. EditablePanel *ep = reinterpret_cast< EditablePanel * >( kv->GetPtr( "ptr" ) );
  1022. if ( ep )
  1023. {
  1024. ep->ActivateBuildMode();
  1025. }
  1026. }
  1027. }
  1028. if ( panel == m_pEditableParents )
  1029. {
  1030. KeyValues *kv = m_pEditableParents->GetActiveItemUserData();
  1031. if ( kv )
  1032. {
  1033. EditablePanel *ep = reinterpret_cast< EditablePanel * >( kv->GetPtr( "ptr" ) );
  1034. if ( ep )
  1035. {
  1036. ep->ActivateBuildMode();
  1037. }
  1038. }
  1039. }
  1040. if (m_pCurrentPanel && m_pCurrentPanel->IsBuildModeEditable())
  1041. {
  1042. m_pApplyButton->SetEnabled(true);
  1043. }
  1044. if (_autoUpdate)
  1045. {
  1046. ApplyDataToControls();
  1047. }
  1048. }
  1049. //-----------------------------------------------------------------------------
  1050. // Purpose:
  1051. //-----------------------------------------------------------------------------
  1052. void BuildModeDialog::ExitBuildMode( void )
  1053. {
  1054. // make sure rulers are off
  1055. if (m_pBuildGroup->HasRulersOn())
  1056. {
  1057. m_pBuildGroup->ToggleRulerDisplay();
  1058. }
  1059. m_pBuildGroup->SetEnabled(false);
  1060. }
  1061. //-----------------------------------------------------------------------------
  1062. // Purpose: Create a new control in the context panel
  1063. //-----------------------------------------------------------------------------
  1064. Panel *BuildModeDialog::OnNewControl( const char *name, int x, int y)
  1065. {
  1066. // returns NULL on failure
  1067. Panel *newPanel = m_pBuildGroup->NewControl(name, x, y);
  1068. if (newPanel)
  1069. {
  1070. // call mouse commands to simulate selecting the new
  1071. // panel. This will set everything up correctly in the buildGroup.
  1072. m_pBuildGroup->MousePressed(MOUSE_LEFT, newPanel);
  1073. m_pBuildGroup->MouseReleased(MOUSE_LEFT, newPanel);
  1074. }
  1075. m_pSaveButton->SetEnabled(true);
  1076. return newPanel;
  1077. }
  1078. //-----------------------------------------------------------------------------
  1079. // Purpose: enable the save button, useful when buildgroup needs to Activate it.
  1080. //-----------------------------------------------------------------------------
  1081. void BuildModeDialog::EnableSaveButton()
  1082. {
  1083. m_pSaveButton->SetEnabled(true);
  1084. }
  1085. //-----------------------------------------------------------------------------
  1086. // Purpose: Revert to the saved settings in the .res file
  1087. //-----------------------------------------------------------------------------
  1088. void BuildModeDialog::RevertToSaved()
  1089. {
  1090. // hide the dialog as reloading will destroy it
  1091. surface()->SetPanelVisible(this->GetVPanel(), false);
  1092. m_pBuildGroup->ReloadControlSettings();
  1093. }
  1094. //-----------------------------------------------------------------------------
  1095. // Purpose: Display some information about the editor
  1096. //-----------------------------------------------------------------------------
  1097. void BuildModeDialog::ShowHelp()
  1098. {
  1099. char helpText[]= "In the Build Mode Dialog Window:\n"
  1100. "Delete button - deletes the currently selected panel if it is deletable.\n"
  1101. "Apply button - applies changes to the Context Panel.\n"
  1102. "Save button - saves all settings to file. \n"
  1103. "Revert to saved- reloads the last saved file.\n"
  1104. "Auto Update - any changes apply instantly.\n"
  1105. "Typing Enter in any text field applies changes.\n"
  1106. "New Control menu - creates a new panel in the upper left corner.\n\n"
  1107. "In the Context Panel:\n"
  1108. "After selecting and moving a panel Ctrl-z will undo the move.\n"
  1109. "Shift clicking panels allows multiple panels to be selected into a group.\n"
  1110. "Ctrl-c copies the settings of the last selected panel.\n"
  1111. "Ctrl-v creates a new panel with the copied settings at the location of the mouse pointer.\n"
  1112. "Arrow keys slowly move panels, holding shift + arrow will slowly resize it.\n"
  1113. "Holding right mouse button down opens a dropdown panel creation menu.\n"
  1114. " Panel will be created where the menu was opened.\n"
  1115. "Delete key deletes the currently selected panel if it is deletable.\n"
  1116. " Does nothing to multiple selections.";
  1117. MessageBox *helpDlg = new MessageBox ("Build Mode Help", helpText, this);
  1118. helpDlg->AddActionSignalTarget(this);
  1119. helpDlg->DoModal();
  1120. }
  1121. void BuildModeDialog::ShutdownBuildMode()
  1122. {
  1123. m_pBuildGroup->SetEnabled(false);
  1124. }
  1125. void BuildModeDialog::OnPanelMoved()
  1126. {
  1127. m_pApplyButton->SetEnabled(true);
  1128. }
  1129. //-----------------------------------------------------------------------------
  1130. // Purpose: message handles thats sets the text in the clipboard
  1131. //-----------------------------------------------------------------------------
  1132. void BuildModeDialog::OnSetClipboardText(const char *text)
  1133. {
  1134. system()->SetClipboardText(text, strlen(text));
  1135. }
  1136. void BuildModeDialog::OnCreateNewControl( char const *text )
  1137. {
  1138. if ( !Q_stricmp( text, "None" ) )
  1139. return;
  1140. OnNewControl( text, m_nClick[ 0 ], m_nClick[ 1 ] );
  1141. }
  1142. void BuildModeDialog::OnShowNewControlMenu()
  1143. {
  1144. if ( !m_pBuildGroup )
  1145. return;
  1146. int i;
  1147. input()->GetCursorPos( m_nClick[ 0 ], m_nClick[ 1 ] );
  1148. m_pBuildGroup->GetContextPanel()->ScreenToLocal( m_nClick[ 0 ], m_nClick[ 1 ] );
  1149. if ( m_hContextMenu )
  1150. delete m_hContextMenu.Get();
  1151. m_hContextMenu = new Menu( this, "NewControls" );
  1152. // Show popup menu
  1153. m_hContextMenu->AddMenuItem( "None", "None", new KeyValues( "CreateNewControl", "text", "None" ), this );
  1154. CUtlVector< char const * > names;
  1155. CBuildFactoryHelper::GetFactoryNames( names );
  1156. // Sort the names
  1157. CUtlRBTree< char const *, int > sorted( 0, 0, StringLessThan );
  1158. for ( i = 0; i < names.Count(); ++i )
  1159. {
  1160. sorted.Insert( names[ i ] );
  1161. }
  1162. for ( i = sorted.FirstInorder(); i != sorted.InvalidIndex(); i = sorted.NextInorder( i ) )
  1163. {
  1164. m_hContextMenu->AddMenuItem( sorted[ i ], sorted[ i ], new KeyValues( "CreateNewControl", "text", sorted[ i ] ), this );
  1165. }
  1166. Menu::PlaceContextMenu( this, m_hContextMenu );
  1167. }
  1168. void BuildModeDialog::OnReloadLocalization()
  1169. {
  1170. // reload localization files
  1171. g_pVGuiLocalize->ReloadLocalizationFiles( );
  1172. }
  1173. bool BuildModeDialog::IsBuildGroupEnabled()
  1174. {
  1175. // Don't ever edit the actual build dialog!!!
  1176. return false;
  1177. }
  1178. void BuildModeDialog::OnChangeChild( int direction )
  1179. {
  1180. Assert( direction == 1 || direction == -1 );
  1181. if ( !m_pBuildGroup )
  1182. return;
  1183. Panel *current = m_pCurrentPanel;
  1184. Panel *context = m_pBuildGroup->GetContextPanel();
  1185. if ( !current || current == context )
  1186. {
  1187. current = NULL;
  1188. if ( context->GetChildCount() > 0 )
  1189. {
  1190. current = context->GetChild( 0 );
  1191. }
  1192. }
  1193. else
  1194. {
  1195. int i;
  1196. // Move in direction requested
  1197. int children = context->GetChildCount();
  1198. for ( i = 0; i < children; ++i )
  1199. {
  1200. Panel *child = context->GetChild( i );
  1201. if ( child == current )
  1202. {
  1203. break;
  1204. }
  1205. }
  1206. if ( i < children )
  1207. {
  1208. for ( int offset = 1; offset < children; ++offset )
  1209. {
  1210. int test = ( i + ( direction * offset ) ) % children;
  1211. if ( test < 0 )
  1212. test += children;
  1213. if ( test == i )
  1214. continue;
  1215. Panel *check = context->GetChild( test );
  1216. BuildModeDialog *bm = dynamic_cast< BuildModeDialog * >( check );
  1217. if ( bm )
  1218. continue;
  1219. current = check;
  1220. break;
  1221. }
  1222. }
  1223. }
  1224. if ( !current )
  1225. {
  1226. return;
  1227. }
  1228. SetActiveControl( current );
  1229. }