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.

750 lines
19 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //===========================================================================//
  7. #include <vgui/IScheme.h>
  8. #include <vgui/Cursor.h>
  9. #include <vgui/IInput.h>
  10. #include <vgui_controls/Splitter.h>
  11. #include "tier1/keyvalues.h"
  12. #include <limits.h>
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. using namespace vgui;
  16. enum
  17. {
  18. SPLITTER_HANDLE_WIDTH = 4
  19. };
  20. //-----------------------------------------------------------------------------
  21. // Splitter handle
  22. //-----------------------------------------------------------------------------
  23. namespace vgui
  24. {
  25. class SplitterHandle : public Panel
  26. {
  27. DECLARE_CLASS_SIMPLE( SplitterHandle, Panel );
  28. public:
  29. SplitterHandle( Splitter *parent, const char *name, SplitterMode_t mode, int nIndex );
  30. ~SplitterHandle();
  31. virtual void ApplySchemeSettings( IScheme *pScheme );
  32. virtual void OnMousePressed( MouseCode code );
  33. virtual void OnMouseReleased( MouseCode code );
  34. virtual void OnCursorMoved( int x, int y );
  35. virtual void OnMouseDoublePressed( MouseCode code );
  36. private:
  37. SplitterMode_t m_nMode;
  38. int m_nIndex;
  39. bool m_bDragging;
  40. };
  41. } // end namespace vgui
  42. //-----------------------------------------------------------------------------
  43. // Purpose: Constructor
  44. //-----------------------------------------------------------------------------
  45. SplitterHandle::SplitterHandle( Splitter *parent, const char *name, SplitterMode_t mode, int nIndex ) : BaseClass( parent, name )
  46. {
  47. int w, h;
  48. parent->GetSize( w, h );
  49. if ( mode == SPLITTER_MODE_HORIZONTAL )
  50. {
  51. SetSize( w, SPLITTER_HANDLE_WIDTH );
  52. SetCursor( dc_sizens );
  53. }
  54. else
  55. {
  56. SetSize( SPLITTER_HANDLE_WIDTH, h );
  57. SetCursor( dc_sizewe );
  58. }
  59. SetVisible( true );
  60. SetPaintBackgroundEnabled( false );
  61. SetPaintEnabled( false );
  62. SetPaintBorderEnabled( true );
  63. m_bDragging = false;
  64. m_nIndex = nIndex;
  65. m_nMode = mode;
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Purpose: Destructor
  69. //-----------------------------------------------------------------------------
  70. SplitterHandle::~SplitterHandle()
  71. {
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Scheme settings
  75. //-----------------------------------------------------------------------------
  76. void SplitterHandle::ApplySchemeSettings(IScheme *pScheme)
  77. {
  78. // Cache off background color stored in SetSplitterColor
  79. Color c = GetBgColor();
  80. SetBorder(pScheme->GetBorder("ButtonDepressedBorder"));
  81. BaseClass::ApplySchemeSettings(pScheme);
  82. SetBgColor( c );
  83. }
  84. //-----------------------------------------------------------------------------
  85. // Capture mouse when dragging
  86. //-----------------------------------------------------------------------------
  87. void SplitterHandle::OnMousePressed(MouseCode code)
  88. {
  89. if ( !m_bDragging )
  90. {
  91. input()->SetMouseCapture(GetVPanel());
  92. m_bDragging = true;
  93. }
  94. }
  95. //-----------------------------------------------------------------------------
  96. // Release mouse capture when finished dragging
  97. //-----------------------------------------------------------------------------
  98. void SplitterHandle::OnMouseReleased(MouseCode code)
  99. {
  100. if ( m_bDragging )
  101. {
  102. input()->SetMouseCapture(NULL);
  103. m_bDragging = false;
  104. }
  105. }
  106. //-----------------------------------------------------------------------------
  107. // While dragging, update the splitter position
  108. //-----------------------------------------------------------------------------
  109. void SplitterHandle::OnCursorMoved(int x, int y)
  110. {
  111. if (m_bDragging)
  112. {
  113. input()->GetCursorPos( x, y );
  114. Splitter *pSplitter = assert_cast<Splitter*>( GetParent() );
  115. pSplitter->ScreenToLocal( x,y );
  116. pSplitter->SetSplitterPosition( m_nIndex, (m_nMode == SPLITTER_MODE_HORIZONTAL) ? y : x );
  117. }
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Double-click: make both panels on either side of the splitter equal size
  121. //-----------------------------------------------------------------------------
  122. void SplitterHandle::OnMouseDoublePressed( MouseCode code )
  123. {
  124. Splitter *pSplitter = assert_cast<Splitter*>( GetParent() );
  125. pSplitter->EvenlyRespaceSplitters();
  126. }
  127. //-----------------------------------------------------------------------------
  128. // Returns a panel that chains user configs
  129. //-----------------------------------------------------------------------------
  130. namespace vgui
  131. {
  132. class SplitterChildPanel : public EditablePanel
  133. {
  134. DECLARE_CLASS_SIMPLE( SplitterChildPanel, EditablePanel );
  135. public:
  136. SplitterChildPanel( Panel *parent, const char *panelName ) : BaseClass( parent, panelName )
  137. {
  138. SetPaintBackgroundEnabled( false );
  139. SetPaintEnabled( false );
  140. SetPaintBorderEnabled( false );
  141. }
  142. virtual ~SplitterChildPanel() {}
  143. // Children may have user config settings
  144. bool HasUserConfigSettings()
  145. {
  146. return true;
  147. }
  148. };
  149. } // end namespace vgui
  150. //-----------------------------------------------------------------------------
  151. // Purpose: Constructor
  152. //-----------------------------------------------------------------------------
  153. Splitter::Splitter( Panel *parent, const char *name, SplitterMode_t mode, int nCount ) : BaseClass( parent, name )
  154. {
  155. Assert( nCount >= 1 );
  156. m_Mode = mode;
  157. SetPaintBackgroundEnabled( false );
  158. SetPaintEnabled( false );
  159. SetPaintBorderEnabled( false );
  160. RecreateSplitters( nCount );
  161. EvenlyRespaceSplitters();
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Purpose: Destructor
  165. //-----------------------------------------------------------------------------
  166. Splitter::~Splitter()
  167. {
  168. m_Splitters.RemoveAll();
  169. }
  170. void Splitter::RecreateSplitters( int nCount )
  171. {
  172. int i;
  173. int c = m_Splitters.Count();
  174. for ( i = 0; i < c; ++i )
  175. {
  176. delete m_Splitters[ i ].m_pPanel;
  177. delete m_Splitters[ i ].m_pHandle;
  178. }
  179. m_Splitters.RemoveAll();
  180. for ( i = 0; i < (nCount + 1); ++i )
  181. {
  182. char pBuffer[512];
  183. Q_snprintf( pBuffer, sizeof(pBuffer), "child%d", i );
  184. int nIndex = m_Splitters.AddToTail( );
  185. SplitterChildPanel *pEditablePanel = new SplitterChildPanel( this, pBuffer );
  186. m_Splitters[nIndex].m_pPanel = pEditablePanel;
  187. m_Splitters[nIndex].m_bLocked = false;
  188. m_Splitters[nIndex].m_nLockedSize = 0;
  189. }
  190. // We do this in 2 loops so that the first N children are actual child panels
  191. for ( i = 0; i < nCount; ++i )
  192. {
  193. SplitterHandle *pHandle = new SplitterHandle( this, "SplitterHandle", m_Mode, i );
  194. m_Splitters[i].m_pHandle = pHandle;
  195. pHandle->MoveToFront();
  196. }
  197. m_Splitters[nCount].m_pHandle = NULL;
  198. }
  199. //-----------------------------------------------------------------------------
  200. // Sets the splitter color
  201. //-----------------------------------------------------------------------------
  202. void Splitter::SetSplitterColor( Color c )
  203. {
  204. int nCount = m_Splitters.Count() - 1;
  205. if ( c.a() != 0 )
  206. {
  207. for ( int i = 0; i < nCount; ++i )
  208. {
  209. m_Splitters[i].m_pHandle->SetBgColor( c );
  210. m_Splitters[i].m_pHandle->SetPaintBackgroundEnabled( true );
  211. }
  212. }
  213. else
  214. {
  215. for ( int i = 0; i < nCount; ++i )
  216. {
  217. m_Splitters[i].m_pHandle->SetPaintBackgroundEnabled( false );
  218. }
  219. }
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Enables borders on the splitters
  223. //-----------------------------------------------------------------------------
  224. void Splitter::EnableBorders( bool bEnable )
  225. {
  226. int nCount = m_Splitters.Count() - 1;
  227. for ( int i = 0; i < nCount; ++i )
  228. {
  229. m_Splitters[i].m_pHandle->SetPaintBorderEnabled( bEnable );
  230. }
  231. }
  232. //-----------------------------------------------------------------------------
  233. // controls splitters
  234. //-----------------------------------------------------------------------------
  235. int Splitter::GetSplitterCount() const
  236. {
  237. return m_Splitters.Count() - 1;
  238. }
  239. //-----------------------------------------------------------------------------
  240. // controls splitters
  241. //-----------------------------------------------------------------------------
  242. int Splitter::GetSubPanelCount() const
  243. {
  244. return m_Splitters.Count();
  245. }
  246. //-----------------------------------------------------------------------------
  247. // Purpose: Applies resouce settings
  248. //-----------------------------------------------------------------------------
  249. void Splitter::ApplySettings(KeyValues *inResourceData)
  250. {
  251. BaseClass::ApplySettings(inResourceData);
  252. // Look for splitter positions
  253. int nSplitterCount = GetSplitterCount();
  254. for ( int i = 0; i < nSplitterCount; ++i )
  255. {
  256. char pBuffer[512];
  257. Q_snprintf( pBuffer, sizeof(pBuffer), "splitter%d", i );
  258. int nSplitterPos = inResourceData->GetInt( pBuffer , -1 );
  259. if ( nSplitterPos >= 0 )
  260. {
  261. SetSplitterPosition( i, nSplitterPos );
  262. }
  263. }
  264. }
  265. //-----------------------------------------------------------------------------
  266. // Purpose:
  267. //-----------------------------------------------------------------------------
  268. int Splitter::GetPosRange()
  269. {
  270. int w, h;
  271. GetSize( w, h );
  272. int nPosRange = (m_Mode == SPLITTER_MODE_HORIZONTAL) ? h : w;
  273. return nPosRange;
  274. }
  275. //-----------------------------------------------------------------------------
  276. // Locks the size of a particular child in pixels.
  277. //-----------------------------------------------------------------------------
  278. void Splitter::LockChildSize( int nChildIndex, int nSize )
  279. {
  280. Assert( nChildIndex < m_Splitters.Count() );
  281. SplitterInfo_t &info = m_Splitters[nChildIndex];
  282. nSize += SPLITTER_HANDLE_WIDTH;
  283. if ( !info.m_bLocked || (info.m_nLockedSize != nSize) )
  284. {
  285. float flPrevPos = (nChildIndex > 0) ? m_Splitters[nChildIndex-1].m_flPos : 0.0f;
  286. float flOldSize = info.m_flPos - flPrevPos;
  287. float flDelta = nSize - flOldSize;
  288. int nCount = m_Splitters.Count();
  289. for ( int i = nChildIndex; i < nCount-1; ++i )
  290. {
  291. m_Splitters[i].m_flPos += flDelta;
  292. }
  293. m_Splitters[nCount-1].m_flPos = GetPosRange();
  294. info.m_bLocked = true;
  295. info.m_nLockedSize = nSize;
  296. InvalidateLayout();
  297. }
  298. }
  299. void Splitter::UnlockChildSize( int nChildIndex )
  300. {
  301. Assert( nChildIndex < m_Splitters.Count() );
  302. SplitterInfo_t &info = m_Splitters[nChildIndex];
  303. if ( info.m_bLocked )
  304. {
  305. info.m_bLocked = false;
  306. float flPrevPos = (nChildIndex > 0) ? m_Splitters[nChildIndex-1].m_flPos : 0.0f;
  307. float flBelowSize = GetPosRange() - flPrevPos;
  308. int nLockedSize = ComputeLockedSize( nChildIndex + 1 );
  309. int nUnlockedCount = 1;
  310. int nCount = m_Splitters.Count();
  311. for ( int i = nChildIndex + 1; i < nCount; ++i )
  312. {
  313. if ( !m_Splitters[i].m_bLocked )
  314. {
  315. ++nUnlockedCount;
  316. }
  317. }
  318. float flUnlockedSize = ( flBelowSize - nLockedSize ) / nUnlockedCount;
  319. for ( int i = nChildIndex; i < nCount; ++i )
  320. {
  321. if ( !m_Splitters[i].m_bLocked )
  322. {
  323. m_Splitters[i].m_flPos = flPrevPos + flUnlockedSize;
  324. }
  325. else
  326. {
  327. m_Splitters[i].m_flPos = flPrevPos + m_Splitters[i].m_nLockedSize;
  328. }
  329. flPrevPos = m_Splitters[i].m_flPos;
  330. }
  331. InvalidateLayout();
  332. }
  333. }
  334. //-----------------------------------------------------------------------------
  335. // Called when size changes
  336. //-----------------------------------------------------------------------------
  337. void Splitter::OnSizeChanged( int newWide, int newTall )
  338. {
  339. BaseClass::OnSizeChanged( newWide, newTall );
  340. // Don't resize if it's degenerate and won't show up anyway...
  341. if ( newTall <= 0 || newWide <= 0 )
  342. return;
  343. int nLockedSize = 0;
  344. float flUnlockedSize = 0.0f;
  345. int nCount = m_Splitters.Count();
  346. float flLastPos = 0.0f;
  347. int nUnlockedCount = 0;
  348. for ( int i = 0; i < nCount; ++i )
  349. {
  350. SplitterInfo_t &info = m_Splitters[i];
  351. if ( info.m_bLocked )
  352. {
  353. nLockedSize += info.m_nLockedSize;
  354. }
  355. else
  356. {
  357. ++nUnlockedCount;
  358. flUnlockedSize += info.m_flPos - flLastPos;
  359. }
  360. flLastPos = info.m_flPos;
  361. }
  362. int nNewTotalSize = (m_Mode == SPLITTER_MODE_HORIZONTAL) ? newTall : newWide;
  363. int nNewUnlockedSize = nNewTotalSize - nLockedSize;
  364. if ( nNewUnlockedSize < nUnlockedCount * SPLITTER_HANDLE_WIDTH )
  365. {
  366. nNewUnlockedSize = nUnlockedCount * SPLITTER_HANDLE_WIDTH;
  367. }
  368. float flRatio = nNewUnlockedSize / flUnlockedSize;
  369. float flLastPrevPos = 0.0f;
  370. flLastPos = 0.0f;
  371. for ( int i = 0; i < nCount - 1; ++i )
  372. {
  373. SplitterInfo_t &info = m_Splitters[i];
  374. if ( info.m_bLocked )
  375. {
  376. flLastPrevPos = info.m_flPos;
  377. info.m_flPos = flLastPos + info.m_nLockedSize;
  378. }
  379. else
  380. {
  381. float flNewSize = info.m_flPos - flLastPrevPos;
  382. flNewSize *= flRatio;
  383. flLastPrevPos = info.m_flPos;
  384. info.m_flPos = flLastPos + flNewSize;
  385. }
  386. flLastPos = info.m_flPos;
  387. }
  388. // Clamp the bottom to 1.0
  389. m_Splitters[nCount-1].m_flPos = nNewTotalSize;
  390. }
  391. //-----------------------------------------------------------------------------
  392. // Splitter position
  393. //-----------------------------------------------------------------------------
  394. int Splitter::GetSplitterPosition( int nIndex )
  395. {
  396. return (int)( m_Splitters[nIndex].m_flPos + 0.5f );
  397. }
  398. void Splitter::SetSplitterPosition( int nIndex, int nPos )
  399. {
  400. int nPosRange = GetPosRange();
  401. if ( nPosRange == 0 )
  402. return;
  403. // If we're locked to a sibling, move the previous sibling first
  404. while ( ( nIndex >= 0 ) && m_Splitters[nIndex].m_bLocked )
  405. {
  406. nPos -= m_Splitters[nIndex].m_nLockedSize;
  407. --nIndex;
  408. }
  409. if ( nIndex < 0 )
  410. return;
  411. // Clamp to the valid positional range
  412. int i;
  413. int nMinPos = 0;
  414. for ( i = 0; i < nIndex; ++i )
  415. {
  416. if ( !m_Splitters[i].m_bLocked )
  417. {
  418. nMinPos += SPLITTER_HANDLE_WIDTH;
  419. }
  420. else
  421. {
  422. nMinPos += m_Splitters[i].m_nLockedSize;
  423. }
  424. }
  425. int nMaxPos = nPosRange - SPLITTER_HANDLE_WIDTH;
  426. int c = GetSplitterCount();
  427. for ( i = nIndex + 1; i < c; ++i )
  428. {
  429. if ( !m_Splitters[i].m_bLocked )
  430. {
  431. nMaxPos -= SPLITTER_HANDLE_WIDTH;
  432. }
  433. else
  434. {
  435. nMaxPos -= m_Splitters[i].m_nLockedSize;
  436. }
  437. }
  438. nPos = clamp( nPos, nMinPos, nMaxPos );
  439. m_Splitters[nIndex].m_flPos = nPos;
  440. int p = nPos;
  441. for ( i = nIndex - 1 ; i >= 0; --i )
  442. {
  443. int nMinPrevPos;
  444. int nMaxPrevPos;
  445. if ( !m_Splitters[i+1].m_bLocked )
  446. {
  447. nMinPrevPos = -INT_MAX;
  448. nMaxPrevPos = nPos - SPLITTER_HANDLE_WIDTH;
  449. }
  450. else
  451. {
  452. nMinPrevPos = nMaxPrevPos = p - m_Splitters[i+1].m_nLockedSize;
  453. }
  454. int nCurPos = GetSplitterPosition( i );
  455. if ( nMaxPrevPos < nCurPos || nMinPrevPos > nCurPos )
  456. {
  457. m_Splitters[ i ].m_flPos = nMaxPrevPos;
  458. p = nMaxPrevPos;
  459. }
  460. else
  461. {
  462. p = m_Splitters[ i ].m_flPos;
  463. }
  464. }
  465. for ( i = nIndex + 1 ; i < c; ++i )
  466. {
  467. int nMinNextPos;
  468. int nMaxNextPos;
  469. if ( !m_Splitters[i].m_bLocked )
  470. {
  471. nMinNextPos = nPos + SPLITTER_HANDLE_WIDTH;
  472. nMaxNextPos = INT_MAX;
  473. }
  474. else
  475. {
  476. nMinNextPos = nMaxNextPos = nPos + m_Splitters[i].m_nLockedSize;
  477. }
  478. int nCurPos = GetSplitterPosition( i );
  479. if ( nMinNextPos > nCurPos || nMaxNextPos < nCurPos )
  480. {
  481. m_Splitters[ i ].m_flPos = nMinNextPos;
  482. nPos = nMinNextPos;
  483. }
  484. else
  485. {
  486. nPos = m_Splitters[ i ].m_flPos;
  487. }
  488. }
  489. InvalidateLayout();
  490. }
  491. //-----------------------------------------------------------------------------
  492. // Computes the locked size
  493. //-----------------------------------------------------------------------------
  494. int Splitter::ComputeLockedSize( int nStartingIndex )
  495. {
  496. int nLockedSize = 0;
  497. int nCount = m_Splitters.Count();
  498. for ( int i = nStartingIndex; i < nCount; ++i )
  499. {
  500. if ( m_Splitters[i].m_bLocked )
  501. {
  502. nLockedSize += m_Splitters[i].m_nLockedSize;
  503. }
  504. }
  505. return nLockedSize;
  506. }
  507. //-----------------------------------------------------------------------------
  508. // Evenly respaces all the splitters
  509. //-----------------------------------------------------------------------------
  510. void Splitter::EvenlyRespaceSplitters( )
  511. {
  512. int nSplitterCount = GetSubPanelCount();
  513. if ( nSplitterCount == 0 )
  514. return;
  515. int nLockedSize = ComputeLockedSize( 0 );
  516. float flUnlockedSize = (float)( GetPosRange() - nLockedSize );
  517. float flDPos = flUnlockedSize / (float)nSplitterCount;
  518. if ( flDPos < SPLITTER_HANDLE_WIDTH )
  519. {
  520. flDPos = SPLITTER_HANDLE_WIDTH;
  521. }
  522. float flPos = 0.0f;
  523. for ( int i = 0; i < nSplitterCount; ++i )
  524. {
  525. if ( !m_Splitters[i].m_bLocked )
  526. {
  527. flPos += flDPos;
  528. }
  529. else
  530. {
  531. flPos += m_Splitters[i].m_nLockedSize;
  532. }
  533. m_Splitters[i].m_flPos = flPos;
  534. }
  535. InvalidateLayout();
  536. }
  537. void Splitter::RespaceSplitters( float *flFractions )
  538. {
  539. int nSplitterCount = GetSubPanelCount();
  540. if ( nSplitterCount == 0 )
  541. return;
  542. float flPos = 0.0f;
  543. int nPosRange = GetPosRange();
  544. for ( int i = 0; i < nSplitterCount; ++i )
  545. {
  546. flPos += flFractions[i];
  547. m_Splitters[i].m_flPos = flPos * nPosRange;
  548. }
  549. Assert( flPos == 1.0f );
  550. InvalidateLayout();
  551. }
  552. //-----------------------------------------------------------------------------
  553. // Purpose: sets user settings
  554. //-----------------------------------------------------------------------------
  555. void Splitter::ApplyUserConfigSettings(KeyValues *userConfig)
  556. {
  557. BaseClass::ApplyUserConfigSettings( userConfig );
  558. // read the splitter sizes
  559. int c = m_Splitters.Count();
  560. float *pFractions = (float*)stackalloc( c * sizeof(float) );
  561. float flTotalSize = 0.0f;
  562. for ( int i = 0; i < c; i++ )
  563. {
  564. char name[128];
  565. _snprintf(name, sizeof(name), "%d_splitter_pos", i);
  566. pFractions[i] = userConfig->GetFloat( name, flTotalSize + SPLITTER_HANDLE_WIDTH + 1 );
  567. flTotalSize = pFractions[i];
  568. }
  569. if ( flTotalSize != 0.0f )
  570. {
  571. int nPosRange = GetPosRange();
  572. for ( int i = 0; i < c; ++i )
  573. {
  574. pFractions[i] /= flTotalSize;
  575. m_Splitters[i].m_flPos = pFractions[i] * nPosRange;
  576. }
  577. }
  578. }
  579. //-----------------------------------------------------------------------------
  580. // Purpose: returns user config settings for this control
  581. //-----------------------------------------------------------------------------
  582. void Splitter::GetUserConfigSettings(KeyValues *userConfig)
  583. {
  584. BaseClass::GetUserConfigSettings( userConfig );
  585. // save which columns are hidden
  586. int c = m_Splitters.Count();
  587. for ( int i = 0 ; i < c; i++ )
  588. {
  589. char name[128];
  590. _snprintf(name, sizeof(name), "%d_splitter_pos", i);
  591. userConfig->SetFloat( name, m_Splitters[i].m_flPos );
  592. }
  593. }
  594. //-----------------------------------------------------------------------------
  595. // Called to perform layout
  596. //-----------------------------------------------------------------------------
  597. void Splitter::PerformLayout( )
  598. {
  599. BaseClass::PerformLayout();
  600. int nSplitterCount = GetSubPanelCount();
  601. if ( nSplitterCount == 0 )
  602. return;
  603. int w, h;
  604. GetSize( w, h );
  605. int nLastPos = 0;
  606. for ( int i = 0; i < nSplitterCount; ++i )
  607. {
  608. Panel *pChild = m_Splitters[i].m_pPanel;
  609. SplitterHandle *pHandle = m_Splitters[i].m_pHandle;
  610. int nSplitterPos = (int)( m_Splitters[i].m_flPos + 0.5f );
  611. if ( m_Mode == SPLITTER_MODE_HORIZONTAL )
  612. {
  613. pChild->SetPos( 0, nLastPos );
  614. pChild->SetSize( w, nSplitterPos - nLastPos );
  615. if ( pHandle )
  616. {
  617. pHandle->SetPos( 0, nSplitterPos );
  618. pHandle->SetSize( w, SPLITTER_HANDLE_WIDTH );
  619. }
  620. }
  621. else
  622. {
  623. pChild->SetPos( nLastPos, 0 );
  624. pChild->SetSize( nSplitterPos - nLastPos, h );
  625. if ( pHandle )
  626. {
  627. pHandle->SetPos( nSplitterPos, 0 );
  628. pHandle->SetSize( SPLITTER_HANDLE_WIDTH, h );
  629. }
  630. }
  631. nLastPos = nSplitterPos + SPLITTER_HANDLE_WIDTH;
  632. }
  633. }
  634. //-----------------------------------------------------------------------------
  635. // Purpose:
  636. //-----------------------------------------------------------------------------
  637. void Splitter::GetSettings( KeyValues *outResourceData )
  638. {
  639. BaseClass::GetSettings( outResourceData );
  640. }