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.

362 lines
9.8 KiB

  1. //========= Copyright (c) 1996-2005, 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. BaseClass::DoModal();
  155. ShowWindow(pFrameOver);
  156. }
  157. void MessageBox::ShowWindow(Frame *pFrameOver)
  158. {
  159. m_pFrameOver = pFrameOver;
  160. SetVisible( true );
  161. SetEnabled( true );
  162. MoveToFront();
  163. if ( m_pOkButton->IsVisible() )
  164. {
  165. m_pOkButton->RequestFocus();
  166. }
  167. else // handle message boxes with no button
  168. {
  169. RequestFocus();
  170. }
  171. InvalidateLayout();
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose: Put the text and OK buttons in correct place
  175. //-----------------------------------------------------------------------------
  176. void MessageBox::PerformLayout()
  177. {
  178. int x, y, wide, tall;
  179. GetClientArea(x, y, wide, tall);
  180. wide += x;
  181. tall += y;
  182. int boxWidth, boxTall;
  183. GetSize(boxWidth, boxTall);
  184. int oldWide, oldTall;
  185. m_pOkButton->GetSize(oldWide, oldTall);
  186. int btnWide, btnTall;
  187. m_pOkButton->GetContentSize(btnWide, btnTall);
  188. btnWide = max(oldWide, btnWide + 10);
  189. btnTall = max(oldTall, btnTall + 10);
  190. m_pOkButton->SetSize(btnWide, btnTall);
  191. int btnWide2 = 0, btnTall2 = 0;
  192. if ( m_pCancelButton->IsVisible() )
  193. {
  194. m_pCancelButton->GetSize(oldWide, oldTall);
  195. m_pCancelButton->GetContentSize(btnWide2, btnTall2);
  196. btnWide2 = max(oldWide, btnWide2 + 10);
  197. btnTall2 = max(oldTall, btnTall2 + 10);
  198. m_pCancelButton->SetSize(btnWide2, btnTall2);
  199. }
  200. boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100);
  201. boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30);
  202. SetSize(boxWidth, boxTall);
  203. GetSize(boxWidth, boxTall);
  204. m_pMessageLabel->SetPos((wide/2)-(m_pMessageLabel->GetWide()/2) + x, y + 5 );
  205. if ( !m_pCancelButton->IsVisible() )
  206. {
  207. m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
  208. }
  209. else
  210. {
  211. m_pOkButton->SetPos((wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
  212. m_pCancelButton->SetPos((3*wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15);
  213. }
  214. BaseClass::PerformLayout();
  215. GetSize(boxWidth, boxTall);
  216. }
  217. //-----------------------------------------------------------------------------
  218. // Purpose: Set a string command to be sent when the OK button is pressed.
  219. //-----------------------------------------------------------------------------
  220. void MessageBox::SetCommand(const char *command)
  221. {
  222. if (m_OkCommand)
  223. {
  224. m_OkCommand->deleteThis();
  225. }
  226. m_OkCommand = new KeyValues("Command", "command", command);
  227. }
  228. //-----------------------------------------------------------------------------
  229. // Purpose: Sets the command
  230. //-----------------------------------------------------------------------------
  231. void MessageBox::SetCommand(KeyValues *command)
  232. {
  233. if (m_OkCommand)
  234. {
  235. m_OkCommand->deleteThis();
  236. }
  237. m_OkCommand = command;
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose:
  241. //-----------------------------------------------------------------------------
  242. void MessageBox::OnShutdownRequest()
  243. {
  244. // Shutdown the dialog
  245. PostMessage(this, new KeyValues("Close"));
  246. }
  247. //-----------------------------------------------------------------------------
  248. // Purpose: Set the visibility of the OK button.
  249. //-----------------------------------------------------------------------------
  250. void MessageBox::SetOKButtonVisible(bool state)
  251. {
  252. m_pOkButton->SetVisible(state);
  253. }
  254. //-----------------------------------------------------------------------------
  255. // Purpose: Sets the Text on the OK button
  256. //-----------------------------------------------------------------------------
  257. void MessageBox::SetOKButtonText(const char *buttonText)
  258. {
  259. m_pOkButton->SetText(buttonText);
  260. InvalidateLayout();
  261. }
  262. //-----------------------------------------------------------------------------
  263. // Purpose: Sets the Text on the OK button
  264. //-----------------------------------------------------------------------------
  265. void MessageBox::SetOKButtonText(const wchar_t *wszButtonText)
  266. {
  267. m_pOkButton->SetText(wszButtonText);
  268. InvalidateLayout();
  269. }
  270. //-----------------------------------------------------------------------------
  271. // Cancel button (off by default)
  272. //-----------------------------------------------------------------------------
  273. void MessageBox::SetCancelButtonVisible(bool state)
  274. {
  275. m_pCancelButton->SetVisible(state);
  276. InvalidateLayout();
  277. }
  278. void MessageBox::SetCancelButtonText(const char *buttonText)
  279. {
  280. m_pCancelButton->SetText(buttonText);
  281. InvalidateLayout();
  282. }
  283. void MessageBox::SetCancelButtonText(const wchar_t *wszButtonText)
  284. {
  285. m_pCancelButton->SetText(wszButtonText);
  286. InvalidateLayout();
  287. }
  288. void MessageBox::SetCancelCommand( KeyValues *command )
  289. {
  290. if (m_CancelCommand)
  291. {
  292. m_CancelCommand->deleteThis();
  293. }
  294. m_CancelCommand = command;
  295. }
  296. //-----------------------------------------------------------------------------
  297. // Purpose: Toggles visibility of the close box.
  298. //-----------------------------------------------------------------------------
  299. void MessageBox::DisableCloseButton(bool state)
  300. {
  301. BaseClass::SetCloseButtonVisible(state);
  302. m_bNoAutoClose = true;
  303. }