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.

364 lines
9.1 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <stdio.h>
  8. #include "vgui_controls/BitmapImagePanel.h"
  9. #include "vgui/ISurface.h"
  10. #include "vgui/IScheme.h"
  11. #include "vgui/IBorder.h"
  12. #include "KeyValues.h"
  13. // memdbgon must be the last include file in a .cpp file!!!
  14. #include "tier0/memdbgon.h"
  15. #ifndef min
  16. #define min(a, b) (((a) < (b)) ? (a) : (b))
  17. #endif
  18. using namespace vgui;
  19. //-----------------------------------------------------------------------------
  20. /**
  21. * Simple utility function to allocate memory and duplicate a string
  22. */
  23. static inline char *CloneString( const char *str )
  24. {
  25. char *cloneStr = new char [ strlen(str)+1 ];
  26. strcpy( cloneStr, str );
  27. return cloneStr;
  28. }
  29. DECLARE_BUILD_FACTORY_DEFAULT_TEXT( CBitmapImagePanel, BitmapImagePanel );
  30. //-----------------------------------------------------------------------------
  31. // Purpose: Constructor
  32. //-----------------------------------------------------------------------------
  33. CBitmapImagePanel::CBitmapImagePanel( Panel *parent, char const *panelName,
  34. char const *filename /*= NULL*/ ) : Panel( parent, panelName )
  35. {
  36. m_pImage = NULL;
  37. SetBounds( 0, 0, 100, 100 );
  38. m_pszImageName = NULL;
  39. m_pszColorName = NULL;
  40. m_hardwareFiltered = false;
  41. m_preserveAspectRatio = false;
  42. m_contentAlignment = Label::a_center;
  43. if ( filename && filename[ 0 ] )
  44. {
  45. m_pImage = scheme()->GetImage( filename, NULL );
  46. m_pszImageName = CloneString( filename );
  47. }
  48. m_bgColor = Color(255, 255, 255, 255);
  49. }
  50. CBitmapImagePanel::~CBitmapImagePanel()
  51. {
  52. delete [] m_pszImageName;
  53. delete [] m_pszColorName;
  54. }
  55. //-----------------------------------------------------------------------------
  56. // Purpose:
  57. //-----------------------------------------------------------------------------
  58. void CBitmapImagePanel::ComputeImagePosition(int &x, int &y, int &w, int &h)
  59. {
  60. if (!m_pImage)
  61. {
  62. x = y = w = h = 0;
  63. return;
  64. }
  65. if ( !m_preserveAspectRatio )
  66. {
  67. x = y = 0;
  68. GetSize( w, h );
  69. return;
  70. }
  71. int panelWide, panelTall;
  72. GetSize( panelWide, panelTall );
  73. int imageWide, imageTall;
  74. m_pImage->GetSize( imageWide, imageTall );
  75. if ( panelWide > 0 && panelTall > 0 && imageWide > 0 && imageTall > 0 )
  76. {
  77. float xScale = (float)panelWide / (float)imageWide;
  78. float yScale = (float)panelTall / (float)imageTall;
  79. float scale = min( xScale, yScale );
  80. w = (int) (imageWide * scale);
  81. h = (int) (imageTall * scale);
  82. switch (m_contentAlignment)
  83. {
  84. case Label::a_northwest:
  85. x = y = 0;
  86. break;
  87. case Label::a_north:
  88. x = (panelWide - w) / 2;
  89. y = 0;
  90. break;
  91. case Label::a_northeast:
  92. x = (panelWide - w);
  93. y = 0;
  94. break;
  95. case Label::a_west:
  96. x = 0;
  97. y = (panelTall - h) / 2;
  98. break;
  99. case Label::a_center:
  100. x = (panelWide - w) / 2;
  101. y = (panelTall - h) / 2;
  102. break;
  103. case Label::a_east:
  104. x = (panelWide - w);
  105. y = (panelTall - h) / 2;
  106. break;
  107. case Label::a_southwest:
  108. x = (panelWide - w);
  109. y = 0;
  110. break;
  111. case Label::a_south:
  112. x = (panelWide - w);
  113. y = (panelTall - h) / 2;
  114. break;
  115. case Label::a_southeast:
  116. x = (panelWide - w);
  117. y = (panelTall - h);
  118. break;
  119. default:
  120. x = y = 0;
  121. break;
  122. }
  123. }
  124. else
  125. {
  126. x = y = 0;
  127. w = panelWide;
  128. h = panelTall;
  129. return;
  130. }
  131. }
  132. //-----------------------------------------------------------------------------
  133. // Purpose:
  134. //-----------------------------------------------------------------------------
  135. void CBitmapImagePanel::PaintBorder()
  136. {
  137. int x, y, w, h;
  138. ComputeImagePosition(x, y, w, h);
  139. IBorder *pBorder = GetBorder();
  140. if ( pBorder )
  141. pBorder->Paint( x, y, x+w, y+h, -1, 0, 0 );
  142. }
  143. //-----------------------------------------------------------------------------
  144. // Purpose:
  145. //-----------------------------------------------------------------------------
  146. void CBitmapImagePanel::PaintBackground()
  147. {
  148. if (!m_pImage)
  149. return;
  150. int x, y, w, h;
  151. ComputeImagePosition(x, y, w, h);
  152. m_pImage->SetPos(x, y);
  153. m_pImage->SetSize( w, h );
  154. m_pImage->SetColor( m_bgColor );
  155. surface()->DrawSetColor( m_bgColor );
  156. m_pImage->Paint();
  157. }
  158. //-----------------------------------------------------------------------------
  159. // Purpose:
  160. //-----------------------------------------------------------------------------
  161. void CBitmapImagePanel::setTexture( char const *filename, bool hardwareFiltered )
  162. {
  163. m_hardwareFiltered = hardwareFiltered;
  164. if ( m_pszImageName )
  165. {
  166. delete[] m_pszImageName;
  167. m_pszImageName = NULL;
  168. }
  169. if ( filename && filename[ 0 ] )
  170. {
  171. m_pImage = scheme()->GetImage( filename, m_hardwareFiltered );
  172. m_pszImageName = CloneString( filename );
  173. }
  174. else
  175. {
  176. m_pImage = NULL;
  177. }
  178. }
  179. //-----------------------------------------------------------------------------
  180. // Purpose:
  181. //-----------------------------------------------------------------------------
  182. void CBitmapImagePanel::SetContentAlignment(Label::Alignment alignment)
  183. {
  184. m_contentAlignment=alignment;
  185. Repaint();
  186. }
  187. //-----------------------------------------------------------------------------
  188. // Purpose: Gets control settings for editing
  189. //-----------------------------------------------------------------------------
  190. void CBitmapImagePanel::GetSettings(KeyValues *outResourceData)
  191. {
  192. BaseClass::GetSettings(outResourceData);
  193. if (m_pszImageName)
  194. {
  195. outResourceData->SetString("image", m_pszImageName);
  196. }
  197. if (m_pszColorName)
  198. {
  199. outResourceData->SetString("imagecolor", m_pszColorName);
  200. }
  201. const char *alignmentString = "";
  202. switch ( m_contentAlignment )
  203. {
  204. case Label::a_northwest: alignmentString = "north-west"; break;
  205. case Label::a_north: alignmentString = "north"; break;
  206. case Label::a_northeast: alignmentString = "north-east"; break;
  207. case Label::a_center: alignmentString = "center"; break;
  208. case Label::a_east: alignmentString = "east"; break;
  209. case Label::a_southwest: alignmentString = "south-west"; break;
  210. case Label::a_south: alignmentString = "south"; break;
  211. case Label::a_southeast: alignmentString = "south-east"; break;
  212. case Label::a_west:
  213. default: alignmentString = "center"; break;
  214. }
  215. outResourceData->SetString( "imageAlignment", alignmentString );
  216. outResourceData->SetInt("preserveAspectRatio", m_preserveAspectRatio);
  217. outResourceData->SetInt("filtered", m_hardwareFiltered);
  218. }
  219. //-----------------------------------------------------------------------------
  220. // Purpose: Applies designer settings from res file
  221. //-----------------------------------------------------------------------------
  222. void CBitmapImagePanel::ApplySettings(KeyValues *inResourceData)
  223. {
  224. if ( m_pszImageName )
  225. {
  226. delete[] m_pszImageName;
  227. m_pszImageName = NULL;
  228. }
  229. if ( m_pszColorName )
  230. {
  231. delete[] m_pszColorName;
  232. m_pszColorName = NULL;
  233. }
  234. const char *imageName = inResourceData->GetString("image", "");
  235. if (*imageName)
  236. {
  237. setTexture( imageName );
  238. }
  239. const char *colorName = inResourceData->GetString("imagecolor", "");
  240. if (*colorName)
  241. {
  242. m_pszColorName = CloneString( colorName );
  243. InvalidateLayout(false,true); // force ApplySchemeSettings to run
  244. }
  245. const char *keyString = inResourceData->GetString("imageAlignment", "");
  246. if (keyString && *keyString)
  247. {
  248. int align = -1;
  249. if ( !stricmp(keyString, "north-west") )
  250. {
  251. align = Label::a_northwest;
  252. }
  253. else if ( !stricmp(keyString, "north") )
  254. {
  255. align = Label::a_north;
  256. }
  257. else if ( !stricmp(keyString, "north-east") )
  258. {
  259. align = Label::a_northeast;
  260. }
  261. else if ( !stricmp(keyString, "west") )
  262. {
  263. align = Label::a_west;
  264. }
  265. else if ( !stricmp(keyString, "center") )
  266. {
  267. align = Label::a_center;
  268. }
  269. else if ( !stricmp(keyString, "east") )
  270. {
  271. align = Label::a_east;
  272. }
  273. else if ( !stricmp(keyString, "south-west") )
  274. {
  275. align = Label::a_southwest;
  276. }
  277. else if ( !stricmp(keyString, "south") )
  278. {
  279. align = Label::a_south;
  280. }
  281. else if ( !stricmp(keyString, "south-east") )
  282. {
  283. align = Label::a_southeast;
  284. }
  285. if ( align != -1 )
  286. {
  287. SetContentAlignment( (Label::Alignment)align );
  288. }
  289. }
  290. keyString = inResourceData->GetString("preserveAspectRatio", "");
  291. if (keyString && *keyString)
  292. {
  293. m_preserveAspectRatio = atoi( keyString ) != 0;
  294. }
  295. keyString = inResourceData->GetString("filtered", "");
  296. if (keyString && *keyString)
  297. {
  298. m_hardwareFiltered = atoi( keyString ) != 0;
  299. }
  300. BaseClass::ApplySettings(inResourceData);
  301. }
  302. //-----------------------------------------------------------------------------
  303. // Purpose: load the image, this is done just before this control is displayed
  304. //-----------------------------------------------------------------------------
  305. void CBitmapImagePanel::ApplySchemeSettings( IScheme *pScheme )
  306. {
  307. BaseClass::ApplySchemeSettings(pScheme);
  308. if ( m_pszColorName )
  309. {
  310. setImageColor( pScheme->GetColor( m_pszColorName, m_bgColor ) );
  311. }
  312. }
  313. //-----------------------------------------------------------------------------
  314. // Purpose: Describes editing details
  315. //-----------------------------------------------------------------------------
  316. const char *CBitmapImagePanel::GetDescription()
  317. {
  318. static char buf[1024];
  319. _snprintf(buf, sizeof(buf), "%s, string image, string imagecolor, alignment imageAlignment, int preserveAspectRatio, int filtered", BaseClass::GetDescription());
  320. return buf;
  321. }