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.

1543 lines
41 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. //========= Copyright � 1996-2003, Valve LLC, All rights reserved. ============
  9. //
  10. // The copyright to the contents herein is the property of Valve, L.L.C.
  11. // The contents may be used and/or copied only with the written permission of
  12. // Valve, L.L.C., or in accordance with the terms and conditions stipulated in
  13. // the agreement/contract under which the contents have been supplied.
  14. //
  15. // Purpose:
  16. //
  17. // $NoKeywords: $
  18. //=============================================================================
  19. #include <stdio.h>
  20. #define PROTECTED_THINGS_DISABLE
  21. #include "utldict.h"
  22. #include <vgui/KeyCode.h>
  23. #include <vgui/Cursor.h>
  24. #include <vgui/MouseCode.h>
  25. #include <KeyValues.h>
  26. #include <vgui/IInput.h>
  27. #include <vgui/ISystem.h>
  28. #include <vgui/IVGui.h>
  29. #include <vgui/ISurface.h>
  30. #include <vgui_controls/BuildGroup.h>
  31. #include <vgui_controls/Panel.h>
  32. #include <vgui_controls/PHandle.h>
  33. #include <vgui_controls/Label.h>
  34. #include <vgui_controls/EditablePanel.h>
  35. #include <vgui_controls/MessageBox.h>
  36. #include "filesystem.h"
  37. #include "tier0/icommandline.h"
  38. #include "const.h"
  39. #if defined( _X360 )
  40. #include "xbox/xbox_win32stubs.h"
  41. #endif
  42. // memdbgon must be the last include file in a .cpp file!!!
  43. #include <tier0/memdbgon.h>
  44. ConVar vgui_cache_res_files( "vgui_cache_res_files", "1" );
  45. using namespace vgui;
  46. //-----------------------------------------------------------------------------
  47. // Handle table
  48. //-----------------------------------------------------------------------------
  49. IMPLEMENT_HANDLES( BuildGroup, 20 )
  50. CUtlDict< KeyValues* > BuildGroup::m_dictCachedResFiles;
  51. //-----------------------------------------------------------------------------
  52. // Purpose: Constructor
  53. //-----------------------------------------------------------------------------
  54. BuildGroup::BuildGroup(Panel *parentPanel, Panel *contextPanel)
  55. {
  56. CONSTRUCT_HANDLE( );
  57. _enabled=false;
  58. _snapX=1;
  59. _snapY=1;
  60. _cursor_sizenwse = dc_sizenwse;
  61. _cursor_sizenesw = dc_sizenesw;
  62. _cursor_sizewe = dc_sizewe;
  63. _cursor_sizens = dc_sizens;
  64. _cursor_sizeall = dc_sizeall;
  65. _currentPanel=null;
  66. _dragging=false;
  67. m_pResourceName=NULL;
  68. m_pResourcePathID = NULL;
  69. m_hBuildDialog=NULL;
  70. m_pParentPanel=parentPanel;
  71. for (int i=0; i<4; ++i)
  72. _rulerNumber[i] = NULL;
  73. SetContextPanel(contextPanel);
  74. _showRulers = false;
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose: Destructor
  78. //-----------------------------------------------------------------------------
  79. BuildGroup::~BuildGroup()
  80. {
  81. if (m_hBuildDialog)
  82. delete m_hBuildDialog.Get();
  83. m_hBuildDialog = NULL;
  84. delete [] m_pResourceName;
  85. delete [] m_pResourcePathID;
  86. for (int i=0; i <4; ++i)
  87. {
  88. if (_rulerNumber[i])
  89. {
  90. delete _rulerNumber[i];
  91. _rulerNumber[i]= NULL;
  92. }
  93. }
  94. DESTRUCT_HANDLE();
  95. }
  96. //-----------------------------------------------------------------------------
  97. // Purpose: Toggles build mode on/off
  98. // Input : state - new state
  99. //-----------------------------------------------------------------------------
  100. void BuildGroup::SetEnabled(bool state)
  101. {
  102. if(_enabled != state)
  103. {
  104. _enabled = state;
  105. _currentPanel = NULL;
  106. if ( state )
  107. {
  108. ActivateBuildDialog();
  109. }
  110. else
  111. {
  112. // hide the build dialog
  113. if ( m_hBuildDialog )
  114. {
  115. m_hBuildDialog->OnCommand("Close");
  116. }
  117. // request focus for our main panel
  118. m_pParentPanel->RequestFocus();
  119. }
  120. }
  121. }
  122. //-----------------------------------------------------------------------------
  123. // Purpose: Check if buildgroup is enabled
  124. //-----------------------------------------------------------------------------
  125. bool BuildGroup::IsEnabled()
  126. {
  127. return _enabled;
  128. }
  129. //-----------------------------------------------------------------------------
  130. // Purpose: Get the list of panels that are currently selected
  131. //-----------------------------------------------------------------------------
  132. CUtlVector<PHandle> *BuildGroup::GetControlGroup()
  133. {
  134. return &_controlGroup;
  135. }
  136. //-----------------------------------------------------------------------------
  137. // Purpose: Check if ruler display is activated
  138. //-----------------------------------------------------------------------------
  139. bool BuildGroup::HasRulersOn()
  140. {
  141. return _showRulers;
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose: Toggle ruler display
  145. //-----------------------------------------------------------------------------
  146. void BuildGroup::ToggleRulerDisplay()
  147. {
  148. _showRulers = !_showRulers;
  149. if (_rulerNumber[0] == NULL) // rulers haven't been initialized
  150. {
  151. _rulerNumber[0] = new Label(m_pBuildContext, NULL, "");
  152. _rulerNumber[1] = new Label(m_pBuildContext, NULL, "");
  153. _rulerNumber[2] = new Label(m_pBuildContext, NULL, "");
  154. _rulerNumber[3] = new Label(m_pBuildContext, NULL, "");
  155. }
  156. SetRulerLabelsVisible(_showRulers);
  157. m_pBuildContext->Repaint();
  158. }
  159. //-----------------------------------------------------------------------------
  160. // Purpose: Tobble visibility of ruler number labels
  161. //-----------------------------------------------------------------------------
  162. void BuildGroup::SetRulerLabelsVisible(bool state)
  163. {
  164. _rulerNumber[0]->SetVisible(state);
  165. _rulerNumber[1]->SetVisible(state);
  166. _rulerNumber[2]->SetVisible(state);
  167. _rulerNumber[3]->SetVisible(state);
  168. }
  169. void BuildGroup::ApplySchemeSettings( IScheme *pScheme )
  170. {
  171. DrawRulers();
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose: Draw Rulers on screen if conditions are right
  175. //-----------------------------------------------------------------------------
  176. void BuildGroup::DrawRulers()
  177. {
  178. // don't draw if visibility is off
  179. if (!_showRulers)
  180. {
  181. return;
  182. }
  183. // no drawing if we selected the context panel
  184. if (m_pBuildContext == _currentPanel)
  185. {
  186. SetRulerLabelsVisible(false);
  187. return;
  188. }
  189. else
  190. SetRulerLabelsVisible(true);
  191. int x, y, wide, tall;
  192. // get base panel's postition
  193. m_pBuildContext->GetBounds(x, y, wide, tall);
  194. m_pBuildContext->ScreenToLocal(x,y);
  195. int cx, cy, cwide, ctall;
  196. _currentPanel->GetBounds (cx, cy, cwide, ctall);
  197. surface()->PushMakeCurrent(m_pBuildContext->GetVPanel(), false);
  198. // draw rulers
  199. surface()->DrawSetColor(255, 255, 255, 255); // white color
  200. surface()->DrawFilledRect(0, cy, cx, cy+1); //top horiz left
  201. surface()->DrawFilledRect(cx+cwide, cy, wide, cy+1); //top horiz right
  202. surface()->DrawFilledRect(0, cy+ctall-1, cx, cy+ctall); //bottom horiz left
  203. surface()->DrawFilledRect(cx+cwide, cy+ctall-1, wide, cy+ctall); //bottom horiz right
  204. surface()->DrawFilledRect(cx,0,cx+1,cy); //top vert left
  205. surface()->DrawFilledRect(cx+cwide-1,0, cx+cwide, cy); //top vert right
  206. surface()->DrawFilledRect(cx,cy+ctall, cx+1, tall); //bottom vert left
  207. surface()->DrawFilledRect(cx+cwide-1, cy+ctall, cx+cwide, tall); //bottom vert right
  208. surface()->PopMakeCurrent(m_pBuildContext->GetVPanel());
  209. // now let's put numbers with the rulers
  210. char textstring[20];
  211. Q_snprintf (textstring, sizeof( textstring ), "%d", cx);
  212. _rulerNumber[0]->SetText(textstring);
  213. int twide, ttall;
  214. _rulerNumber[0]->GetContentSize(twide,ttall);
  215. _rulerNumber[0]->SetSize(twide,ttall);
  216. _rulerNumber[0]->SetPos(cx/2-twide/2, cy-ttall+3);
  217. Q_snprintf (textstring, sizeof( textstring ), "%d", cy);
  218. _rulerNumber[1]->SetText(textstring);
  219. _rulerNumber[1]->GetContentSize(twide,ttall);
  220. _rulerNumber[1]->SetSize(twide,ttall);
  221. _rulerNumber[1]->GetSize(twide,ttall);
  222. _rulerNumber[1]->SetPos(cx-twide + 3, cy/2-ttall/2);
  223. Q_snprintf (textstring, sizeof( textstring ), "%d", cy);
  224. _rulerNumber[2]->SetText(textstring);
  225. _rulerNumber[2]->GetContentSize(twide,ttall);
  226. _rulerNumber[2]->SetSize(twide,ttall);
  227. _rulerNumber[2]->SetPos(cx+cwide+(wide-cx-cwide)/2 - twide/2, cy+ctall-3);
  228. Q_snprintf (textstring, sizeof( textstring ), "%d", cy);
  229. _rulerNumber[3]->SetText(textstring);
  230. _rulerNumber[3]->GetContentSize(twide,ttall);
  231. _rulerNumber[3]->SetSize(twide,ttall);
  232. _rulerNumber[3]->SetPos(cx+cwide, cy+ctall+(tall-cy-ctall)/2 - ttall/2);
  233. }
  234. //-----------------------------------------------------------------------------
  235. // Purpose: respond to cursor movments
  236. //-----------------------------------------------------------------------------
  237. bool BuildGroup::CursorMoved(int x, int y, Panel *panel)
  238. {
  239. Assert(panel);
  240. if ( !m_hBuildDialog.Get() )
  241. {
  242. if ( panel->GetParent() )
  243. {
  244. EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() );
  245. if ( ep )
  246. {
  247. BuildGroup *bg = ep->GetBuildGroup();
  248. if ( bg && bg != this )
  249. {
  250. bg->CursorMoved( x, y, panel );
  251. }
  252. }
  253. }
  254. return false;
  255. }
  256. // no moving uneditable panels
  257. // commented out because this has issues with panels moving
  258. // to front and obscuring other panels
  259. //if (!panel->IsBuildModeEditable())
  260. // return;
  261. if (_dragging)
  262. {
  263. input()->GetCursorPos(x, y);
  264. if (_dragMouseCode == MOUSE_RIGHT)
  265. {
  266. int newW = max( 1, _dragStartPanelSize[ 0 ] + x - _dragStartCursorPos[0] );
  267. int newH = max( 1, _dragStartPanelSize[ 1 ] + y - _dragStartCursorPos[1] );
  268. bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) );
  269. bool ctrl = ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) );
  270. if ( shift )
  271. {
  272. newW = _dragStartPanelSize[ 0 ];
  273. }
  274. if ( ctrl )
  275. {
  276. newH = _dragStartPanelSize[ 1 ];
  277. }
  278. panel->SetSize( newW, newH );
  279. ApplySnap(panel);
  280. }
  281. else
  282. {
  283. for (int i=0; i < _controlGroup.Count(); ++i)
  284. {
  285. // now fix offset of member panels with respect to the one we are dragging
  286. Panel *groupMember = _controlGroup[i].Get();
  287. groupMember->SetPos(_dragStartPanelPos[0] + _groupDeltaX[i] +(x-_dragStartCursorPos[0]), _dragStartPanelPos[1] + _groupDeltaY[i] +(y-_dragStartCursorPos[1]));
  288. ApplySnap(groupMember);
  289. }
  290. }
  291. // update the build dialog
  292. if (m_hBuildDialog)
  293. {
  294. KeyValues *keyval = new KeyValues("UpdateControlData");
  295. keyval->SetPtr("panel", GetCurrentPanel());
  296. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL);
  297. keyval = new KeyValues("EnableSaveButton");
  298. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL);
  299. }
  300. panel->Repaint();
  301. panel->CallParentFunction(new KeyValues("Repaint"));
  302. }
  303. return true;
  304. }
  305. //-----------------------------------------------------------------------------
  306. // Purpose:
  307. //-----------------------------------------------------------------------------
  308. bool BuildGroup::MousePressed(MouseCode code, Panel *panel)
  309. {
  310. Assert(panel);
  311. if ( !m_hBuildDialog.Get() )
  312. {
  313. if ( panel->GetParent() )
  314. {
  315. EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() );
  316. if ( ep )
  317. {
  318. BuildGroup *bg = ep->GetBuildGroup();
  319. if ( bg && bg != this )
  320. {
  321. bg->MousePressed( code, panel );
  322. }
  323. }
  324. }
  325. return false;
  326. }
  327. // if people click on the base build dialog panel.
  328. if (panel == m_hBuildDialog)
  329. {
  330. // hide the click menu if its up
  331. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("HideNewControlMenu"), NULL);
  332. return true;
  333. }
  334. // don't select unnamed items
  335. if (strlen(panel->GetName()) < 1)
  336. return true;
  337. bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) );
  338. if (!shift)
  339. {
  340. _controlGroup.RemoveAll();
  341. }
  342. // Show new ctrl menu if they click on the bg (not on a subcontrol)
  343. if ( code == MOUSE_RIGHT && panel == GetContextPanel())
  344. {
  345. // trigger a drop down menu to create new controls
  346. ivgui()->PostMessage (m_hBuildDialog->GetVPanel(), new KeyValues("ShowNewControlMenu"), NULL);
  347. }
  348. else
  349. {
  350. // don't respond if we click on ruler numbers
  351. if (_showRulers) // rulers are visible
  352. {
  353. for ( int i=0; i < 4; i++)
  354. {
  355. if ( panel == _rulerNumber[i])
  356. return true;
  357. }
  358. }
  359. _dragging = true;
  360. _dragMouseCode = code;
  361. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("HideNewControlMenu"), NULL);
  362. int x, y;
  363. input()->GetCursorPos(x, y);
  364. _dragStartCursorPos[0] = x;
  365. _dragStartCursorPos[1] = y;
  366. input()->SetMouseCapture(panel->GetVPanel());
  367. _groupDeltaX.RemoveAll();
  368. _groupDeltaY.RemoveAll();
  369. // basepanel is the panel that all the deltas will be calculated from.
  370. // it is the last panel we clicked in because if we move the panels as a group
  371. // it would be from that one
  372. Panel *basePanel = NULL;
  373. // find the panel we clicked in, that is the base panel
  374. // it might already be in the group
  375. for (int i=0; i< _controlGroup.Count(); ++i)
  376. {
  377. if (panel == _controlGroup[i].Get())
  378. {
  379. basePanel = panel;
  380. break;
  381. }
  382. }
  383. // if its not in the group we just added this panel. get it in the group
  384. if (basePanel == NULL)
  385. {
  386. PHandle temp;
  387. temp = panel;
  388. _controlGroup.AddToTail(temp);
  389. basePanel = panel;
  390. }
  391. basePanel->GetPos(x,y);
  392. _dragStartPanelPos[0]=x;
  393. _dragStartPanelPos[1]=y;
  394. basePanel->GetSize( _dragStartPanelSize[ 0 ], _dragStartPanelSize[ 1 ] );
  395. // figure out the deltas of the other panels from the base panel
  396. for (int i=0; i<_controlGroup.Count(); ++i)
  397. {
  398. int cx, cy;
  399. _controlGroup[i].Get()->GetPos(cx, cy);
  400. _groupDeltaX.AddToTail(cx - x);
  401. _groupDeltaY.AddToTail(cy - y);
  402. }
  403. // if this panel wasn't already selected update the buildmode dialog controls to show its info
  404. if(_currentPanel != panel)
  405. {
  406. _currentPanel = panel;
  407. if ( m_hBuildDialog )
  408. {
  409. // think this is taken care of by SetActiveControl.
  410. //ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("ApplyDataToControls"), NULL);
  411. KeyValues *keyval = new KeyValues("SetActiveControl");
  412. keyval->SetPtr("PanelPtr", GetCurrentPanel());
  413. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL);
  414. }
  415. }
  416. // store undo information upon panel selection.
  417. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("StoreUndo"), NULL);
  418. panel->RequestFocus();
  419. }
  420. return true;
  421. }
  422. //-----------------------------------------------------------------------------
  423. // Purpose:
  424. //-----------------------------------------------------------------------------
  425. bool BuildGroup::MouseReleased(MouseCode code, Panel *panel)
  426. {
  427. if ( !m_hBuildDialog.Get() )
  428. {
  429. if ( panel->GetParent() )
  430. {
  431. EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() );
  432. if ( ep )
  433. {
  434. BuildGroup *bg = ep->GetBuildGroup();
  435. if ( bg && bg != this )
  436. {
  437. bg->MouseReleased( code, panel );
  438. }
  439. }
  440. }
  441. return false;
  442. }
  443. Assert(panel);
  444. _dragging=false;
  445. input()->SetMouseCapture(null);
  446. return true;
  447. }
  448. //-----------------------------------------------------------------------------
  449. // Purpose:
  450. //-----------------------------------------------------------------------------
  451. bool BuildGroup::MouseDoublePressed(MouseCode code, Panel *panel)
  452. {
  453. Assert(panel);
  454. return MousePressed( code, panel );
  455. }
  456. bool BuildGroup::KeyTyped( wchar_t unichar, Panel *panel )
  457. {
  458. if ( !m_hBuildDialog.Get() )
  459. {
  460. if ( panel->GetParent() )
  461. {
  462. EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() );
  463. if ( ep )
  464. {
  465. BuildGroup *bg = ep->GetBuildGroup();
  466. if ( bg && bg != this )
  467. {
  468. bg->KeyTyped( unichar, panel );
  469. }
  470. }
  471. }
  472. return false;
  473. }
  474. return true;
  475. }
  476. //-----------------------------------------------------------------------------
  477. // Purpose:
  478. //-----------------------------------------------------------------------------
  479. bool BuildGroup::KeyCodeTyped(KeyCode code, Panel *panel)
  480. {
  481. if ( !m_hBuildDialog.Get() )
  482. {
  483. if ( panel->GetParent() )
  484. {
  485. EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() );
  486. if ( ep )
  487. {
  488. BuildGroup *bg = ep->GetBuildGroup();
  489. if ( bg && bg != this )
  490. {
  491. bg->KeyCodeTyped( code, panel );
  492. }
  493. }
  494. }
  495. return false;
  496. }
  497. Assert(panel);
  498. int dx=0;
  499. int dy=0;
  500. bool shift = ( input()->IsKeyDown(KEY_LSHIFT) || input()->IsKeyDown(KEY_RSHIFT) );
  501. bool ctrl = ( input()->IsKeyDown(KEY_LCONTROL) || input()->IsKeyDown(KEY_RCONTROL) );
  502. bool alt = (input()->IsKeyDown(KEY_LALT) || input()->IsKeyDown(KEY_RALT));
  503. if ( ctrl && shift && alt && code == KEY_B)
  504. {
  505. // enable build mode
  506. EditablePanel *ep = dynamic_cast< EditablePanel * >( panel );
  507. if ( ep )
  508. {
  509. ep->ActivateBuildMode();
  510. }
  511. return true;
  512. }
  513. switch (code)
  514. {
  515. case KEY_LEFT:
  516. {
  517. dx-=_snapX;
  518. break;
  519. }
  520. case KEY_RIGHT:
  521. {
  522. dx+=_snapX;
  523. break;
  524. }
  525. case KEY_UP:
  526. {
  527. dy-=_snapY;
  528. break;
  529. }
  530. case KEY_DOWN:
  531. {
  532. dy+=_snapY;
  533. break;
  534. }
  535. case KEY_DELETE:
  536. {
  537. // delete the panel we have selected
  538. ivgui()->PostMessage (m_hBuildDialog->GetVPanel(), new KeyValues ("DeletePanel"), NULL);
  539. break;
  540. }
  541. }
  542. if (ctrl)
  543. {
  544. switch (code)
  545. {
  546. case KEY_Z:
  547. {
  548. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Undo"), NULL);
  549. break;
  550. }
  551. case KEY_C:
  552. {
  553. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Copy"), NULL);
  554. break;
  555. }
  556. case KEY_V:
  557. {
  558. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("Paste"), NULL);
  559. break;
  560. }
  561. }
  562. }
  563. if(dx||dy)
  564. {
  565. //TODO: make this stuff actually snap
  566. int x,y,wide,tall;
  567. panel->GetBounds(x,y,wide,tall);
  568. if(shift)
  569. {
  570. panel->SetSize(wide+dx,tall+dy);
  571. }
  572. else
  573. {
  574. panel->SetPos(x+dx,y+dy);
  575. }
  576. ApplySnap(panel);
  577. panel->Repaint();
  578. if (panel->GetVParent() != 0)
  579. {
  580. panel->PostMessage(panel->GetVParent(), new KeyValues("Repaint"));
  581. }
  582. // update the build dialog
  583. if (m_hBuildDialog)
  584. {
  585. // post that it's active
  586. KeyValues *keyval = new KeyValues("SetActiveControl");
  587. keyval->SetPtr("PanelPtr", GetCurrentPanel());
  588. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL);
  589. // post that it's been changed
  590. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), new KeyValues("PanelMoved"), NULL);
  591. }
  592. }
  593. // If holding key while dragging, simulate moving cursor so shift/ctrl key changes take effect
  594. if ( _dragging && panel != GetContextPanel() )
  595. {
  596. int x, y;
  597. input()->GetCursorPos( x, y );
  598. CursorMoved( x, y, panel );
  599. }
  600. return true;
  601. }
  602. bool BuildGroup::KeyCodeReleased(KeyCode code, Panel *panel )
  603. {
  604. if ( !m_hBuildDialog.Get() )
  605. {
  606. if ( panel->GetParent() )
  607. {
  608. EditablePanel *ep = dynamic_cast< EditablePanel * >( panel->GetParent() );
  609. if ( ep )
  610. {
  611. BuildGroup *bg = ep->GetBuildGroup();
  612. if ( bg && bg != this )
  613. {
  614. bg->KeyCodeTyped( code, panel );
  615. }
  616. }
  617. }
  618. return false;
  619. }
  620. // If holding key while dragging, simulate moving cursor so shift/ctrl key changes take effect
  621. if ( _dragging && panel != GetContextPanel() )
  622. {
  623. int x, y;
  624. input()->GetCursorPos( x, y );
  625. CursorMoved( x, y, panel );
  626. }
  627. return true;
  628. }
  629. //-----------------------------------------------------------------------------
  630. // Purpose: Searches for a BuildModeDialog in the hierarchy
  631. //-----------------------------------------------------------------------------
  632. Panel *BuildGroup::CreateBuildDialog( void )
  633. {
  634. // request the panel
  635. Panel *buildDialog = NULL;
  636. KeyValues *data = new KeyValues("BuildDialog");
  637. data->SetPtr("BuildGroupPtr", this);
  638. if (m_pBuildContext->RequestInfo(data))
  639. {
  640. buildDialog = (Panel *)data->GetPtr("PanelPtr");
  641. }
  642. // initialize the build dialog if found
  643. if ( buildDialog )
  644. {
  645. input()->ReleaseAppModalSurface();
  646. }
  647. return buildDialog;
  648. }
  649. //-----------------------------------------------------------------------------
  650. // Purpose: Activates the build mode settings dialog
  651. //-----------------------------------------------------------------------------
  652. void BuildGroup::ActivateBuildDialog( void )
  653. {
  654. // create the build mode dialog first time through
  655. if (!m_hBuildDialog.Get())
  656. {
  657. m_hBuildDialog = CreateBuildDialog();
  658. if (!m_hBuildDialog.Get())
  659. return;
  660. }
  661. m_hBuildDialog->SetVisible( true );
  662. // send a message to set the initial dialog controls info
  663. _currentPanel = m_pParentPanel;
  664. KeyValues *keyval = new KeyValues("SetActiveControl");
  665. keyval->SetPtr("PanelPtr", GetCurrentPanel());
  666. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL);
  667. }
  668. //-----------------------------------------------------------------------------
  669. // Purpose:
  670. //-----------------------------------------------------------------------------
  671. HCursor BuildGroup::GetCursor(Panel *panel)
  672. {
  673. Assert(panel);
  674. int x,y,wide,tall;
  675. input()->GetCursorPos(x,y);
  676. panel->ScreenToLocal(x,y);
  677. panel->GetSize(wide,tall);
  678. if(x < 2)
  679. {
  680. if(y < 4)
  681. {
  682. return _cursor_sizenwse;
  683. }
  684. else
  685. if(y<(tall-4))
  686. {
  687. return _cursor_sizewe;
  688. }
  689. else
  690. {
  691. return _cursor_sizenesw;
  692. }
  693. }
  694. return _cursor_sizeall;
  695. }
  696. //-----------------------------------------------------------------------------
  697. // Purpose:
  698. //-----------------------------------------------------------------------------
  699. void BuildGroup::ApplySnap(Panel *panel)
  700. {
  701. Assert(panel);
  702. int x,y,wide,tall;
  703. panel->GetBounds(x,y,wide,tall);
  704. x=(x/_snapX)*_snapX;
  705. y=(y/_snapY)*_snapY;
  706. panel->SetPos(x,y);
  707. int xx,yy;
  708. xx=x+wide;
  709. yy=y+tall;
  710. xx=(xx/_snapX)*_snapX;
  711. yy=(yy/_snapY)*_snapY;
  712. panel->SetSize(xx-x,yy-y);
  713. }
  714. //-----------------------------------------------------------------------------
  715. // Purpose: Return the currently selected panel
  716. //-----------------------------------------------------------------------------
  717. Panel *BuildGroup::GetCurrentPanel()
  718. {
  719. return _currentPanel;
  720. }
  721. //-----------------------------------------------------------------------------
  722. // Purpose: Add panel the list of panels that are in the build group
  723. //-----------------------------------------------------------------------------
  724. void BuildGroup::PanelAdded(Panel *panel)
  725. {
  726. Assert(panel);
  727. PHandle temp;
  728. temp = panel;
  729. int c = _panelDar.Count();
  730. for ( int i = 0; i < c; ++i )
  731. {
  732. if ( _panelDar[ i ] == temp )
  733. {
  734. return;
  735. }
  736. }
  737. _panelDar.AddToTail(temp);
  738. }
  739. //-----------------------------------------------------------------------------
  740. // Purpose: loads the control settings from file
  741. //-----------------------------------------------------------------------------
  742. void BuildGroup::LoadControlSettings(const char *controlResourceName, const char *pathID, KeyValues *pPreloadedKeyValues, KeyValues *pConditions)
  743. {
  744. // make sure the file is registered
  745. RegisterControlSettingsFile(controlResourceName, pathID);
  746. // Use the keyvalues they passed in or load them.
  747. KeyValues *rDat = pPreloadedKeyValues;
  748. bool bUsePrecaching = vgui_cache_res_files.GetBool();
  749. bool bUsingPrecachedSourceKeys = false;
  750. bool bShouldCacheKeys = true;
  751. bool bDeleteKeys = false;
  752. while ( !rDat )
  753. {
  754. if ( bUsePrecaching )
  755. {
  756. int nIndex = m_dictCachedResFiles.Find( controlResourceName );
  757. if ( nIndex != m_dictCachedResFiles.InvalidIndex() )
  758. {
  759. rDat = m_dictCachedResFiles[nIndex];
  760. bUsingPrecachedSourceKeys = true;
  761. bDeleteKeys = false;
  762. bShouldCacheKeys = false;
  763. break;
  764. }
  765. }
  766. // load the resource data from the file
  767. rDat = new KeyValues( controlResourceName );
  768. // check the skins directory first, if an explicit pathID hasn't been set
  769. bool bSuccess = false;
  770. if ( !pathID )
  771. {
  772. bSuccess = rDat->LoadFromFile( g_pFullFileSystem, controlResourceName, "SKIN" );
  773. }
  774. if ( !V_stricmp( CommandLine()->ParmValue( "-game", "hl2" ), "tf" ) )
  775. {
  776. if ( !bSuccess )
  777. {
  778. bSuccess = rDat->LoadFromFile( g_pFullFileSystem, controlResourceName, "custom_mod" );
  779. }
  780. if ( !bSuccess )
  781. {
  782. bSuccess = rDat->LoadFromFile( g_pFullFileSystem, controlResourceName, "vgui" );
  783. }
  784. if ( !bSuccess )
  785. {
  786. bSuccess = rDat->LoadFromFile( g_pFullFileSystem, controlResourceName, "BSP" );
  787. }
  788. // only allow to load loose files when using insecure mode
  789. if ( !bSuccess && CommandLine()->FindParm( "-insecure" ) )
  790. {
  791. bSuccess = rDat->LoadFromFile( g_pFullFileSystem, controlResourceName, pathID );
  792. }
  793. }
  794. else
  795. {
  796. if ( !bSuccess )
  797. {
  798. bSuccess = rDat->LoadFromFile( g_pFullFileSystem, controlResourceName, pathID );
  799. }
  800. }
  801. if ( bSuccess )
  802. {
  803. if ( IsX360() )
  804. {
  805. rDat->ProcessResolutionKeys( surface()->GetResolutionKey() );
  806. }
  807. if ( IsPC() )
  808. {
  809. ConVarRef cl_hud_minmode( "cl_hud_minmode", true );
  810. if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() )
  811. {
  812. rDat->ProcessResolutionKeys( "_minmode" );
  813. }
  814. }
  815. bDeleteKeys = true;
  816. bShouldCacheKeys = true;
  817. }
  818. else
  819. {
  820. Warning( "Failed to load %s\n", controlResourceName );
  821. }
  822. break;
  823. }
  824. if ( pConditions && pConditions->GetFirstSubKey() )
  825. {
  826. if ( bUsingPrecachedSourceKeys )
  827. {
  828. // ProcessConditionalKeys modifies the KVs in place. We dont want
  829. // that to happen to our cached keys
  830. rDat = rDat->MakeCopy();
  831. bDeleteKeys = true;
  832. }
  833. ProcessConditionalKeys(rDat, pConditions);
  834. bShouldCacheKeys = false;
  835. }
  836. // save off the resource name
  837. delete [] m_pResourceName;
  838. m_pResourceName = new char[strlen(controlResourceName) + 1];
  839. strcpy(m_pResourceName, controlResourceName);
  840. if (pathID)
  841. {
  842. delete [] m_pResourcePathID;
  843. m_pResourcePathID = new char[strlen(pathID) + 1];
  844. strcpy(m_pResourcePathID, pathID);
  845. }
  846. // delete any controls not in both files
  847. DeleteAllControlsCreatedByControlSettingsFile();
  848. // loop through the resource data sticking info into controls
  849. ApplySettings(rDat);
  850. if (m_pParentPanel)
  851. {
  852. m_pParentPanel->InvalidateLayout();
  853. m_pParentPanel->Repaint();
  854. }
  855. if ( bShouldCacheKeys && bUsePrecaching )
  856. {
  857. Assert( m_dictCachedResFiles.Find( controlResourceName ) == m_dictCachedResFiles.InvalidIndex() );
  858. m_dictCachedResFiles.Insert( controlResourceName, rDat );
  859. }
  860. else if ( bDeleteKeys )
  861. {
  862. Assert( m_dictCachedResFiles.Find( controlResourceName ) != m_dictCachedResFiles.InvalidIndex() || pConditions || pPreloadedKeyValues );
  863. rDat->deleteThis();
  864. }
  865. }
  866. void BuildGroup::ProcessConditionalKeys( KeyValues *pData, KeyValues *pConditions )
  867. {
  868. // for each condition, look for it in keys
  869. // if its a positive condition, promote all of its children, replacing values
  870. if ( pData )
  871. {
  872. KeyValues *pSubKey = pData->GetFirstSubKey();
  873. if ( !pSubKey )
  874. {
  875. // not a block
  876. return;
  877. }
  878. for ( ; pSubKey != NULL; pSubKey = pSubKey->GetNextKey() )
  879. {
  880. // recursively descend each sub block
  881. ProcessConditionalKeys( pSubKey, pConditions );
  882. KeyValues *pCondition = pConditions->GetFirstSubKey();
  883. for ( ; pCondition != NULL; pCondition = pCondition->GetNextKey() )
  884. {
  885. // if we match any conditions in this sub block, copy up
  886. KeyValues *pConditionBlock = pSubKey->FindKey( pCondition->GetName() );
  887. if ( pConditionBlock )
  888. {
  889. KeyValues *pOverridingKey;
  890. for ( pOverridingKey = pConditionBlock->GetFirstSubKey(); pOverridingKey != NULL; pOverridingKey = pOverridingKey->GetNextKey() )
  891. {
  892. KeyValues *pExistingKey = pSubKey->FindKey( pOverridingKey->GetName() );
  893. if ( pExistingKey )
  894. {
  895. pExistingKey->SetStringValue( pOverridingKey->GetString() );
  896. }
  897. else
  898. {
  899. KeyValues *copy = pOverridingKey->MakeCopy();
  900. pSubKey->AddSubKey( copy );
  901. }
  902. }
  903. }
  904. }
  905. }
  906. }
  907. }
  908. //-----------------------------------------------------------------------------
  909. // Purpose: registers that a control settings file may be loaded
  910. // use when the dialog may have multiple states and the editor will need to be able to switch between them
  911. //-----------------------------------------------------------------------------
  912. void BuildGroup::RegisterControlSettingsFile(const char *controlResourceName, const char *pathID)
  913. {
  914. // add the file into a list for build mode
  915. CUtlSymbol sym(controlResourceName);
  916. if (!m_RegisteredControlSettingsFiles.IsValidIndex(m_RegisteredControlSettingsFiles.Find(sym)))
  917. {
  918. m_RegisteredControlSettingsFiles.AddToTail(sym);
  919. }
  920. }
  921. //-----------------------------------------------------------------------------
  922. // Purpose: data accessor / iterator
  923. //-----------------------------------------------------------------------------
  924. int BuildGroup::GetRegisteredControlSettingsFileCount()
  925. {
  926. return m_RegisteredControlSettingsFiles.Count();
  927. }
  928. //-----------------------------------------------------------------------------
  929. // Purpose: data accessor
  930. //-----------------------------------------------------------------------------
  931. const char *BuildGroup::GetRegisteredControlSettingsFileByIndex(int index)
  932. {
  933. return m_RegisteredControlSettingsFiles[index].String();
  934. }
  935. //-----------------------------------------------------------------------------
  936. // Purpose: reloads the control settings from file
  937. //-----------------------------------------------------------------------------
  938. void BuildGroup::ReloadControlSettings()
  939. {
  940. delete m_hBuildDialog.Get();
  941. m_hBuildDialog = NULL;
  942. // loop though objects in the current control group and remove them all
  943. // the 0th panel is always the contextPanel which is not deletable
  944. for( int i = 1; i < _panelDar.Count(); i++ )
  945. {
  946. if (!_panelDar[i].Get()) // this can happen if we had two of the same handle in the list
  947. {
  948. _panelDar.Remove(i);
  949. --i;
  950. continue;
  951. }
  952. // only delete deletable panels, as the only deletable panels
  953. // are the ones created using the resource file
  954. if ( _panelDar[i].Get()->IsBuildModeDeletable())
  955. {
  956. delete _panelDar[i].Get();
  957. _panelDar.Remove(i);
  958. --i;
  959. }
  960. }
  961. if (m_pResourceName)
  962. {
  963. EditablePanel *edit = dynamic_cast<EditablePanel *>(m_pParentPanel);
  964. if (edit)
  965. {
  966. edit->LoadControlSettings(m_pResourceName, m_pResourcePathID);
  967. }
  968. else
  969. {
  970. LoadControlSettings(m_pResourceName, m_pResourcePathID);
  971. }
  972. }
  973. _controlGroup.RemoveAll();
  974. ActivateBuildDialog();
  975. }
  976. //-----------------------------------------------------------------------------
  977. // Purpose: changes which control settings are currently loaded
  978. //-----------------------------------------------------------------------------
  979. void BuildGroup::ChangeControlSettingsFile(const char *controlResourceName)
  980. {
  981. // clear any current state
  982. _controlGroup.RemoveAll();
  983. _currentPanel = m_pParentPanel;
  984. // load the new state, via the dialog if possible
  985. EditablePanel *edit = dynamic_cast<EditablePanel *>(m_pParentPanel);
  986. if (edit)
  987. {
  988. edit->LoadControlSettings(controlResourceName, m_pResourcePathID);
  989. }
  990. else
  991. {
  992. LoadControlSettings(controlResourceName, m_pResourcePathID);
  993. }
  994. // force it to update
  995. KeyValues *keyval = new KeyValues("SetActiveControl");
  996. keyval->SetPtr("PanelPtr", GetCurrentPanel());
  997. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL);
  998. }
  999. //-----------------------------------------------------------------------------
  1000. // Purpose: saves control settings to file
  1001. //-----------------------------------------------------------------------------
  1002. bool BuildGroup::SaveControlSettings( void )
  1003. {
  1004. bool bSuccess = false;
  1005. if ( m_pResourceName )
  1006. {
  1007. KeyValues *rDat = new KeyValues( m_pResourceName );
  1008. // get the data from our controls
  1009. GetSettings( rDat );
  1010. char fullpath[ 512 ];
  1011. g_pFullFileSystem->RelativePathToFullPath( m_pResourceName, m_pResourcePathID, fullpath, sizeof( fullpath ) );
  1012. // save the data out to a file
  1013. bSuccess = rDat->SaveToFile( g_pFullFileSystem, fullpath, NULL );
  1014. if (!bSuccess)
  1015. {
  1016. MessageBox *dlg = new MessageBox("BuildMode - Error saving file", "Error: Could not save changes. File is most likely read only.");
  1017. dlg->DoModal();
  1018. }
  1019. rDat->deleteThis();
  1020. }
  1021. return bSuccess;
  1022. }
  1023. //-----------------------------------------------------------------------------
  1024. // Purpose: Deletes all the controls not created by the code
  1025. //-----------------------------------------------------------------------------
  1026. void BuildGroup::DeleteAllControlsCreatedByControlSettingsFile()
  1027. {
  1028. // loop though objects in the current control group and remove them all
  1029. // the 0th panel is always the contextPanel which is not deletable
  1030. for ( int i = 1; i < _panelDar.Count(); i++ )
  1031. {
  1032. if (!_panelDar[i].Get()) // this can happen if we had two of the same handle in the list
  1033. {
  1034. _panelDar.Remove(i);
  1035. --i;
  1036. continue;
  1037. }
  1038. // only delete deletable panels, as the only deletable panels
  1039. // are the ones created using the resource file
  1040. if ( _panelDar[i].Get()->IsBuildModeDeletable())
  1041. {
  1042. delete _panelDar[i].Get();
  1043. _panelDar.Remove(i);
  1044. --i;
  1045. }
  1046. }
  1047. _currentPanel = m_pBuildContext;
  1048. _currentPanel->InvalidateLayout();
  1049. m_pBuildContext->Repaint();
  1050. }
  1051. //-----------------------------------------------------------------------------
  1052. // Purpose: serializes settings from a resource data container
  1053. //-----------------------------------------------------------------------------
  1054. void BuildGroup::ApplySettings( KeyValues *resourceData )
  1055. {
  1056. tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s", __FUNCTION__ );
  1057. // loop through all the keys, applying them wherever
  1058. for (KeyValues *controlKeys = resourceData->GetFirstSubKey(); controlKeys != NULL; controlKeys = controlKeys->GetNextKey())
  1059. {
  1060. bool bFound = false;
  1061. // Skip keys that are atomic..
  1062. if (controlKeys->GetDataType() != KeyValues::TYPE_NONE)
  1063. continue;
  1064. char const *keyName = controlKeys->GetName();
  1065. // check to see if any buildgroup panels have this name
  1066. for ( int i = 0; i < _panelDar.Count(); i++ )
  1067. {
  1068. Panel *panel = _panelDar[i].Get();
  1069. if (!panel) // this can happen if we had two of the same handle in the list
  1070. {
  1071. _panelDar.Remove(i);
  1072. --i;
  1073. continue;
  1074. }
  1075. Assert (panel);
  1076. // make the control name match CASE INSENSITIVE!
  1077. char const *panelName = panel->GetName();
  1078. if (!Q_stricmp(panelName, keyName))
  1079. {
  1080. // apply the settings
  1081. panel->ApplySettings(controlKeys);
  1082. bFound = true;
  1083. break;
  1084. }
  1085. }
  1086. if ( !bFound )
  1087. {
  1088. // the key was not found in the registered list, check to see if we should create it
  1089. if ( keyName /*controlKeys->GetInt("AlwaysCreate", false)*/ )
  1090. {
  1091. // create the control even though it wasn't registered
  1092. NewControl( controlKeys );
  1093. }
  1094. }
  1095. }
  1096. }
  1097. //-----------------------------------------------------------------------------
  1098. // Purpose: Create a new control in the context panel
  1099. // Input: name: class name of control to create
  1100. // controlKeys: keyvalues of settings for the panel.
  1101. // name OR controlKeys should be set, not both.
  1102. // x,y position relative to base panel
  1103. // Output: Panel *newPanel, NULL if failed to create new control.
  1104. //-----------------------------------------------------------------------------
  1105. Panel *BuildGroup::NewControl( const char *name, int x, int y)
  1106. {
  1107. Assert (name);
  1108. Panel *newPanel = NULL;
  1109. // returns NULL on failure
  1110. newPanel = static_cast<EditablePanel *>(m_pParentPanel)->CreateControlByName(name);
  1111. if (newPanel)
  1112. {
  1113. // panel successfully created
  1114. newPanel->SetParent(m_pParentPanel);
  1115. newPanel->SetBuildGroup(this);
  1116. newPanel->SetPos(x, y);
  1117. char newFieldName[255];
  1118. GetNewFieldName(newFieldName, sizeof(newFieldName), newPanel);
  1119. newPanel->SetName(newFieldName);
  1120. newPanel->AddActionSignalTarget(m_pParentPanel);
  1121. newPanel->SetBuildModeEditable(true);
  1122. newPanel->SetBuildModeDeletable(true);
  1123. // make sure it gets freed
  1124. newPanel->SetAutoDelete(true);
  1125. }
  1126. return newPanel;
  1127. }
  1128. //-----------------------------------------------------------------------------
  1129. // Purpose: Create a new control in the context panel
  1130. // Input: controlKeys: keyvalues of settings for the panel only works when applying initial settings.
  1131. // Output: Panel *newPanel, NULL if failed to create new control.
  1132. //-----------------------------------------------------------------------------
  1133. Panel *BuildGroup::NewControl( KeyValues *controlKeys, int x, int y)
  1134. {
  1135. Assert (controlKeys);
  1136. Panel *newPanel = NULL;
  1137. if (controlKeys)
  1138. {
  1139. // Warning( "Creating new control \"%s\" of type \"%s\"\n", controlKeys->GetString( "fieldName" ), controlKeys->GetString( "ControlName" ) );
  1140. KeyValues *keyVal = new KeyValues("ControlFactory", "ControlName", controlKeys->GetString("ControlName"));
  1141. m_pBuildContext->RequestInfo(keyVal);
  1142. // returns NULL on failure
  1143. newPanel = (Panel *)keyVal->GetPtr("PanelPtr");
  1144. keyVal->deleteThis();
  1145. }
  1146. else
  1147. {
  1148. return NULL;
  1149. }
  1150. if (newPanel)
  1151. {
  1152. // panel successfully created
  1153. newPanel->SetParent(m_pParentPanel);
  1154. newPanel->SetBuildGroup(this);
  1155. newPanel->SetPos(x, y);
  1156. newPanel->SetName(controlKeys->GetName()); // name before applysettings :)
  1157. newPanel->ApplySettings(controlKeys);
  1158. newPanel->AddActionSignalTarget(m_pParentPanel);
  1159. newPanel->SetBuildModeEditable(true);
  1160. newPanel->SetBuildModeDeletable(true);
  1161. // make sure it gets freed
  1162. newPanel->SetAutoDelete(true);
  1163. }
  1164. return newPanel;
  1165. }
  1166. //-----------------------------------------------------------------------------
  1167. // Purpose: Get a new unique fieldname for a new control
  1168. //-----------------------------------------------------------------------------
  1169. void BuildGroup::GetNewFieldName(char *newFieldName, int newFieldNameSize, Panel *newPanel)
  1170. {
  1171. int fieldNameNumber=1;
  1172. char defaultName[25];
  1173. Q_strncpy( defaultName, newPanel->GetClassName(), sizeof( defaultName ) );
  1174. while (1)
  1175. {
  1176. Q_snprintf (newFieldName, newFieldNameSize, "%s%d", defaultName, fieldNameNumber);
  1177. if ( FieldNameTaken(newFieldName) == NULL)
  1178. break;
  1179. ++fieldNameNumber;
  1180. }
  1181. }
  1182. //-----------------------------------------------------------------------------
  1183. // Purpose: check to see if any buildgroup panels have this fieldname
  1184. // Input : fieldName, name to check
  1185. // Output : ptr to a panel that has the name if it is taken
  1186. //-----------------------------------------------------------------------------
  1187. Panel *BuildGroup::FieldNameTaken(const char *fieldName)
  1188. {
  1189. for ( int i = 0; i < _panelDar.Count(); i++ )
  1190. {
  1191. Panel *panel = _panelDar[i].Get();
  1192. if ( !panel )
  1193. continue;
  1194. if (!stricmp(panel->GetName(), fieldName) )
  1195. {
  1196. return panel;
  1197. }
  1198. }
  1199. return NULL;
  1200. }
  1201. //-----------------------------------------------------------------------------
  1202. // Purpose: serializes settings to a resource data container
  1203. //-----------------------------------------------------------------------------
  1204. void BuildGroup::GetSettings( KeyValues *resourceData )
  1205. {
  1206. // loop through all the objects getting their settings
  1207. for( int i = 0; i < _panelDar.Count(); i++ )
  1208. {
  1209. Panel *panel = _panelDar[i].Get();
  1210. if (!panel)
  1211. continue;
  1212. bool isRuler = false;
  1213. // do not get setting for ruler labels.
  1214. if (_showRulers) // rulers are visible
  1215. {
  1216. for (int j = 0; j < 4; j++)
  1217. {
  1218. if (panel == _rulerNumber[j])
  1219. {
  1220. isRuler = true;
  1221. break;
  1222. }
  1223. }
  1224. if (isRuler)
  1225. {
  1226. isRuler = false;
  1227. continue;
  1228. }
  1229. }
  1230. // Don't save the setting of the buildmodedialog
  1231. if (!stricmp(panel->GetName(), "BuildDialog"))
  1232. continue;
  1233. // get the keys section from the data file
  1234. if (panel->GetName() && *panel->GetName())
  1235. {
  1236. KeyValues *datKey = resourceData->FindKey(panel->GetName(), true);
  1237. // get the settings
  1238. panel->GetSettings(datKey);
  1239. }
  1240. }
  1241. }
  1242. //-----------------------------------------------------------------------------
  1243. // Purpose: loop though objects in the current control group and remove them all
  1244. //-----------------------------------------------------------------------------
  1245. void BuildGroup::RemoveSettings()
  1246. {
  1247. // loop though objects in the current control group and remove them all
  1248. int i;
  1249. for( i = 0; i < _controlGroup.Count(); i++ )
  1250. {
  1251. // only delete delatable panels
  1252. if ( _controlGroup[i].Get()->IsBuildModeDeletable())
  1253. {
  1254. delete _controlGroup[i].Get();
  1255. _controlGroup.Remove(i);
  1256. --i;
  1257. }
  1258. }
  1259. // remove deleted panels from the handle list
  1260. for( i = 0; i < _panelDar.Count(); i++ )
  1261. {
  1262. if ( !_panelDar[i].Get() )
  1263. {
  1264. _panelDar.Remove(i);
  1265. --i;
  1266. }
  1267. }
  1268. _currentPanel = m_pBuildContext;
  1269. _currentPanel->InvalidateLayout();
  1270. m_pBuildContext->Repaint();
  1271. }
  1272. //-----------------------------------------------------------------------------
  1273. // Purpose: sets the panel from which the build group gets all it's object creation info
  1274. //-----------------------------------------------------------------------------
  1275. void BuildGroup::SetContextPanel(Panel *contextPanel)
  1276. {
  1277. m_pBuildContext = contextPanel;
  1278. }
  1279. //-----------------------------------------------------------------------------
  1280. // Purpose: gets the panel from which the build group gets all it's object creation info
  1281. //-----------------------------------------------------------------------------
  1282. Panel *BuildGroup::GetContextPanel()
  1283. {
  1284. return m_pBuildContext;
  1285. }
  1286. //-----------------------------------------------------------------------------
  1287. // Purpose: get the list of panels in the buildgroup
  1288. //-----------------------------------------------------------------------------
  1289. CUtlVector<PHandle> *BuildGroup::GetPanelList()
  1290. {
  1291. return &_panelDar;
  1292. }
  1293. //-----------------------------------------------------------------------------
  1294. // Purpose: dialog variables
  1295. //-----------------------------------------------------------------------------
  1296. KeyValues *BuildGroup::GetDialogVariables()
  1297. {
  1298. EditablePanel *edit = dynamic_cast<EditablePanel *>(m_pParentPanel);
  1299. if (edit)
  1300. {
  1301. return edit->GetDialogVariables();
  1302. }
  1303. return NULL;
  1304. }
  1305. bool BuildGroup::PrecacheResFile( const char* pszResFileName )
  1306. {
  1307. KeyValues *pkvResFile = new KeyValues( pszResFileName );
  1308. if ( pkvResFile->LoadFromFile( g_pFullFileSystem, pszResFileName, "GAME" ) )
  1309. {
  1310. Assert( m_dictCachedResFiles.Find( pszResFileName ) == m_dictCachedResFiles.InvalidIndex() );
  1311. m_dictCachedResFiles.Insert( pszResFileName, pkvResFile );
  1312. return true;
  1313. }
  1314. return false;
  1315. }
  1316. void BuildGroup::ClearResFileCache()
  1317. {
  1318. int nIndex = m_dictCachedResFiles.First();
  1319. while( m_dictCachedResFiles.IsValidIndex( nIndex ) )
  1320. {
  1321. m_dictCachedResFiles[ nIndex ]->deleteThis();
  1322. nIndex = m_dictCachedResFiles.Next( nIndex );
  1323. }
  1324. m_dictCachedResFiles.Purge();
  1325. }