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.

403 lines
11 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. // This class is a message box that has two buttons, ok and cancel instead of
  5. // just the ok button of a message box. We use a message box class for the ok button
  6. // and implement another button here.
  7. //=============================================================================//
  8. #include <math.h>
  9. #define PROTECTED_THINGS_DISABLE
  10. #include <vgui/IInput.h>
  11. #include <vgui/ISystem.h>
  12. #include <vgui/ISurface.h>
  13. #include <vgui/IScheme.h>
  14. #include <vgui/IVGui.h>
  15. #include <vgui/IPanel.h>
  16. #include <vgui_controls/Tooltip.h>
  17. #include <vgui_controls/TextEntry.h>
  18. #include <vgui_controls/Controls.h>
  19. // memdbgon must be the last include file in a .cpp file!!!
  20. #include <tier0/memdbgon.h>
  21. using namespace vgui;
  22. //-----------------------------------------------------------------------------
  23. // Purpose: Constructor
  24. //-----------------------------------------------------------------------------
  25. BaseTooltip::BaseTooltip(Panel *parent, const char *text)
  26. {
  27. SetText(text);
  28. _displayOnOneLine = false;
  29. _makeVisible = false;
  30. _isDirty = false;
  31. _tooltipDelay = 500; // default delay for opening tooltips
  32. _delay = 0;
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Purpose: Reset the tooltip delay timer
  36. //-----------------------------------------------------------------------------
  37. void BaseTooltip::ResetDelay()
  38. {
  39. _isDirty = true;
  40. _delay = system()->GetTimeMillis() + _tooltipDelay;
  41. }
  42. //-----------------------------------------------------------------------------
  43. // Purpose: Set the tooltip delay before a tooltip comes up.
  44. //-----------------------------------------------------------------------------
  45. void BaseTooltip::SetTooltipDelay( int tooltipDelay )
  46. {
  47. _tooltipDelay = tooltipDelay;
  48. }
  49. //-----------------------------------------------------------------------------
  50. // Purpose: Get the tooltip delay before a tooltip comes up.
  51. //-----------------------------------------------------------------------------
  52. int BaseTooltip::GetTooltipDelay()
  53. {
  54. return _tooltipDelay;
  55. }
  56. //-----------------------------------------------------------------------------
  57. // Purpose: Set the tool tip to display on one line only
  58. // Default is multiple lines.
  59. //-----------------------------------------------------------------------------
  60. void BaseTooltip::SetTooltipFormatToSingleLine()
  61. {
  62. _displayOnOneLine = true;
  63. _isDirty = true;
  64. }
  65. //-----------------------------------------------------------------------------
  66. // Purpose: Set the tool tip to display on multiple lines.
  67. //-----------------------------------------------------------------------------
  68. void BaseTooltip::SetTooltipFormatToMultiLine()
  69. {
  70. _displayOnOneLine = false;
  71. _isDirty = true;
  72. }
  73. //-----------------------------------------------------------------------------
  74. // Purpose: Display the tooltip
  75. //-----------------------------------------------------------------------------
  76. void BaseTooltip::ShowTooltip(Panel *currentPanel)
  77. {
  78. _makeVisible = true;
  79. PerformLayout();
  80. }
  81. //-----------------------------------------------------------------------------
  82. // Purpose:
  83. //-----------------------------------------------------------------------------
  84. bool BaseTooltip::ShouldLayout( void )
  85. {
  86. if (!_makeVisible)
  87. return false;
  88. if (_delay > system()->GetTimeMillis())
  89. return false;
  90. // We only need to layout when we first become visible
  91. if ( !_isDirty )
  92. return false;
  93. return true;
  94. }
  95. //-----------------------------------------------------------------------------
  96. // Purpose: Display the tooltip
  97. //-----------------------------------------------------------------------------
  98. void BaseTooltip::HideTooltip()
  99. {
  100. _makeVisible = false;
  101. _isDirty = true;
  102. }
  103. //-----------------------------------------------------------------------------
  104. // Purpose: Set the tooltip text
  105. //-----------------------------------------------------------------------------
  106. void BaseTooltip::SetText(const char *text)
  107. {
  108. _isDirty = true;
  109. if (!text)
  110. {
  111. text = "";
  112. }
  113. if (m_Text.Count() > 0)
  114. {
  115. m_Text.RemoveAll();
  116. }
  117. for (unsigned int i = 0; i < strlen(text); i++)
  118. {
  119. m_Text.AddToTail(text[i]);
  120. }
  121. m_Text.AddToTail('\0');
  122. }
  123. //-----------------------------------------------------------------------------
  124. // Purpose: Get the tooltip text
  125. //-----------------------------------------------------------------------------
  126. const char *BaseTooltip::GetText()
  127. {
  128. return m_Text.Base();
  129. }
  130. //-----------------------------------------------------------------------------
  131. // Purpose: Position the tool tip
  132. //-----------------------------------------------------------------------------
  133. void BaseTooltip::PositionWindow( Panel *pTipPanel )
  134. {
  135. int iTipW, iTipH;
  136. pTipPanel->GetSize( iTipW, iTipH );
  137. int cursorX, cursorY;
  138. input()->GetCursorPos(cursorX, cursorY);
  139. int wide, tall;
  140. surface()->GetScreenSize(wide, tall);
  141. if (wide - iTipW > cursorX)
  142. {
  143. cursorY += 20;
  144. // menu hanging right
  145. if (tall - iTipH > cursorY)
  146. {
  147. // menu hanging down
  148. pTipPanel->SetPos(cursorX, cursorY);
  149. }
  150. else
  151. {
  152. // menu hanging up
  153. pTipPanel->SetPos(cursorX, cursorY - iTipH - 20);
  154. }
  155. }
  156. else
  157. {
  158. // menu hanging left
  159. if (tall - iTipH > cursorY)
  160. {
  161. // menu hanging down
  162. pTipPanel->SetPos(cursorX - iTipW, cursorY);
  163. }
  164. else
  165. {
  166. // menu hanging up
  167. pTipPanel->SetPos(cursorX - iTipW, cursorY - iTipH - 20 );
  168. }
  169. }
  170. }
  171. //------------------------------------------------------------------------------------------------------
  172. //------------------------------------------------------------------------------------------------------
  173. static vgui::DHANDLE< TextEntry > s_TooltipWindow;
  174. static int s_iTooltipWindowCount = 0;
  175. //-----------------------------------------------------------------------------
  176. // Purpose: Constructor
  177. //-----------------------------------------------------------------------------
  178. TextTooltip::TextTooltip(Panel *parent, const char *text) : BaseTooltip( parent, text )
  179. {
  180. m_pParent = parent;
  181. if (!s_TooltipWindow.Get())
  182. {
  183. s_TooltipWindow = new TextEntry(NULL, "tooltip");
  184. s_TooltipWindow->InvalidateLayout(false, true);
  185. // this bit of hackery is necessary because tooltips don't get ApplySchemeSettings called from their parents
  186. IScheme *pScheme = scheme()->GetIScheme( s_TooltipWindow->GetScheme() );
  187. s_TooltipWindow->SetBgColor(s_TooltipWindow->GetSchemeColor("Tooltip.BgColor", s_TooltipWindow->GetBgColor(), pScheme));
  188. s_TooltipWindow->SetFgColor(s_TooltipWindow->GetSchemeColor("Tooltip.TextColor", s_TooltipWindow->GetFgColor(), pScheme));
  189. s_TooltipWindow->SetBorder(pScheme->GetBorder("ToolTipBorder"));
  190. s_TooltipWindow->SetFont( pScheme->GetFont("DefaultSmall", s_TooltipWindow->IsProportional()));
  191. }
  192. s_iTooltipWindowCount++;
  193. // this line prevents the main window from losing focus
  194. // when a tooltip pops up
  195. s_TooltipWindow->MakePopup(false, true);
  196. s_TooltipWindow->SetKeyBoardInputEnabled( false );
  197. s_TooltipWindow->SetMouseInputEnabled( false );
  198. SetText(text);
  199. if (s_TooltipWindow.Get()->GetParent() == NULL)
  200. {
  201. s_TooltipWindow->SetText(m_Text.Base());
  202. s_TooltipWindow->SetEditable(false);
  203. s_TooltipWindow->SetMultiline(true);
  204. s_TooltipWindow->SetVisible(false);
  205. }
  206. _displayOnOneLine = false;
  207. _makeVisible = false;
  208. _isDirty = false;
  209. _enabled = true;
  210. _tooltipDelay = 500; // default delay for opening tooltips
  211. _delay = 0;
  212. }
  213. //-----------------------------------------------------------------------------
  214. // Purpose: Destructor
  215. //-----------------------------------------------------------------------------
  216. TextTooltip::~TextTooltip()
  217. {
  218. if (--s_iTooltipWindowCount < 1)
  219. {
  220. if ( s_TooltipWindow.Get() )
  221. {
  222. s_TooltipWindow->MarkForDeletion();
  223. }
  224. s_TooltipWindow = NULL;
  225. }
  226. }
  227. void BaseTooltip::SetEnabled( bool bState )
  228. {
  229. _enabled = bState;
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose: Set the tooltip text
  233. //-----------------------------------------------------------------------------
  234. void TextTooltip::SetText(const char *text)
  235. {
  236. BaseTooltip::SetText( text );
  237. if (s_TooltipWindow.Get() && m_pParent == s_TooltipWindow.Get()->GetParent())
  238. {
  239. s_TooltipWindow->SetText(m_Text.Base());
  240. }
  241. }
  242. //-----------------------------------------------------------------------------
  243. // Purpose: Display the tooltip
  244. //-----------------------------------------------------------------------------
  245. void TextTooltip::ShowTooltip(Panel *currentPanel)
  246. {
  247. if ( s_TooltipWindow.Get() )
  248. {
  249. Panel *pCurrentParent = s_TooltipWindow->GetParent();
  250. _isDirty = _isDirty || ( pCurrentParent != currentPanel );
  251. s_TooltipWindow->SetText( m_Text.Base() );
  252. s_TooltipWindow->SetParent(currentPanel);
  253. int nLen = s_TooltipWindow->GetTextLength();
  254. if ( nLen <= 0 )
  255. {
  256. // Empty tool tip, no need to show it
  257. _makeVisible = false;
  258. return;
  259. }
  260. }
  261. BaseTooltip::ShowTooltip( currentPanel );
  262. }
  263. //-----------------------------------------------------------------------------
  264. // Purpose: Display the tooltip
  265. //-----------------------------------------------------------------------------
  266. void TextTooltip::PerformLayout()
  267. {
  268. if ( !ShouldLayout() )
  269. return;
  270. // we're ready, just make us visible
  271. if ( !s_TooltipWindow.Get() )
  272. return;
  273. _isDirty = false;
  274. s_TooltipWindow->SetVisible(true);
  275. s_TooltipWindow->MakePopup( false, true );
  276. s_TooltipWindow->SetKeyBoardInputEnabled( false );
  277. s_TooltipWindow->SetMouseInputEnabled( false );
  278. // force the tooltip window to apply scheme settings (and pick a font) before we size it and color it
  279. surface()->SolveTraverse( s_TooltipWindow->GetVPanel(), true );
  280. // get cursor position
  281. int cursorX, cursorY;
  282. input()->GetCursorPos(cursorX, cursorY);
  283. // relayout the textwindow immediately so that we know it's size
  284. //m_pTextEntry->InvalidateLayout(true);
  285. SizeTextWindow();
  286. PositionWindow( s_TooltipWindow );
  287. }
  288. //-----------------------------------------------------------------------------
  289. // Purpose: Size the text window so all the text fits inside it.
  290. //-----------------------------------------------------------------------------
  291. void TextTooltip::SizeTextWindow()
  292. {
  293. if ( !s_TooltipWindow.Get() )
  294. return;
  295. if (_displayOnOneLine)
  296. {
  297. // We want the tool tip to be one line
  298. s_TooltipWindow->SetMultiline(false);
  299. s_TooltipWindow->SetToFullWidth();
  300. }
  301. else
  302. {
  303. // We want the tool tip to be one line
  304. s_TooltipWindow->SetMultiline(false);
  305. s_TooltipWindow->SetToFullWidth();
  306. int wide, tall;
  307. s_TooltipWindow->GetSize( wide, tall );
  308. double newWide = sqrt( (2.0/1) * wide * tall );
  309. double newTall = (1/2) * newWide;
  310. s_TooltipWindow->SetMultiline(true);
  311. s_TooltipWindow->SetSize((int)newWide, (int)newTall );
  312. s_TooltipWindow->SetToFullHeight();
  313. s_TooltipWindow->GetSize( wide, tall );
  314. if (( wide < 100 ) && ( s_TooltipWindow->GetNumLines() == 2) )
  315. {
  316. s_TooltipWindow->SetMultiline(false);
  317. s_TooltipWindow->SetToFullWidth();
  318. }
  319. else
  320. {
  321. while ( (float)wide/(float)tall < 2 )
  322. {
  323. s_TooltipWindow->SetSize( wide + 1, tall );
  324. s_TooltipWindow->SetToFullHeight();
  325. s_TooltipWindow->GetSize( wide, tall );
  326. }
  327. }
  328. s_TooltipWindow->GetSize( wide, tall );
  329. // ivgui()->DPrintf("End Ratio: %f\n", (float)wide/(float)tall);
  330. }
  331. }
  332. //-----------------------------------------------------------------------------
  333. // Purpose: Display the tooltip
  334. //-----------------------------------------------------------------------------
  335. void TextTooltip::HideTooltip()
  336. {
  337. if ( s_TooltipWindow.Get() )
  338. {
  339. s_TooltipWindow->SetVisible(false);
  340. }
  341. BaseTooltip::HideTooltip();
  342. }