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.

475 lines
14 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //=============================================================================//
  7. #include <stdio.h>
  8. #include <vgui/IBorder.h>
  9. #include <vgui/ISurface.h>
  10. #include <vgui/IScheme.h>
  11. #include <vgui/IBorder.h>
  12. #include <KeyValues.h>
  13. #include <vgui_controls/ImagePanel.h>
  14. #include <vgui_controls/Image.h>
  15. #include <vgui_controls/Controls.h>
  16. // memdbgon must be the last include file in a .cpp file!!!
  17. #include <tier0/memdbgon.h>
  18. using namespace vgui;
  19. DECLARE_BUILD_FACTORY( ImagePanel );
  20. //-----------------------------------------------------------------------------
  21. // Purpose:
  22. //-----------------------------------------------------------------------------
  23. ImagePanel::ImagePanel(Panel *parent, const char *name) : Panel(parent, name)
  24. {
  25. m_pImage = NULL;
  26. m_pszImageName = NULL;
  27. m_pszFillColorName = NULL;
  28. m_pszDrawColorName = NULL; // HPE addition
  29. m_bCenterImage = false;
  30. m_bScaleImage = false;
  31. m_bTileImage = false;
  32. m_bTileHorizontally = false;
  33. m_bTileVertically = false;
  34. m_bPositionImage = true;
  35. m_fScaleAmount = 0.0f;
  36. m_FillColor = Color(0, 0, 0, 0);
  37. m_DrawColor = Color(255,255,255,255);
  38. m_iRotation = ROTATED_UNROTATED;
  39. SetImage( m_pImage );
  40. REGISTER_COLOR_AS_OVERRIDABLE( m_FillColor, "fillcolor_override" );
  41. REGISTER_COLOR_AS_OVERRIDABLE( m_DrawColor, "drawcolor_override" );
  42. }
  43. //-----------------------------------------------------------------------------
  44. // Purpose:
  45. //-----------------------------------------------------------------------------
  46. ImagePanel::~ImagePanel()
  47. {
  48. delete [] m_pszImageName;
  49. delete [] m_pszFillColorName;
  50. delete [] m_pszDrawColorName; // HPE addition
  51. }
  52. //-----------------------------------------------------------------------------
  53. // Purpose: handles size changing
  54. //-----------------------------------------------------------------------------
  55. void ImagePanel::OnSizeChanged(int newWide, int newTall)
  56. {
  57. BaseClass::OnSizeChanged(newWide, newTall);
  58. }
  59. //-----------------------------------------------------------------------------
  60. // Purpose:
  61. //-----------------------------------------------------------------------------
  62. void ImagePanel::SetImage(IImage *image)
  63. {
  64. m_pImage = image;
  65. Repaint();
  66. }
  67. //-----------------------------------------------------------------------------
  68. // Purpose: sets an image by file name
  69. //-----------------------------------------------------------------------------
  70. void ImagePanel::SetImage(const char *imageName)
  71. {
  72. if ( imageName && m_pszImageName && V_stricmp( imageName, m_pszImageName ) == 0 )
  73. return;
  74. int len = Q_strlen(imageName) + 1;
  75. delete [] m_pszImageName;
  76. m_pszImageName = new char[ len ];
  77. Q_strncpy(m_pszImageName, imageName, len );
  78. InvalidateLayout(false, true); // force applyschemesettings to run
  79. }
  80. //-----------------------------------------------------------------------------
  81. // Purpose:
  82. //-----------------------------------------------------------------------------
  83. IImage *ImagePanel::GetImage()
  84. {
  85. return m_pImage;
  86. }
  87. //-----------------------------------------------------------------------------
  88. // Purpose:
  89. //-----------------------------------------------------------------------------
  90. Color ImagePanel::GetDrawColor( void )
  91. {
  92. return m_DrawColor;
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose:
  96. //-----------------------------------------------------------------------------
  97. void ImagePanel::SetDrawColor( Color drawColor )
  98. {
  99. m_DrawColor = drawColor;
  100. }
  101. //-----------------------------------------------------------------------------
  102. // Purpose:
  103. //-----------------------------------------------------------------------------
  104. void ImagePanel::PaintBackground()
  105. {
  106. if (m_FillColor[3] > 0)
  107. {
  108. // draw the specified fill color
  109. int wide, tall;
  110. GetSize(wide, tall);
  111. surface()->DrawSetColor(m_FillColor);
  112. surface()->DrawFilledRect(0, 0, wide, tall);
  113. }
  114. if ( m_pImage )
  115. {
  116. //=============================================================================
  117. // HPE_BEGIN:
  118. // [pfreese] Color should be always set from GetDrawColor(), not just when
  119. // scaling is true (see previous code)
  120. //=============================================================================
  121. // surface()->DrawSetColor( 255, 255, 255, GetAlpha() );
  122. m_pImage->SetColor( GetDrawColor() );
  123. m_pImage->SetRotation( m_iRotation );
  124. //=============================================================================
  125. // HPE_END
  126. //=============================================================================
  127. if ( m_bPositionImage )
  128. {
  129. if ( m_bCenterImage )
  130. {
  131. int wide, tall;
  132. GetSize(wide, tall);
  133. int imageWide, imageTall;
  134. m_pImage->GetSize( imageWide, imageTall );
  135. if ( m_bScaleImage && m_fScaleAmount > 0.0f )
  136. {
  137. imageWide = static_cast<int>( static_cast<float>(imageWide) * m_fScaleAmount );
  138. imageTall = static_cast<int>( static_cast<float>(imageTall) * m_fScaleAmount );
  139. }
  140. m_pImage->SetPos( (wide - imageWide) / 2, (tall - imageTall) / 2 );
  141. }
  142. else
  143. {
  144. m_pImage->SetPos(0, 0);
  145. }
  146. }
  147. if (m_bScaleImage)
  148. {
  149. // Image size is stored in the bitmap, so temporarily set its size
  150. // to our panel size and then restore after we draw it.
  151. int imageWide, imageTall;
  152. m_pImage->GetSize( imageWide, imageTall );
  153. if ( m_fScaleAmount > 0.0f )
  154. {
  155. float wide, tall;
  156. wide = static_cast<float>(imageWide) * m_fScaleAmount;
  157. tall = static_cast<float>(imageTall) * m_fScaleAmount;
  158. m_pImage->SetSize( static_cast<int>(wide), static_cast<int>(tall) );
  159. }
  160. else
  161. {
  162. int wide, tall;
  163. GetSize( wide, tall );
  164. m_pImage->SetSize( wide, tall );
  165. }
  166. m_pImage->Paint();
  167. m_pImage->SetSize( imageWide, imageTall );
  168. }
  169. else if ( m_bTileImage || m_bTileHorizontally || m_bTileVertically )
  170. {
  171. int wide, tall;
  172. GetSize(wide, tall);
  173. int imageWide, imageTall;
  174. m_pImage->GetSize( imageWide, imageTall );
  175. int y = 0;
  176. while ( y < tall )
  177. {
  178. int x = 0;
  179. while (x < wide)
  180. {
  181. m_pImage->SetPos(x,y);
  182. m_pImage->Paint();
  183. x += imageWide;
  184. if ( !m_bTileHorizontally )
  185. break;
  186. }
  187. y += imageTall;
  188. if ( !m_bTileVertically )
  189. break;
  190. }
  191. if ( m_bPositionImage )
  192. {
  193. m_pImage->SetPos(0, 0);
  194. }
  195. }
  196. else
  197. {
  198. m_pImage->SetColor( GetDrawColor() );
  199. m_pImage->Paint();
  200. }
  201. }
  202. }
  203. //-----------------------------------------------------------------------------
  204. // Purpose: Gets control settings for editing
  205. //-----------------------------------------------------------------------------
  206. void ImagePanel::GetSettings(KeyValues *outResourceData)
  207. {
  208. BaseClass::GetSettings(outResourceData);
  209. if (m_pszImageName)
  210. {
  211. outResourceData->SetString("image", m_pszImageName);
  212. }
  213. if (m_pszFillColorName)
  214. {
  215. outResourceData->SetString("fillcolor", m_pszFillColorName);
  216. }
  217. //=============================================================================
  218. // HPE_BEGIN:
  219. // [pfreese] Added support for specifying drawcolor
  220. //=============================================================================
  221. if (m_pszDrawColorName)
  222. {
  223. outResourceData->SetString("drawcolor", m_pszDrawColorName);
  224. }
  225. //=============================================================================
  226. // HPE_END
  227. //=============================================================================
  228. if (GetBorder())
  229. {
  230. outResourceData->SetString("border", GetBorder()->GetName());
  231. }
  232. outResourceData->GetInt("positionImage", m_bPositionImage );
  233. outResourceData->SetInt("scaleImage", m_bScaleImage);
  234. outResourceData->SetFloat("scaleAmount", m_fScaleAmount);
  235. outResourceData->SetInt("tileImage", m_bTileImage);
  236. outResourceData->SetInt("tileHorizontally", m_bTileHorizontally);
  237. outResourceData->SetInt("tileVertically", m_bTileVertically);
  238. }
  239. //-----------------------------------------------------------------------------
  240. // Purpose: Applies designer settings from res file
  241. //-----------------------------------------------------------------------------
  242. void ImagePanel::ApplySettings(KeyValues *inResourceData)
  243. {
  244. delete [] m_pszImageName;
  245. delete [] m_pszFillColorName;
  246. delete [] m_pszDrawColorName; // HPE addition
  247. m_pszImageName = NULL;
  248. m_pszFillColorName = NULL;
  249. m_pszDrawColorName = NULL; // HPE addition
  250. m_bPositionImage = inResourceData->GetInt("positionImage", 1);
  251. m_bScaleImage = inResourceData->GetInt("scaleImage", 0);
  252. m_fScaleAmount = inResourceData->GetFloat("scaleAmount", 0.0f);
  253. m_bTileImage = inResourceData->GetInt("tileImage", 0);
  254. m_bTileHorizontally = inResourceData->GetInt("tileHorizontally", m_bTileImage);
  255. m_bTileVertically = inResourceData->GetInt("tileVertically", m_bTileImage);
  256. m_iRotation = inResourceData->GetInt( "rotation", ROTATED_UNROTATED );
  257. const char *imageName = inResourceData->GetString("image", "");
  258. if ( *imageName )
  259. {
  260. SetImage( imageName );
  261. }
  262. const char *pszFillColor = inResourceData->GetString("fillcolor", "");
  263. if (*pszFillColor)
  264. {
  265. int r = 0, g = 0, b = 0, a = 255;
  266. int len = Q_strlen(pszFillColor) + 1;
  267. m_pszFillColorName = new char[ len ];
  268. Q_strncpy( m_pszFillColorName, pszFillColor, len );
  269. if (sscanf(pszFillColor, "%d %d %d %d", &r, &g, &b, &a) >= 3)
  270. {
  271. // it's a direct color
  272. m_FillColor = Color(r, g, b, a);
  273. }
  274. else
  275. {
  276. IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
  277. m_FillColor = pScheme->GetColor(pszFillColor, Color(0, 0, 0, 0));
  278. }
  279. }
  280. //=============================================================================
  281. // HPE_BEGIN:
  282. // [pfreese] Added support for specifying drawcolor
  283. //=============================================================================
  284. const char *pszDrawColor = inResourceData->GetString("drawcolor", "");
  285. if (*pszDrawColor)
  286. {
  287. int r = 255, g = 255, b = 255, a = 255;
  288. int len = Q_strlen(pszDrawColor) + 1;
  289. m_pszDrawColorName = new char[ len ];
  290. Q_strncpy( m_pszDrawColorName, pszDrawColor, len );
  291. if (sscanf(pszDrawColor, "%d %d %d %d", &r, &g, &b, &a) >= 3)
  292. {
  293. // it's a direct color
  294. m_DrawColor = Color(r, g, b, a);
  295. }
  296. else
  297. {
  298. IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
  299. m_DrawColor = pScheme->GetColor(pszDrawColor, Color(255, 255, 255, 255));
  300. }
  301. }
  302. //=============================================================================
  303. // HPE_END
  304. //=============================================================================
  305. const char *pszBorder = inResourceData->GetString("border", "");
  306. if (*pszBorder)
  307. {
  308. IScheme *pScheme = scheme()->GetIScheme( GetScheme() );
  309. SetBorder(pScheme->GetBorder(pszBorder));
  310. }
  311. BaseClass::ApplySettings(inResourceData);
  312. }
  313. //-----------------------------------------------------------------------------
  314. // Purpose: load the image, this is done just before this control is displayed
  315. //-----------------------------------------------------------------------------
  316. void ImagePanel::ApplySchemeSettings( IScheme *pScheme )
  317. {
  318. BaseClass::ApplySchemeSettings(pScheme);
  319. if ( m_pszImageName && strlen( m_pszImageName ) > 0 )
  320. {
  321. SetImage(scheme()->GetImage(m_pszImageName, m_bScaleImage));
  322. }
  323. }
  324. //-----------------------------------------------------------------------------
  325. // Purpose: Describes editing details
  326. //-----------------------------------------------------------------------------
  327. const char *ImagePanel::GetDescription()
  328. {
  329. static char buf[1024];
  330. _snprintf(buf, sizeof(buf), "%s, string image, string border, string fillcolor, bool scaleImage", BaseClass::GetDescription());
  331. return buf;
  332. }
  333. //-----------------------------------------------------------------------------
  334. // Purpose: sets whether or not the image should scale to fit the size of the ImagePanel (defaults to false)
  335. //-----------------------------------------------------------------------------
  336. void ImagePanel::SetShouldScaleImage( bool state )
  337. {
  338. m_bScaleImage = state;
  339. }
  340. //-----------------------------------------------------------------------------
  341. // Purpose: gets whether or not the image should be scaled to fit the size of the ImagePanel
  342. //-----------------------------------------------------------------------------
  343. bool ImagePanel::GetShouldScaleImage()
  344. {
  345. return m_bScaleImage;
  346. }
  347. //-----------------------------------------------------------------------------
  348. // Purpose: used in conjunction with setting that the image should scale and defines an absolute scale amount
  349. //-----------------------------------------------------------------------------
  350. void ImagePanel::SetScaleAmount( float scale )
  351. {
  352. m_fScaleAmount = scale;
  353. }
  354. float ImagePanel::GetScaleAmount( void )
  355. {
  356. return m_fScaleAmount;
  357. }
  358. //-----------------------------------------------------------------------------
  359. // Purpose: set the color to fill with, if no Image is specified
  360. //-----------------------------------------------------------------------------
  361. void ImagePanel::SetFillColor( Color col )
  362. {
  363. m_FillColor = col;
  364. }
  365. //-----------------------------------------------------------------------------
  366. // Purpose: data accessor
  367. //-----------------------------------------------------------------------------
  368. Color ImagePanel::GetFillColor()
  369. {
  370. return m_FillColor;
  371. }
  372. char *ImagePanel::GetImageName()
  373. {
  374. return m_pszImageName;
  375. }
  376. bool ImagePanel::EvictImage()
  377. {
  378. if ( !m_pImage )
  379. {
  380. // nothing to do
  381. return false;
  382. }
  383. if ( !scheme()->DeleteImage( m_pszImageName ) )
  384. {
  385. // no eviction occured, could have an outstanding reference
  386. return false;
  387. }
  388. // clear out our cached concept of it
  389. // as it may change
  390. // the next SetImage() will re-establish
  391. m_pImage = NULL;
  392. delete [] m_pszImageName;
  393. m_pszImageName = NULL;
  394. return true;
  395. }
  396. int ImagePanel::GetNumFrames()
  397. {
  398. if ( !m_pImage )
  399. {
  400. return 0;
  401. }
  402. return m_pImage->GetNumFrames();
  403. }
  404. void ImagePanel::SetFrame( int nFrame )
  405. {
  406. if ( !m_pImage )
  407. {
  408. return;
  409. }
  410. return m_pImage->SetFrame( nFrame );
  411. }