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.

478 lines
12 KiB

  1. //========= Copyright 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. // memdbgon must be the last include file in a .cpp file!!!
  15. #include <tier0/memdbgon.h>
  16. using namespace vgui;
  17. CUtlVector< ToolWindow * > ToolWindow::s_ToolWindows;
  18. //-----------------------------------------------------------------------------
  19. // Purpose:
  20. // Input : -
  21. // Output : int
  22. //-----------------------------------------------------------------------------
  23. int ToolWindow::GetToolWindowCount()
  24. {
  25. return s_ToolWindows.Count();
  26. }
  27. //-----------------------------------------------------------------------------
  28. // Purpose:
  29. // Input : index -
  30. // Output : PropertySheet
  31. //-----------------------------------------------------------------------------
  32. ToolWindow *ToolWindow::GetToolWindow( int index )
  33. {
  34. return s_ToolWindows[ index ];
  35. }
  36. //-----------------------------------------------------------------------------
  37. // Purpose: Constructor
  38. //-----------------------------------------------------------------------------
  39. ToolWindow::ToolWindow(
  40. Panel *parent,
  41. bool contextlabel,
  42. IToolWindowFactory *factory /*= 0*/,
  43. Panel *page /*= NULL*/,
  44. char const *title /*= NULL */,
  45. bool contextMenu /*=false*/,
  46. bool inGlobalList /*= true*/ ) : BaseClass( parent, "ToolWindow" ),
  47. m_pFactory( factory )
  48. {
  49. if ( inGlobalList )
  50. {
  51. s_ToolWindows.AddToTail( this );
  52. }
  53. // create the property sheet
  54. m_pPropertySheet = new PropertySheet(this, "ToolWindowSheet", true );
  55. m_pPropertySheet->ShowContextButtons( contextlabel );
  56. m_pPropertySheet->AddPage( page, title, 0, contextMenu );
  57. m_pPropertySheet->AddActionSignalTarget(this);
  58. m_pPropertySheet->SetSmallTabs( true );
  59. m_pPropertySheet->SetKBNavigationEnabled( false );
  60. SetSmallCaption( true );
  61. SetMenuButtonResponsive(false);
  62. SetMinimizeButtonVisible(false);
  63. SetCloseButtonVisible(true);
  64. SetMoveable( true );
  65. SetSizeable(true);
  66. SetClipToParent( false );
  67. SetVisible( true );
  68. SetDeleteSelfOnClose( true );
  69. SetTitle( "", false );
  70. }
  71. //-----------------------------------------------------------------------------
  72. // Purpose: Destructor
  73. //-----------------------------------------------------------------------------
  74. ToolWindow::~ToolWindow()
  75. {
  76. // These don't actually kill the children of the property sheet
  77. m_pPropertySheet->RemoveAllPages();
  78. s_ToolWindows.FindAndRemove( this );
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose: Pass through to sheet
  82. // Input : -
  83. // Output : Returns true on success, false on failure.
  84. //-----------------------------------------------------------------------------
  85. bool ToolWindow::IsDraggableTabContainer() const
  86. {
  87. return m_pPropertySheet->IsDraggableTab();
  88. }
  89. //-----------------------------------------------------------------------------
  90. // Purpose: Returns a pointer to the PropertySheet this dialog encapsulates
  91. // Output : PropertySheet *
  92. //-----------------------------------------------------------------------------
  93. PropertySheet *ToolWindow::GetPropertySheet()
  94. {
  95. return m_pPropertySheet;
  96. }
  97. //-----------------------------------------------------------------------------
  98. // Purpose: Gets a pointer to the currently active page.
  99. // Output : Panel
  100. //-----------------------------------------------------------------------------
  101. Panel *ToolWindow::GetActivePage()
  102. {
  103. return m_pPropertySheet->GetActivePage();
  104. }
  105. void ToolWindow::SetActivePage( Panel *page )
  106. {
  107. m_pPropertySheet->SetActivePage( page );
  108. }
  109. //-----------------------------------------------------------------------------
  110. // Purpose: Wrapped function
  111. //-----------------------------------------------------------------------------
  112. void ToolWindow::AddPage(Panel *page, const char *title, bool contextMenu)
  113. {
  114. m_pPropertySheet->AddPage(page, title, 0, contextMenu );
  115. }
  116. //-----------------------------------------------------------------------------
  117. // Purpose:
  118. // Input : *page -
  119. //-----------------------------------------------------------------------------
  120. void ToolWindow::RemovePage( Panel *page )
  121. {
  122. m_pPropertySheet->RemovePage( page );
  123. if ( m_pPropertySheet->GetNumPages() == 0 )
  124. {
  125. MarkForDeletion();
  126. }
  127. }
  128. //-----------------------------------------------------------------------------
  129. // Purpose: Sets up the sheet
  130. //-----------------------------------------------------------------------------
  131. void ToolWindow::PerformLayout()
  132. {
  133. BaseClass::PerformLayout();
  134. int x, y, wide, tall;
  135. GetClientArea(x, y, wide, tall);
  136. m_pPropertySheet->SetBounds(x, y, wide, tall);
  137. m_pPropertySheet->InvalidateLayout(); // tell the propertysheet to redraw!
  138. Repaint();
  139. }
  140. //-----------------------------------------------------------------------------
  141. // Purpose: Overrides build mode so it edits the sub panel
  142. //-----------------------------------------------------------------------------
  143. void ToolWindow::ActivateBuildMode()
  144. {
  145. // no subpanel, no build mode
  146. EditablePanel *panel = dynamic_cast<EditablePanel *>(GetActivePage());
  147. if (!panel)
  148. return;
  149. panel->ActivateBuildMode();
  150. }
  151. //-----------------------------------------------------------------------------
  152. // Purpose:
  153. //-----------------------------------------------------------------------------
  154. void ToolWindow::RequestFocus(int direction)
  155. {
  156. m_pPropertySheet->RequestFocus(direction);
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Purpose:
  160. // Input : *factory -
  161. //-----------------------------------------------------------------------------
  162. void ToolWindow::SetToolWindowFactory( IToolWindowFactory *factory )
  163. {
  164. m_pFactory = factory;
  165. }
  166. //-----------------------------------------------------------------------------
  167. // Purpose:
  168. // Input : -
  169. // Output : IToolWindowFactory
  170. //-----------------------------------------------------------------------------
  171. IToolWindowFactory *ToolWindow::GetToolWindowFactory()
  172. {
  173. return m_pFactory;
  174. }
  175. //-----------------------------------------------------------------------------
  176. // Purpose: To fill the space left by other tool windows
  177. // Input : edge: 0=all, 1=top, 2=right, 3=bottom, 4=left
  178. // Output :
  179. //-----------------------------------------------------------------------------
  180. void ToolWindow::Grow( int edge, int from_x, int from_y )
  181. {
  182. int status_h = 24;
  183. int menubar_h = 27;
  184. int sw, sh;
  185. surface()->GetScreenSize( sw, sh );
  186. int old_x, old_y, old_w, old_h;
  187. GetBounds( old_x, old_y, old_w, old_h );
  188. int new_x, new_y, new_w, new_h;
  189. new_x = old_x;
  190. new_y = old_y;
  191. new_w = old_w;
  192. new_h = old_h;
  193. int c = GetToolWindowCount();
  194. // grow up
  195. if ( ( edge == 0 ) || ( edge == 1 ) )
  196. {
  197. // first shrink the edge back to the grow point
  198. if ( from_y >= 0 )
  199. {
  200. old_h = old_h - ( from_y - old_y );
  201. old_y = from_y;
  202. }
  203. // now grow the edge as far as it can go
  204. new_h = old_h + ( old_y - menubar_h );
  205. new_y = menubar_h;
  206. for ( int i = 0 ; i < c; ++i )
  207. {
  208. ToolWindow *tw = GetToolWindow( i );
  209. Assert( tw );
  210. if ( ( !tw ) || ( tw == this ) )
  211. continue;
  212. // Get panel bounds
  213. int x, y, w, h;
  214. tw->GetBounds( x, y, w, h );
  215. // grow it
  216. if ( ( ( ( old_x > x ) && ( old_x < x + w ) )
  217. || ( ( old_x + old_w > x ) && ( old_x + old_w < x + w ) )
  218. || ( ( old_x <= x ) && old_x + old_w >= x + w ))
  219. && ( ( old_y >= y + h ) && ( new_y < y + h ) ) )
  220. {
  221. new_h = old_h + ( old_y - ( y + h ) );
  222. new_y = y + h;
  223. }
  224. }
  225. old_h = new_h;
  226. old_y = new_y;
  227. }
  228. // grow right
  229. if ( ( edge == 0 ) || ( edge == 2 ) )
  230. {
  231. // first shrink the edge back to the grow point
  232. if ( from_x >= 0 )
  233. {
  234. old_w = from_x - old_x;
  235. }
  236. // now grow the edge as far as it can go
  237. new_w = sw - old_x;
  238. for ( int i = 0 ; i < c; ++i )
  239. {
  240. ToolWindow *tw = GetToolWindow( i );
  241. Assert( tw );
  242. if ( ( !tw ) || ( tw == this ) )
  243. continue;
  244. // Get panel bounds
  245. int x, y, w, h;
  246. tw->GetBounds( x, y, w, h );
  247. // grow it
  248. if ( ( ( ( old_y > y ) && ( old_y < y + h ) )
  249. || ( ( old_y + old_h > y ) && ( old_y + old_h < y + h ) )
  250. || ( ( old_y <= y ) && old_y + old_h >= y + h ))
  251. && ( ( old_x + old_w <= x ) && ( new_w > x - old_x ) ) )
  252. {
  253. new_w = x - old_x;
  254. }
  255. }
  256. old_w = new_w;
  257. }
  258. // grow down
  259. if ( ( edge == 0 ) || ( edge == 3 ) )
  260. {
  261. // first shrink the edge back to the grow point
  262. if ( from_y >= 0 )
  263. {
  264. old_h = from_y - old_y;
  265. }
  266. // now grow the edge as far as it can go
  267. new_h = sh - old_y - status_h;
  268. for ( int i = 0 ; i < c; ++i )
  269. {
  270. ToolWindow *tw = GetToolWindow( i );
  271. Assert( tw );
  272. if ( ( !tw ) || ( tw == this ) )
  273. continue;
  274. // Get panel bounds
  275. int x, y, w, h;
  276. tw->GetBounds( x, y, w, h );
  277. // grow it
  278. if ( ( ( ( old_x > x ) && ( old_x < x + w ) )
  279. || ( ( old_x + old_w > x ) && ( old_x + old_w < x + w ) )
  280. || ( ( old_x <= x ) && old_x + old_w >= x + w ))
  281. && ( ( old_y + old_h <= y ) && ( new_h > y - old_y ) ) )
  282. {
  283. new_h = y - old_y;
  284. }
  285. }
  286. old_h = new_h;
  287. }
  288. // grow left
  289. if ( ( edge == 0 ) || ( edge == 4 ) )
  290. {
  291. // first shrink the edge back to the grow point
  292. if ( from_x >= 0 )
  293. {
  294. old_w = old_w - ( from_x - old_x );
  295. old_x = from_x;
  296. }
  297. // now grow the edge as far as it can go
  298. new_w = old_w + old_x;
  299. new_x = 0;
  300. for ( int i = 0 ; i < c; ++i )
  301. {
  302. ToolWindow *tw = GetToolWindow( i );
  303. Assert( tw );
  304. if ( ( !tw ) || ( tw == this ) )
  305. continue;
  306. // Get panel bounds
  307. int x, y, w, h;
  308. tw->GetBounds( x, y, w, h );
  309. // grow it
  310. if ( ( ( ( old_y > y ) && ( old_y < y + h ) )
  311. || ( ( old_y + old_h > y ) && ( old_y + old_h < y + h ) )
  312. || ( ( old_y <= y ) && old_y + old_h >= y + h ))
  313. && ( ( old_x >= x + w ) && ( new_x < x + w ) ) )
  314. {
  315. new_w = old_w + ( old_x - ( x + w ) );
  316. new_x = x + w;
  317. }
  318. }
  319. old_w = new_w;
  320. old_x = new_x;
  321. }
  322. // Set panel bounds
  323. SetBounds( new_x, new_y, new_w, new_h );
  324. }
  325. //-----------------------------------------------------------------------------
  326. // Purpose: Calls Grow based on where the mouse is.
  327. // over titlebar: grows all edges ( from mouse pos )
  328. // over edge grab area: grows just that edge
  329. // over corner grab area: grows the two adjacent edges
  330. // Input :
  331. // Output :
  332. //-----------------------------------------------------------------------------
  333. void ToolWindow::GrowFromClick()
  334. {
  335. int mx, my;
  336. input()->GetCursorPos( mx, my );
  337. int esz, csz, brsz, ch;
  338. esz = GetDraggerSize();
  339. csz = GetCornerSize();
  340. brsz = GetBottomRightSize();
  341. ch = GetCaptionHeight();
  342. int x, y, w, h;
  343. GetBounds( x, y, w, h );
  344. // upper right
  345. if ( ( mx > x+w-csz-1 ) && ( my < y+csz ) )
  346. {
  347. Grow(1);
  348. Grow(2);
  349. }
  350. // lower right (the big one)
  351. else if ( ( mx > x+w-brsz-1 ) && ( my > y+h-brsz-1 ) )
  352. {
  353. Grow(2);
  354. Grow(3);
  355. }
  356. // lower left
  357. else if ( ( mx < x+csz ) && ( my > y+h-csz-1 ) )
  358. {
  359. Grow(3);
  360. Grow(4);
  361. }
  362. // upper left
  363. else if ( ( mx < x+csz ) && ( my < y+csz ) )
  364. {
  365. Grow(4);
  366. Grow(1);
  367. }
  368. // top edge
  369. else if ( my < y+esz )
  370. {
  371. Grow(1);
  372. }
  373. // right edge
  374. else if ( mx > x+w-esz-1 )
  375. {
  376. Grow(2);
  377. }
  378. // bottom edge
  379. else if ( my > y+h-esz-1 )
  380. {
  381. Grow(3);
  382. }
  383. // left edge
  384. else if ( mx < x+esz )
  385. {
  386. Grow(4);
  387. }
  388. // otherwise (if over the grab bar), grow all edges (from the clicked point)
  389. else if ( my < y + ch )
  390. {
  391. Grow(0, mx, my);
  392. }
  393. }
  394. //-----------------------------------------------------------------------------
  395. // Purpose:
  396. // Input : -
  397. // Output :
  398. //-----------------------------------------------------------------------------
  399. void ToolWindow::OnMouseDoublePressed( MouseCode code )
  400. {
  401. GrowFromClick();
  402. }
  403. void ToolWindow::OnMousePressed( MouseCode code )
  404. {
  405. switch ( code )
  406. {
  407. case MOUSE_MIDDLE:
  408. GrowFromClick();
  409. break;
  410. default:
  411. BaseClass::OnMousePressed( code );
  412. }
  413. }