FileRequester.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  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. #include "stdh.h"
  13. #include <Engine/Templates/Stock_CTextureData.h>
  14. // thumbnail window
  15. static CWnd _wndThumbnail;
  16. CDrawPort *_pDrawPort = NULL;
  17. CViewPort *_pViewPort = NULL;
  18. static INDEX gui_bEnableRequesterThumbnails=TRUE;
  19. UINT APIENTRY FileOpenRequesterHook( HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
  20. {
  21. _pShell->DeclareSymbol("persistent user INDEX gui_bEnableRequesterThumbnails;", &gui_bEnableRequesterThumbnails);
  22. if( !gui_bEnableRequesterThumbnails)
  23. {
  24. return 0;
  25. }
  26. CTextureData *pTextureData = NULL;
  27. if( uiMsg == WM_NOTIFY)
  28. {
  29. // obtain file open notification structure
  30. OFNOTIFY *pONNotify = (OFNOTIFY *) lParam;
  31. // obtain notification message header structure
  32. NMHDR *pNMHeader = &pONNotify->hdr;
  33. if(pNMHeader->code == CDN_INITDONE)
  34. {
  35. HWND hwnd = GetDlgItem( hdlg, IDC_THUMBNAIL_RECT);
  36. RECT rect;
  37. BOOL bSuccess = GetClientRect( hwnd, &rect);
  38. POINT pointParent;
  39. pointParent.x=0;
  40. pointParent.y=0;
  41. POINT pointThumbnail;
  42. pointThumbnail.x=0;
  43. pointThumbnail.y=0;
  44. ClientToScreen(hdlg, &pointParent);
  45. ClientToScreen(hwnd, &pointThumbnail);
  46. POINT point;
  47. point.x = pointThumbnail.x-pointParent.x;
  48. point.y = pointThumbnail.y-pointParent.y;
  49. OffsetRect(&rect, point.x, point.y);
  50. if( !bSuccess)
  51. {
  52. ASSERT( FALSE);
  53. return 0;
  54. }
  55. PIX pixLeft = 120;
  56. PIX pixTop = 250;
  57. // try to create thumbnail window
  58. _wndThumbnail.Create( NULL, NULL, WS_BORDER|WS_VISIBLE, rect,
  59. CWnd::FromHandle(hdlg), IDW_FILE_THUMBNAIL);
  60. /*_wndThumbnail.Create( NULL, NULL, WS_BORDER|WS_VISIBLE,
  61. CRect( pixLeft, pixTop, pixLeft+128, pixTop+128),
  62. CWnd::FromHandle(hdlg), IDW_FILE_THUMBNAIL);
  63. */
  64. // initialize canvas for thumbnail window
  65. _pGfx->CreateWindowCanvas( _wndThumbnail.m_hWnd, &_pViewPort, &_pDrawPort);
  66. }
  67. char strSelectedFullPath[ PATH_MAX];
  68. CTFileName fnSelectedFileFullPath;
  69. // obtain selected file's path
  70. CommDlg_OpenSave_GetFilePath(GetParent(hdlg), &strSelectedFullPath, PATH_MAX);
  71. // if multi select was turned on
  72. fnSelectedFileFullPath = CTString(strSelectedFullPath);
  73. // try to
  74. try
  75. {
  76. // remove application path
  77. fnSelectedFileFullPath.RemoveApplicationPath_t();
  78. CTFileName fnThumbnail = CTString("");
  79. if( (fnSelectedFileFullPath.FileExt() == ".wld") ||
  80. (fnSelectedFileFullPath.FileExt() == ".mdl") )
  81. {
  82. fnThumbnail = fnSelectedFileFullPath.FileDir()+fnSelectedFileFullPath.FileName()+".tbn";
  83. }
  84. else if( (fnSelectedFileFullPath.FileExt() == ".tex") ||
  85. (fnSelectedFileFullPath.FileExt() == ".tbn") )
  86. {
  87. fnThumbnail = fnSelectedFileFullPath;
  88. }
  89. else if( (fnSelectedFileFullPath.FileExt() == ".pcx") ||
  90. (fnSelectedFileFullPath.FileExt() == ".tga") )
  91. {
  92. CImageInfo iiImageInfo;
  93. iiImageInfo.LoadAnyGfxFormat_t( fnSelectedFileFullPath);
  94. // both dimension must be potentions of 2
  95. if( (iiImageInfo.ii_Width == 1<<((int)Log2( iiImageInfo.ii_Width))) &&
  96. (iiImageInfo.ii_Height == 1<<((int)Log2( iiImageInfo.ii_Height))) )
  97. {
  98. fnThumbnail = CTString( "Temp\\Temp.tex");
  99. // creates new texture with one frame
  100. CTextureData tdForPictureConverting;
  101. tdForPictureConverting.Create_t( &iiImageInfo, iiImageInfo.ii_Width, 1, FALSE);
  102. tdForPictureConverting.Save_t( fnThumbnail);
  103. }
  104. }
  105. if( fnThumbnail != "")
  106. {
  107. // obtain thumbnail
  108. pTextureData = _pTextureStock->Obtain_t( fnThumbnail);
  109. pTextureData->Reload();
  110. }
  111. }
  112. catch( char* err_str)
  113. {
  114. (void)err_str;
  115. pTextureData = NULL;
  116. }
  117. if( IsWindow( _wndThumbnail) )
  118. {
  119. // if there is a valid drawport, and the drawport can be locked
  120. if( (_pDrawPort != NULL) && (_pDrawPort->Lock()) )
  121. {
  122. PIXaabbox2D rectPict;
  123. rectPict = PIXaabbox2D( PIX2D(0, 0),
  124. PIX2D(_pDrawPort->GetWidth(), _pDrawPort->GetHeight()));
  125. // clear texture area to black
  126. _pDrawPort->Fill( C_BLACK|CT_OPAQUE);
  127. // erase z-buffer
  128. _pDrawPort->FillZBuffer(ZBUF_BACK);
  129. // if there is valid active texture
  130. if( pTextureData != NULL)
  131. {
  132. CTextureObject toPreview;
  133. toPreview.SetData( pTextureData);
  134. _pDrawPort->PutTexture( &toPreview, rectPict);
  135. CWnd::FromHandle( GetDlgItem( hdlg, IDC_THUMBNAIL_DESCRIPTION))->SetWindowText(
  136. CString(pTextureData->GetDescription()));
  137. // release the texture
  138. _pTextureStock->Release( pTextureData);
  139. }
  140. else
  141. {
  142. // no thumbnail, draw crossed lines
  143. PIX pixRad = Max( _pDrawPort->GetWidth(), _pDrawPort->GetWidth()) * 3/4/2;
  144. PIX CX = _pDrawPort->GetWidth()/2;
  145. PIX CY = _pDrawPort->GetWidth()/2;
  146. for( INDEX iPix=-2;iPix<2;iPix++)
  147. {
  148. _pDrawPort->DrawLine( CX-pixRad+iPix, CY-pixRad, CX+pixRad+iPix, CY+pixRad, C_RED|CT_OPAQUE);
  149. _pDrawPort->DrawLine( CX-pixRad+iPix, CY+pixRad, CX+pixRad+iPix, CY-pixRad, C_RED|CT_OPAQUE);
  150. }
  151. CWnd::FromHandle( GetDlgItem( hdlg, IDC_THUMBNAIL_DESCRIPTION))->SetWindowText( L"No thumbnail");
  152. }
  153. // unlock the drawport
  154. _pDrawPort->Unlock();
  155. }
  156. // if there is a valid viewport
  157. if (_pViewPort!=NULL)
  158. {
  159. // swap it
  160. _pViewPort->SwapBuffers();
  161. }
  162. }
  163. }
  164. return 0;
  165. }
  166. CTFileName CEngineGUI::FileRequester(
  167. char *pchrTitle/*="Choose file"*/,
  168. char *pchrFilters/*=FILTER_ALL FILTER_END*/,
  169. char *pchrRegistry/*="KEY_NAME_REQUEST_FILE_DIR"*/,
  170. CTString strDefaultDir/*=""*/,
  171. CTString strFileSelectedByDefault/*=""*/,
  172. CDynamicArray<CTFileName> *pafnSelectedFiles/*=NULL*/,
  173. BOOL bIfOpen/*=TRUE*/)
  174. {
  175. _pDrawPort = NULL;
  176. _pViewPort = NULL;
  177. // stupid way to change resources, but it must be done
  178. HANDLE hOldResource = AfxGetResourceHandle();
  179. // activate CTGfx resources
  180. AfxSetResourceHandle( GetModuleHandleA(ENGINEGUI_DLL_NAME) );
  181. // call multiple file requester
  182. char chrFiles[ 2048];
  183. OPENFILENAMEA ofnRequestFiles;
  184. memset( &ofnRequestFiles, 0, sizeof( OPENFILENAME));
  185. ofnRequestFiles.lStructSize = sizeof(OPENFILENAME);
  186. ofnRequestFiles.hwndOwner = AfxGetMainWnd()->m_hWnd;
  187. ofnRequestFiles.lpstrFilter = pchrFilters;
  188. ofnRequestFiles.lpstrFile = chrFiles;
  189. sprintf( chrFiles, "%s", strFileSelectedByDefault);
  190. ofnRequestFiles.nMaxFile = 2048;
  191. CString strRequestInDirectory = _fnmApplicationPath+strDefaultDir;
  192. if( pchrRegistry != NULL)
  193. {
  194. strRequestInDirectory = AfxGetApp()->GetProfileString(L"Scape", CString(pchrRegistry),
  195. CString(_fnmApplicationPath+strDefaultDir));
  196. }
  197. // if directory is not inside engine dir
  198. CTString strTest = CStringA(strRequestInDirectory);
  199. if (!strTest.RemovePrefix(_fnmApplicationPath)) {
  200. // force it there
  201. strRequestInDirectory = _fnmApplicationPath;
  202. }
  203. ofnRequestFiles.lpstrInitialDir = CStringA(strRequestInDirectory);
  204. ofnRequestFiles.lpstrTitle = pchrTitle;
  205. ofnRequestFiles.Flags = OFN_EXPLORER | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE | OFN_HIDEREADONLY;
  206. // setup preview dialog
  207. ofnRequestFiles.lpfnHook = &::FileOpenRequesterHook;
  208. ofnRequestFiles.hInstance = GetModuleHandleA(ENGINEGUI_DLL_NAME);
  209. ofnRequestFiles.lpTemplateName = MAKEINTRESOURCEA( IDD_GFX_FILE_REQUESTER);
  210. // allow multi select
  211. if( pafnSelectedFiles != NULL) ofnRequestFiles.Flags |= OFN_ALLOWMULTISELECT;
  212. ofnRequestFiles.lpstrDefExt = "";
  213. BOOL bResult;
  214. if( bIfOpen)
  215. {
  216. bResult = GetOpenFileNameA( &ofnRequestFiles);
  217. }
  218. else
  219. {
  220. bResult = GetSaveFileNameA( &ofnRequestFiles);
  221. }
  222. if( bResult)
  223. {
  224. // if multiple file requester is called
  225. if( pafnSelectedFiles != NULL)
  226. {
  227. chrFiles[ ofnRequestFiles.nFileOffset-1] = 0;
  228. if( pchrRegistry != NULL)
  229. {
  230. AfxGetApp()->WriteProfileString(L"Scape", CString(pchrRegistry), CString(chrFiles));
  231. }
  232. CTFileName fnDirectory = CTString( chrFiles) + "\\";
  233. INDEX iOffset = ofnRequestFiles.nFileOffset;
  234. FOREVER
  235. {
  236. try
  237. {
  238. if( CTString( chrFiles + iOffset) == "")
  239. {
  240. // restore resources
  241. AfxSetResourceHandle( (HINSTANCE) hOldResource);
  242. return( CTString( "Multiple files selected"));
  243. }
  244. CTFileName fnSource = fnDirectory + CTString( chrFiles + iOffset);
  245. // remove application path
  246. fnSource.RemoveApplicationPath_t();
  247. CTFileName *pfnSelectedFile = pafnSelectedFiles->New();
  248. *pfnSelectedFile = fnSource;
  249. }
  250. catch( char *strError)
  251. {
  252. WarningMessage( strError);
  253. // restore resources
  254. AfxSetResourceHandle( (HINSTANCE) hOldResource);
  255. // return error
  256. return( CTString( ""));
  257. }
  258. iOffset += strlen( chrFiles + iOffset) + 1;
  259. }
  260. }
  261. else
  262. {
  263. CString strChooseFilePath = chrFiles;
  264. strChooseFilePath.SetAt( ofnRequestFiles.nFileOffset, 0);
  265. if( pchrRegistry != NULL)
  266. {
  267. AfxGetApp()->WriteProfileString(L"Scape", CString(pchrRegistry), strChooseFilePath);
  268. }
  269. CTFileName fnResult = CTString( chrFiles);
  270. try
  271. {
  272. fnResult.RemoveApplicationPath_t();
  273. }
  274. catch( char *strError)
  275. {
  276. WarningMessage( strError);
  277. // restore resources
  278. AfxSetResourceHandle( (HINSTANCE) hOldResource);
  279. // return error
  280. return( CTString( ""));
  281. }
  282. // restore resources
  283. AfxSetResourceHandle( (HINSTANCE) hOldResource);
  284. return fnResult;
  285. }
  286. }
  287. if( _pViewPort != NULL)
  288. {
  289. _pGfx->DestroyWindowCanvas( _pViewPort);
  290. _pViewPort = NULL;
  291. }
  292. // restore resources
  293. AfxSetResourceHandle( (HINSTANCE) hOldResource);
  294. // return error
  295. return CTString( "");
  296. }
  297. ENGINEGUI_API CTFileName FileRequester(
  298. char *pchrTitle,
  299. char *pchrFilters,
  300. char *pchrRegistry,
  301. char *pchrFileSelectedByDefault)
  302. {
  303. return _EngineGUI.FileRequester(pchrTitle, pchrFilters, pchrRegistry, "", pchrFileSelectedByDefault);
  304. }
  305. CTFileName CEngineGUI::BrowseTexture(CTFileName fnDefaultSelected/*=""*/,
  306. char *pchrIniKeyName/*=KEY_NAME_REQUEST_FILE_DIR*/,
  307. char *pchrWindowTitle/*="Choose texture"*/,
  308. BOOL bIfOpen/*=TRUE*/)
  309. {
  310. return FileRequester( pchrWindowTitle, FILTER_TEX FILTER_END, pchrIniKeyName,
  311. "Textures\\", fnDefaultSelected, NULL, bIfOpen);
  312. }