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.

718 lines
18 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <vgui/KeyCode.h>
  8. #include <keyvalues.h>
  9. #include "vgui/IInput.h"
  10. #include "vgui/MouseCode.h"
  11. #include "vgui/ISurface.h"
  12. #include <vgui_controls/ToolWindow.h>
  13. #include <vgui_controls/PropertySheet.h>
  14. #include "tier1/tokenset.h"
  15. // memdbgon must be the last include file in a .cpp file!!!
  16. #include <tier0/memdbgon.h>
  17. using namespace vgui;
  18. CUtlVector< ToolWindow * > ToolWindow::s_ToolWindows;
  19. //-----------------------------------------------------------------------------
  20. // Purpose:
  21. // Input : -
  22. // Output : int
  23. //-----------------------------------------------------------------------------
  24. int ToolWindow::GetToolWindowCount()
  25. {
  26. return s_ToolWindows.Count();
  27. }
  28. //-----------------------------------------------------------------------------
  29. // Purpose:
  30. // Input : index -
  31. // Output : PropertySheet
  32. //-----------------------------------------------------------------------------
  33. ToolWindow *ToolWindow::GetToolWindow( int index )
  34. {
  35. return s_ToolWindows[ index ];
  36. }
  37. //-----------------------------------------------------------------------------
  38. // Purpose: Constructor
  39. //-----------------------------------------------------------------------------
  40. ToolWindow::ToolWindow(
  41. Panel *parent,
  42. bool contextlabel,
  43. IToolWindowFactory *factory /*= 0*/,
  44. Panel *page /*= NULL*/,
  45. char const *title /*= NULL */,
  46. bool contextMenu /*=false*/,
  47. bool inGlobalList /*= true*/ ) :
  48. BaseClass( parent, "ToolWindow" ),
  49. m_bStickyEdges( true ),
  50. m_pFactory( NULL )
  51. {
  52. if ( inGlobalList )
  53. {
  54. s_ToolWindows.AddToTail( this );
  55. }
  56. // create the property sheet
  57. m_pPropertySheet = new PropertySheet(this, "ToolWindowSheet", true );
  58. m_pPropertySheet->ShowContextButtons( contextlabel );
  59. m_pPropertySheet->AddPage( page, title, 0, contextMenu );
  60. m_pPropertySheet->AddActionSignalTarget(this);
  61. m_pPropertySheet->SetSmallTabs( true );
  62. m_pPropertySheet->SetKBNavigationEnabled( false );
  63. SetSmallCaption( true );
  64. SetMenuButtonResponsive(false);
  65. SetMinimizeButtonVisible(false);
  66. SetCloseButtonVisible(true);
  67. SetMoveable( true );
  68. SetSizeable(true);
  69. SetClipToParent( false );
  70. SetVisible( true );
  71. SetDeleteSelfOnClose( true );
  72. SetTitle( "", false );
  73. }
  74. //-----------------------------------------------------------------------------
  75. // Purpose: Destructor
  76. //-----------------------------------------------------------------------------
  77. ToolWindow::~ToolWindow()
  78. {
  79. // These don't actually kill the children of the property sheet
  80. m_pPropertySheet->RemoveAllPages();
  81. s_ToolWindows.FindAndRemove( this );
  82. }
  83. //-----------------------------------------------------------------------------
  84. // Purpose: Pass through to sheet
  85. // Input : -
  86. // Output : Returns true on success, false on failure.
  87. //-----------------------------------------------------------------------------
  88. bool ToolWindow::IsDraggableTabContainer() const
  89. {
  90. return m_pPropertySheet->IsDraggableTab();
  91. }
  92. //-----------------------------------------------------------------------------
  93. // Purpose: Returns a pointer to the PropertySheet this dialog encapsulates
  94. // Output : PropertySheet *
  95. //-----------------------------------------------------------------------------
  96. PropertySheet *ToolWindow::GetPropertySheet()
  97. {
  98. return m_pPropertySheet;
  99. }
  100. //-----------------------------------------------------------------------------
  101. // Purpose: Gets a pointer to the currently active page.
  102. // Output : Panel
  103. //-----------------------------------------------------------------------------
  104. Panel *ToolWindow::GetActivePage()
  105. {
  106. return m_pPropertySheet->GetActivePage();
  107. }
  108. void ToolWindow::SetActivePage( Panel *page )
  109. {
  110. m_pPropertySheet->SetActivePage( page );
  111. }
  112. //-----------------------------------------------------------------------------
  113. // Purpose: Wrapped function
  114. //-----------------------------------------------------------------------------
  115. void ToolWindow::AddPage(Panel *page, const char *title, bool contextMenu)
  116. {
  117. m_pPropertySheet->AddPage(page, title, 0, contextMenu );
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Purpose:
  121. // Input : *page -
  122. //-----------------------------------------------------------------------------
  123. void ToolWindow::RemovePage( Panel *page )
  124. {
  125. m_pPropertySheet->RemovePage( page );
  126. if ( m_pPropertySheet->GetNumPages() == 0 )
  127. {
  128. MarkForDeletion();
  129. }
  130. }
  131. //-----------------------------------------------------------------------------
  132. // Purpose: Sets up the sheet
  133. //-----------------------------------------------------------------------------
  134. void ToolWindow::PerformLayout()
  135. {
  136. BaseClass::PerformLayout();
  137. int x, y, wide, tall;
  138. GetClientArea(x, y, wide, tall);
  139. m_pPropertySheet->SetBounds(x, y, wide, tall);
  140. m_pPropertySheet->InvalidateLayout(); // tell the propertysheet to redraw!
  141. Repaint();
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose: Overrides build mode so it edits the sub panel
  145. //-----------------------------------------------------------------------------
  146. void ToolWindow::ActivateBuildMode()
  147. {
  148. // no subpanel, no build mode
  149. EditablePanel *panel = dynamic_cast<EditablePanel *>(GetActivePage());
  150. if (!panel)
  151. return;
  152. panel->ActivateBuildMode();
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Purpose:
  156. //-----------------------------------------------------------------------------
  157. void ToolWindow::RequestFocus(int direction)
  158. {
  159. m_pPropertySheet->RequestFocus(direction);
  160. }
  161. void ToolWindow::OnSetFocus()
  162. {
  163. m_pPropertySheet->RequestFocus();
  164. }
  165. //-----------------------------------------------------------------------------
  166. // Purpose:
  167. // Input : *factory -
  168. //-----------------------------------------------------------------------------
  169. void ToolWindow::SetToolWindowFactory( IToolWindowFactory *factory )
  170. {
  171. m_pFactory = factory;
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose:
  175. // Input : -
  176. // Output : IToolWindowFactory
  177. //-----------------------------------------------------------------------------
  178. IToolWindowFactory *ToolWindow::GetToolWindowFactory()
  179. {
  180. return m_pFactory;
  181. }
  182. //-----------------------------------------------------------------------------
  183. // Purpose: To fill the space left by other tool windows
  184. // Input : edge: 0=all, 1=top, 2=right, 3=bottom, 4=left
  185. // Output :
  186. //-----------------------------------------------------------------------------
  187. void ToolWindow::Grow( int edge, int from_x, int from_y )
  188. {
  189. int status_h = 24;
  190. int menubar_h = 27;
  191. int sw, sh;
  192. surface()->GetScreenSize( sw, sh );
  193. int old_x, old_y, old_w, old_h;
  194. GetBounds( old_x, old_y, old_w, old_h );
  195. int new_x, new_y, new_w, new_h;
  196. new_x = old_x;
  197. new_y = old_y;
  198. new_w = old_w;
  199. new_h = old_h;
  200. int c = GetToolWindowCount();
  201. // grow up
  202. if ( ( edge == 0 ) || ( edge == 1 ) )
  203. {
  204. // first shrink the edge back to the grow point
  205. if ( from_y >= 0 )
  206. {
  207. old_h = old_h - ( from_y - old_y );
  208. old_y = from_y;
  209. }
  210. // now grow the edge as far as it can go
  211. new_h = old_h + ( old_y - menubar_h );
  212. new_y = menubar_h;
  213. for ( int i = 0 ; i < c; ++i )
  214. {
  215. ToolWindow *tw = GetToolWindow( i );
  216. Assert( tw );
  217. if ( ( !tw ) || ( tw == this ) )
  218. continue;
  219. // Get panel bounds
  220. int x, y, w, h;
  221. tw->GetBounds( x, y, w, h );
  222. // grow it
  223. if ( ( ( ( old_x > x ) && ( old_x < x + w ) )
  224. || ( ( old_x + old_w > x ) && ( old_x + old_w < x + w ) )
  225. || ( ( old_x <= x ) && old_x + old_w >= x + w ))
  226. && ( ( old_y >= y + h ) && ( new_y < y + h ) ) )
  227. {
  228. new_h = old_h + ( old_y - ( y + h ) );
  229. new_y = y + h;
  230. }
  231. }
  232. old_h = new_h;
  233. old_y = new_y;
  234. }
  235. // grow right
  236. if ( ( edge == 0 ) || ( edge == 2 ) )
  237. {
  238. // first shrink the edge back to the grow point
  239. if ( from_x >= 0 )
  240. {
  241. old_w = from_x - old_x;
  242. }
  243. // now grow the edge as far as it can go
  244. new_w = sw - old_x;
  245. for ( int i = 0 ; i < c; ++i )
  246. {
  247. ToolWindow *tw = GetToolWindow( i );
  248. Assert( tw );
  249. if ( ( !tw ) || ( tw == this ) )
  250. continue;
  251. // Get panel bounds
  252. int x, y, w, h;
  253. tw->GetBounds( x, y, w, h );
  254. // grow it
  255. if ( ( ( ( old_y > y ) && ( old_y < y + h ) )
  256. || ( ( old_y + old_h > y ) && ( old_y + old_h < y + h ) )
  257. || ( ( old_y <= y ) && old_y + old_h >= y + h ))
  258. && ( ( old_x + old_w <= x ) && ( new_w > x - old_x ) ) )
  259. {
  260. new_w = x - old_x;
  261. }
  262. }
  263. old_w = new_w;
  264. }
  265. // grow down
  266. if ( ( edge == 0 ) || ( edge == 3 ) )
  267. {
  268. // first shrink the edge back to the grow point
  269. if ( from_y >= 0 )
  270. {
  271. old_h = from_y - old_y;
  272. }
  273. // now grow the edge as far as it can go
  274. new_h = sh - old_y - status_h;
  275. for ( int i = 0 ; i < c; ++i )
  276. {
  277. ToolWindow *tw = GetToolWindow( i );
  278. Assert( tw );
  279. if ( ( !tw ) || ( tw == this ) )
  280. continue;
  281. // Get panel bounds
  282. int x, y, w, h;
  283. tw->GetBounds( x, y, w, h );
  284. // grow it
  285. if ( ( ( ( old_x > x ) && ( old_x < x + w ) )
  286. || ( ( old_x + old_w > x ) && ( old_x + old_w < x + w ) )
  287. || ( ( old_x <= x ) && old_x + old_w >= x + w ))
  288. && ( ( old_y + old_h <= y ) && ( new_h > y - old_y ) ) )
  289. {
  290. new_h = y - old_y;
  291. }
  292. }
  293. old_h = new_h;
  294. }
  295. // grow left
  296. if ( ( edge == 0 ) || ( edge == 4 ) )
  297. {
  298. // first shrink the edge back to the grow point
  299. if ( from_x >= 0 )
  300. {
  301. old_w = old_w - ( from_x - old_x );
  302. old_x = from_x;
  303. }
  304. // now grow the edge as far as it can go
  305. new_w = old_w + old_x;
  306. new_x = 0;
  307. for ( int i = 0 ; i < c; ++i )
  308. {
  309. ToolWindow *tw = GetToolWindow( i );
  310. Assert( tw );
  311. if ( ( !tw ) || ( tw == this ) )
  312. continue;
  313. // Get panel bounds
  314. int x, y, w, h;
  315. tw->GetBounds( x, y, w, h );
  316. // grow it
  317. if ( ( ( ( old_y > y ) && ( old_y < y + h ) )
  318. || ( ( old_y + old_h > y ) && ( old_y + old_h < y + h ) )
  319. || ( ( old_y <= y ) && old_y + old_h >= y + h ))
  320. && ( ( old_x >= x + w ) && ( new_x < x + w ) ) )
  321. {
  322. new_w = old_w + ( old_x - ( x + w ) );
  323. new_x = x + w;
  324. }
  325. }
  326. old_w = new_w;
  327. old_x = new_x;
  328. }
  329. // Set panel bounds
  330. SetBounds( new_x, new_y, new_w, new_h );
  331. }
  332. //-----------------------------------------------------------------------------
  333. // Purpose: Calls Grow based on where the mouse is.
  334. // over titlebar: grows all edges ( from mouse pos )
  335. // over edge grab area: grows just that edge
  336. // over corner grab area: grows the two adjacent edges
  337. // Input :
  338. // Output :
  339. //-----------------------------------------------------------------------------
  340. void ToolWindow::GrowFromClick()
  341. {
  342. int mx, my;
  343. input()->GetCursorPos( mx, my );
  344. int esz, csz, brsz, ch;
  345. esz = GetDraggerSize();
  346. csz = GetCornerSize();
  347. brsz = GetBottomRightSize();
  348. ch = GetCaptionHeight();
  349. int x, y, w, h;
  350. GetBounds( x, y, w, h );
  351. // upper right
  352. if ( ( mx > x+w-csz-1 ) && ( my < y+csz ) )
  353. {
  354. Grow(1);
  355. Grow(2);
  356. }
  357. // lower right (the big one)
  358. else if ( ( mx > x+w-brsz-1 ) && ( my > y+h-brsz-1 ) )
  359. {
  360. Grow(2);
  361. Grow(3);
  362. }
  363. // lower left
  364. else if ( ( mx < x+csz ) && ( my > y+h-csz-1 ) )
  365. {
  366. Grow(3);
  367. Grow(4);
  368. }
  369. // upper left
  370. else if ( ( mx < x+csz ) && ( my < y+csz ) )
  371. {
  372. Grow(4);
  373. Grow(1);
  374. }
  375. // top edge
  376. else if ( my < y+esz )
  377. {
  378. Grow(1);
  379. }
  380. // right edge
  381. else if ( mx > x+w-esz-1 )
  382. {
  383. Grow(2);
  384. }
  385. // bottom edge
  386. else if ( my > y+h-esz-1 )
  387. {
  388. Grow(3);
  389. }
  390. // left edge
  391. else if ( mx < x+esz )
  392. {
  393. Grow(4);
  394. }
  395. // otherwise (if over the grab bar), grow all edges (from the clicked point)
  396. else if ( my < y + ch )
  397. {
  398. Grow(0, mx, my);
  399. }
  400. }
  401. //-----------------------------------------------------------------------------
  402. // Purpose:
  403. // Input : -
  404. // Output :
  405. //-----------------------------------------------------------------------------
  406. void ToolWindow::OnMouseDoublePressed( MouseCode code )
  407. {
  408. GrowFromClick();
  409. }
  410. void ToolWindow::OnMousePressed( MouseCode code )
  411. {
  412. switch ( code )
  413. {
  414. case MOUSE_MIDDLE:
  415. GrowFromClick();
  416. break;
  417. default:
  418. BaseClass::OnMousePressed( code );
  419. }
  420. }
  421. void ToolWindow::OnPageChanged( )
  422. {
  423. //char szTitle[ 256 ];
  424. //m_pPropertySheet->GetActiveTabTitle( szTitle, sizeof( szTitle ) );
  425. //SetTitle( szTitle, false );
  426. }
  427. static void GetParentSpaceExtents( Panel *p, int bounds[ 4 ] )
  428. {
  429. // Get parent space bounds
  430. p->GetBounds( bounds[ 0 ], bounds[ 1 ], bounds[ 2 ], bounds[ 3 ] );
  431. // x1, y1
  432. bounds[ 2 ] += bounds[ 0 ];
  433. bounds[ 3 ] += bounds[ 1 ];
  434. }
  435. static ESharedEdge GetOppositeEdge( ESharedEdge eEdge )
  436. {
  437. switch ( eEdge )
  438. {
  439. default:
  440. break;
  441. case TOOLWINDOW_LEFT:
  442. return TOOLWINDOW_RIGHT;
  443. case TOOLWINDOW_TOP:
  444. return TOOLWINDOW_BOTTOM;
  445. case TOOLWINDOW_RIGHT:
  446. return TOOLWINDOW_LEFT;
  447. case TOOLWINDOW_BOTTOM:
  448. return TOOLWINDOW_TOP;
  449. }
  450. Assert( 0 );
  451. return TOOLWINDOW_NONE;
  452. }
  453. static void GetParentSpaceEdge( Panel *p, int bounds[ 4 ], ESharedEdge eEdge )
  454. {
  455. GetParentSpaceExtents( p, bounds );
  456. // Collapse down to single edge
  457. bounds[ GetOppositeEdge( eEdge ) ] = bounds[ eEdge ];
  458. }
  459. static const tokenset_t< ESharedEdge > s_EdgeTypes[] =
  460. {
  461. { "TOOLWINDOW_NONE", TOOLWINDOW_NONE },
  462. { "TOOLWINDOW_LEFT", TOOLWINDOW_LEFT },
  463. { "TOOLWINDOW_TOP", TOOLWINDOW_TOP },
  464. { "TOOLWINDOW_RIGHT", TOOLWINDOW_RIGHT },
  465. { "TOOLWINDOW_BOTTOM", TOOLWINDOW_BOTTOM },
  466. { NULL, TOOLWINDOW_NONE }
  467. };
  468. void ToolWindow::MoveSibling( ToolWindow *pSibling, ESharedEdge eEdge, int dpixels )
  469. {
  470. int bounds[ 4 ];
  471. GetParentSpaceExtents( pSibling, bounds );
  472. bounds[ eEdge ] += dpixels;
  473. // Convert back to local pos and width/height
  474. bounds[ 2 ] = bounds[ 2 ] - bounds[ 0 ];
  475. bounds[ 3 ] = bounds[ 3 ] - bounds[ 1 ];
  476. pSibling->SetBounds( bounds[ 0 ], bounds[ 1 ], bounds[ 2 ], bounds[ 3 ] );
  477. }
  478. struct TWEdgePair_t
  479. {
  480. ToolWindow *m_pWindow;
  481. ESharedEdge m_EdgeType;
  482. static bool Less( const TWEdgePair_t &lhs, const TWEdgePair_t &rhs )
  483. {
  484. if ( lhs.m_pWindow < rhs.m_pWindow )
  485. return true;
  486. if ( lhs.m_pWindow > rhs.m_pWindow )
  487. return false;
  488. return lhs.m_EdgeType < rhs.m_EdgeType;
  489. }
  490. };
  491. static bool SpanOverlaps( int line1[ 4 ], int line2[ 4 ] )
  492. {
  493. bool bXOverlap = ( MAX( line1[ 0 ], line2[ 0 ] ) - MIN( line1[ 2 ], line2[ 2 ] ) ) <= 0 ? true : false;
  494. bool bYOverlap = ( MAX( line1[ 1 ], line2[ 1 ] ) - MIN( line1[ 3 ], line2[ 3 ] ) ) <= 0 ? true : false;
  495. return bXOverlap && bYOverlap;
  496. }
  497. // Find any parallel edges that overlap and aren't already in the tree. If we add an edge, we recursively see if anything else overlaps it on the same line
  498. void ToolWindow::FindOverlappingEdges_R( CUtlVector< ToolWindow * > &vecSiblings, CUtlRBTree< TWEdgePair_t > &rbCurrentEdges, ESharedEdge eEdgeType, int line[ 4 ] )
  499. {
  500. // L/R or T/B
  501. for ( int et = 0; et < 2; ++et )
  502. {
  503. for ( int i = 0; i < vecSiblings.Count(); ++i )
  504. {
  505. ToolWindow *pSibling = vecSiblings[ i ];
  506. int edgeline[ 4 ];
  507. GetParentSpaceEdge( pSibling, edgeline, eEdgeType );
  508. if ( SpanOverlaps( edgeline, line ) )
  509. {
  510. TWEdgePair_t ep;
  511. ep.m_pWindow = pSibling;
  512. ep.m_EdgeType = eEdgeType;
  513. if ( rbCurrentEdges.Find( ep ) == rbCurrentEdges.InvalidIndex() )
  514. {
  515. /*
  516. Msg( "Found overlap %d, %d, %d, %d with %d %d %d %d on edge %s\n",
  517. edgeline[ 0 ],edgeline[ 1 ],edgeline[ 2 ],edgeline[ 3 ],
  518. line[ 0 ],line[ 1 ],line[ 2 ],line[ 3 ],
  519. s_EdgeTypes->GetNameByToken( eEdgeType ) );
  520. */
  521. rbCurrentEdges.Insert( ep );
  522. // Extend search out along the line!!!
  523. FindOverlappingEdges_R( vecSiblings, rbCurrentEdges, eEdgeType, edgeline );
  524. }
  525. }
  526. }
  527. // Try opposite on next pass
  528. eEdgeType = GetOppositeEdge( eEdgeType );
  529. }
  530. }
  531. // Override Frame method in order to grow adjoining sibling tool windows if possible
  532. void ToolWindow::OnGripPanelMoved( int nNewX, int nNewY, int nNewW, int nNewH )
  533. {
  534. bool bShiftDown = input()->IsKeyDown( KEY_LSHIFT ) || input()->IsKeyDown( KEY_RSHIFT );
  535. if ( IsStickEdgesEnabled() && !bShiftDown )
  536. {
  537. // Snag old values
  538. int x, y, w, h;
  539. GetBounds( x, y, w, h );
  540. // Get list of siblings
  541. CUtlVector< ToolWindow * > vecSiblings;
  542. GetSiblingToolWindows( vecSiblings );
  543. // Msg( "%d siblings\n", vecSiblings.Count() );
  544. if ( vecSiblings.Count() > 0 )
  545. {
  546. // Determine what type of grip panel movement(s) occurred
  547. int d[ 4 ];
  548. d[ 0 ] = nNewX - x; // L
  549. d[ 1 ] = nNewY - y; // T
  550. d[ 2 ] = ( nNewX + nNewW ) - ( x + w ); // R
  551. d[ 3 ] = ( nNewY + nNewH ) - ( y + h ); // B
  552. // For each moved edge, find and edges along the same line that overlap. If we find an overlap, check it for additional overlaps against the siblings:
  553. //
  554. // ------------------------------------ e.g: clicking at the base of panel B should find the "top" of panel C, which then recurses and gets the bottom line of panel A as well
  555. // | | |
  556. // | A | B |
  557. // | | |
  558. // | | |
  559. // |-----------------xxxxxxxxxxxxxxxxxx|
  560. // | C |
  561. // | |
  562. // -------------------------------------
  563. //
  564. for ( int edge = 0; edge < 4; ++edge )
  565. {
  566. if ( !d[ edge ] )
  567. continue;
  568. CUtlRBTree< TWEdgePair_t > rbEdges( 0, 0, TWEdgePair_t::Less );
  569. ESharedEdge eEdge = (ESharedEdge)( edge );
  570. // Msg( "movement on edge %s is %d pixels\n", s_EdgeTypes->GetNameByToken( eEdge ), d[ edge ] );
  571. // Now find any overlapping ones along the same "line"
  572. int edgeline[ 4 ];
  573. GetParentSpaceEdge( this, edgeline, eEdge );
  574. FindOverlappingEdges_R( vecSiblings, rbEdges, eEdge, edgeline );
  575. FOR_EACH_UTLRBTREE( rbEdges, i )
  576. {
  577. TWEdgePair_t &ep = rbEdges[ i ];
  578. // Msg( "moving tw %p on edge %s\n", ep.m_pWindow, s_EdgeTypes->GetNameByToken( ep.m_EdgeType ) );
  579. // Move the sibling
  580. MoveSibling( ep.m_pWindow, ep.m_EdgeType, d[ edge ] );
  581. }
  582. }
  583. }
  584. }
  585. // Move panel in question
  586. BaseClass::OnGripPanelMoved( nNewX, nNewY, nNewW, nNewH );
  587. }
  588. void ToolWindow::GetSiblingToolWindows( CUtlVector< ToolWindow * > &vecSiblings )
  589. {
  590. Panel *parent = GetParent();
  591. if ( NULL == parent )
  592. return;
  593. int nChildCount = parent->GetChildCount();
  594. for ( int i = 0 ; i < nChildCount; ++i )
  595. {
  596. ToolWindow *pChildTool = dynamic_cast< ToolWindow * >( parent->GetChild( i ) );
  597. if ( !pChildTool ||
  598. !pChildTool->IsVisible() ||
  599. pChildTool == this )
  600. continue;
  601. vecSiblings.AddToTail( pChildTool );
  602. }
  603. }
  604. void ToolWindow::OnGripPanelMoveFinished()
  605. {
  606. }
  607. // Static method
  608. void ToolWindow::EnableStickyEdges( bool bEnable )
  609. {
  610. m_bStickyEdges = bEnable;
  611. }
  612. bool ToolWindow::IsStickEdgesEnabled() const
  613. {
  614. return m_bStickyEdges;
  615. }