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.

280 lines
7.3 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: Handles the selection of faces and material application.
  4. //
  5. // TODO: consider making face selection a mode of the selection tool
  6. //
  7. // $NoKeywords: $
  8. //=============================================================================//
  9. #include "stdafx.h"
  10. #include "FaceEditSheet.h"
  11. #include "History.h"
  12. #include "MainFrm.h"
  13. #include "MapDoc.h"
  14. #include "MapSolid.h"
  15. #include "MapView2D.h"
  16. #include "MapView3D.h"
  17. #include "StatusBarIDs.h"
  18. #include "ToolManager.h"
  19. #include "ToolMaterial.h"
  20. #include "Options.h"
  21. // memdbgon must be the last include file in a .cpp file!!!
  22. #include <tier0/memdbgon.h>
  23. //-----------------------------------------------------------------------------
  24. // Purpose: Called when this tool is deactivated in favor of another tool.
  25. // Input : eNewTool - The tool that is being activated.
  26. //-----------------------------------------------------------------------------
  27. void CToolMaterial::OnDeactivate()
  28. {
  29. if ( m_pDocument->GetTools()->GetActiveToolID() != TOOL_FACEEDIT_DISP )
  30. {
  31. // Clear the selected faces when we are deactivated.
  32. m_pDocument->SelectFace(NULL, 0, scClear );
  33. }
  34. }
  35. //-----------------------------------------------------------------------------
  36. // Purpose:
  37. // Input : pView -
  38. // nFlags -
  39. // point -
  40. // Output : Returns true if the message was handled, false if not.
  41. //-----------------------------------------------------------------------------
  42. bool CToolMaterial::OnLMouseDown2D(CMapView2D *pView, UINT nFlags, const Vector2D &vPoint)
  43. {
  44. if (nFlags & MK_CONTROL)
  45. {
  46. //
  47. // CONTROL is down, perform selection only.
  48. //
  49. pView->SelectAt( vPoint, false, true);
  50. }
  51. else
  52. {
  53. pView->SelectAt( vPoint, true, true);
  54. }
  55. return (true);
  56. }
  57. //-----------------------------------------------------------------------------
  58. // Purpose: Handles left mouse button down events in the 3D view.
  59. // Input : Per CWnd::OnLButtonDown.
  60. // Output : Returns true if the message was handled, false if not.
  61. //-----------------------------------------------------------------------------
  62. bool CToolMaterial::OnLMouseDown3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
  63. {
  64. CMapDoc *pDoc = pView->GetMapDoc();
  65. if (pDoc == NULL)
  66. {
  67. return false;
  68. }
  69. bool bShift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0);
  70. ULONG ulFace;
  71. CMapClass *pObject = pView->NearestObjectAt( vPoint, ulFace);
  72. if ((pObject != NULL) && (pObject->IsMapClass(MAPCLASS_TYPE(CMapSolid))))
  73. {
  74. CMapSolid *pSolid = (CMapSolid *)pObject;
  75. int cmd = scToggle | scClear;
  76. // No clear if CTRL pressed.
  77. if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
  78. {
  79. cmd &= ~scClear;
  80. }
  81. // If they are holding down SHIFT, select the entire solid.
  82. if (bShift)
  83. {
  84. pDoc->SelectFace(pSolid, -1, cmd);
  85. }
  86. // Otherwise, select a single face.
  87. else
  88. {
  89. pDoc->SelectFace(pSolid, ulFace, cmd);
  90. }
  91. }
  92. return true;
  93. }
  94. //-----------------------------------------------------------------------------
  95. // Purpose: Handles right mouse button down events in the 3D view.
  96. // Input : Per CWnd::OnRButtonDown.
  97. // Output : Returns true if the message was handled, false if not.
  98. //-----------------------------------------------------------------------------
  99. bool CToolMaterial::OnRMouseDown3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
  100. {
  101. BOOL bShift = ((GetAsyncKeyState(VK_SHIFT) & 0x8000) != 0);
  102. BOOL bEdgeAlign = ((GetAsyncKeyState(VK_MENU) & 0x8000) != 0);
  103. ULONG ulFace;
  104. CMapClass *pObject = pView->NearestObjectAt( vPoint, ulFace);
  105. if (pObject != NULL)
  106. {
  107. if (pObject->IsMapClass(MAPCLASS_TYPE(CMapSolid)))
  108. {
  109. CMapSolid *pSolid = (CMapSolid *)pObject;
  110. GetHistory()->MarkUndoPosition(NULL, "Apply texture");
  111. GetHistory()->Keep(pSolid);
  112. // Setup the flags.
  113. int cmdFlags = 0;
  114. if (bEdgeAlign)
  115. {
  116. cmdFlags |= CFaceEditSheet::cfEdgeAlign;
  117. }
  118. // If we're in a lightmap grid preview window, only apply the lightmap scale.
  119. int eMode;
  120. if (pView->GetDrawType() == VIEW3D_LIGHTMAP_GRID)
  121. {
  122. eMode = CFaceEditSheet::ModeApplyLightmapScale;
  123. }
  124. else
  125. {
  126. eMode = CFaceEditSheet::ModeApplyAll;
  127. }
  128. // If they are holding down the shift key, apply to the entire solid.
  129. if (bShift)
  130. {
  131. int nFaces = pSolid->GetFaceCount();
  132. for(int i = 0; i < nFaces; i++)
  133. {
  134. GetMainWnd()->m_pFaceEditSheet->ClickFace(pSolid, i, cmdFlags, eMode);
  135. }
  136. }
  137. // If not, apply to a single face.
  138. else
  139. {
  140. GetMainWnd()->m_pFaceEditSheet->ClickFace(pSolid, ulFace, cmdFlags, eMode);
  141. }
  142. }
  143. }
  144. return true;
  145. }
  146. //-----------------------------------------------------------------------------
  147. // Purpose: Handles the mouse move message in the 3D view.
  148. // Input : Per CWnd::OnMouseMove.
  149. //-----------------------------------------------------------------------------
  150. bool CToolMaterial::OnMouseMove3D(CMapView3D *pView, UINT nFlags, const Vector2D &vPoint)
  151. {
  152. //
  153. // Manage the cursor.
  154. //
  155. static HCURSOR hcurFacePaint = 0;
  156. if (!hcurFacePaint)
  157. {
  158. hcurFacePaint = LoadCursor(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDC_FACEPAINT));
  159. }
  160. SetCursor(hcurFacePaint);
  161. return true;
  162. }
  163. //-----------------------------------------------------------------------------
  164. // Purpose:
  165. //-----------------------------------------------------------------------------
  166. void CToolMaterial::UpdateStatusBar()
  167. {
  168. CString str;
  169. str.Format("%d faces selected", GetMainWnd()->m_pFaceEditSheet->GetFaceListCount() );
  170. SetStatusText(SBI_SELECTION, str);
  171. SetStatusText(SBI_SIZE, "");
  172. }
  173. //-----------------------------------------------------------------------------
  174. // Purpose: Handles the key down event in the 3D view.
  175. // Input : Per CWnd::OnKeyDown.
  176. // Output : Returns true if the message was handled, false if not.
  177. //-----------------------------------------------------------------------------
  178. bool CToolMaterial::OnKeyDown3D( CMapView3D *pView, UINT nChar, UINT nRepCnt, UINT nFlags )
  179. {
  180. // TO DO: undo?
  181. // justify (SHIFT?)
  182. CMapDoc *pDoc = pView->GetMapDoc();
  183. if ( pDoc == NULL )
  184. {
  185. return false;
  186. }
  187. if ( nChar == VK_UP || nChar == VK_DOWN || nChar == VK_LEFT || nChar == VK_RIGHT )
  188. {
  189. // Bail out if the user doesn't have Nudging enabled.
  190. if ( !Options.view2d.bNudge )
  191. {
  192. return false;
  193. }
  194. CFaceEditSheet *pSheet = GetMainWnd()->m_pFaceEditSheet;
  195. if( pSheet )
  196. {
  197. // Check for a face list.
  198. int nFaceCount = pSheet->GetFaceListCount();
  199. if( nFaceCount == 0 )
  200. {
  201. return false;
  202. }
  203. int nGridSize = m_pDocument->GetGridSpacing();
  204. bool bCtrlDown = ( ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) != 0 );
  205. if ( bCtrlDown )
  206. {
  207. nGridSize = 1;
  208. }
  209. for( int ndxface = 0; ndxface < nFaceCount; ndxface++ )
  210. {
  211. CMapFace *pFace;
  212. pFace = pSheet->GetFaceListDataFace( ndxface );
  213. TEXTURE &t = pFace->texture;
  214. if ( nChar == VK_UP )
  215. {
  216. t.VAxis[ 3 ] = ( (int)( t.VAxis[ 3 ] + nGridSize ) % 1024 );
  217. }
  218. else if ( nChar == VK_DOWN )
  219. {
  220. t.VAxis[ 3 ] = ( (int)( t.VAxis[ 3 ] - nGridSize ) % 1024 );
  221. }
  222. else if ( nChar == VK_LEFT )
  223. {
  224. t.UAxis[ 3 ] = ( (int)( t.UAxis[ 3 ] + nGridSize ) % 1024 );
  225. }
  226. else
  227. {
  228. t.UAxis[ 3 ] = ( (int)( t.UAxis[ 3 ] - nGridSize ) % 1024 );
  229. }
  230. pFace->CalcTextureCoords();
  231. pSheet->m_MaterialPage.UpdateDialogData( pFace );
  232. }
  233. pDoc->SetModifiedFlag();
  234. return true;
  235. }
  236. }
  237. return false;
  238. }