TextureMgrDialog.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : LevelEdit *
  23. * *
  24. * $Archive:: /Commando/Code/Tools/W3DView/TextureMgrDialog.cpp $*
  25. * *
  26. * Author:: Patrick Smith *
  27. * *
  28. * $Modtime:: 3/01/01 3:16p $*
  29. * *
  30. * $Revision:: 4 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "StdAfx.H"
  36. #include "W3DView.H"
  37. #include "TextureMgrDialog.H"
  38. #include "Mesh.H"
  39. #include "MatInfo.H"
  40. #include "TextureSettingsDialog.H"
  41. #include "AssetMgr.H"
  42. #include "texture.h"
  43. #ifdef _DEBUG
  44. #define new DEBUG_NEW
  45. #undef THIS_FILE
  46. static char THIS_FILE[] = __FILE__;
  47. #endif
  48. #ifdef WW3D_DX8
  49. /////////////////////////////////////////////////////////////////////////////
  50. //
  51. // Local constants
  52. //
  53. const int TEXTURE_THUMB_X = 96;
  54. const int TEXTURE_THUMB_Y = 96;
  55. const int TEXTURE_THUMBSMALL_X = 48;
  56. const int TEXTURE_THUMBSMALL_Y = 48;
  57. const int COL_NAME = 0;
  58. const int COL_TEXTURES = 1;
  59. const int COL_DIMENSIONS = 1;
  60. const int COL_TEXTURE_TYPE = 2;
  61. /////////////////////////////////////////////////////////////////////////////
  62. //
  63. // TextureMgrDialogClass
  64. //
  65. TextureMgrDialogClass::TextureMgrDialogClass
  66. (
  67. RenderObjClass *pbase_model,
  68. CWnd *pParent
  69. )
  70. : m_pBaseModel (pbase_model),
  71. m_bContainsMeshes (true),
  72. m_pImageList (NULL),
  73. m_pImageListSmall (NULL),
  74. m_pTextureImageList (NULL),
  75. m_pTextureImageListSmall (NULL),
  76. CDialog (TextureMgrDialogClass::IDD, pParent)
  77. {
  78. //{{AFX_DATA_INIT(TextureMgrDialogClass)
  79. // NOTE: the ClassWizard will add member initialization here
  80. //}}AFX_DATA_INIT
  81. return ;
  82. }
  83. /////////////////////////////////////////////////////////////////////////////
  84. //
  85. // DoDataExchange
  86. //
  87. void
  88. TextureMgrDialogClass::DoDataExchange (CDataExchange *pDX)
  89. {
  90. CDialog::DoDataExchange(pDX);
  91. //{{AFX_DATA_MAP(TextureMgrDialogClass)
  92. DDX_Control(pDX, IDC_MESH_TEXTURE_LIST_CTRL, m_ListCtrl);
  93. //}}AFX_DATA_MAP
  94. return ;
  95. }
  96. BEGIN_MESSAGE_MAP(TextureMgrDialogClass, CDialog)
  97. //{{AFX_MSG_MAP(TextureMgrDialogClass)
  98. ON_NOTIFY(NM_DBLCLK, IDC_MESH_TEXTURE_LIST_CTRL, OnDblclkMeshTextureListCtrl)
  99. ON_NOTIFY(LVN_KEYDOWN, IDC_MESH_TEXTURE_LIST_CTRL, OnKeydownMeshTextureListCtrl)
  100. ON_WM_DESTROY()
  101. ON_COMMAND(IDC_BACK, OnBack)
  102. ON_COMMAND(IDC_DETAILS, OnDetails)
  103. ON_COMMAND(IDC_LARGE, OnLarge)
  104. ON_COMMAND(IDC_LIST, OnList)
  105. ON_COMMAND(IDC_SMALL, OnSmall)
  106. ON_COMMAND(IDC_PROPAGATE, OnPropagate)
  107. //}}AFX_MSG_MAP
  108. END_MESSAGE_MAP()
  109. /////////////////////////////////////////////////////////////////////////////
  110. //
  111. // Fill_List_Ctrl_With_Meshes
  112. //
  113. void
  114. TextureMgrDialogClass::Fill_List_Ctrl_With_Meshes (void)
  115. {
  116. m_ListCtrl.DeleteAllItems ();
  117. m_ListCtrl.SetImageList (m_pImageList, LVSIL_NORMAL);
  118. m_ListCtrl.SetImageList (m_pImageListSmall, LVSIL_SMALL);
  119. m_ListCtrl.DeleteColumn (COL_TEXTURE_TYPE);
  120. m_ListCtrl.DeleteColumn (COL_DIMENSIONS);
  121. // Add the textures column
  122. CRect rect;
  123. m_ListCtrl.GetClientRect (&rect);
  124. m_ListCtrl.InsertColumn (COL_TEXTURES, "Textures", LVCFMT_LEFT, (rect.Width () / 2) - 20);
  125. // Loop through the list of mesh's and add them to the list control
  126. for (int index = 0; index < m_NodeList.Count (); index ++) {
  127. // Add this mesh to the list control
  128. TextureListNodeClass *pnode = m_NodeList[index];
  129. int list_index = m_ListCtrl.InsertItem (0, pnode->Get_Name (), pnode->Get_Icon_Index ());
  130. if (list_index != -1) {
  131. // Insert the texture count in the second column
  132. CString texture_string;
  133. texture_string.Format ("%d textures", pnode->Get_Subobj_List ().Count ());
  134. if (pnode->Get_Subobj_List ().Count () == 1) {
  135. texture_string = "1 texture";
  136. }
  137. m_ListCtrl.SetItemText (list_index, COL_TEXTURES, texture_string);
  138. // Associate the node with the list entry
  139. m_ListCtrl.SetItemData (list_index, (DWORD)pnode);
  140. }
  141. }
  142. m_bContainsMeshes = true;
  143. m_Toolbar.Enable_Button (IDC_BACK, false);
  144. m_Toolbar.Enable_Button (IDC_PROPAGATE, true);
  145. return ;
  146. }
  147. /////////////////////////////////////////////////////////////////////////////
  148. //
  149. // Fill_List_Ctrl_With_Textures
  150. //
  151. void
  152. TextureMgrDialogClass::Fill_List_Ctrl_With_Textures (TextureListNodeClass &parent_node)
  153. {
  154. m_ListCtrl.DeleteAllItems ();
  155. m_ListCtrl.SetImageList (m_pTextureImageList, LVSIL_NORMAL);
  156. m_ListCtrl.SetImageList (m_pTextureImageListSmall, LVSIL_SMALL);
  157. m_ListCtrl.DeleteColumn (COL_TEXTURES);
  158. // Add the textures column
  159. CRect rect;
  160. m_ListCtrl.GetClientRect (&rect);
  161. m_ListCtrl.InsertColumn (COL_DIMENSIONS, "Dimensions", LVCFMT_LEFT, (rect.Width () / 4) - 10);
  162. m_ListCtrl.InsertColumn (COL_TEXTURE_TYPE, "Texture Type", LVCFMT_LEFT, (rect.Width () / 4) - 10);
  163. // Loop through the list of textures and add them to the list control
  164. TEXTURE_NODE_LIST &node_list = parent_node.Get_Subobj_List ();
  165. for (int index = 0; index < node_list.Count (); index ++) {
  166. // Add this mesh to the list control
  167. TextureListNodeClass *pnode = node_list[index];
  168. int list_index = m_ListCtrl.InsertItem (0, pnode->Get_Name (), pnode->Get_Icon_Index ());
  169. Insert_Texture_Details (pnode, list_index);
  170. }
  171. m_bContainsMeshes = false;
  172. m_Toolbar.Enable_Button (IDC_BACK, true);
  173. m_Toolbar.Enable_Button (IDC_PROPAGATE, false);
  174. return ;
  175. }
  176. /////////////////////////////////////////////////////////////////////////////
  177. //
  178. // OnInitDialog
  179. //
  180. BOOL
  181. TextureMgrDialogClass::OnInitDialog (void)
  182. {
  183. CWaitCursor wait_cursor;
  184. // Allow the base class to process this message
  185. CDialog::OnInitDialog ();
  186. m_ListCtrl.SetExtendedStyle (LVS_EX_FULLROWSELECT);
  187. m_Toolbar.CreateEx (this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect(0, 0, 0, 0), 101);
  188. m_Toolbar.SetOwner (this);
  189. m_Toolbar.LoadToolBar (IDR_INSTANCES_TOOLBAR);
  190. m_Toolbar.SetBarStyle (m_Toolbar.GetBarStyle () | CBRS_TOOLTIPS | CBRS_FLYBY);
  191. // Get the bounding rectangle of the form window
  192. CRect rect;
  193. ::GetWindowRect (::GetDlgItem (m_hWnd, IDC_TOOLBAR_SLOT), &rect);
  194. ScreenToClient (&rect);
  195. m_Toolbar.SetWindowPos (NULL, rect.left, rect.top, rect.Width (), rect.Height (), SWP_NOZORDER);
  196. ASSERT (m_pBaseModel != NULL);
  197. // Create an icon imagelist for the tree control
  198. m_pImageList = new CImageList;
  199. m_pImageListSmall = new CImageList;
  200. m_pTextureImageList = new CImageList;
  201. m_pTextureImageListSmall = new CImageList;
  202. m_pImageList->Create (32, 32, ILC_COLOR | ILC_MASK, 1, 2);
  203. m_pImageListSmall->Create (16, 16, ILC_COLOR | ILC_MASK, 1, 2);
  204. m_pTextureImageList->Create (TEXTURE_THUMB_X, TEXTURE_THUMB_Y, ILC_COLOR24, 10, 20);
  205. m_pTextureImageListSmall->Create (TEXTURE_THUMBSMALL_X, TEXTURE_THUMBSMALL_Y, ILC_COLOR24, 10, 20);
  206. // Load this icon and add it to our imagelist
  207. m_pImageList->Add ((HICON)::LoadImage (::AfxGetResourceHandle (),
  208. MAKEINTRESOURCE (IDI_MESH_FOLDER),
  209. IMAGE_ICON,
  210. 32,
  211. 32,
  212. LR_SHARED));
  213. // Load this icon and add it to our imagelist
  214. m_pImageListSmall->Add ((HICON)::LoadImage (::AfxGetResourceHandle (),
  215. MAKEINTRESOURCE (IDI_MESH_FOLDER),
  216. IMAGE_ICON,
  217. 16,
  218. 16,
  219. LR_SHARED));
  220. // Add the name column to the list control
  221. m_ListCtrl.GetClientRect (&rect);
  222. m_ListCtrl.InsertColumn (COL_NAME, "Name", LVCFMT_LEFT, (rect.Width () / 2) - 20);
  223. // Build a list of mesh's and textures
  224. Add_Subobjs_To_List (m_pBaseModel);
  225. Fill_List_Ctrl_With_Meshes ();
  226. return TRUE;
  227. }
  228. /////////////////////////////////////////////////////////////////////////////
  229. //
  230. // Add_Subobjs_To_List
  231. //
  232. void
  233. TextureMgrDialogClass::Add_Subobjs_To_List (RenderObjClass *prender_obj)
  234. {
  235. // Loop through all the subobjs in this render object
  236. int subobj_count = prender_obj->Get_Num_Sub_Objects ();
  237. for (int index = 0; index < subobj_count; index ++) {
  238. // Get a pointer to this subobject
  239. RenderObjClass *psubobj = prender_obj->Get_Sub_Object (index);
  240. if (psubobj != NULL) {
  241. // Recursively add subobjs to the list
  242. Add_Subobjs_To_List (psubobj);
  243. MEMBER_RELEASE (psubobj);
  244. }
  245. }
  246. // If this is a mesh, then add it to the list
  247. if (prender_obj->Class_ID () == RenderObjClass::CLASSID_MESH) {
  248. // Create a new node and add it to our list
  249. TextureListNodeClass *pnode = new TextureListNodeClass (prender_obj->Get_Name ());
  250. m_NodeList.Add (pnode);
  251. // Add all the mesh's textures to this list
  252. Add_Textures_To_Node ((MeshClass *)prender_obj, pnode);
  253. }
  254. return ;
  255. }
  256. /////////////////////////////////////////////////////////////////////////////
  257. //
  258. // Add_Textures_To_Node
  259. //
  260. void
  261. TextureMgrDialogClass::Add_Textures_To_Node
  262. (
  263. MeshClass *pmesh,
  264. TextureListNodeClass *pmesh_node
  265. )
  266. {
  267. MaterialInfoClass *pmat_info = pmesh->Get_Material_Info ();
  268. if (pmat_info != NULL) {
  269. // Loop through all the textures and add them as subobjs
  270. for (int index = 0; index < pmat_info->Texture_Count (); index ++) {
  271. TextureClass *ptexture = pmat_info->Get_Texture (index);
  272. if (ptexture != NULL) {
  273. // Create a node from this texture and add it to the mesh
  274. TextureListNodeClass *pnode = new TextureListNodeClass (ptexture, ::Get_Texture_Name (*ptexture));
  275. pmesh_node->Add_Subobj (pnode);
  276. pnode->Set_Parent (pmesh_node);
  277. pnode->Set_Texture_Index (index);
  278. // Give this texture a thumbnail
  279. pnode->Set_Icon_Index (Get_Thumbnail (ptexture));
  280. // Release our hold on this pointer
  281. REF_PTR_RELEASE (ptexture);
  282. }
  283. }
  284. // Release our hold on this pointer
  285. MEMBER_RELEASE (pmat_info);
  286. }
  287. return ;
  288. }
  289. /////////////////////////////////////////////////////////////////////////////
  290. //
  291. // Find_Texture_Thumbnail
  292. //
  293. int
  294. TextureMgrDialogClass::Find_Texture_Thumbnail (LPCTSTR name)
  295. {
  296. int icon_index = -1;
  297. // Loop through the names in our list and if we find the texture
  298. // name, return its index
  299. for (int index = 0; (index < m_TextureNames.Count ()) && (icon_index == -1); index ++) {
  300. if (::lstrcmpi (name, m_TextureNames[index]) == 0) {
  301. icon_index = index;
  302. }
  303. }
  304. // Return the icon index (-1 if not found)
  305. return icon_index;
  306. }
  307. /////////////////////////////////////////////////////////////////////////////
  308. //
  309. // OnOK
  310. //
  311. void
  312. TextureMgrDialogClass::OnOK (void)
  313. {
  314. // Allow the base class to process this message
  315. CDialog::OnOK ();
  316. return ;
  317. }
  318. /////////////////////////////////////////////////////////////////////////////
  319. //
  320. // OnCancel
  321. //
  322. void
  323. TextureMgrDialogClass::OnCancel (void)
  324. {
  325. // Allow the base class to process this message
  326. CDialog::OnCancel ();
  327. return ;
  328. }
  329. /////////////////////////////////////////////////////////////////////////////
  330. //
  331. // OnDblclkMeshTextureListCtrl
  332. //
  333. void
  334. TextureMgrDialogClass::OnDblclkMeshTextureListCtrl
  335. (
  336. NMHDR *pNMHDR,
  337. LRESULT *pResult
  338. )
  339. {
  340. // Determine which item is selected
  341. int index = m_ListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
  342. if (index != -1) {
  343. // Get the node associated with this entry
  344. TextureListNodeClass *pnode = (TextureListNodeClass *)m_ListCtrl.GetItemData (index);
  345. if (pnode != NULL) {
  346. // Is this a mesh or a texture?
  347. if (pnode->Get_Type () == TextureListNodeClass::TYPE_MESH) {
  348. Fill_List_Ctrl_With_Textures (*pnode);
  349. } else {
  350. // Is this a texture the user can modify?
  351. TextureClass *ptexture = pnode->Peek_Texture ();
  352. if (ptexture->getClassID () != ID_INDIRECT_TEXTURE_CLASS) {
  353. MessageBox ("This texture can not be edited. Only indirect textures are modifiable", "Invalid Type", MB_OK | MB_ICONEXCLAMATION);
  354. } else {
  355. // Get an original instance of this model so we can compare textures to
  356. // try and find an original texture...
  357. TextureListNodeClass *pmesh_node = pnode->Get_Parent ();
  358. RenderObjClass *prender_obj = WW3DAssetManager::Get_Instance ()->Create_Render_Obj (pmesh_node->Get_Name ());
  359. TextureClass *poriginal_texture = NULL;
  360. if (prender_obj != NULL) {
  361. // Get the material information for this render object
  362. MaterialInfoClass *pmat_info = prender_obj->Get_Material_Info ();
  363. if (pmat_info != NULL) {
  364. // Attempt to find the original texture
  365. poriginal_texture = pmat_info->Get_Texture (pnode->Get_Texture_Index ());
  366. if (poriginal_texture->getClassID () != ID_INDIRECT_TEXTURE_CLASS) {
  367. SR_RELEASE (poriginal_texture);
  368. }
  369. MEMBER_RELEASE (pmat_info);
  370. }
  371. }
  372. // Show the user a dialog containing the texture's properties
  373. TextureSettingsDialogClass dialog ((IndirectTextureClass *)ptexture,
  374. (IndirectTextureClass *)poriginal_texture,
  375. this);
  376. dialog.DoModal ();
  377. // If the settings we modified, then update the list control information
  378. if (dialog.Were_Settings_Modified ()) {
  379. // Recreate the thumbnail (if necessary)
  380. pnode->Set_Icon_Index (Get_Thumbnail (ptexture));
  381. pnode->Set_Name (::Get_Texture_Name (*ptexture));
  382. // Update the list control with the new settings
  383. Insert_Texture_Details (pnode, index);
  384. m_ListCtrl.Update (index);
  385. }
  386. // Release our hold on the originaltexture
  387. SR_RELEASE (poriginal_texture);
  388. }
  389. }
  390. }
  391. }
  392. (*pResult) = 0;
  393. return ;
  394. }
  395. /////////////////////////////////////////////////////////////////////////////
  396. //
  397. // OnKeydownMeshTextureListCtrl
  398. //
  399. void
  400. TextureMgrDialogClass::OnKeydownMeshTextureListCtrl
  401. (
  402. NMHDR* pNMHDR,
  403. LRESULT* pResult
  404. )
  405. {
  406. // Did the user press the backspace key?
  407. LV_KEYDOWN *pLVKeyDown = (LV_KEYDOWN *)pNMHDR;
  408. if (pLVKeyDown && (pLVKeyDown->wVKey == VK_BACK)) {
  409. // Display the mesh list
  410. if (m_bContainsMeshes == false) {
  411. Fill_List_Ctrl_With_Meshes ();
  412. }
  413. }
  414. (*pResult) = 0;
  415. return ;
  416. }
  417. /////////////////////////////////////////////////////////////////////////////
  418. //
  419. // OnDestroy
  420. //
  421. void
  422. TextureMgrDialogClass::OnDestroy (void)
  423. {
  424. // Free the state image list we associated with the control
  425. m_ListCtrl.SetImageList (NULL, LVSIL_NORMAL);
  426. m_ListCtrl.SetImageList (NULL, LVSIL_SMALL);
  427. SAFE_DELETE (m_pImageList);
  428. SAFE_DELETE (m_pImageListSmall);
  429. SAFE_DELETE (m_pTextureImageList);
  430. SAFE_DELETE (m_pTextureImageListSmall);
  431. m_TextureNames.Delete_All ();
  432. // Loop through the list of nodes and free them
  433. for (int index = 0; index < m_NodeList.Count (); index ++) {
  434. TextureListNodeClass *pnode = m_NodeList[index];
  435. SAFE_DELETE (pnode);
  436. }
  437. // Remove all the entries from the list
  438. m_NodeList.Delete_All ();
  439. // Allow the base class to process this message
  440. CDialog::OnDestroy ();
  441. return ;
  442. }
  443. /////////////////////////////////////////////////////////////////////////////
  444. //
  445. // OnBack
  446. //
  447. void
  448. TextureMgrDialogClass::OnBack (void)
  449. {
  450. // Display the mesh list
  451. if (m_bContainsMeshes == false) {
  452. Fill_List_Ctrl_With_Meshes ();
  453. }
  454. return ;
  455. }
  456. /////////////////////////////////////////////////////////////////////////////
  457. //
  458. // OnDetails
  459. //
  460. void
  461. TextureMgrDialogClass::OnDetails (void)
  462. {
  463. LONG style = ::GetWindowLong (m_ListCtrl, GWL_STYLE);
  464. SetWindowLong (m_ListCtrl, GWL_STYLE, (style & (~LVS_TYPEMASK)) | LVS_REPORT);
  465. return ;
  466. }
  467. /////////////////////////////////////////////////////////////////////////////
  468. //
  469. // OnLarge
  470. //
  471. void
  472. TextureMgrDialogClass::OnLarge (void)
  473. {
  474. LONG style = ::GetWindowLong (m_ListCtrl, GWL_STYLE);
  475. SetWindowLong (m_ListCtrl, GWL_STYLE, (style & (~LVS_TYPEMASK)) | LVS_ICON);
  476. return ;
  477. }
  478. /////////////////////////////////////////////////////////////////////////////
  479. //
  480. // OnList
  481. //
  482. void
  483. TextureMgrDialogClass::OnList (void)
  484. {
  485. LONG style = ::GetWindowLong (m_ListCtrl, GWL_STYLE);
  486. SetWindowLong (m_ListCtrl, GWL_STYLE, (style & (~LVS_TYPEMASK)) | LVS_LIST);
  487. return ;
  488. }
  489. /////////////////////////////////////////////////////////////////////////////
  490. //
  491. // OnSmall
  492. //
  493. void
  494. TextureMgrDialogClass::OnSmall (void)
  495. {
  496. LONG style = ::GetWindowLong (m_ListCtrl, GWL_STYLE);
  497. SetWindowLong (m_ListCtrl, GWL_STYLE, (style & (~LVS_TYPEMASK)) | LVS_SMALLICON);
  498. return ;
  499. }
  500. /////////////////////////////////////////////////////////////////////////////
  501. //
  502. // Get_Thumbnail
  503. //
  504. int
  505. TextureMgrDialogClass::Get_Thumbnail (srTextureIFace *ptexture)
  506. {
  507. int icon_index = 0;
  508. // See if this texture already has a thumbnail
  509. icon_index = Find_Texture_Thumbnail (::Get_Texture_Name (*ptexture));
  510. if (icon_index == -1) {
  511. // Create a windows bitmap from this texture
  512. HBITMAP hbmp = ::Make_Bitmap_From_Texture (*ptexture, TEXTURE_THUMB_X, TEXTURE_THUMB_Y);
  513. if (hbmp != NULL) {
  514. // Insert this bitmap into our imagelist
  515. CBitmap temp_obj;
  516. temp_obj.Attach (hbmp);
  517. icon_index = m_pTextureImageList->Add (&temp_obj, (CBitmap *)NULL);
  518. // Create a smaller bitmap and insert it into the other imagelist
  519. HBITMAP hsmall_bitmap = (HBITMAP)::CopyImage (hbmp, IMAGE_BITMAP, TEXTURE_THUMBSMALL_X, TEXTURE_THUMBSMALL_Y, 0);
  520. CBitmap small_obj;
  521. small_obj.Attach (hsmall_bitmap);
  522. m_pTextureImageListSmall->Add (&small_obj, (CBitmap *)NULL);
  523. // Add a name to our list to represent this texture
  524. m_TextureNames.Add (::Get_Texture_Name (*ptexture));
  525. }
  526. }
  527. // Return the icon index
  528. return icon_index;
  529. }
  530. /////////////////////////////////////////////////////////////////////////////
  531. //
  532. // Insert_Texture_Details
  533. //
  534. void
  535. TextureMgrDialogClass::Insert_Texture_Details
  536. (
  537. TextureListNodeClass *pnode,
  538. int index
  539. )
  540. {
  541. TextureClass *ptexture = pnode->Peek_Texture ();
  542. if ((index != -1) && (ptexture != NULL)) {
  543. // Get the name of the texture (mark it differently if its an editable texture)
  544. CString texture_name = ::Get_Texture_Name (*ptexture);
  545. if (ptexture->getClassID () == ID_INDIRECT_TEXTURE_CLASS) {
  546. texture_name += " *";
  547. }
  548. // Update the texture's icon and name in the list control
  549. m_ListCtrl.SetItem (index,
  550. COL_NAME,
  551. LVIF_IMAGE | LVIF_TEXT,
  552. texture_name,
  553. pnode->Get_Icon_Index (),
  554. 0, 0, 0);
  555. // Insert the texture dimensions in the second column
  556. SurfaceClass::SurfaceDescription surface_desc;
  557. ptexture->Get_Level_Description(surface_desc);
  558. CString dimension_string;
  559. dimension_string.Format ("(%dx%d)", surface_desc.Width, surface_desc.Height);
  560. m_ListCtrl.SetItemText (index, COL_DIMENSIONS, dimension_string);
  561. // Determine what type the texture is
  562. CString type_string;
  563. switch (ptexture->getClassID ())
  564. {
  565. case srClass::ID_TEXTURE_FILE:
  566. type_string = "Simple file";
  567. break;
  568. case ID_MANUAL_ANIM_TEXTURE_INSTANCE_CLASS:
  569. case ID_TIME_ANIM_TEXTURE_INSTANCE_CLASS:
  570. type_string = "Animated";
  571. break;
  572. case ID_RESIZEABLE_TEXTURE_INSTANCE_CLASS:
  573. type_string = "Resizeable";
  574. break;
  575. case ID_INDIRECT_TEXTURE_CLASS:
  576. type_string = "Indirect (editable)";
  577. break;
  578. default:
  579. ASSERT (0);
  580. break;
  581. }
  582. // Set the texture type information
  583. m_ListCtrl.SetItemText (index, COL_TEXTURE_TYPE, type_string);
  584. // Associate the node with the list entry
  585. m_ListCtrl.SetItemData (index, (DWORD)pnode);
  586. }
  587. return ;
  588. }
  589. /////////////////////////////////////////////////////////////////////////////
  590. //
  591. // Propogate_Changes
  592. //
  593. /////////////////////////////////////////////////////////////////////////////
  594. void
  595. TextureMgrDialogClass::OnPropagate (void)
  596. {
  597. //
  598. // Determine the currently selected item
  599. //
  600. int sel_index = m_ListCtrl.GetNextItem (-1, LVNI_ALL | LVNI_SELECTED);
  601. if (m_bContainsMeshes == false || sel_index == -1) {
  602. return ;
  603. }
  604. if (MessageBox ("Warning, this operation will copy the texture settings from the currently selected mesh into all meshes with the same texture count. Do you wish to continue?", "Texture Propagate", MB_ICONQUESTION | MB_YESNO) == IDNO) {
  605. return ;
  606. }
  607. TextureListNodeClass *src_node = (TextureListNodeClass *)m_ListCtrl.GetItemData (sel_index);
  608. TEXTURE_NODE_LIST &src_texture_list = src_node->Get_Subobj_List ();
  609. int src_texture_count = src_texture_list.Count ();
  610. //
  611. // Loop over all the other meshes in the list
  612. //
  613. int counter = m_ListCtrl.GetItemCount ();
  614. while (counter --) {
  615. //
  616. // Does this node have the same number of replaceable textures as the src node?
  617. //
  618. TextureListNodeClass *curr_node = (TextureListNodeClass *)m_ListCtrl.GetItemData (counter);
  619. if ( (curr_node != NULL) &&
  620. (curr_node->Get_Subobj_List ().Count () == src_texture_count))
  621. {
  622. TEXTURE_NODE_LIST &curr_texture_list = curr_node->Get_Subobj_List ();
  623. //
  624. // Copy the textures...
  625. //
  626. int texture_counter = src_texture_count;
  627. while (texture_counter --) {
  628. TextureListNodeClass *curr_texture_node = curr_texture_list[texture_counter];
  629. TextureListNodeClass *src_texture_node = src_texture_list[texture_counter];
  630. if (curr_texture_node != NULL && src_texture_node != NULL) {
  631. TextureClass *curr_texture = curr_texture_node->Peek_Texture ();
  632. TextureClass *src_texture = src_texture_node->Peek_Texture ();
  633. //
  634. // Are the textures both indirect textures?
  635. //
  636. if ( curr_texture != NULL && src_texture != NULL &&
  637. curr_texture->getClassID () == ID_INDIRECT_TEXTURE_CLASS &&
  638. src_texture->getClassID () == ID_INDIRECT_TEXTURE_CLASS)
  639. {
  640. TextureClass *real_texture = ((IndirectTextureClass *)src_texture)->Peek_Texture ();
  641. ((IndirectTextureClass *)curr_texture)->Set_Texture (real_texture);
  642. }
  643. }
  644. }
  645. }
  646. }
  647. return ;
  648. }
  649. #endif // WW3D_DX8