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.

252 lines
6.7 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <vgui/IInput.h>
  8. #include <vgui/IPanel.h>
  9. #include <vgui/IScheme.h>
  10. #include <vgui/IBorder.h>
  11. #include <vgui/ISurface.h>
  12. #include <vgui/KeyCode.h>
  13. #include <KeyValues.h>
  14. #include <vgui_controls/MenuBar.h>
  15. #include <vgui_controls/MenuButton.h>
  16. #include <vgui_controls/Label.h>
  17. #include <vgui_controls/Controls.h>
  18. // memdbgon must be the last include file in a .cpp file!!!
  19. #include <tier0/memdbgon.h>
  20. using namespace vgui;
  21. enum
  22. {
  23. MENUBARINDENT = 4, // indent from top and bottom of panel.
  24. };
  25. DECLARE_BUILD_FACTORY( MenuBar );
  26. //-----------------------------------------------------------------------------
  27. // Purpose: Constructor
  28. //-----------------------------------------------------------------------------
  29. MenuBar::MenuBar(Panel *parent, const char *panelName) :
  30. Panel(parent, panelName),
  31. m_nRightEdge( 0 )
  32. {
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Purpose: Destructor
  36. //-----------------------------------------------------------------------------
  37. MenuBar::~MenuBar()
  38. {
  39. }
  40. //-----------------------------------------------------------------------------
  41. // Purpose:
  42. //-----------------------------------------------------------------------------
  43. void MenuBar::AddButton(MenuButton *button)
  44. {
  45. button->SetParent(this);
  46. button->AddActionSignalTarget(this);
  47. m_pMenuButtons.AddToTail(button);
  48. }
  49. //-----------------------------------------------------------------------------
  50. // This will add the menu to the menu bar
  51. //-----------------------------------------------------------------------------
  52. void MenuBar::AddMenu( const char *pButtonName, Menu *pMenu )
  53. {
  54. MenuButton *pMenuButton = new MenuButton(this, pButtonName, pButtonName);
  55. pMenuButton->SetMenu(pMenu);
  56. AddButton(pMenuButton);
  57. }
  58. //-----------------------------------------------------------------------------
  59. // Purpose: Handle key presses, Activate shortcuts
  60. //-----------------------------------------------------------------------------
  61. void MenuBar::OnKeyCodeTyped(KeyCode code)
  62. {
  63. switch(code)
  64. {
  65. case KEY_RIGHT:
  66. {
  67. // iterate the menu items looking for one that is open
  68. // if we find one open, open the one to the right
  69. for (int i = 0; i < m_pMenuButtons.Count() - 1; i++)
  70. {
  71. MenuButton *panel = m_pMenuButtons[i];
  72. if (panel->IsDepressed())
  73. {
  74. m_pMenuButtons[i]->DoClick();
  75. m_pMenuButtons[i+1]->DoClick();
  76. break;
  77. }
  78. }
  79. break;
  80. }
  81. case KEY_LEFT:
  82. {
  83. // iterate the menu items looking for one that is open
  84. // if we find one open, open the one to the left
  85. for (int i = 1; i < m_pMenuButtons.Count(); i++)
  86. {
  87. MenuButton *panel = m_pMenuButtons[i];
  88. if (panel->IsDepressed())
  89. {
  90. m_pMenuButtons[i]->DoClick();
  91. m_pMenuButtons[i-1]->DoClick();
  92. break;
  93. }
  94. }
  95. break;
  96. }
  97. default:
  98. {
  99. break;
  100. }
  101. }
  102. // don't chain back
  103. }
  104. //-----------------------------------------------------------------------------
  105. // Purpose: Handle key presses, Activate shortcuts
  106. // Input : code -
  107. //-----------------------------------------------------------------------------
  108. void MenuBar::OnKeyTyped(wchar_t unichar)
  109. {
  110. if (unichar)
  111. {
  112. // iterate the menu items looking for one with the matching hotkey
  113. for (int i = 0; i < m_pMenuButtons.Count(); i++)
  114. {
  115. MenuButton *panel = m_pMenuButtons[i];
  116. if (panel->IsVisible())
  117. {
  118. Panel *hot = panel->HasHotkey(unichar);
  119. if (hot)
  120. {
  121. // post a message to the menuitem telling it it's hotkey was pressed
  122. PostMessage(hot, new KeyValues("Hotkey"));
  123. return;
  124. }
  125. }
  126. }
  127. }
  128. // don't chain back
  129. }
  130. void MenuBar::Paint()
  131. {
  132. IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
  133. for ( int i = 0; i < m_pMenuButtons.Count(); i++)
  134. {
  135. if (!m_pMenuButtons[i]->IsArmed())
  136. m_pMenuButtons[i]->SetDefaultBorder(NULL);
  137. else
  138. {
  139. m_pMenuButtons[i]->SetDefaultBorder(pScheme->GetBorder( "ButtonBorder"));
  140. }
  141. }
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose: Message map
  145. //-----------------------------------------------------------------------------
  146. void MenuBar::ApplySchemeSettings(IScheme *pScheme)
  147. {
  148. BaseClass::ApplySchemeSettings(pScheme);
  149. // get the borders we need
  150. SetBorder(pScheme->GetBorder("ButtonBorder"));
  151. // get the background color
  152. SetBgColor(pScheme->GetColor( "MenuBar.BgColor", GetBgColor() ));
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Purpose: Reformat according to the new layout
  156. //-----------------------------------------------------------------------------
  157. void MenuBar::PerformLayout()
  158. {
  159. int nBarWidth, nBarHeight;
  160. GetSize( nBarWidth, nBarHeight );
  161. // Now position + resize all buttons
  162. int x = MENUBARINDENT;
  163. for ( int i = 0; i < m_pMenuButtons.Count(); ++i )
  164. {
  165. int nWide, nTall;
  166. m_pMenuButtons[i]->GetContentSize(nWide, nTall);
  167. m_pMenuButtons[i]->SetPos( x, MENUBARINDENT );
  168. m_pMenuButtons[i]->SetSize( nWide + Label::Content, nBarHeight - 2 * MENUBARINDENT );
  169. x += nWide + MENUBARINDENT;
  170. }
  171. m_nRightEdge = x;
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose: Get the size of the menus in the bar (so other children can be added to menu bar)
  175. // Input : w -
  176. // int&h -
  177. //-----------------------------------------------------------------------------
  178. void MenuBar::GetContentSize( int& w, int&h )
  179. {
  180. w = m_nRightEdge + 2;
  181. h = GetTall();
  182. }
  183. //-----------------------------------------------------------------------------
  184. // Purpose: Message map
  185. //-----------------------------------------------------------------------------
  186. void MenuBar::OnMenuClose()
  187. {
  188. RequestFocus();
  189. }
  190. //-----------------------------------------------------------------------------
  191. // Purpose: Message map
  192. //-----------------------------------------------------------------------------
  193. void MenuBar::OnCursorEnteredMenuButton(int VPanel)
  194. {
  195. VPANEL menuButton = (VPANEL)VPanel;
  196. // see if we had a menu open
  197. for ( int i = 0; i < m_pMenuButtons.Count(); i++)
  198. {
  199. // one of our buttons was pressed.
  200. if (m_pMenuButtons[i]->IsDepressed())
  201. {
  202. int oldbutton = i;
  203. // now see if menuButton is one of ours.
  204. for ( int j = 0; j < m_pMenuButtons.Count(); j++)
  205. {
  206. MenuButton *button = static_cast<MenuButton *>(ipanel()->GetPanel(menuButton, GetModuleName()));
  207. // it is one of ours.
  208. if ( button == m_pMenuButtons[j])
  209. {
  210. // if its a different button than the one we already had open,
  211. if (j != oldbutton)
  212. {
  213. // close this menu and open the one we just entered
  214. m_pMenuButtons[oldbutton]->DoClick();
  215. button->DoClick();
  216. }
  217. }
  218. }
  219. }
  220. }
  221. }