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.

414 lines
9.5 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $Workfile: $
  6. // $Date: $
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #include "cbase.h"
  10. #include "itextmessage.h"
  11. #include <vgui_controls/Panel.h>
  12. #include <vgui/IVGui.h>
  13. #include <vgui/ILocalize.h>
  14. #include "VGuiMatSurface/IMatSystemSurface.h"
  15. #include <vgui_controls/Controls.h>
  16. #include <vgui/ISurface.h>
  17. #include "hud.h"
  18. // memdbgon must be the last include file in a .cpp file!!!
  19. #include "tier0/memdbgon.h"
  20. // Simultaneous message limit
  21. #define MAX_TEXTMESSAGE_CHARS 2048
  22. //-----------------------------------------------------------------------------
  23. // Purpose: For rendering the Titles.txt characters to the screen from the HUD
  24. //-----------------------------------------------------------------------------
  25. class CTextMessagePanel : public vgui::Panel
  26. {
  27. typedef vgui::Panel BaseClass;
  28. public:
  29. enum
  30. {
  31. TYPE_UNKNOWN = 0,
  32. TYPE_POSITION,
  33. TYPE_CHARACTER,
  34. TYPE_FONT,
  35. };
  36. struct message_t
  37. {
  38. vgui::HFont font;
  39. short x, y;
  40. wchar_t ch;
  41. byte type;
  42. byte r, g, b, a;
  43. };
  44. CTextMessagePanel( vgui::VPANEL parent );
  45. virtual ~CTextMessagePanel( void );
  46. virtual void SetPosition( int x, int y );
  47. virtual void AddChar( int r, int g, int b, int a, wchar_t ch );
  48. virtual void GetTextExtents( int *wide, int *tall, const char *string );
  49. virtual void SetFont( vgui::HFont hCustomFont );
  50. virtual void SetDefaultFont( void );
  51. virtual void OnTick( void );
  52. virtual void Paint();
  53. virtual bool ShouldDraw( void );
  54. // Get character data for textmessage text
  55. virtual int GetFontInfo( FONTABC *pABCs, vgui::HFont hFont );
  56. virtual void ApplySchemeSettings( vgui::IScheme *pScheme )
  57. {
  58. BaseClass::ApplySchemeSettings( pScheme );
  59. SetSize( ScreenWidth(), ScreenHeight() );
  60. SetPos( 0, 0 );
  61. }
  62. private:
  63. message_t *AllocMessage( void );
  64. void Reset( void );
  65. vgui::HFont m_hFont;
  66. vgui::HFont m_hDefaultFont;
  67. CUtlVector< message_t > m_Messages;
  68. };
  69. //-----------------------------------------------------------------------------
  70. // Purpose: Constructor
  71. // Input : *parent -
  72. //-----------------------------------------------------------------------------
  73. CTextMessagePanel::CTextMessagePanel( vgui::VPANEL parent )
  74. : BaseClass( NULL, "CTextMessagePanel" )
  75. {
  76. SetParent( parent );
  77. SetSize( ScreenWidth(), ScreenHeight() );
  78. SetPos( 0, 0 );
  79. SetVisible( false );
  80. SetCursor( null );
  81. SetKeyBoardInputEnabled( false );
  82. SetMouseInputEnabled( false );
  83. m_hFont = g_hFontTrebuchet24;
  84. m_hDefaultFont = m_hFont;
  85. SetFgColor( Color( 0, 0, 0, 255 ) );
  86. SetPaintBackgroundEnabled( false );
  87. // Clear memory out
  88. Reset();
  89. vgui::ivgui()->AddTickSignal( GetVPanel(), 100 );
  90. }
  91. //-----------------------------------------------------------------------------
  92. // Purpose:
  93. //-----------------------------------------------------------------------------
  94. CTextMessagePanel::~CTextMessagePanel( void )
  95. {
  96. }
  97. //-----------------------------------------------------------------------------
  98. // Purpose: Get font sizes
  99. // Input : *pWidth -
  100. // Output : int
  101. //-----------------------------------------------------------------------------
  102. int CTextMessagePanel::GetFontInfo( FONTABC *pABCs, vgui::HFont hFont )
  103. {
  104. int i;
  105. if ( !hFont )
  106. {
  107. hFont = m_hFont;
  108. }
  109. if ( !hFont )
  110. return 0;
  111. if ( pABCs )
  112. {
  113. for ( i =0; i < 256; i++ )
  114. {
  115. int a, b, c;
  116. vgui::surface()->GetCharABCwide( hFont, (char)i, a, b, c );
  117. pABCs[i].abcA = a;
  118. pABCs[i].abcB = b;
  119. pABCs[i].abcC = c;
  120. pABCs[i].total = a+b+c;
  121. }
  122. }
  123. return vgui::surface()->GetFontTall( hFont );
  124. }
  125. //-----------------------------------------------------------------------------
  126. // Purpose: Clear all messages out of active list, etc.
  127. //-----------------------------------------------------------------------------
  128. void CTextMessagePanel::Reset( void )
  129. {
  130. m_Messages.Purge();
  131. SetVisible( false );
  132. }
  133. //-----------------------------------------------------------------------------
  134. // Purpose: Grab next free message, if any
  135. // Output : CTextMessagePanel::message_t
  136. //-----------------------------------------------------------------------------
  137. CTextMessagePanel::message_t *CTextMessagePanel::AllocMessage( void )
  138. {
  139. CTextMessagePanel::message_t *msg;
  140. if ( m_Messages.Count() >= MAX_TEXTMESSAGE_CHARS )
  141. return NULL;
  142. msg = &m_Messages[ m_Messages.AddToTail() ];
  143. msg->type = TYPE_UNKNOWN;
  144. msg->x = 0;
  145. msg->y = 0;
  146. msg->ch = 0;
  147. msg->r = 0;
  148. msg->g = 0;
  149. msg->b = 0;
  150. msg->a = 0;
  151. SetVisible( true );
  152. return msg;
  153. }
  154. //-----------------------------------------------------------------------------
  155. // Purpose:
  156. // Input : x -
  157. // y -
  158. //-----------------------------------------------------------------------------
  159. void CTextMessagePanel::SetPosition( int x, int y )
  160. {
  161. CTextMessagePanel::message_t *msg = AllocMessage();
  162. if ( !msg )
  163. return;
  164. msg->type = TYPE_POSITION;
  165. // Used fields
  166. msg->x = x;
  167. msg->y = y;
  168. }
  169. //-----------------------------------------------------------------------------
  170. // Purpose: Adds a character to the active list, if possible
  171. // Input : x -
  172. // y -
  173. // r -
  174. // g -
  175. // b -
  176. // a -
  177. // ch -
  178. // Output : int
  179. //-----------------------------------------------------------------------------
  180. void CTextMessagePanel::AddChar( int r, int g, int b, int a, wchar_t ch )
  181. {
  182. CTextMessagePanel::message_t *msg = AllocMessage();
  183. if ( !msg )
  184. return;
  185. msg->type = TYPE_CHARACTER;
  186. // Used fields
  187. msg->r = r;
  188. msg->g = g;
  189. msg->b = b;
  190. msg->a = a;
  191. msg->ch = ch;
  192. }
  193. //-----------------------------------------------------------------------------
  194. // Purpose: Determine width and height of specified string
  195. // Input : *wide -
  196. // *tall -
  197. // *string -
  198. //-----------------------------------------------------------------------------
  199. void CTextMessagePanel::GetTextExtents( int *wide, int *tall, const char *string )
  200. {
  201. *wide = g_pMatSystemSurface->DrawTextLen( m_hFont, "%s", (char *)string );
  202. *tall = vgui::surface()->GetFontTall( m_hFont );
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose:
  206. //-----------------------------------------------------------------------------
  207. void CTextMessagePanel::SetFont( vgui::HFont hCustomFont )
  208. {
  209. m_hFont = hCustomFont;
  210. CTextMessagePanel::message_t *msg = AllocMessage();
  211. if ( !msg )
  212. return;
  213. msg->type = TYPE_FONT;
  214. // Used fields
  215. msg->font = m_hFont;
  216. }
  217. //-----------------------------------------------------------------------------
  218. // Purpose:
  219. //-----------------------------------------------------------------------------
  220. void CTextMessagePanel::SetDefaultFont( void )
  221. {
  222. SetFont( m_hDefaultFont );
  223. }
  224. //-----------------------------------------------------------------------------
  225. // Purpose:
  226. //-----------------------------------------------------------------------------
  227. void CTextMessagePanel::OnTick( void )
  228. {
  229. SetVisible( ShouldDraw() );
  230. }
  231. //-----------------------------------------------------------------------------
  232. // Purpose:
  233. // Output : Returns true on success, false on failure.
  234. //-----------------------------------------------------------------------------
  235. bool CTextMessagePanel::ShouldDraw( void )
  236. {
  237. if ( !m_Messages.Count() )
  238. return false;
  239. return true;
  240. }
  241. //-----------------------------------------------------------------------------
  242. // Purpose: Draw current text items
  243. //-----------------------------------------------------------------------------
  244. void CTextMessagePanel::Paint()
  245. {
  246. CTextMessagePanel::message_t *msg;
  247. int xpos = 0, ypos = 0;
  248. vgui::surface()->DrawSetTextFont( m_hFont );
  249. int messageCount = m_Messages.Count();
  250. for ( int i = 0 ; i < messageCount; ++i )
  251. {
  252. msg = &m_Messages[ i ];
  253. switch ( msg->type )
  254. {
  255. default:
  256. case TYPE_UNKNOWN:
  257. Assert( 0 );
  258. break;
  259. case TYPE_POSITION:
  260. xpos = msg->x;
  261. ypos = msg->y;
  262. break;
  263. case TYPE_FONT:
  264. m_hFont = msg->font;
  265. vgui::surface()->DrawSetTextFont( m_hFont );
  266. break;
  267. case TYPE_CHARACTER:
  268. if ( m_hFont )
  269. {
  270. int a, b, c;
  271. vgui::surface()->GetCharABCwide( m_hFont, msg->ch, a, b, c );
  272. if ( msg->ch > 32 )
  273. {
  274. vgui::surface()->DrawSetTextColor( msg->r, msg->g, msg->b, msg->a );
  275. vgui::surface()->DrawSetTextPos( xpos, ypos );
  276. vgui::surface()->DrawUnicodeChar( msg->ch );
  277. }
  278. xpos += a + b + c;
  279. }
  280. break;
  281. }
  282. }
  283. Reset();
  284. }
  285. class CTextMessage : public ITextMessage
  286. {
  287. private:
  288. CTextMessagePanel *textMessagePanel;
  289. public:
  290. CTextMessage( void )
  291. {
  292. textMessagePanel = NULL;
  293. }
  294. void Create( vgui::VPANEL parent )
  295. {
  296. textMessagePanel = new CTextMessagePanel( parent );
  297. }
  298. void Destroy( void )
  299. {
  300. if ( textMessagePanel )
  301. {
  302. textMessagePanel->SetParent( (vgui::Panel *)NULL );
  303. delete textMessagePanel;
  304. }
  305. }
  306. void SetPosition( int x, int y )
  307. {
  308. if ( !textMessagePanel )
  309. return;
  310. textMessagePanel->SetPosition( x, y );
  311. }
  312. void AddChar( int r, int g, int b, int a, wchar_t ch )
  313. {
  314. if ( !textMessagePanel )
  315. return;
  316. textMessagePanel->AddChar( r, g, b, a, ch );
  317. }
  318. void GetLength( int *wide, int *tall, const char *string )
  319. {
  320. if ( !textMessagePanel )
  321. {
  322. *wide = *tall = 0;
  323. return;
  324. }
  325. textMessagePanel->GetTextExtents( wide, tall, string );
  326. }
  327. int GetFontInfo( FONTABC *pABCs, vgui::HFont hFont )
  328. {
  329. return textMessagePanel ? textMessagePanel->GetFontInfo( pABCs, hFont ) : 0;
  330. }
  331. void SetFont( vgui::HFont hCustomFont )
  332. {
  333. if ( !textMessagePanel )
  334. return;
  335. textMessagePanel->SetFont( hCustomFont );
  336. }
  337. void SetDefaultFont( void )
  338. {
  339. if ( !textMessagePanel )
  340. return;
  341. textMessagePanel->SetDefaultFont();
  342. }
  343. };
  344. static CTextMessage g_TextMessage;
  345. ITextMessage *textmessage = &g_TextMessage;