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.

395 lines
10 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <vgui/ISurface.h>
  8. #include <KeyValues.h>
  9. #include <vgui/IInput.h>
  10. #include <vgui_controls/Button.h>
  11. #include <vgui_controls/Controls.h>
  12. #include <vgui_controls/Label.h>
  13. #include <vgui_controls/MessageBox.h>
  14. // memdbgon must be the last include file in a .cpp file!!!
  15. #include <tier0/memdbgon.h>
  16. using namespace vgui;
  17. #ifndef max
  18. #define max(a,b) (((a) > (b)) ? (a) : (b))
  19. #endif
  20. vgui::Panel *MessageBox_Factory()
  21. {
  22. return new MessageBox("MessageBox", "MessageBoxText");
  23. }
  24. DECLARE_BUILD_FACTORY_CUSTOM( MessageBox, MessageBox_Factory );
  25. //-----------------------------------------------------------------------------
  26. // Purpose: Constructor
  27. //-----------------------------------------------------------------------------
  28. MessageBox::MessageBox(const char *title, const char *text, Panel *parent) : Frame(parent, NULL, false)
  29. {
  30. SetTitle(title, true);
  31. m_pMessageLabel = new Label(this, NULL, text);
  32. Init();
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Purpose: Constructor
  36. //-----------------------------------------------------------------------------
  37. MessageBox::MessageBox(const wchar_t *wszTitle, const wchar_t *wszText, Panel *parent) : Frame(parent, NULL, false)
  38. {
  39. SetTitle(wszTitle, true);
  40. m_pMessageLabel = new Label(this, NULL, wszText);
  41. Init();
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Purpose: Constructor Helper
  45. //-----------------------------------------------------------------------------
  46. void MessageBox::Init()
  47. {
  48. SetDeleteSelfOnClose(true);
  49. m_pFrameOver = NULL;
  50. m_bShowMessageBoxOverCursor = false;
  51. SetMenuButtonResponsive(false);
  52. SetMinimizeButtonVisible(false);
  53. SetCloseButtonVisible(false);
  54. SetSizeable(false);
  55. m_pOkButton = new Button(this, NULL, "#MessageBox_OK");
  56. m_pOkButton->SetCommand( "OnOk" );
  57. m_pOkButton->AddActionSignalTarget(this);
  58. m_pCancelButton = new Button(this, NULL, "#MessageBox_Cancel");
  59. m_pCancelButton->SetCommand( "OnCancel" );
  60. m_pCancelButton->AddActionSignalTarget(this);
  61. m_pCancelButton->SetVisible( false );
  62. m_OkCommand = m_CancelCommand = NULL;
  63. m_bNoAutoClose = false;
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Purpose: Destructor
  67. //-----------------------------------------------------------------------------
  68. MessageBox::~MessageBox()
  69. {
  70. if ( m_OkCommand )
  71. {
  72. m_OkCommand->deleteThis();
  73. }
  74. if ( m_CancelCommand )
  75. {
  76. m_CancelCommand->deleteThis();
  77. }
  78. }
  79. //-----------------------------------------------------------------------------
  80. // Shows the message box over the cursor
  81. //-----------------------------------------------------------------------------
  82. void MessageBox::ShowMessageBoxOverCursor( bool bEnable )
  83. {
  84. m_bShowMessageBoxOverCursor = bEnable;
  85. }
  86. //-----------------------------------------------------------------------------
  87. // Purpose: size the message label properly
  88. //-----------------------------------------------------------------------------
  89. void MessageBox::OnCommand( const char *pCommand )
  90. {
  91. if ( vgui::input()->GetAppModalSurface() == GetVPanel() )
  92. {
  93. vgui::input()->ReleaseAppModalSurface();
  94. }
  95. if ( !Q_stricmp( pCommand, "OnOk" ) )
  96. {
  97. if ( m_OkCommand )
  98. {
  99. PostActionSignal(m_OkCommand->MakeCopy());
  100. }
  101. }
  102. else if ( !Q_stricmp( pCommand, "OnCancel" ) )
  103. {
  104. if ( m_CancelCommand )
  105. {
  106. PostActionSignal(m_CancelCommand->MakeCopy());
  107. }
  108. }
  109. if ( !m_bNoAutoClose )
  110. {
  111. OnShutdownRequest();
  112. }
  113. }
  114. //-----------------------------------------------------------------------------
  115. // Purpose: size the message label properly
  116. //-----------------------------------------------------------------------------
  117. void MessageBox::ApplySchemeSettings(IScheme *pScheme)
  118. {
  119. BaseClass::ApplySchemeSettings(pScheme);
  120. int wide, tall;
  121. m_pMessageLabel->GetContentSize(wide, tall);
  122. m_pMessageLabel->SetSize(wide, tall);
  123. wide += 100;
  124. tall += 100;
  125. SetSize(wide, tall);
  126. if ( m_bShowMessageBoxOverCursor )
  127. {
  128. PlaceUnderCursor();
  129. return;
  130. }
  131. // move to the middle of the screen
  132. if ( m_pFrameOver )
  133. {
  134. int frameX, frameY;
  135. int frameWide, frameTall;
  136. m_pFrameOver->GetPos(frameX, frameY);
  137. m_pFrameOver->GetSize(frameWide, frameTall);
  138. SetPos((frameWide - wide) / 2 + frameX, (frameTall - tall) / 2 + frameY);
  139. }
  140. else
  141. {
  142. int swide, stall;
  143. surface()->GetScreenSize(swide, stall);
  144. // put the dialog in the middle of the screen
  145. SetPos((swide - wide) / 2, (stall - tall) / 2);
  146. }
  147. }
  148. //-----------------------------------------------------------------------------
  149. // Purpose: Put the message box into a modal state
  150. // Does not suspend execution - use addActionSignal to get return value
  151. //-----------------------------------------------------------------------------
  152. void MessageBox::DoModal(Frame* pFrameOver)
  153. {
  154. ShowWindow(pFrameOver);
  155. /*
  156. // move to the middle of the screen
  157. // get the screen size
  158. int wide, tall;
  159. // get our dialog size
  160. GetSize(wide, tall);
  161. if (pFrameOver)
  162. {
  163. int frameX, frameY;
  164. int frameWide, frameTall;
  165. pFrameOver->GetPos(frameX, frameY);
  166. pFrameOver->GetSize(frameWide, frameTall);
  167. SetPos((frameWide - wide) / 2 + frameX, (frameTall - tall) / 2 + frameY);
  168. }
  169. else
  170. {
  171. int swide, stall;
  172. surface()->GetScreenSize(swide, stall);
  173. // put the dialog in the middle of the screen
  174. SetPos((swide - wide) / 2, (stall - tall) / 2);
  175. }
  176. SetVisible( true );
  177. SetEnabled( true );
  178. MoveToFront();
  179. if (m_pOkButton->IsVisible())
  180. m_pOkButton->RequestFocus();
  181. else // handle message boxes with no button
  182. RequestFocus();
  183. */
  184. input()->SetAppModalSurface(GetVPanel());
  185. }
  186. void MessageBox::ShowWindow(Frame *pFrameOver)
  187. {
  188. m_pFrameOver = pFrameOver;
  189. SetVisible( true );
  190. SetEnabled( true );
  191. MoveToFront();
  192. if ( m_pOkButton->IsVisible() )
  193. {
  194. m_pOkButton->RequestFocus();
  195. }
  196. else // handle message boxes with no button
  197. {
  198. RequestFocus();
  199. }
  200. InvalidateLayout();
  201. }
  202. //-----------------------------------------------------------------------------
  203. // Purpose: Put the text and OK buttons in correct place
  204. //-----------------------------------------------------------------------------
  205. void MessageBox::PerformLayout()
  206. {
  207. int x, y, wide, tall;
  208. GetClientArea(x, y, wide, tall);
  209. wide += x;
  210. tall += y;
  211. int boxWidth, boxTall;
  212. GetSize(boxWidth, boxTall);
  213. int oldWide, oldTall;
  214. m_pOkButton->GetSize(oldWide, oldTall);
  215. int btnWide, btnTall;
  216. m_pOkButton->GetContentSize(btnWide, btnTall);
  217. btnWide = max(oldWide, btnWide + 10);
  218. btnTall = max(oldTall, btnTall + 10);
  219. m_pOkButton->SetSize(btnWide, btnTall);
  220. int btnWide2 = 0, btnTall2 = 0;
  221. if ( m_pCancelButton->IsVisible() )
  222. {
  223. m_pCancelButton->GetSize(oldWide, oldTall);
  224. m_pCancelButton->GetContentSize(btnWide2, btnTall2);
  225. btnWide2 = max(oldWide, btnWide2 + 10);
  226. btnTall2 = max(oldTall, btnTall2 + 10);
  227. m_pCancelButton->SetSize(btnWide2, btnTall2);
  228. }
  229. boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100);
  230. boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30);
  231. SetSize(boxWidth, boxTall);
  232. GetSize(boxWidth, boxTall);
  233. m_pMessageLabel->SetPos((wide/2)-(m_pMessageLabel->GetWide()/2) + x, y + 5 );
  234. if ( !m_pCancelButton->IsVisible() )
  235. {
  236. m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
  237. }
  238. else
  239. {
  240. m_pOkButton->SetPos((wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
  241. m_pCancelButton->SetPos((3*wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
  242. }
  243. BaseClass::PerformLayout();
  244. GetSize(boxWidth, boxTall);
  245. }
  246. //-----------------------------------------------------------------------------
  247. // Purpose: Set a string command to be sent when the OK button is pressed.
  248. //-----------------------------------------------------------------------------
  249. void MessageBox::SetCommand(const char *command)
  250. {
  251. if (m_OkCommand)
  252. {
  253. m_OkCommand->deleteThis();
  254. }
  255. m_OkCommand = new KeyValues("Command", "command", command);
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Purpose: Sets the command
  259. //-----------------------------------------------------------------------------
  260. void MessageBox::SetCommand(KeyValues *command)
  261. {
  262. if (m_OkCommand)
  263. {
  264. m_OkCommand->deleteThis();
  265. }
  266. m_OkCommand = command;
  267. }
  268. //-----------------------------------------------------------------------------
  269. // Purpose:
  270. //-----------------------------------------------------------------------------
  271. void MessageBox::OnShutdownRequest()
  272. {
  273. // Shutdown the dialog
  274. PostMessage(this, new KeyValues("Close"));
  275. }
  276. //-----------------------------------------------------------------------------
  277. // Purpose: Set the visibility of the OK button.
  278. //-----------------------------------------------------------------------------
  279. void MessageBox::SetOKButtonVisible(bool state)
  280. {
  281. m_pOkButton->SetVisible(state);
  282. }
  283. //-----------------------------------------------------------------------------
  284. // Purpose: Sets the Text on the OK button
  285. //-----------------------------------------------------------------------------
  286. void MessageBox::SetOKButtonText(const char *buttonText)
  287. {
  288. m_pOkButton->SetText(buttonText);
  289. InvalidateLayout();
  290. }
  291. //-----------------------------------------------------------------------------
  292. // Purpose: Sets the Text on the OK button
  293. //-----------------------------------------------------------------------------
  294. void MessageBox::SetOKButtonText(const wchar_t *wszButtonText)
  295. {
  296. m_pOkButton->SetText(wszButtonText);
  297. InvalidateLayout();
  298. }
  299. //-----------------------------------------------------------------------------
  300. // Cancel button (off by default)
  301. //-----------------------------------------------------------------------------
  302. void MessageBox::SetCancelButtonVisible(bool state)
  303. {
  304. m_pCancelButton->SetVisible(state);
  305. InvalidateLayout();
  306. }
  307. void MessageBox::SetCancelButtonText(const char *buttonText)
  308. {
  309. m_pCancelButton->SetText(buttonText);
  310. InvalidateLayout();
  311. }
  312. void MessageBox::SetCancelButtonText(const wchar_t *wszButtonText)
  313. {
  314. m_pCancelButton->SetText(wszButtonText);
  315. InvalidateLayout();
  316. }
  317. void MessageBox::SetCancelCommand( KeyValues *command )
  318. {
  319. if (m_CancelCommand)
  320. {
  321. m_CancelCommand->deleteThis();
  322. }
  323. m_CancelCommand = command;
  324. }
  325. //-----------------------------------------------------------------------------
  326. // Purpose: Toggles visibility of the close box.
  327. //-----------------------------------------------------------------------------
  328. void MessageBox::DisableCloseButton(bool state)
  329. {
  330. BaseClass::SetCloseButtonVisible(state);
  331. m_bNoAutoClose = true;
  332. }