BrowseWindow.cpp 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533
  1. /* Copyright (c) 2002-2012 Croteam Ltd.
  2. This program is free software; you can redistribute it and/or modify
  3. it under the terms of version 2 of the GNU General Public License as published by
  4. the Free Software Foundation
  5. This program is distributed in the hope that it will be useful,
  6. but WITHOUT ANY WARRANTY; without even the implied warranty of
  7. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  8. GNU General Public License for more details.
  9. You should have received a copy of the GNU General Public License along
  10. with this program; if not, write to the Free Software Foundation, Inc.,
  11. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
  12. // BrowseWindow.cpp : implementation file
  13. //
  14. #include "stdafx.h"
  15. #include "BrowseWindow.h"
  16. #include <shlobj.h>
  17. #include <Engine/Templates/Stock_CTextureData.h>
  18. #include <Engine/Templates/Stock_CEntityClass.h>
  19. #ifdef _DEBUG
  20. #undef new
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. INDEX _iLastHittedItem = -1;
  26. static CTFileName _fnRightClickedItemFileName;
  27. static BOOL _bRightClickedIsSelected;
  28. /////////////////////////////////////////////////////////////////////////////
  29. // CBrowseWindow
  30. CBrowseWindow::CBrowseWindow()
  31. {
  32. m_pDrawPort = NULL;
  33. m_pViewPort = NULL;
  34. m_iLastHittedItem = 0;
  35. m_bDirectoryOpen = FALSE;
  36. }
  37. CBrowseWindow::~CBrowseWindow()
  38. {
  39. if( m_pViewPort != NULL)
  40. {
  41. _pGfx->DestroyWindowCanvas( m_pViewPort);
  42. m_pViewPort = NULL;
  43. }
  44. }
  45. BEGIN_MESSAGE_MAP(CBrowseWindow, CWnd)
  46. //{{AFX_MSG_MAP(CBrowseWindow)
  47. ON_WM_VSCROLL()
  48. ON_WM_PAINT()
  49. ON_WM_DROPFILES()
  50. ON_WM_SIZE()
  51. ON_COMMAND(ID_INSERT_ITEMS, OnInsertItems)
  52. ON_WM_LBUTTONDOWN()
  53. ON_COMMAND(ID_DELETE_ITEMS, OnDeleteItems)
  54. ON_COMMAND(ID_BIG_ICONS, OnBigIcons)
  55. ON_COMMAND(ID_MEDIUM_ICONS, OnMediumIcons)
  56. ON_COMMAND(ID_SMALL_ICONS, OnSmallIcons)
  57. ON_COMMAND(ID_SHOW_DESCRIPTION, OnShowDescription)
  58. ON_COMMAND(ID_SHOW_FILENAME, OnShowFilename)
  59. ON_WM_LBUTTONDBLCLK()
  60. ON_COMMAND(ID_RECREATE_TEXTURE, OnRecreateTexture)
  61. ON_COMMAND(ID_CREATE_AND_ADD_TEXTURE, OnCreateAndAddTexture)
  62. ON_COMMAND(ID_SELECT_BY_TEXTURE_IN_SELECTED_SECTORS, OnSelectByTextureInSelectedSectors)
  63. ON_COMMAND(ID_SELECT_BY_TEXTURE_IN_WORLD, OnSelectByTextureInWorld)
  64. ON_COMMAND(ID_SELECT_FOR_DROP_MARKER, OnSelectForDropMarker)
  65. ON_COMMAND(ID_SET_AS_CURRENT_TEXTURE, OnSetAsCurrentTexture)
  66. ON_COMMAND(ID_CONVERT_CLASS, OnConvertClass)
  67. ON_WM_MOUSEMOVE()
  68. ON_COMMAND(ID_MICRO_ICONS, OnMicroIcons)
  69. ON_COMMAND(ID_SELECT_EXCEPT_TEXTURES, OnSelectExceptTextures)
  70. ON_COMMAND(ID_ADD_TEXTURES_FROM_WORLD, OnAddTexturesFromWorld)
  71. ON_COMMAND(ID_SHOW_TREE_SHORTCUTS, OnShowTreeShortcuts)
  72. ON_COMMAND(ID_EXPORT_TEXTURE, OnExportTexture)
  73. ON_COMMAND(ID_BROWSER_CONTEXT_HELP, OnBrowserContextHelp)
  74. //}}AFX_MSG_MAP
  75. END_MESSAGE_MAP()
  76. /////////////////////////////////////////////////////////////////////////////
  77. // CBrowseWindow message handlers
  78. BOOL CBrowseWindow::AttachToControl( CWnd *pwndParent)
  79. {
  80. BOOL bResult = TRUE;
  81. bResult = Create( NULL, NULL, WS_BORDER|WS_VISIBLE|WS_VSCROLL, CRect(0,0,10,10),
  82. pwndParent, IDW_BROWSER);
  83. if( bResult)
  84. {
  85. DragAcceptFiles();
  86. }
  87. SetFocus();
  88. EnableToolTips( TRUE);
  89. return bResult;
  90. }
  91. void CBrowseWindow::SetBrowserPtr( CBrowser *pBrowser)
  92. {
  93. m_pBrowser = pBrowser;
  94. }
  95. void CBrowseWindow::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
  96. {
  97. int iPosition = GetScrollPos(SB_VERT);
  98. int intMin, intMax;
  99. GetScrollRange( SB_VERT, &intMin, &intMax);
  100. INDEX iMin = intMin;
  101. INDEX iMax = intMax;
  102. switch( nSBCode )
  103. {
  104. case SB_THUMBTRACK:
  105. case SB_THUMBPOSITION:
  106. {
  107. SetScrollPos(SB_VERT, nPos);
  108. break;
  109. }
  110. case SB_LINEDOWN:
  111. {
  112. iPosition = Clamp( iPosition+m_IconHeight, iMin, iMax);
  113. SetScrollPos(SB_VERT, iPosition);
  114. break;
  115. }
  116. case SB_PAGEDOWN:
  117. {
  118. iPosition = Clamp( iPosition+m_IconsInColumn*m_IconHeight, iMin, iMax);
  119. SetScrollPos(SB_VERT, iPosition);
  120. break;
  121. }
  122. case SB_LINEUP:
  123. {
  124. iPosition = Clamp( iPosition-m_IconHeight, iMin, iMax);
  125. SetScrollPos(SB_VERT, iPosition);
  126. break;
  127. }
  128. case SB_PAGEUP:
  129. {
  130. iPosition = Clamp( iPosition-m_IconsInColumn*m_IconHeight, iMin, iMax);
  131. SetScrollPos(SB_VERT, iPosition);
  132. break;
  133. }
  134. }
  135. CWnd::OnVScroll(nSBCode, nPos, pScrollBar);
  136. Invalidate(FALSE);
  137. }
  138. #define BOX( dp, xs, ys, w, h, color, type) \
  139. dp->DrawLine( xs, ys, xs, ys+h, color, type); \
  140. dp->DrawLine( xs, ys+h, xs+w, ys+h, color, type); \
  141. dp->DrawLine( xs+w, ys+h, xs+w, ys, color, type); \
  142. dp->DrawLine( xs+w, ys, xs, ys, color, type);
  143. #define ICONS_TRAY_WIDTH 16
  144. #define ICONS_TRAY_HEIGHT 16
  145. void CBrowseWindow::OnPaint()
  146. {
  147. {
  148. CPaintDC dc(this); // device context for painting (does BeginPaint()/EndPaint()!)
  149. }
  150. CWorldEditorApp *pApp = (CWorldEditorApp *)AfxGetApp();
  151. PIXaabbox2D rectPict;
  152. INDEX i;
  153. if (m_pDrawPort==NULL || !m_pDrawPort->Lock()) {
  154. return;
  155. }
  156. // To write description
  157. m_pDrawPort->SetFont( theApp.m_pfntSystem);
  158. m_pDrawPort->SetTextAspect( 1.0f);
  159. // clear browsing window
  160. m_pDrawPort->FillZBuffer( ZBUF_BACK);
  161. m_pDrawPort->Fill( C_BLACK | CT_OPAQUE);
  162. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  163. if (pVTNDir==NULL) {
  164. m_pDrawPort->Unlock();
  165. return;
  166. }
  167. if(m_bDirectoryOpen)
  168. {
  169. INDEX iYOffset = GetScrollPos( SB_VERT);
  170. INDEX iLineVisible = iYOffset/m_IconHeight;
  171. PIX pixStart = iYOffset%m_IconHeight;
  172. for( i=0; i<m_IconsVisible+m_IconsInLine; i++)
  173. {
  174. CVirtualTreeNode *pVTN = GetItem( i + iLineVisible*m_IconsInLine);
  175. if( pVTN == NULL)
  176. {
  177. break;
  178. }
  179. PIX x = (i%m_IconsInLine) * m_IconWidth;
  180. PIX y = (i/m_IconsInLine) * m_IconHeight - pixStart + ICONS_TRAY_HEIGHT + 1;
  181. switch( pVTNDir->vtn_bmBrowsingMode)
  182. {
  183. case BM_ICONS_MICRO:
  184. case BM_ICONS_SMALL:
  185. case BM_ICONS_MEDIUM:
  186. case BM_ICONS_LARGE:
  187. {
  188. PIX pixIconWidth = m_IconWidth;
  189. PIX pixIconHeight = m_IconHeight;
  190. // if we are browsing large icons, leave some space for icon text
  191. if( pVTNDir->vtn_bmBrowsingMode == BM_ICONS_LARGE)
  192. {
  193. pixIconHeight -= STRING_HEIGHT;
  194. }
  195. // set error texture
  196. CTextureData *ptdIcon = pApp->m_ptdError;
  197. if( pVTN->vtn_pTextureData != NULL)
  198. {
  199. ptdIcon = pVTN->vtn_pTextureData;
  200. }
  201. // get texture width and height
  202. PIX pixTextureWidth = ptdIcon->GetWidth();
  203. PIX pixTextureHeight= ptdIcon->GetHeight();
  204. // apply texture aspect ratio to icon
  205. if( pixTextureWidth>pixTextureHeight)
  206. {
  207. pixIconHeight /= pixTextureWidth/pixTextureHeight;
  208. }
  209. else
  210. {
  211. pixIconWidth /= pixTextureHeight/pixTextureWidth;
  212. }
  213. // if we have large icons
  214. if( pVTNDir->vtn_bmBrowsingMode == BM_ICONS_LARGE)
  215. {
  216. // rectangle for texture polygon is smaller because of subtitling info text
  217. rectPict = PIXaabbox2D(
  218. PIX2D(x+m_IconWidth/2-pixIconWidth/2+1, y+m_IconHeight/2-pixIconHeight/2+1),
  219. PIX2D(x+m_IconWidth/2+pixIconWidth/2-2, y+m_IconHeight/2+pixIconHeight/2-2-STRING_HEIGHT));
  220. }
  221. else
  222. {
  223. // texture box covers maximum space
  224. rectPict = PIXaabbox2D(
  225. PIX2D(x+m_IconWidth/2-pixIconWidth/2+1, y+m_IconHeight/2-pixIconHeight/2+1),
  226. PIX2D(x+m_IconWidth/2+pixIconWidth/2-2, y+m_IconHeight/2+pixIconHeight/2-2));
  227. }
  228. // draw icon
  229. CTextureObject toIcon;
  230. toIcon.SetData( ptdIcon);
  231. m_pDrawPort->PutTexture( &toIcon, rectPict);
  232. // if we have large icons
  233. if( pVTNDir->vtn_bmBrowsingMode == BM_ICONS_LARGE)
  234. {
  235. // type info text
  236. if( pVTN->vtn_fnItem.FileExt() == ".tex")
  237. {
  238. m_pDrawPort->PutText( pVTN->vtn_fnItem.FileName(), x, y + m_IconHeight-2-STRING_HEIGHT);
  239. }
  240. else
  241. {
  242. m_pDrawPort->PutText( pVTN->vtn_strName, x, y + m_IconHeight-2-STRING_HEIGHT);
  243. }
  244. }
  245. if( pVTN->vtn_bSelected)
  246. {
  247. BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_WHITE|CT_OPAQUE, _FULL_);
  248. BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_lRED|CT_OPAQUE, _POINT_);
  249. }
  250. break;
  251. }
  252. case BM_DESCRIPTION:
  253. case BM_FILENAME:
  254. {
  255. // First paint little icon
  256. rectPict = PIXaabbox2D( PIX2D(x, y), PIX2D(x+STRING_HEIGHT, y+STRING_HEIGHT));
  257. if( pVTN->vtn_pTextureData != NULL)
  258. {
  259. CTextureObject toIcon;
  260. toIcon.SetData( pVTN->vtn_pTextureData);
  261. m_pDrawPort->PutTexture( &toIcon, rectPict);
  262. }
  263. else
  264. {
  265. m_pDrawPort->PutTexture( pApp->m_ptoError, rectPict);
  266. }
  267. // if we are using descriptive name
  268. if( pVTNDir->vtn_bmBrowsingMode == BM_DESCRIPTION)
  269. {
  270. if( pVTN->vtn_fnItem.FileExt() == ".tex")
  271. {
  272. m_pDrawPort->PutText( pVTN->vtn_fnItem.FileName(), x + STRING_HEIGHT, y);
  273. }
  274. else
  275. {
  276. m_pDrawPort->PutText( pVTN->vtn_strName, x + STRING_HEIGHT, y);
  277. }
  278. }
  279. // if we are using file name
  280. else
  281. {
  282. m_pDrawPort->PutText( pVTN->vtn_fnItem, x + STRING_HEIGHT, y);
  283. }
  284. if( pVTN->vtn_bSelected)
  285. {
  286. BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_WHITE|CT_OPAQUE, _FULL_);
  287. BOX( m_pDrawPort, x, y, m_IconWidth-1, m_IconHeight-1, C_lRED|CT_OPAQUE, _POINT_);
  288. }
  289. break;
  290. }
  291. default:
  292. {
  293. ASSERTALWAYS( "Unrecognizible browsing type found !");
  294. }
  295. }
  296. }
  297. }
  298. // draw icons tray
  299. CTextureObject to;
  300. to.SetData(theApp.m_ptdIconsTray);
  301. INDEX iSelected=0;
  302. switch( pVTNDir->vtn_bmBrowsingMode)
  303. {
  304. case BM_ICONS_MICRO: iSelected = 0; break;
  305. case BM_ICONS_SMALL: iSelected = 1; break;
  306. case BM_ICONS_MEDIUM: iSelected = 2; break;
  307. case BM_ICONS_LARGE: iSelected = 3; break;
  308. case BM_DESCRIPTION: iSelected = 4; break;
  309. case BM_FILENAME: iSelected = 5; break;
  310. }
  311. FLOAT fRatio = theApp.m_ptdIconsTray->GetWidth()/theApp.m_ptdIconsTray->GetPixWidth();
  312. MEX2D mex2dStart = MEX2D(0, MEX(iSelected*16*fRatio));
  313. MEX2D mex2dEnd = MEX2D(MEX(16*8*fRatio), MEX((iSelected*16+16)*fRatio));
  314. MEXaabbox2D boxTexture = MEXaabbox2D( mex2dStart, mex2dEnd);
  315. PIXaabbox2D boxScreen = PIXaabbox2D( PIX2D(0, 0), PIX2D(8*16, 16));
  316. m_pDrawPort->Fill( 0, 0, m_pDrawPort->GetWidth(), 17, C_BLACK|CT_OPAQUE);
  317. m_pDrawPort->PutTexture( &to, boxScreen, boxTexture);
  318. m_pDrawPort->Unlock();
  319. m_pViewPort->SwapBuffers();
  320. }
  321. void CBrowseWindow::OnContextMenu( CPoint point)
  322. {
  323. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  324. if( pVTNDir == NULL)
  325. {
  326. AfxMessageBox( L"Virtual tree doesn't yet exists. Create at least one virtual directory "
  327. L"to be able to insert items into it.");
  328. return;
  329. }
  330. CWorldEditorDoc *pDoc = theApp.GetDocument();
  331. // convert coordinates from screen to client
  332. CPoint ptClientCoordinates = point;
  333. ScreenToClient( &ptClientCoordinates);
  334. // Add hit icon to selection
  335. FLOAT fDummyX, fDummyY;
  336. INDEX iHittedItem = HitItem( ptClientCoordinates, fDummyX, fDummyY);
  337. _fnRightClickedItemFileName = CTString("");
  338. if( iHittedItem != -1)
  339. {
  340. CVirtualTreeNode *pVTN = GetItem( iHittedItem);
  341. ASSERT( pVTN != NULL);
  342. _fnRightClickedItemFileName = pVTN->vtn_fnItem;
  343. _bRightClickedIsSelected = pVTN->vtn_bSelected;
  344. }
  345. CMenu menu;
  346. if( menu.LoadMenu(IDR_BROWSERPOPUP))
  347. {
  348. CMenu* pPopup = menu.GetSubMenu(0);
  349. UINT iRecreateTextureCommandState = MF_DISABLED|MF_GRAYED;
  350. if( _fnRightClickedItemFileName.FileExt()==CTString(".tex") ||
  351. _fnRightClickedItemFileName.FileExt()==CTString(".tbn") )
  352. {
  353. iRecreateTextureCommandState = MF_ENABLED;
  354. }
  355. // enable recreate texture and set as current texture commands if texture right-clicked
  356. pPopup->EnableMenuItem(ID_RECREATE_TEXTURE, iRecreateTextureCommandState);
  357. pPopup->EnableMenuItem(ID_SET_AS_CURRENT_TEXTURE, iRecreateTextureCommandState);
  358. pPopup->EnableMenuItem(ID_EXPORT_TEXTURE, iRecreateTextureCommandState);
  359. UINT iSelectForDropMarkerCommandState = MF_DISABLED|MF_GRAYED;
  360. if( _fnRightClickedItemFileName.FileExt()==CTString(".ecl"))
  361. {
  362. iSelectForDropMarkerCommandState = MF_ENABLED;
  363. }
  364. // enable recreate texture command if texture right-clicked
  365. pPopup->EnableMenuItem(ID_SELECT_FOR_DROP_MARKER, iSelectForDropMarkerCommandState);
  366. if( pDoc == NULL)
  367. {
  368. pPopup->EnableMenuItem(ID_ADD_TEXTURES_FROM_WORLD, MF_DISABLED|MF_GRAYED);
  369. pPopup->EnableMenuItem(ID_SELECT_EXCEPT_TEXTURES, MF_DISABLED|MF_GRAYED);
  370. }
  371. // enable select by texture commands only if texture is right-clicked and document exists
  372. UINT iSelectByTextureCommandState = MF_DISABLED|MF_GRAYED;
  373. if( (_fnRightClickedItemFileName.FileExt()==CTString(".tex")) && (pDoc!=NULL))
  374. {
  375. iSelectByTextureCommandState = MF_ENABLED;
  376. }
  377. UINT iConvertClassCommandState = MF_DISABLED|MF_GRAYED;
  378. if( (_fnRightClickedItemFileName.FileExt()==CTString(".ecl")) &&
  379. (pDoc!=NULL) &&
  380. (pDoc->m_selEntitySelection.Count() != 0) &&
  381. (pDoc->m_iMode == ENTITY_MODE) )
  382. {
  383. iConvertClassCommandState = MF_ENABLED;
  384. }
  385. pPopup->EnableMenuItem(ID_SELECT_BY_TEXTURE_IN_SELECTED_SECTORS, iSelectByTextureCommandState);
  386. pPopup->EnableMenuItem(ID_SELECT_BY_TEXTURE_IN_WORLD, iSelectByTextureCommandState);
  387. pPopup->EnableMenuItem(ID_CONVERT_CLASS, iConvertClassCommandState);
  388. UINT iClassHelp = MF_DISABLED|MF_GRAYED;
  389. if( _fnRightClickedItemFileName.FileExt()==CTString(".ecl"))
  390. {
  391. iClassHelp = MF_ENABLED;
  392. }
  393. pPopup->EnableMenuItem(ID_BROWSER_CONTEXT_HELP, iClassHelp);
  394. pPopup->TrackPopupMenu(TPM_LEFTBUTTON | TPM_RIGHTBUTTON | TPM_LEFTALIGN,
  395. point.x, point.y, this);
  396. }
  397. }
  398. INDEX CBrowseWindow::HitItem( CPoint point, FLOAT &fHitXOffset, FLOAT &fHitYOffset) const
  399. {
  400. PIXaabbox2D rectItem;
  401. PIXaabbox2D boxPoint;
  402. INDEX i;
  403. INDEX iYOffset = GetScrollPos( SB_VERT);
  404. INDEX iLineVisible = iYOffset/m_IconHeight;
  405. PIX pixStart = iYOffset%m_IconHeight;
  406. for( i=0; i<m_IconsVisible; i++)
  407. {
  408. CVirtualTreeNode *pVTN = GetItem( i + iLineVisible*m_IconsInLine);
  409. if( pVTN == NULL)
  410. {
  411. break;
  412. }
  413. PIX x = i%m_IconsInLine * m_IconWidth;
  414. PIX y = i/m_IconsInLine * m_IconHeight - pixStart + ICONS_TRAY_HEIGHT + 1;
  415. rectItem = PIXaabbox2D( PIX2D(x, y), PIX2D(x+m_IconWidth, y+m_IconHeight));
  416. boxPoint = PIXaabbox2D( PIX2D(point.x, point.y) );
  417. if( (rectItem & boxPoint) == boxPoint)
  418. {
  419. fHitXOffset = FLOAT((point.x-x))/m_IconWidth;
  420. fHitYOffset = FLOAT((point.y-y))/m_IconHeight;
  421. return (i + iLineVisible*m_IconsInLine);
  422. }
  423. }
  424. return -1;
  425. }
  426. HGLOBAL CreateHDrop( const CTFileName &fnToDrag, BOOL bAddAppPath/*=TRUE*/)
  427. {
  428. CTFileName fnFullToDrag;
  429. if( bAddAppPath)
  430. {
  431. fnFullToDrag = _fnmApplicationPath + fnToDrag;
  432. }
  433. else
  434. {
  435. fnFullToDrag = fnToDrag;
  436. }
  437. HGLOBAL hGlobal;
  438. // allocate space for DROPFILE structure plus the number of file and one extra byte for final NULL terminator
  439. hGlobal = GlobalAlloc(GHND|GMEM_SHARE,(DWORD) (sizeof(DROPFILES)+strlen(fnFullToDrag)+2));
  440. if(hGlobal == NULL)
  441. return hGlobal;
  442. LPDROPFILES pDropFiles;
  443. char *pchDropFileName;
  444. pDropFiles = (LPDROPFILES)GlobalLock(hGlobal);
  445. pchDropFileName = ((char *)pDropFiles)+sizeof(DROPFILES);
  446. // set the offset where the starting point of the file start
  447. pDropFiles->pFiles = sizeof(DROPFILES);
  448. // filename does not contain wide characters
  449. pDropFiles->fWide = FALSE;
  450. // we want drop point's coordinates in client area
  451. pDropFiles->fNC = FALSE;
  452. strcpy(pchDropFileName, (const char *)fnFullToDrag);
  453. // final null terminator as per CF_HDROP Format specs.
  454. pchDropFileName[strlen(pchDropFileName)+1]=0;
  455. GlobalUnlock(hGlobal);
  456. return hGlobal;
  457. }
  458. void CBrowseWindow::OnLButtonDown(UINT nFlags, CPoint point)
  459. {
  460. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  461. if( pVTNDir == NULL) return;
  462. // if we hitted icons tray
  463. if( (point.x < ICONS_TRAY_WIDTH*6) && (point.y < (ICONS_TRAY_HEIGHT + 1)) )
  464. {
  465. INDEX iSelected = point.x/ICONS_TRAY_WIDTH;
  466. switch( iSelected)
  467. {
  468. case 0: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MICRO; break;
  469. case 1: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_SMALL; break;
  470. case 2: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MEDIUM; break;
  471. case 3: pVTNDir->vtn_bmBrowsingMode = BM_ICONS_LARGE; break;
  472. case 4: pVTNDir->vtn_bmBrowsingMode = BM_DESCRIPTION; break;
  473. case 5: pVTNDir->vtn_bmBrowsingMode = BM_FILENAME; break;
  474. }
  475. Refresh();
  476. return;
  477. }
  478. // toggle hitted icon selection status
  479. FLOAT fDummyX, fDummyY;
  480. INDEX iHittedItem = HitItem( point, fDummyX, fDummyY);
  481. if( iHittedItem == -1) return;
  482. BOOL bShift = (nFlags & MK_SHIFT);
  483. BOOL bCtrl = (nFlags & MK_CONTROL);
  484. if( !bCtrl)
  485. {
  486. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  487. {
  488. it->vtn_bSelected = FALSE;
  489. }
  490. }
  491. INDEX ctItems = 0;
  492. {FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  493. {
  494. if( !it->vtn_bIsDirectory) ctItems++;
  495. }}
  496. INDEX iMin = iHittedItem;
  497. INDEX iMax = iHittedItem;
  498. if( bShift)
  499. {
  500. iMin = ClampDn( Min( m_iLastHittedItem, iHittedItem), (INDEX)0);
  501. iMax = ClampUp( Max( m_iLastHittedItem, iHittedItem), ctItems);
  502. }
  503. INDEX iCurrent = 0;
  504. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  505. {
  506. CVirtualTreeNode &vtn = *it;
  507. if( !vtn.vtn_bIsDirectory)
  508. {
  509. if( (iCurrent >= iMin) && (iCurrent <= iMax) )
  510. {
  511. if( bCtrl&&!bShift)
  512. {
  513. vtn.vtn_bSelected = !vtn.vtn_bSelected;
  514. }
  515. else
  516. {
  517. vtn.vtn_bSelected = TRUE;
  518. }
  519. }
  520. iCurrent++;
  521. }
  522. }
  523. if( !bShift) m_iLastHittedItem = iHittedItem;
  524. CVirtualTreeNode *pVTNHit = GetItem( iHittedItem);
  525. HGLOBAL hglobal = CreateHDrop( pVTNHit->vtn_fnItem);
  526. m_DataSource.CacheGlobalData( CF_HDROP, hglobal);
  527. m_DataSource.DoDragDrop( DROPEFFECT_COPY);
  528. Invalidate( FALSE);
  529. }
  530. void CBrowseWindow::OnDropFiles(HDROP hDropInfo)
  531. {
  532. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  533. INDEX iNoOfFiles = DragQueryFile( hDropInfo, 0xFFFFFFFF, NULL, 0);
  534. char chrFile[ 256];
  535. // get dropped coordinates
  536. CPoint point;
  537. DragQueryPoint( hDropInfo, &point);
  538. CVirtualTreeNode *pVTN = m_pBrowser->GetSelectedDirectory();
  539. if( pVTN != NULL)
  540. {
  541. CloseDirectory( pVTN);
  542. for( INDEX i=0; i<iNoOfFiles; i++)
  543. {
  544. DragQueryFileA( hDropInfo, i, chrFile, 256);
  545. CTFileName fnDroped = CTString(chrFile);
  546. if( fnDroped != CTString("") )
  547. {
  548. try
  549. {
  550. fnDroped.RemoveApplicationPath_t();
  551. InsertItem( fnDroped, point);
  552. }
  553. catch( char *err_str)
  554. {
  555. AfxMessageBox( CString(err_str));
  556. }
  557. }
  558. }
  559. OpenDirectory( pVTN);
  560. }
  561. else
  562. {
  563. AfxMessageBox( L"ERROR: Virtual tree doesn't exist.");
  564. }
  565. CWnd::OnDropFiles(hDropInfo);
  566. }
  567. CVirtualTreeNode *CBrowseWindow::GetItem( INDEX iItem) const
  568. {
  569. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  570. if( pVTNDir == NULL)
  571. {
  572. return NULL;
  573. }
  574. INDEX ct=0;
  575. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  576. {
  577. //
  578. if( !it->vtn_bIsDirectory)
  579. {
  580. if( ct == iItem)
  581. {
  582. return( &it.Current());
  583. }
  584. ct++;
  585. }
  586. }
  587. return NULL;
  588. }
  589. INDEX CBrowseWindow::GetItemNo( CVirtualTreeNode *pVTN)
  590. {
  591. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  592. if( pVTNDir == NULL)
  593. {
  594. return -1;
  595. }
  596. if( pVTNDir->vtn_lhChildren.IsEmpty())
  597. {
  598. return -1;
  599. }
  600. INDEX ct=0;
  601. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  602. {
  603. if( !it->vtn_bIsDirectory)
  604. {
  605. if( &it.Current() == pVTN)
  606. {
  607. return( ct);
  608. }
  609. ct++;
  610. }
  611. }
  612. return -1;
  613. }
  614. void CBrowseWindow::InsertItem( CTFileName fnItem, CPoint pt)
  615. {
  616. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  617. if( pVTNDir == NULL)
  618. {
  619. return;
  620. }
  621. FLOAT fHitXRatio;
  622. FLOAT fHitYRatio;
  623. INDEX iHittedItem = HitItem( pt, fHitXRatio, fHitYRatio);
  624. CVirtualTreeNode *pVTNHit = NULL;
  625. if( iHittedItem != -1)
  626. {
  627. pVTNHit = GetItem( iHittedItem);
  628. }
  629. CVirtualTreeNode *pvtnToRemove = NULL;
  630. // check for all items in current virtual tree directory
  631. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  632. {
  633. // if it isn't directory means that it is item
  634. if( !it->vtn_bIsDirectory)
  635. {
  636. // don't allow inserting same item twice
  637. if( it->vtn_fnItem == fnItem)
  638. {
  639. if( pt.x == -1) return;
  640. pvtnToRemove = &it.Current();
  641. }
  642. }
  643. }
  644. if( (pVTNHit == pvtnToRemove) && (pVTNHit != NULL) ) return;
  645. if( pvtnToRemove != NULL)
  646. {
  647. pvtnToRemove->vtn_lnInDirectory.Remove();
  648. if( pvtnToRemove->vtn_pTextureData != NULL)
  649. {
  650. _pTextureStock->Release( pvtnToRemove->vtn_pTextureData);
  651. }
  652. delete pvtnToRemove;
  653. }
  654. // if item is texture
  655. if( fnItem.FileExt() == ".tex")
  656. {
  657. CTextureData *ptdTexture;
  658. // try to
  659. try
  660. {
  661. // obtain texture
  662. ptdTexture = _pTextureStock->Obtain_t( fnItem);
  663. }
  664. // catch and
  665. catch( char *err_str)
  666. {
  667. // report errors
  668. AfxMessageBox( CString(err_str));
  669. return;
  670. }
  671. // now it must be valid
  672. ASSERT( ptdTexture != NULL);
  673. // get texture dimensions
  674. MEX mexWidth = ptdTexture->GetWidth();
  675. MEX mexHeight = ptdTexture->GetHeight();
  676. // release texture, we don't need it any more
  677. _pTextureStock->Release( ptdTexture);
  678. // mark both dimensions as incorrect
  679. BOOL bWidthOk = FALSE;
  680. BOOL bHeightOk = FALSE;
  681. // see if both width and height are potentions of 2
  682. for( INDEX i=0; i<32; i++)
  683. {
  684. // check width, mark if correct
  685. if( (1L << i) == mexWidth) bWidthOk = TRUE;
  686. if( (1L << i) == mexHeight) bHeightOk = TRUE;
  687. }
  688. // if width or height are not potentios of 2
  689. if( !bWidthOk || !bHeightOk)
  690. {
  691. char err_str[ 256];
  692. sprintf( err_str, "Dropped texture \"%s\" has incorrect dimensions %.2f x %.2f."
  693. "All textures must have dimensions that are potentions of 2.",
  694. (CTString&)fnItem, METERS_MEX( mexWidth), METERS_MEX( mexHeight));
  695. AfxMessageBox( CString(err_str));
  696. return;
  697. }
  698. }
  699. else if( fnItem.FileExt() == ".ecl")
  700. {
  701. // obtain class
  702. CEntityClass *pec = _pEntityClassStock->Obtain_t( fnItem);
  703. // get thumbnail file name from the class
  704. CTFileName fnThumbnail = CTString(pec->ec_pdecDLLClass->dec_strIconFileName);
  705. // release class
  706. _pEntityClassStock->Release( pec);
  707. // if thumbnail's name is "", don't add this item
  708. if( fnThumbnail == CTString("") )
  709. {
  710. return;
  711. }
  712. }
  713. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  714. CVirtualTreeNode *pVTN = new CVirtualTreeNode;
  715. pVTN->vtn_fnItem = fnItem;
  716. pVTN->vtn_bIsDirectory = FALSE;
  717. pVTN->vtn_strName = fnItem.FileName();
  718. if( pVTNDir->vtn_lhChildren.Count() == 0)
  719. {
  720. pVTN->vtn_bSelected = TRUE;
  721. }
  722. if( pt.x == -1)
  723. {
  724. pVTNDir->vtn_lhChildren.AddTail( pVTN->vtn_lnInDirectory);
  725. }
  726. else
  727. {
  728. if( iHittedItem == -1)
  729. {
  730. pVTNDir->vtn_lhChildren.AddTail( pVTN->vtn_lnInDirectory);
  731. }
  732. else if( ((m_IconsInLine != 1) && (fHitXRatio < 0.5f)) ||
  733. ((m_IconsInLine == 1) && (fHitYRatio < 0.5f)) )
  734. {
  735. ASSERT( pVTNHit != NULL);
  736. pVTNHit->vtn_lnInDirectory.AddBefore( pVTN->vtn_lnInDirectory);
  737. }
  738. else
  739. {
  740. ASSERT( pVTNHit != NULL);
  741. pVTNHit->vtn_lnInDirectory.AddAfter( pVTN->vtn_lnInDirectory);
  742. }
  743. }
  744. m_pBrowser->m_bVirtualTreeChanged = TRUE;
  745. Invalidate(FALSE);
  746. }
  747. void CBrowseWindow::DeleteSelectedItems()
  748. {
  749. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  750. if( pVTNDir == NULL)
  751. {
  752. return;
  753. }
  754. FORDELETELIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  755. {
  756. if( !it->vtn_bIsDirectory)
  757. {
  758. if( it->vtn_bSelected)
  759. {
  760. it->vtn_lnInDirectory.Remove();
  761. if( it->vtn_pTextureData != NULL)
  762. {
  763. _pTextureStock->Release( it->vtn_pTextureData);
  764. }
  765. delete &it.Current();
  766. }
  767. }
  768. }
  769. m_pBrowser->m_bVirtualTreeChanged = TRUE;
  770. Invalidate(FALSE);
  771. }
  772. void CBrowseWindow::Refresh(void)
  773. {
  774. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  775. if( (pVTNDir == NULL) || (!m_bDirectoryOpen) )
  776. {
  777. return;
  778. }
  779. switch( pVTNDir->vtn_bmBrowsingMode)
  780. {
  781. case BM_ICONS_MICRO:
  782. {
  783. m_IconWidth = 16;
  784. m_IconHeight = 16;
  785. break;
  786. }
  787. case BM_ICONS_SMALL:
  788. {
  789. m_IconWidth = 32;
  790. m_IconHeight = 32;
  791. break;
  792. }
  793. case BM_ICONS_MEDIUM:
  794. {
  795. m_IconWidth = 64;
  796. m_IconHeight = 64;
  797. break;
  798. }
  799. case BM_ICONS_LARGE:
  800. {
  801. m_IconWidth = 128;
  802. // allow some space for text
  803. m_IconHeight = 128 + STRING_HEIGHT;
  804. break;
  805. }
  806. case BM_DESCRIPTION:
  807. case BM_FILENAME:
  808. {
  809. m_IconWidth = m_BrowseWndWidth - 8;
  810. m_IconHeight = STRING_HEIGHT;
  811. break;
  812. }
  813. default:
  814. {
  815. ASSERTALWAYS( "Unrecognizible browsing type found !");
  816. }
  817. }
  818. m_IconsInLine = m_BrowseWndWidth/m_IconWidth;
  819. if( m_IconsInLine == 0)
  820. {
  821. m_IconsInLine = 1;
  822. }
  823. m_IconsInColumn = m_BrowseWndHeight/m_IconHeight + 1;
  824. m_IconsVisible = m_IconsInLine * m_IconsInColumn;
  825. INDEX iItemsCt = -1;
  826. if( !pVTNDir->vtn_lhChildren.IsEmpty())
  827. {
  828. iItemsCt = GetItemNo( LIST_TAIL( pVTNDir->vtn_lhChildren,
  829. CVirtualTreeNode, vtn_lnInDirectory) );
  830. }
  831. INDEX ctLines = iItemsCt/m_IconsInLine;
  832. SetScrollRange( SB_VERT, 0, ctLines*m_IconHeight);
  833. Invalidate(FALSE);
  834. }
  835. void CBrowseWindow::OpenDirectory( CVirtualTreeNode *pVTNDir)
  836. {
  837. CWorldEditorApp *pApp = (CWorldEditorApp *)AfxGetApp();
  838. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  839. if(m_bDirectoryOpen || pVTNDir==NULL)
  840. {
  841. return;
  842. }
  843. ASSERT( pVTNDir != NULL);
  844. // remember name of last opened virtual tree
  845. theApp.m_strOpenedVTDirectory = theApp.GetNameForVirtualTreeNode( pVTNDir);
  846. wchar_t achrOpenedDirectoryMessage[ 256];
  847. swprintf( achrOpenedDirectoryMessage, L"Opened directory: \"%s\"",
  848. CString(theApp.m_strOpenedVTDirectory));
  849. // put selected directory name into status line
  850. pMainFrame->m_wndStatusBar.SetPaneText( STATUS_LINE_PANE, achrOpenedDirectoryMessage, TRUE);
  851. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  852. {
  853. try
  854. {
  855. // if not directory
  856. if( !it->vtn_bIsDirectory)
  857. {
  858. CTFileName fnThumbnail; // thumbnail's file name
  859. // if texture
  860. if( it->vtn_fnItem.FileExt() == ".tex")
  861. {
  862. // use same texture for thumbnail
  863. fnThumbnail = it->vtn_fnItem;
  864. }
  865. // if world
  866. else if ( it->vtn_fnItem.FileExt() == ".wld")
  867. {
  868. // use file name with extension .tbn for thumbnail
  869. fnThumbnail = it->vtn_fnItem.FileDir() + it->vtn_fnItem.FileName() + ".tbn";
  870. // use base name for description
  871. it->vtn_strName = it->vtn_fnItem.FileName();
  872. }
  873. // if class
  874. else if ( it->vtn_fnItem.FileExt() == ".ecl")
  875. {
  876. // obtain class
  877. CEntityClass *pec = _pEntityClassStock->Obtain_t( it->vtn_fnItem);
  878. // get thumbnail file name from the class
  879. fnThumbnail = CTString(pec->ec_pdecDLLClass->dec_strIconFileName);
  880. // get description name from the class
  881. it->vtn_strName = pec->ec_pdecDLLClass->dec_strName;
  882. // release class
  883. _pEntityClassStock->Release( pec);
  884. }
  885. // if unknown extension
  886. else
  887. {
  888. // use no thumbnail
  889. fnThumbnail = CTString("");
  890. }
  891. // if no thumbnail
  892. if( fnThumbnail == "")
  893. {
  894. it->vtn_pTextureData = NULL;
  895. }
  896. // if there is valid thumbnail file name
  897. else
  898. {
  899. // obtain thumbnail
  900. it->vtn_pTextureData = _pTextureStock->Obtain_t( fnThumbnail);
  901. // must be valid
  902. ASSERT( it->vtn_pTextureData != NULL);
  903. // if it is really texture, type full info
  904. if( it->vtn_fnItem.FileExt() == ".tex")
  905. {
  906. // use base name and dimension for desription
  907. it->vtn_strName = (CTString&)it->vtn_fnItem+" "+it->vtn_pTextureData->GetDescription();
  908. }
  909. // else description is just item's file name
  910. else
  911. {
  912. it->vtn_strName = it->vtn_fnItem.FileName();
  913. }
  914. }
  915. }
  916. }
  917. catch( char *error)
  918. {
  919. // ingnore errors
  920. (void) error;
  921. it->vtn_pTextureData = NULL;
  922. }
  923. }
  924. SetScrollPos(SB_VERT, 0);
  925. m_bDirectoryOpen = TRUE;
  926. Refresh();
  927. Invalidate(FALSE);
  928. }
  929. void CBrowseWindow::CloseDirectory( CVirtualTreeNode *pVTN)
  930. {
  931. if( !m_bDirectoryOpen)
  932. {
  933. return;
  934. }
  935. ASSERT( pVTN != NULL);
  936. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTN->vtn_lhChildren, it)
  937. {
  938. if( !it->vtn_bIsDirectory)
  939. {
  940. if( it->vtn_pTextureData != NULL)
  941. {
  942. _pTextureStock->Release( it->vtn_pTextureData);
  943. it->vtn_pTextureData = NULL;
  944. }
  945. }
  946. }
  947. m_bDirectoryOpen = FALSE;
  948. }
  949. void CBrowseWindow::OnSize(UINT nType, int cx, int cy)
  950. {
  951. CWnd::OnSize(nType, cx, cy);
  952. // if window canvas is valid
  953. if( m_pViewPort!=NULL)
  954. {
  955. // resize it
  956. m_pViewPort->Resize();
  957. Refresh();
  958. }
  959. }
  960. void CBrowseWindow::OnInsertItems()
  961. {
  962. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  963. if( pVTNDir == NULL)
  964. {
  965. AfxMessageBox( L"ERROR: Virtual tree doesn't exist.");
  966. return;
  967. }
  968. char *pFilters = "Items (*.tex, *.wld, *.ecl)\0*.tex;*.wld;*.ecl\0"
  969. "World Files (*.wld)\0*.wld\0"
  970. "Texture files (*.tex)\0*.tex\0"
  971. "Class files (*.ecl)\0*.ecl\0"
  972. "All files (*.*)\0*.*\0\0";
  973. // call file requester for opening textures
  974. CDynamicArray<CTFileName> afnItems;
  975. _EngineGUI.FileRequester( "Insert items", pFilters, KEY_NAME_CREATE_TEXTURE_DIR,
  976. "Textures\\", "", &afnItems);
  977. if( afnItems.Count() == 0) return;
  978. // insert items
  979. FOREACHINDYNAMICARRAY( afnItems, CTFileName, itItem)
  980. {
  981. try
  982. {
  983. InsertItem( *itItem, CPoint(-1, -1));
  984. }
  985. catch( char *err_str)
  986. {
  987. AfxMessageBox( CString(err_str));
  988. }
  989. }
  990. CloseDirectory( pVTNDir);
  991. OpenDirectory( pVTNDir);
  992. }
  993. void CBrowseWindow::OnDeleteItems()
  994. {
  995. DeleteSelectedItems();
  996. }
  997. void CBrowseWindow::OnBigIcons()
  998. {
  999. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1000. ASSERT( pVTNDir != NULL);
  1001. pVTNDir->vtn_bmBrowsingMode = BM_ICONS_LARGE;
  1002. Refresh();
  1003. }
  1004. void CBrowseWindow::OnMediumIcons()
  1005. {
  1006. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1007. ASSERT( pVTNDir != NULL);
  1008. pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MEDIUM;
  1009. Refresh();
  1010. }
  1011. void CBrowseWindow::OnMicroIcons()
  1012. {
  1013. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1014. ASSERT( pVTNDir != NULL);
  1015. pVTNDir->vtn_bmBrowsingMode = BM_ICONS_MICRO;
  1016. Refresh();
  1017. }
  1018. void CBrowseWindow::OnSmallIcons()
  1019. {
  1020. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1021. ASSERT( pVTNDir != NULL);
  1022. pVTNDir->vtn_bmBrowsingMode = BM_ICONS_SMALL;
  1023. Refresh();
  1024. }
  1025. void CBrowseWindow::OnShowDescription()
  1026. {
  1027. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1028. ASSERT( pVTNDir != NULL);
  1029. pVTNDir->vtn_bmBrowsingMode = BM_DESCRIPTION;
  1030. Refresh();
  1031. }
  1032. void CBrowseWindow::OnShowFilename()
  1033. {
  1034. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1035. ASSERT( pVTNDir != NULL);
  1036. pVTNDir->vtn_bmBrowsingMode = BM_FILENAME;
  1037. Refresh();
  1038. }
  1039. void CBrowseWindow::OnLButtonDblClk(UINT nFlags, CPoint point)
  1040. {
  1041. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  1042. // get hitted item's index
  1043. FLOAT fDummyX, fDummyY;
  1044. INDEX iHittedItem = HitItem( point, fDummyX, fDummyY);
  1045. // if hit none reported, return
  1046. if( iHittedItem == -1)
  1047. {
  1048. return;
  1049. }
  1050. // get item object from hitted index
  1051. CVirtualTreeNode *pVTN = GetItem( iHittedItem);
  1052. // must not be null
  1053. ASSERT( pVTN != NULL);
  1054. // get item's file name
  1055. CTFileName fnItem = pVTN->vtn_fnItem;
  1056. // if it is texture
  1057. if( fnItem.FileExt() == ".tex")
  1058. {
  1059. CWorldEditorDoc *pDoc = theApp.GetDocument();
  1060. if(pDoc!=NULL && pDoc->GetEditingMode()==TERRAIN_MODE)
  1061. {
  1062. CTerrainLayer *ptlLayer=GetLayer();
  1063. CTerrain *ptTerrain=GetTerrain();
  1064. if(ptlLayer!=NULL && ptTerrain!=NULL)
  1065. {
  1066. try
  1067. {
  1068. ptlLayer->SetLayerTexture_t(fnItem);
  1069. theApp.m_ctTerrainPageCanvas.MarkChanged();
  1070. ptTerrain->RefreshTerrain();
  1071. }
  1072. catch(char *strError)
  1073. {
  1074. (void) strError;
  1075. }
  1076. }
  1077. }
  1078. else
  1079. {
  1080. // set it as new primitive's material default texture
  1081. theApp.SetNewActiveTexture( _fnmApplicationPath + fnItem);
  1082. // paste new active texture over polygon selection
  1083. theApp.TexturizeSelection();
  1084. }
  1085. }
  1086. // if it is world (template)
  1087. else if( fnItem.FileExt() == ".wld")
  1088. {
  1089. // open document with item's file name
  1090. theApp.m_pDocTemplate->OpenDocumentFile( CString(_fnmApplicationPath + fnItem));
  1091. }
  1092. }
  1093. void CBrowseWindow::OnRecreateTexture()
  1094. {
  1095. if( _bRightClickedIsSelected)
  1096. {
  1097. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1098. ASSERT( pVTNDir != NULL);
  1099. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  1100. {
  1101. if( it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tex") )
  1102. {
  1103. _EngineGUI.CreateTexture( it->vtn_fnItem);
  1104. }
  1105. }
  1106. }
  1107. else if( _fnRightClickedItemFileName.FileExt()==CTString(".tex"))
  1108. {
  1109. _EngineGUI.CreateTexture( _fnRightClickedItemFileName);
  1110. }
  1111. Refresh();
  1112. CWorldEditorDoc *pDoc = theApp.GetDocument();
  1113. if( pDoc != NULL) pDoc->UpdateAllViews( NULL);
  1114. }
  1115. void CBrowseWindow::OnSelectByTextureInSelectedSectors()
  1116. {
  1117. SelectByTextures( TRUE, FALSE);
  1118. }
  1119. void CBrowseWindow::OnCreateAndAddTexture()
  1120. {
  1121. CDynamicArray<CTFileName> afnCreatedTextures;
  1122. CTFileName fnCreatedTexture = _EngineGUI.CreateTexture( CTString(""), &afnCreatedTextures);
  1123. if( afnCreatedTextures.Count() != 0)
  1124. {
  1125. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1126. if( pVTNDir != NULL)
  1127. {
  1128. CloseDirectory( pVTNDir);
  1129. }
  1130. // insert created textures
  1131. FOREACHINDYNAMICARRAY( afnCreatedTextures, CTFileName, itTexture)
  1132. {
  1133. CTFileName &fn=*itTexture;
  1134. InsertItem( fn, CPoint(-1, -1));
  1135. }
  1136. if( pVTNDir != NULL)
  1137. {
  1138. OpenDirectory( pVTNDir);
  1139. }
  1140. }
  1141. }
  1142. void CBrowseWindow::OnSelectForDropMarker()
  1143. {
  1144. theApp.m_fnClassForDropMarker = _fnRightClickedItemFileName;
  1145. }
  1146. void CBrowseWindow::OnSetAsCurrentTexture()
  1147. {
  1148. // set it as new primitive's material default texture
  1149. theApp.SetNewActiveTexture( _fnmApplicationPath + _fnRightClickedItemFileName);
  1150. }
  1151. void CBrowseWindow::OnConvertClass()
  1152. {
  1153. if( _fnRightClickedItemFileName.FileExt()!=CTString(".ecl"))
  1154. {
  1155. WarningMessage( "Only classes can be used for converting classe");
  1156. return;
  1157. }
  1158. try
  1159. {
  1160. CWorldEditorDoc *pDoc = theApp.GetDocument();
  1161. FOREACHINDYNAMICCONTAINER(pDoc->m_selEntitySelection, CEntity, iten)
  1162. {
  1163. // create the entity of requested class
  1164. CEntity *penNewClass;
  1165. penNewClass = pDoc->m_woWorld.CreateEntity_t(
  1166. iten->GetPlacement(), _fnRightClickedItemFileName);
  1167. // try to copy entity properties
  1168. CDLLEntityClass *pdecDLLClassNew = penNewClass->GetClass()->ec_pdecDLLClass;
  1169. for(;pdecDLLClassNew!=NULL; pdecDLLClassNew = pdecDLLClassNew->dec_pdecBase)
  1170. {
  1171. for(INDEX iPropertyNew=0; iPropertyNew<pdecDLLClassNew->dec_ctProperties; iPropertyNew++)
  1172. {
  1173. CEntityProperty &epPropertyNew = pdecDLLClassNew->dec_aepProperties[iPropertyNew];
  1174. CDLLEntityClass *pdecDLLClassOld = iten->GetClass()->ec_pdecDLLClass;
  1175. for(;pdecDLLClassOld!=NULL; pdecDLLClassOld = pdecDLLClassOld->dec_pdecBase)
  1176. {
  1177. for(INDEX iPropertyOld=0; iPropertyOld<pdecDLLClassOld->dec_ctProperties; iPropertyOld++)
  1178. {
  1179. CEntityProperty &epPropertyOld = pdecDLLClassOld->dec_aepProperties[iPropertyOld];
  1180. if( (CTString(epPropertyNew.ep_strName) == epPropertyOld.ep_strName) &&
  1181. (epPropertyNew.ep_eptType == epPropertyOld.ep_eptType) )
  1182. {
  1183. penNewClass->CopyOneProperty( epPropertyOld, epPropertyNew, *iten, FALSE);
  1184. }
  1185. }
  1186. }
  1187. }
  1188. }
  1189. // prepare the entity
  1190. penNewClass->Initialize();
  1191. }
  1192. CWorldEditorView *pWorldEditorView = theApp.GetActiveView();
  1193. if( pWorldEditorView != NULL)
  1194. {
  1195. pWorldEditorView->OnDeleteEntities();
  1196. }
  1197. }
  1198. catch( char *err_str)
  1199. {
  1200. AfxMessageBox( CString(err_str));
  1201. }
  1202. }
  1203. static void GetToolTipText(void *pBrowser, char *pToolTipText)
  1204. {
  1205. CBrowseWindow *pBrowseWindow = (CBrowseWindow *) pBrowser;
  1206. pBrowseWindow->GetToolTipText( pToolTipText);
  1207. }
  1208. void CBrowseWindow::GetToolTipText( char *pToolTipText)
  1209. {
  1210. CPoint point;
  1211. ::GetCursorPos(&point);
  1212. ScreenToClient(&point);
  1213. // get hitted item's index
  1214. FLOAT fDummyX, fDummyY;
  1215. INDEX iHittedItem = HitItem( point, fDummyX, fDummyY);
  1216. // if hit none reported, return
  1217. if( iHittedItem == -1)
  1218. {
  1219. strcpy( pToolTipText, "");
  1220. return;
  1221. }
  1222. // get item object from hitted index
  1223. CVirtualTreeNode *pVTN = GetItem( iHittedItem);
  1224. strcpy(pToolTipText, pVTN->vtn_strName);
  1225. }
  1226. void CBrowseWindow::OnMouseMove(UINT nFlags, CPoint point)
  1227. {
  1228. theApp.m_cttToolTips.MouseMoveNotify( m_hWnd, 500, &::GetToolTipText, this);
  1229. CWnd::OnMouseMove(nFlags, point);
  1230. }
  1231. void CBrowseWindow::OnSelectByTextureInWorld()
  1232. {
  1233. SelectByTextures( FALSE, FALSE);
  1234. }
  1235. void CBrowseWindow::OnSelectExceptTextures( void)
  1236. {
  1237. SelectByTextures( FALSE, TRUE);
  1238. }
  1239. void CBrowseWindow::SelectByTextures( BOOL bInSelectedSectors, BOOL bExceptSelected)
  1240. {
  1241. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1242. CWorldEditorDoc *pDoc = theApp.GetDocument();
  1243. if( pDoc == NULL) return;
  1244. // for each entity in the world
  1245. FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten) {
  1246. // if it is brush entity
  1247. if (iten->en_RenderType == CEntity::RT_BRUSH) {
  1248. // for each mip in its brush
  1249. FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm) {
  1250. // for all sectors in this mip
  1251. FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc) {
  1252. // if sector is selected
  1253. if( !bInSelectedSectors || itbsc->IsSelected(BSCF_SELECTED))
  1254. {
  1255. // for all polygons in sector
  1256. FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
  1257. {
  1258. // if it is not non translucent portal and is not selected and has same texture
  1259. if ( /*(!(itbpo->bpo_ulFlags&BPOF_PORTAL) || (itbpo->bpo_ulFlags&BPOF_TRANSLUCENT) ||
  1260. (itbpo->bpo_bppProperties.bpp_uwPretenderDistance!=0) ) &&*/
  1261. !itbpo->IsSelected(BPOF_SELECTED) &&
  1262. (itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData() != NULL) )
  1263. {
  1264. CTFileName fnTexture = itbpo->bpo_abptTextures[pDoc->m_iTexture].bpt_toTexture.GetData()->GetName();
  1265. BOOL bSelect = bExceptSelected;
  1266. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  1267. {
  1268. if( _bRightClickedIsSelected)
  1269. {
  1270. if(it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tex") &&
  1271. fnTexture == it->vtn_fnItem)
  1272. {
  1273. bSelect = !bExceptSelected;
  1274. break;
  1275. }
  1276. }
  1277. else if( fnTexture == _fnRightClickedItemFileName)
  1278. {
  1279. bSelect = !bExceptSelected;
  1280. break;
  1281. }
  1282. }
  1283. if( bSelect) pDoc->m_selPolygonSelection.Select(*itbpo);
  1284. }
  1285. }
  1286. }
  1287. }
  1288. }
  1289. }
  1290. }
  1291. pDoc->SetEditingMode( POLYGON_MODE);
  1292. pDoc->m_chSelections.MarkChanged();
  1293. pDoc->UpdateAllViews( NULL);
  1294. }
  1295. void CBrowseWindow::OnAddTexturesFromWorld()
  1296. {
  1297. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1298. CWorldEditorDoc *pDoc = theApp.GetDocument();
  1299. if (pDoc == NULL) return;
  1300. CloseDirectory( pVTNDir);
  1301. // for each entity in the world
  1302. FOREACHINDYNAMICCONTAINER(pDoc->m_woWorld.wo_cenEntities, CEntity, iten) {
  1303. // if it is brush entity
  1304. if (iten->en_RenderType == CEntity::RT_BRUSH) {
  1305. // for each mip in its brush
  1306. FOREACHINLIST(CBrushMip, bm_lnInBrush, iten->en_pbrBrush->br_lhBrushMips, itbm) {
  1307. // for all sectors in this mip
  1308. FOREACHINDYNAMICARRAY(itbm->bm_abscSectors, CBrushSector, itbsc) {
  1309. // for all polygons in sector
  1310. FOREACHINSTATICARRAY(itbsc->bsc_abpoPolygons, CBrushPolygon, itbpo)
  1311. {
  1312. try
  1313. {
  1314. CTextureObject &to1 = itbpo->bpo_abptTextures[0].bpt_toTexture;
  1315. if(to1.GetData() != NULL)
  1316. InsertItem( to1.GetData()->GetName(), CPoint(-1, -1));
  1317. CTextureObject &to2 = itbpo->bpo_abptTextures[1].bpt_toTexture;
  1318. if(to2.GetData() != NULL)
  1319. InsertItem( to2.GetData()->GetName(), CPoint(-1, -1));
  1320. CTextureObject &to3 = itbpo->bpo_abptTextures[2].bpt_toTexture;
  1321. if(to3.GetData() != NULL)
  1322. InsertItem( to3.GetData()->GetName(), CPoint(-1, -1));
  1323. }
  1324. catch( char *err_str)
  1325. {
  1326. AfxMessageBox( CString(err_str));
  1327. }
  1328. }
  1329. }
  1330. }
  1331. }
  1332. }
  1333. OpenDirectory( pVTNDir);
  1334. }
  1335. void CBrowseWindow::OnShowTreeShortcuts()
  1336. {
  1337. CMainFrame* pMainFrame = STATIC_DOWNCAST(CMainFrame, AfxGetMainWnd());
  1338. pMainFrame->OnShowTreeShortcuts();
  1339. }
  1340. void ExportTexture( CTFileName fnTexture)
  1341. {
  1342. CTextureData *ptd;
  1343. CImageInfo ii;
  1344. try
  1345. {
  1346. ptd = _pTextureStock->Obtain_t( fnTexture);
  1347. for( INDEX iFrame=0; iFrame<ptd->td_ctFrames; iFrame++)
  1348. {
  1349. ptd->Export_t( ii, iFrame);
  1350. // obtain name for export file
  1351. CTFileName fnFrame;
  1352. if( ptd->td_ctFrames == 1)
  1353. {
  1354. fnFrame = fnTexture.NoExt()+".tga";
  1355. }
  1356. else
  1357. {
  1358. fnFrame.PrintF("%s%03d.tga", (const char *)fnTexture.NoExt(), iFrame);
  1359. }
  1360. // if file exists, ask for substitution name
  1361. if( FileExists( fnFrame) && iFrame==0 )
  1362. {
  1363. CTString strDefaultDir = fnFrame.FileDir();
  1364. CTString strDefaultFile = fnFrame.FileName()+fnFrame.FileExt();
  1365. // invoke "Save as" dialog
  1366. fnFrame = _EngineGUI.FileRequester( "Save As", FILTER_TGA FILTER_END,
  1367. "Export texture directory", strDefaultDir, strDefaultFile, NULL, FALSE);
  1368. }
  1369. if( fnFrame != "")
  1370. {
  1371. ii.SaveTGA_t(fnFrame);
  1372. ii.Clear();
  1373. }
  1374. }
  1375. }
  1376. catch( char *strError)
  1377. {
  1378. AfxMessageBox( CString(strError));
  1379. ii.Clear();
  1380. }
  1381. }
  1382. void CBrowseWindow::OnExportTexture()
  1383. {
  1384. if( _bRightClickedIsSelected)
  1385. {
  1386. CVirtualTreeNode *pVTNDir = m_pBrowser->GetSelectedDirectory();
  1387. ASSERT( pVTNDir != NULL);
  1388. FOREACHINLIST( CVirtualTreeNode, vtn_lnInDirectory, pVTNDir->vtn_lhChildren, it)
  1389. {
  1390. if( it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tex") ||
  1391. it->vtn_bSelected && it->vtn_fnItem.FileExt()==CTString(".tbn") )
  1392. {
  1393. ExportTexture( it->vtn_fnItem);
  1394. }
  1395. }
  1396. }
  1397. else if( _fnRightClickedItemFileName.FileExt()==CTString(".tex") ||
  1398. _fnRightClickedItemFileName.FileExt()==CTString(".tbn") )
  1399. {
  1400. ExportTexture( _fnRightClickedItemFileName);
  1401. }
  1402. }
  1403. void CBrowseWindow::OnBrowserContextHelp()
  1404. {
  1405. if( _fnRightClickedItemFileName.FileExt()==CTString(".ecl"))
  1406. {
  1407. theApp.DisplayHelp(_fnRightClickedItemFileName, HH_DISPLAY_TOPIC, NULL);
  1408. }
  1409. }