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.

442 lines
11 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include "stdafx.h"
  7. #include "hammer.h"
  8. #include "TextureBar.h"
  9. #include "ControlBarIDs.h"
  10. #include "StockSolids.h"
  11. #include "MainFrm.h"
  12. #include "MapDoc.h"
  13. #include "GlobalFunctions.h"
  14. #include "History.h"
  15. #include "IEditorTexture.h"
  16. #include "Options.h"
  17. #include "ReplaceTexDlg.h"
  18. #include "TextureBrowser.h"
  19. #include "TextureSystem.h"
  20. #include "Selection.h"
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include <tier0/memdbgon.h>
  23. BEGIN_MESSAGE_MAP(CTextureBar, CHammerBar)
  24. ON_CBN_SELCHANGE(IDC_TEXTURES, OnSelChangeTexture)
  25. ON_UPDATE_COMMAND_UI(IDC_TEXTURES, UpdateControl)
  26. ON_CBN_SELCHANGE(IDC_TEXTUREGROUPS, OnChangeTextureGroup)
  27. ON_UPDATE_COMMAND_UI(IDC_TEXTUREGROUPS, UpdateControl)
  28. ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
  29. ON_UPDATE_COMMAND_UI(IDC_BROWSE, UpdateControl)
  30. ON_BN_CLICKED(IDC_REPLACE, OnReplace)
  31. ON_UPDATE_COMMAND_UI(IDC_REPLACE, UpdateControl)
  32. ON_WM_WINDOWPOSCHANGED()
  33. END_MESSAGE_MAP()
  34. static char szDefaultTexture[128];
  35. static char szNullTexture[128] = {"editor/obsolete"};
  36. //-----------------------------------------------------------------------------
  37. // Purpose:
  38. // Output : LPCTSTR
  39. //-----------------------------------------------------------------------------
  40. void SetDefaultTextureName( const char *szTexName )
  41. {
  42. int length = strlen( szTexName );
  43. Assert( length < 128 );
  44. strcpy( szDefaultTexture, szTexName );
  45. }
  46. //-----------------------------------------------------------------------------
  47. // Purpose:
  48. // Output : LPCTSTR
  49. //-----------------------------------------------------------------------------
  50. LPCTSTR GetDefaultTextureName(void)
  51. {
  52. return szDefaultTexture;
  53. }
  54. //-----------------------------------------------------------------------------
  55. // Purpose:
  56. // Output : LPCTSTR
  57. //-----------------------------------------------------------------------------
  58. LPCTSTR GetNullTextureName()
  59. {
  60. return szNullTexture;
  61. }
  62. //-----------------------------------------------------------------------------
  63. // Purpose:
  64. // Input : *pParentWnd -
  65. // IDD -
  66. // iBarID -
  67. // Output : Returns TRUE on success, FALSE on failure.
  68. //-----------------------------------------------------------------------------
  69. BOOL CTextureBar::Create(CWnd *pParentWnd, int IDD, int iBarID)
  70. {
  71. m_pCurTex = NULL;
  72. if (!CHammerBar::Create(pParentWnd, IDD, CBRS_RIGHT, iBarID))
  73. {
  74. return(FALSE);
  75. }
  76. SetWindowText("Textures");
  77. // set up controls
  78. m_TextureGroupList.SubclassDlgItem(IDC_TEXTUREGROUPS, this);
  79. m_TextureList.SubclassDlgItem(IDC_TEXTURES, this);
  80. m_TexturePic.SubclassDlgItem(IDC_TEXTUREPIC, this);
  81. NotifyGraphicsChanged();
  82. UpdateTexture();
  83. return(TRUE);
  84. }
  85. //-----------------------------------------------------------------------------
  86. // Purpose:
  87. //-----------------------------------------------------------------------------
  88. void CTextureBar::NotifyGraphicsChanged()
  89. {
  90. if (!IsWindow(m_hWnd))
  91. {
  92. return;
  93. }
  94. // load groups into group list
  95. CString str;
  96. int iCurSel = m_TextureGroupList.GetCurSel();
  97. if (iCurSel != LB_ERR)
  98. {
  99. m_TextureGroupList.GetLBText(iCurSel, str);
  100. }
  101. m_TextureGroupList.SetRedraw(FALSE);
  102. m_TextureGroupList.ResetContent();
  103. m_TextureGroupList.AddString("All Textures");
  104. int nCount = g_Textures.GroupsGetCount();
  105. if (nCount > 1)
  106. {
  107. //
  108. // Skip first group ("All Textures").
  109. //
  110. for (int i = 1; i < nCount; i++)
  111. {
  112. CTextureGroup *pGroup = g_Textures.GroupsGet(i);
  113. if (pGroup->GetTextureFormat() == g_pGameConfig->GetTextureFormat())
  114. {
  115. const char *p = strstr(pGroup->GetName(), "textures\\");
  116. if (p)
  117. {
  118. p += strlen("textures\\");
  119. }
  120. else
  121. {
  122. p = pGroup->GetName();
  123. }
  124. m_TextureGroupList.AddString(p);
  125. }
  126. }
  127. }
  128. m_TextureGroupList.SetRedraw(TRUE);
  129. if (iCurSel == LB_ERR || m_TextureGroupList.SelectString(-1, str) == LB_ERR)
  130. {
  131. m_TextureGroupList.SetCurSel(0);
  132. }
  133. m_TextureGroupList.Invalidate();
  134. char szName[MAX_PATH];
  135. m_TextureGroupList.GetLBText(m_TextureGroupList.GetCurSel(), szName);
  136. g_Textures.SetActiveGroup(szName);
  137. //
  138. // This is called when the loaded graphics list is changed,
  139. // or on first init by this->Create().
  140. //
  141. m_TextureList.LoadGraphicList();
  142. UpdateTexture();
  143. }
  144. void CTextureBar::NotifyNewMaterial( IEditorTexture *pTex )
  145. {
  146. m_TextureList.NotifyNewMaterial( pTex );
  147. }
  148. //-----------------------------------------------------------------------------
  149. // Purpose: Disables the dialog controls when there's no active document.
  150. // Input : pCmdUI - Interface to control being updated.
  151. //-----------------------------------------------------------------------------
  152. void CTextureBar::UpdateControl(CCmdUI *pCmdUI)
  153. {
  154. pCmdUI->Enable(CMapDoc::GetActiveMapDoc() ? TRUE : FALSE);
  155. }
  156. //-----------------------------------------------------------------------------
  157. // Purpose: Handles user-initiated selection changes. Updates the control state
  158. // and adds the selected texture to the MRU list.
  159. //-----------------------------------------------------------------------------
  160. void CTextureBar::OnSelChangeTexture(void)
  161. {
  162. UpdateTexture();
  163. if (m_pCurTex != NULL)
  164. {
  165. m_TextureList.AddMRU(m_pCurTex);
  166. }
  167. }
  168. //-----------------------------------------------------------------------------
  169. // Purpose: Updates the m_pTexture data member based on the current selection.
  170. // Also updates the window text and the texture picture.
  171. //-----------------------------------------------------------------------------
  172. void CTextureBar::UpdateTexture(void)
  173. {
  174. int iSel = m_TextureList.GetCurSel();
  175. if (iSel == LB_ERR)
  176. {
  177. m_TexturePic.SetTexture(NULL);
  178. m_pCurTex = NULL;
  179. return;
  180. }
  181. m_pCurTex = (IEditorTexture *)m_TextureList.GetItemDataPtr(iSel);
  182. m_TexturePic.SetTexture(m_pCurTex);
  183. if (m_pCurTex)
  184. {
  185. // Make sure the current material is loaded..
  186. m_pCurTex->Load();
  187. char szBuf[128];
  188. sprintf(szBuf, "%dx%d", m_pCurTex->GetWidth(), m_pCurTex->GetHeight());
  189. GetDlgItem(IDC_TEXTURESIZE)->SetWindowText(szBuf);
  190. m_pCurTex->GetShortName(szDefaultTexture);
  191. }
  192. }
  193. //-----------------------------------------------------------------------------
  194. // Purpose:
  195. //-----------------------------------------------------------------------------
  196. void CTextureBar::OnUpdateTexname(void)
  197. {
  198. // get texture window and set texture in there
  199. CString strTex;
  200. m_TextureList.GetWindowText(strTex);
  201. IEditorTexture *pTex = g_Textures.FindActiveTexture(strTex);
  202. m_TexturePic.SetTexture(pTex);
  203. }
  204. //-----------------------------------------------------------------------------
  205. // Purpose:
  206. //-----------------------------------------------------------------------------
  207. void CTextureBar::OnChangeTextureGroup(void)
  208. {
  209. int iGroup = m_TextureGroupList.GetCurSel();
  210. //
  211. // Set the active texture group by name.
  212. //
  213. char szName[MAX_PATH];
  214. m_TextureGroupList.GetLBText(iGroup, szName);
  215. g_Textures.SetActiveGroup(szName);
  216. //
  217. // Refresh the texture list contents.
  218. //
  219. m_TextureList.LoadGraphicList();
  220. }
  221. //-----------------------------------------------------------------------------
  222. // Purpose:
  223. //-----------------------------------------------------------------------------
  224. void CTextureBar::OnBrowse(void)
  225. {
  226. CTextureBrowser *pBrowser = GetMainWnd()->pTextureBrowser;
  227. int iSel = m_TextureList.GetCurSel();
  228. if (iSel != LB_ERR)
  229. {
  230. IEditorTexture *pTex = (IEditorTexture *)m_TextureList.GetItemDataPtr(iSel);
  231. if (pTex != NULL)
  232. {
  233. char sz[128];
  234. pTex->GetShortName(sz);
  235. pBrowser->SetInitialTexture(sz);
  236. }
  237. }
  238. if (pBrowser->DoModal() == IDOK)
  239. {
  240. IEditorTexture *pTex = g_Textures.FindActiveTexture(pBrowser->m_cTextureWindow.szCurTexture);
  241. if (pTex != NULL)
  242. {
  243. int iCount = m_TextureList.GetCount();
  244. for (int i = 0; i < iCount; i++)
  245. {
  246. if (pTex == (IEditorTexture *)m_TextureList.GetItemDataPtr(i))
  247. {
  248. m_TextureList.SetCurSel(i);
  249. UpdateTexture();
  250. m_TextureList.AddMRU(pTex);
  251. break;
  252. }
  253. }
  254. }
  255. }
  256. }
  257. //-----------------------------------------------------------------------------
  258. // Purpose: Handles being shown or hidden.
  259. // Input : pPos - Information about show or hide state.
  260. //-----------------------------------------------------------------------------
  261. void CTextureBar::OnWindowPosChanged(WINDOWPOS *pPos)
  262. {
  263. if (GetMainWnd() != NULL)
  264. {
  265. //
  266. // Rebuild our MRU list if we are being shown, because it may
  267. // have changed since we were shown last.
  268. //
  269. if (pPos->flags & SWP_SHOWWINDOW)
  270. {
  271. m_TextureList.RebuildMRU();
  272. UpdateTexture();
  273. }
  274. }
  275. CHammerBar::OnWindowPosChanged(pPos);
  276. }
  277. //-----------------------------------------------------------------------------
  278. // Purpose: Invokes the texture replace dialog.
  279. //-----------------------------------------------------------------------------
  280. void CTextureBar::OnReplace(void)
  281. {
  282. CMapDoc *pDoc = CMapDoc::GetActiveMapDoc();
  283. if (!pDoc)
  284. {
  285. return;
  286. }
  287. CReplaceTexDlg dlg(pDoc->GetSelection()->GetCount());
  288. dlg.m_strFind = GetDefaultTextureName();
  289. if (dlg.DoModal() != IDOK)
  290. {
  291. return;
  292. }
  293. GetHistory()->MarkUndoPosition(pDoc->GetSelection()->GetList(), "Replace Textures");
  294. dlg.DoReplaceTextures();
  295. }
  296. //-----------------------------------------------------------------------------
  297. // Purpose: Selects a texture by name.
  298. // Input : pszTextureName - Texture name to select.
  299. //-----------------------------------------------------------------------------
  300. void CTextureBar::SelectTexture(LPCSTR pszTextureName)
  301. {
  302. int nIndex = m_TextureList.SelectString(-1, pszTextureName);
  303. //
  304. // If the texture is not in the list, add it to the list.
  305. //
  306. if (nIndex == LB_ERR)
  307. {
  308. IEditorTexture *pTex = g_Textures.FindActiveTexture(pszTextureName);
  309. if (pTex != NULL)
  310. {
  311. nIndex = m_TextureList.AddString(pszTextureName);
  312. m_TextureList.SetItemDataPtr(nIndex, pTex);
  313. m_TextureList.SetCurSel(nIndex);
  314. }
  315. }
  316. UpdateTexture();
  317. if (nIndex != LB_ERR)
  318. {
  319. IEditorTexture *pTex = (IEditorTexture *)m_TextureList.GetItemDataPtr(nIndex);
  320. m_TextureList.AddMRU(pTex);
  321. }
  322. }
  323. //-----------------------------------------------------------------------------
  324. // This class renders a given IEditorTexture in its OnPaint handler. It is used in the
  325. // texture Find/Replace dialog, the Face Properties dialog, and the texture bar.
  326. //-----------------------------------------------------------------------------
  327. BEGIN_MESSAGE_MAP(wndTex, CStatic)
  328. ON_WM_PAINT()
  329. END_MESSAGE_MAP()
  330. //-----------------------------------------------------------------------------
  331. // Purpose: Sets the texture to render in the window.
  332. // Input : pTex - Texture to render when painting this window.
  333. //-----------------------------------------------------------------------------
  334. void wndTex::SetTexture(IEditorTexture *pTex)
  335. {
  336. m_pTexture = pTex;
  337. Invalidate();
  338. }
  339. //-----------------------------------------------------------------------------
  340. // Purpose: Paints the texture image (if any) in the window. If not, just fills
  341. // with gray.
  342. //-----------------------------------------------------------------------------
  343. void wndTex::OnPaint(void)
  344. {
  345. // texturewindow.cpp:
  346. CPaintDC dc(this);
  347. CRect r;
  348. GetClientRect(r);
  349. if (!m_pTexture)
  350. {
  351. FillRect(dc.m_hDC, r, HBRUSH(GetStockObject(BLACK_BRUSH)));
  352. return;
  353. }
  354. m_pTexture->Load();
  355. DrawTexData_t DrawTexData;
  356. DrawTexData.nFlags = drawResizeAlways;
  357. dc.SelectPalette(m_pTexture->HasPalette() ? m_pTexture->GetPalette() : g_pGameConfig->Palette, FALSE);
  358. dc.RealizePalette();
  359. m_pTexture->Draw(&dc, r, 0, 0, DrawTexData);
  360. }