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.

1493 lines
39 KiB

  1. //========= Copyright � 1996-2005, 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. #if defined( _X360 )
  38. #include "xbox/xbox_win32stubs.h"
  39. #endif
  40. // memdbgon must be the last include file in a .cpp file!!!
  41. #include <tier0/memdbgon.h>
  42. using namespace vgui;
  43. //-----------------------------------------------------------------------------
  44. // Handle table
  45. //-----------------------------------------------------------------------------
  46. IMPLEMENT_HANDLES( BuildGroup, 20 )
  47. //-----------------------------------------------------------------------------
  48. // Purpose: Constructor
  49. //-----------------------------------------------------------------------------
  50. BuildGroup::BuildGroup(Panel *parentPanel, Panel *contextPanel)
  51. {
  52. CONSTRUCT_HANDLE( );
  53. _enabled=false;
  54. _snapX=1;
  55. _snapY=1;
  56. _cursor_sizenwse = dc_sizenwse;
  57. _cursor_sizenesw = dc_sizenesw;
  58. _cursor_sizewe = dc_sizewe;
  59. _cursor_sizens = dc_sizens;
  60. _cursor_sizeall = dc_sizeall;
  61. _currentPanel=0;
  62. _dragging=false;
  63. m_pResourceName=NULL;
  64. m_pResourcePathID = NULL;
  65. m_hBuildDialog=NULL;
  66. m_pParentPanel=parentPanel;
  67. for (int i=0; i<4; ++i)
  68. _rulerNumber[i] = NULL;
  69. SetContextPanel(contextPanel);
  70. _showRulers = false;
  71. // These are probably not required
  72. _controlGroup.Purge();
  73. _groupDeltaX.Purge();
  74. _groupDeltaY.Purge();
  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(0);
  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() != NULL)
  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. _panelDar.AddToTail(temp);
  730. }
  731. //-----------------------------------------------------------------------------
  732. // Purpose: Add panel the list of panels that are in the build group
  733. //-----------------------------------------------------------------------------
  734. void BuildGroup::PanelRemoved(Panel *panel)
  735. {
  736. Assert(panel);
  737. PHandle temp;
  738. temp = panel;
  739. _panelDar.FindAndRemove(temp);
  740. }
  741. //-----------------------------------------------------------------------------
  742. // Purpose: loads the control settings from file
  743. //-----------------------------------------------------------------------------
  744. void BuildGroup::LoadControlSettings(const char *controlResourceName, const char *pathID, KeyValues *pPreloadedKeyValues, KeyValues *pConditions)
  745. {
  746. // make sure the file is registered
  747. RegisterControlSettingsFile(controlResourceName, pathID);
  748. // Use the keyvalues they passed in or load them.
  749. KeyValues *rDat = pPreloadedKeyValues;
  750. if ( !rDat )
  751. {
  752. // load the resource data from the file
  753. rDat = new KeyValues(controlResourceName);
  754. // check the skins directory first, if an explicit pathID hasn't been set
  755. bool bSuccess = false;
  756. if (!pathID)
  757. {
  758. bSuccess = rDat->LoadFromFile(g_pFullFileSystem, controlResourceName, "SKIN");
  759. }
  760. if (!bSuccess)
  761. {
  762. bSuccess = rDat->LoadFromFile(g_pFullFileSystem, controlResourceName, pathID);
  763. }
  764. if ( bSuccess )
  765. {
  766. if ( IsPC() )
  767. {
  768. ConVarRef cl_hud_minmode( "cl_hud_minmode", true );
  769. if ( cl_hud_minmode.IsValid() && cl_hud_minmode.GetBool() )
  770. {
  771. rDat->ProcessResolutionKeys( "_minmode" );
  772. }
  773. }
  774. if ( pConditions && pConditions->GetFirstSubKey() )
  775. {
  776. ProcessConditionalKeys( rDat, pConditions );
  777. }
  778. }
  779. }
  780. // save off the resource name
  781. delete [] m_pResourceName;
  782. m_pResourceName = new char[strlen(controlResourceName) + 1];
  783. strcpy(m_pResourceName, controlResourceName);
  784. if (pathID)
  785. {
  786. delete [] m_pResourcePathID;
  787. m_pResourcePathID = new char[strlen(pathID) + 1];
  788. strcpy(m_pResourcePathID, pathID);
  789. }
  790. // delete any controls not in both files
  791. DeleteAllControlsCreatedByControlSettingsFile();
  792. // loop through the resource data sticking info into controls
  793. ApplySettings(rDat);
  794. if (m_pParentPanel)
  795. {
  796. m_pParentPanel->InvalidateLayout();
  797. m_pParentPanel->Repaint();
  798. }
  799. if ( rDat != pPreloadedKeyValues )
  800. {
  801. rDat->deleteThis();
  802. }
  803. }
  804. void BuildGroup::ProcessConditionalKeys( KeyValues *pData, KeyValues *pConditions )
  805. {
  806. // for each condition, look for it in keys
  807. // if its a positive condition, promote all of its children, replacing values
  808. /*
  809. Example:
  810. pData = "pDataRoot"
  811. {
  812. "folder1"
  813. {
  814. "file1" "a"
  815. "file2" "b"
  816. "?secret"
  817. {
  818. "file2" "secretHere"
  819. }
  820. }
  821. "folder2"
  822. {
  823. "file1" "a"
  824. "file2" "b"
  825. "?secret"
  826. {
  827. "file1" "secretHere"
  828. "visible" "1"
  829. }
  830. }
  831. }
  832. pConditions = "root"
  833. {
  834. "?secret" "1"
  835. }
  836. */
  837. if ( pData )
  838. {
  839. KeyValues *pSubKey = pData->GetFirstSubKey();
  840. if ( !pSubKey )
  841. {
  842. // not a block
  843. return;
  844. }
  845. for ( ; pSubKey != NULL; pSubKey = pSubKey->GetNextKey() )
  846. {
  847. // recursively descend each sub block
  848. ProcessConditionalKeys( pSubKey, pConditions );
  849. KeyValues *pCondition = pConditions->GetFirstSubKey();
  850. for ( ; pCondition != NULL; pCondition = pCondition->GetNextKey() )
  851. {
  852. // if we match any conditions in this sub block, copy up
  853. KeyValues *pConditionBlock = pSubKey->FindKey( pCondition->GetName() );
  854. /*
  855. pSubKey -> "folder1"
  856. pCondition -> "?secret" "1"
  857. pConditionBlock -> "folder1/?secret"
  858. */
  859. if ( pConditionBlock )
  860. {
  861. KeyValues *pOverridingKey;
  862. for ( pOverridingKey = pConditionBlock->GetFirstSubKey(); pOverridingKey != NULL; pOverridingKey = pOverridingKey->GetNextKey() )
  863. {
  864. /*
  865. Copy up all values under "folder1/?secret" into "folder1"
  866. */
  867. KeyValues *pExistingKey = pSubKey->FindKey( pOverridingKey->GetName() );
  868. if ( pExistingKey )
  869. {
  870. pExistingKey->SetStringValue( pOverridingKey->GetString() );
  871. }
  872. else
  873. {
  874. KeyValues *copy = pOverridingKey->MakeCopy();
  875. pSubKey->AddSubKey( copy );
  876. }
  877. }
  878. }
  879. }
  880. }
  881. }
  882. }
  883. //-----------------------------------------------------------------------------
  884. // Purpose: registers that a control settings file may be loaded
  885. // use when the dialog may have multiple states and the editor will need to be able to switch between them
  886. //-----------------------------------------------------------------------------
  887. void BuildGroup::RegisterControlSettingsFile(const char *controlResourceName, const char *pathID)
  888. {
  889. // add the file into a list for build mode
  890. CUtlSymbol sym(controlResourceName);
  891. if (!m_RegisteredControlSettingsFiles.IsValidIndex(m_RegisteredControlSettingsFiles.Find(sym)))
  892. {
  893. m_RegisteredControlSettingsFiles.AddToTail(sym);
  894. }
  895. }
  896. //-----------------------------------------------------------------------------
  897. // Purpose: data accessor / iterator
  898. //-----------------------------------------------------------------------------
  899. int BuildGroup::GetRegisteredControlSettingsFileCount()
  900. {
  901. return m_RegisteredControlSettingsFiles.Count();
  902. }
  903. //-----------------------------------------------------------------------------
  904. // Purpose: data accessor
  905. //-----------------------------------------------------------------------------
  906. const char *BuildGroup::GetRegisteredControlSettingsFileByIndex(int index)
  907. {
  908. return m_RegisteredControlSettingsFiles[index].String();
  909. }
  910. //-----------------------------------------------------------------------------
  911. // Purpose: reloads the control settings from file
  912. //-----------------------------------------------------------------------------
  913. void BuildGroup::ReloadControlSettings()
  914. {
  915. delete m_hBuildDialog.Get();
  916. m_hBuildDialog = NULL;
  917. // loop though objects in the current control group and remove them all
  918. // the 0th panel is always the contextPanel which is not deletable
  919. for( int i = 1; i < _panelDar.Count(); i++ )
  920. {
  921. Panel *pRemove = _panelDar[i].Get();
  922. if ( !pRemove ) // this can happen if we had two of the same handle in the list
  923. {
  924. _panelDar.Remove(i);
  925. --i;
  926. continue;
  927. }
  928. // only delete deletable panels, as the only deletable panels
  929. // are the ones created using the resource file
  930. if ( pRemove->IsBuildModeDeletable() )
  931. {
  932. _panelDar.Remove(i);
  933. delete pRemove;
  934. --i;
  935. }
  936. }
  937. if (m_pResourceName)
  938. {
  939. EditablePanel *edit = dynamic_cast<EditablePanel *>(m_pParentPanel);
  940. if (edit)
  941. {
  942. edit->LoadControlSettings(m_pResourceName, m_pResourcePathID);
  943. }
  944. else
  945. {
  946. LoadControlSettings(m_pResourceName, m_pResourcePathID);
  947. }
  948. }
  949. _controlGroup.RemoveAll();
  950. ActivateBuildDialog();
  951. }
  952. //-----------------------------------------------------------------------------
  953. // Purpose: changes which control settings are currently loaded
  954. //-----------------------------------------------------------------------------
  955. void BuildGroup::ChangeControlSettingsFile(const char *controlResourceName)
  956. {
  957. // clear any current state
  958. _controlGroup.RemoveAll();
  959. _currentPanel = m_pParentPanel;
  960. // load the new state, via the dialog if possible
  961. EditablePanel *edit = dynamic_cast<EditablePanel *>(m_pParentPanel);
  962. if (edit)
  963. {
  964. edit->LoadControlSettings(controlResourceName, m_pResourcePathID);
  965. }
  966. else
  967. {
  968. LoadControlSettings(controlResourceName, m_pResourcePathID);
  969. }
  970. // force it to update
  971. KeyValues *keyval = new KeyValues("SetActiveControl");
  972. keyval->SetPtr("PanelPtr", GetCurrentPanel());
  973. ivgui()->PostMessage(m_hBuildDialog->GetVPanel(), keyval, NULL);
  974. }
  975. //-----------------------------------------------------------------------------
  976. // Purpose: saves control settings to file
  977. //-----------------------------------------------------------------------------
  978. bool BuildGroup::SaveControlSettings( void )
  979. {
  980. bool bSuccess = false;
  981. if ( m_pResourceName )
  982. {
  983. KeyValues *rDat = new KeyValues( m_pResourceName );
  984. // get the data from our controls
  985. GetSettings( rDat );
  986. char fullpath[ 512 ];
  987. g_pFullFileSystem->RelativePathToFullPath( m_pResourceName, m_pResourcePathID, fullpath, sizeof( fullpath ) );
  988. // save the data out to a file
  989. bSuccess = rDat->SaveToFile( g_pFullFileSystem, fullpath, NULL );
  990. if (!bSuccess)
  991. {
  992. MessageBox *dlg = new MessageBox("BuildMode - Error saving file", "Error: Could not save changes. File is most likely read only.");
  993. dlg->DoModal();
  994. }
  995. rDat->deleteThis();
  996. }
  997. return bSuccess;
  998. }
  999. //-----------------------------------------------------------------------------
  1000. // Purpose: Deletes all the controls not created by the code
  1001. //-----------------------------------------------------------------------------
  1002. void BuildGroup::DeleteAllControlsCreatedByControlSettingsFile()
  1003. {
  1004. // loop though objects in the current control group and remove them all
  1005. // the 0th panel is always the contextPanel which is not deletable
  1006. for ( int i = 1; i < _panelDar.Count(); i++ )
  1007. {
  1008. Panel *pRemove = _panelDar[i].Get();
  1009. if ( !pRemove ) // this can happen if we had two of the same handle in the list
  1010. {
  1011. _panelDar.Remove(i);
  1012. --i;
  1013. continue;
  1014. }
  1015. // only delete deletable panels, as the only deletable panels
  1016. // are the ones created using the resource file
  1017. if ( pRemove->IsBuildModeDeletable() )
  1018. {
  1019. _panelDar.Remove(i);
  1020. delete pRemove;
  1021. --i;
  1022. }
  1023. }
  1024. _currentPanel = m_pBuildContext;
  1025. _currentPanel->InvalidateLayout();
  1026. m_pBuildContext->Repaint();
  1027. }
  1028. //-----------------------------------------------------------------------------
  1029. // Purpose: serializes settings from a resource data container
  1030. //-----------------------------------------------------------------------------
  1031. void BuildGroup::ApplySettings( KeyValues *resourceData )
  1032. {
  1033. // loop through all the keys, applying them wherever
  1034. for (KeyValues *controlKeys = resourceData->GetFirstSubKey(); controlKeys != NULL; controlKeys = controlKeys->GetNextKey())
  1035. {
  1036. bool bFound = false;
  1037. // Skip keys that are atomic..
  1038. if (controlKeys->GetDataType() != KeyValues::TYPE_NONE)
  1039. continue;
  1040. char const *keyName = controlKeys->GetName();
  1041. // check to see if any buildgroup panels have this name
  1042. for ( int i = 0; i < _panelDar.Count(); i++ )
  1043. {
  1044. Panel *panel = _panelDar[i].Get();
  1045. if (!panel) // this can happen if we had two of the same handle in the list
  1046. {
  1047. _panelDar.Remove(i);
  1048. --i;
  1049. continue;
  1050. }
  1051. Assert (panel);
  1052. // make the control name match CASE INSENSITIVE!
  1053. char const *panelName = panel->GetName();
  1054. if (!Q_stricmp(panelName, keyName))
  1055. {
  1056. // apply the settings
  1057. panel->ApplySettings(controlKeys);
  1058. bFound = true;
  1059. break;
  1060. }
  1061. }
  1062. if ( !bFound )
  1063. {
  1064. // the key was not found in the registered list, check to see if we should create it
  1065. if ( keyName /*controlKeys->GetInt("AlwaysCreate", false)*/ )
  1066. {
  1067. // create the control even though it wasn't registered
  1068. NewControl( controlKeys );
  1069. }
  1070. }
  1071. }
  1072. }
  1073. //-----------------------------------------------------------------------------
  1074. // Purpose: Create a new control in the context panel
  1075. // Input: name: class name of control to create
  1076. // controlKeys: keyvalues of settings for the panel.
  1077. // name OR controlKeys should be set, not both.
  1078. // x,y position relative to base panel
  1079. // Output: Panel *newPanel, NULL if failed to create new control.
  1080. //-----------------------------------------------------------------------------
  1081. Panel *BuildGroup::NewControl( const char *name, int x, int y)
  1082. {
  1083. Assert (name);
  1084. Panel *newPanel = NULL;
  1085. // returns NULL on failure
  1086. newPanel = static_cast<EditablePanel *>(m_pParentPanel)->CreateControlByName(name);
  1087. if (newPanel)
  1088. {
  1089. // panel successfully created
  1090. newPanel->SetParent(m_pParentPanel);
  1091. newPanel->SetBuildGroup(this);
  1092. newPanel->SetPos(x, y);
  1093. char newFieldName[255];
  1094. GetNewFieldName(newFieldName, sizeof(newFieldName), newPanel);
  1095. newPanel->SetName(newFieldName);
  1096. newPanel->AddActionSignalTarget(m_pParentPanel);
  1097. newPanel->SetBuildModeEditable(true);
  1098. newPanel->SetBuildModeDeletable(true);
  1099. // make sure it gets freed
  1100. newPanel->SetAutoDelete(true);
  1101. }
  1102. return newPanel;
  1103. }
  1104. //-----------------------------------------------------------------------------
  1105. // Purpose: Create a new control in the context panel
  1106. // Input: controlKeys: keyvalues of settings for the panel only works when applying initial settings.
  1107. // Output: Panel *newPanel, NULL if failed to create new control.
  1108. //-----------------------------------------------------------------------------
  1109. Panel *BuildGroup::NewControl( KeyValues *controlKeys, int x, int y)
  1110. {
  1111. Assert (controlKeys);
  1112. Panel *newPanel = NULL;
  1113. if (controlKeys)
  1114. {
  1115. KeyValues *keyVal = new KeyValues("ControlFactory", "ControlName", controlKeys->GetString("ControlName"));
  1116. m_pBuildContext->RequestInfo(keyVal);
  1117. // returns NULL on failure
  1118. newPanel = (Panel *)keyVal->GetPtr("PanelPtr");
  1119. keyVal->deleteThis();
  1120. }
  1121. else
  1122. {
  1123. return NULL;
  1124. }
  1125. if (newPanel)
  1126. {
  1127. // panel successfully created
  1128. newPanel->SetParent(m_pParentPanel);
  1129. newPanel->SetBuildGroup(this);
  1130. newPanel->SetPos(x, y);
  1131. newPanel->SetName(controlKeys->GetName()); // name before applysettings :)
  1132. newPanel->ApplySettings(controlKeys);
  1133. newPanel->AddActionSignalTarget(m_pParentPanel);
  1134. newPanel->SetBuildModeEditable(true);
  1135. newPanel->SetBuildModeDeletable(true);
  1136. // make sure it gets freed
  1137. newPanel->SetAutoDelete(true);
  1138. }
  1139. return newPanel;
  1140. }
  1141. //-----------------------------------------------------------------------------
  1142. // Purpose: Get a new unique fieldname for a new control
  1143. //-----------------------------------------------------------------------------
  1144. void BuildGroup::GetNewFieldName(char *newFieldName, int newFieldNameSize, Panel *newPanel)
  1145. {
  1146. int fieldNameNumber=1;
  1147. char defaultName[25];
  1148. Q_strncpy( defaultName, newPanel->GetClassName(), sizeof( defaultName ) );
  1149. while (1)
  1150. {
  1151. Q_snprintf (newFieldName, newFieldNameSize, "%s%d", defaultName, fieldNameNumber);
  1152. if ( FieldNameTaken(newFieldName) == NULL)
  1153. break;
  1154. ++fieldNameNumber;
  1155. }
  1156. }
  1157. //-----------------------------------------------------------------------------
  1158. // Purpose: check to see if any buildgroup panels have this fieldname
  1159. // Input : fieldName, name to check
  1160. // Output : ptr to a panel that has the name if it is taken
  1161. //-----------------------------------------------------------------------------
  1162. Panel *BuildGroup::FieldNameTaken(const char *fieldName)
  1163. {
  1164. for ( int i = 0; i < _panelDar.Count(); i++ )
  1165. {
  1166. Panel *panel = _panelDar[i].Get();
  1167. if ( !panel )
  1168. continue;
  1169. if (!stricmp(panel->GetName(), fieldName) )
  1170. {
  1171. return panel;
  1172. }
  1173. }
  1174. return NULL;
  1175. }
  1176. //-----------------------------------------------------------------------------
  1177. // Purpose: serializes settings to a resource data container
  1178. //-----------------------------------------------------------------------------
  1179. void BuildGroup::GetSettings( KeyValues *resourceData )
  1180. {
  1181. // loop through all the objects getting their settings
  1182. for( int i = 0; i < _panelDar.Count(); i++ )
  1183. {
  1184. Panel *panel = _panelDar[i].Get();
  1185. if (!panel)
  1186. continue;
  1187. bool isRuler = false;
  1188. // do not get setting for ruler labels.
  1189. if (_showRulers) // rulers are visible
  1190. {
  1191. for (int i = 0; i < 4; i++)
  1192. {
  1193. if (panel == _rulerNumber[i])
  1194. {
  1195. isRuler = true;
  1196. break;
  1197. }
  1198. }
  1199. if (isRuler)
  1200. {
  1201. isRuler = false;
  1202. continue;
  1203. }
  1204. }
  1205. // Don't save the setting of the buildmodedialog
  1206. if (!stricmp(panel->GetName(), "BuildDialog"))
  1207. continue;
  1208. // get the keys section from the data file
  1209. if (panel->GetName() && *panel->GetName())
  1210. {
  1211. KeyValues *datKey = resourceData->FindKey(panel->GetName(), true);
  1212. // get the settings
  1213. panel->GetSettings(datKey);
  1214. }
  1215. }
  1216. }
  1217. //-----------------------------------------------------------------------------
  1218. // Purpose: loop though objects in the current control group and remove them all
  1219. //-----------------------------------------------------------------------------
  1220. void BuildGroup::RemoveSettings()
  1221. {
  1222. // loop though objects in the current control group and remove them all
  1223. int i;
  1224. for( i = 0; i < _controlGroup.Count(); i++ )
  1225. {
  1226. // only delete delatable panels
  1227. if ( _controlGroup[i].Get()->IsBuildModeDeletable())
  1228. {
  1229. delete _controlGroup[i].Get();
  1230. _controlGroup.Remove(i);
  1231. --i;
  1232. }
  1233. }
  1234. // remove deleted panels from the handle list
  1235. for( i = 0; i < _panelDar.Count(); i++ )
  1236. {
  1237. if ( !_panelDar[i].Get() )
  1238. {
  1239. _panelDar.Remove(i);
  1240. --i;
  1241. }
  1242. }
  1243. _currentPanel = m_pBuildContext;
  1244. _currentPanel->InvalidateLayout();
  1245. m_pBuildContext->Repaint();
  1246. }
  1247. //-----------------------------------------------------------------------------
  1248. // Purpose: sets the panel from which the build group gets all it's object creation info
  1249. //-----------------------------------------------------------------------------
  1250. void BuildGroup::SetContextPanel(Panel *contextPanel)
  1251. {
  1252. m_pBuildContext = contextPanel;
  1253. }
  1254. //-----------------------------------------------------------------------------
  1255. // Purpose: gets the panel from which the build group gets all it's object creation info
  1256. //-----------------------------------------------------------------------------
  1257. Panel *BuildGroup::GetContextPanel()
  1258. {
  1259. return m_pBuildContext;
  1260. }
  1261. //-----------------------------------------------------------------------------
  1262. // Purpose: get the list of panels in the buildgroup
  1263. //-----------------------------------------------------------------------------
  1264. CUtlVector<PHandle> *BuildGroup::GetPanelList()
  1265. {
  1266. return &_panelDar;
  1267. }
  1268. //-----------------------------------------------------------------------------
  1269. // Purpose: dialog variables
  1270. //-----------------------------------------------------------------------------
  1271. KeyValues *BuildGroup::GetDialogVariables()
  1272. {
  1273. EditablePanel *edit = dynamic_cast<EditablePanel *>(m_pParentPanel);
  1274. if (edit)
  1275. {
  1276. return edit->GetDialogVariables();
  1277. }
  1278. return NULL;
  1279. }