GEApp.cpp 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385
  1. /*
  2. ===========================================================================
  3. Doom 3 GPL Source Code
  4. Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
  6. Doom 3 Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 Source Code 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. You should have received a copy of the GNU General Public License
  15. along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "../../idlib/precompiled.h"
  21. #pragma hdrstop
  22. #include <io.h>
  23. #include "../../sys/win32/rc/guied_resource.h"
  24. #include "../../ui/DeviceContext.h"
  25. #include "GEApp.h"
  26. #include "GEOptionsDlg.h"
  27. #include "GEViewer.h"
  28. static const int IDM_WINDOWCHILD = 1000;
  29. static const int ID_GUIED_FILE_MRU1 = 10000;
  30. static INT_PTR CALLBACK AboutDlg_WndProc ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
  31. {
  32. switch ( msg )
  33. {
  34. case WM_COMMAND:
  35. EndDialog ( hwnd, 1 );
  36. break;
  37. }
  38. return FALSE;
  39. }
  40. rvGEApp::rvGEApp ( )
  41. {
  42. mMDIFrame = NULL;
  43. mMDIClient = NULL;
  44. mRecentFileMenu = NULL;
  45. mViewer = NULL;
  46. mRecentFileInsertPos = 0;
  47. }
  48. rvGEApp::~rvGEApp ( )
  49. {
  50. DestroyAcceleratorTable ( mAccelerators );
  51. }
  52. /*
  53. ================
  54. rvGEApp::Initialize
  55. Initialize the gui editor application
  56. ================
  57. */
  58. bool rvGEApp::Initialize ( void )
  59. {
  60. mOptions.Init();
  61. // Mutually exclusive
  62. com_editors = EDITOR_GUI;
  63. Sys_GrabMouseCursor( false );
  64. // Load the options
  65. mOptions.Load ( );
  66. mInstance = win32.hInstance;
  67. // Create the accelerators
  68. mAccelerators = LoadAccelerators ( mInstance, MAKEINTRESOURCE(IDR_GUIED_ACCELERATORS) );
  69. // Register the window classes for the main frame and the mdi child window
  70. WNDCLASSEX wndClass;
  71. memset ( &wndClass, 0, sizeof(wndClass) );
  72. wndClass.cbSize = sizeof(WNDCLASSEX);
  73. wndClass.lpszClassName = "QUAKE4_GUIEDITOR_CLASS";
  74. wndClass.lpfnWndProc = FrameWndProc;
  75. wndClass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE + 1);
  76. wndClass.hCursor = LoadCursor((HINSTANCE) NULL, IDC_ARROW);
  77. wndClass.lpszMenuName = MAKEINTRESOURCE(IDR_GUIED_MAIN);
  78. wndClass.hInstance = mInstance;
  79. RegisterClassEx ( &wndClass );
  80. wndClass.lpszMenuName = NULL;
  81. wndClass.lpfnWndProc = MDIChildProc;
  82. wndClass.lpszClassName = "QUAKE4_GUIEDITOR_CHILD_CLASS";
  83. wndClass.style = CS_OWNDC|CS_DBLCLKS|CS_BYTEALIGNWINDOW|CS_VREDRAW|CS_HREDRAW;
  84. wndClass.hbrBackground = (HBRUSH)GetStockObject( LTGRAY_BRUSH );
  85. RegisterClassEx ( &wndClass );
  86. // Create the main window
  87. mMDIFrame = CreateWindow ( "QUAKE4_GUIEDITOR_CLASS",
  88. "Quake IV GUI Editor",
  89. WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS,
  90. CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
  91. NULL, NULL, mInstance, (LPVOID)this );
  92. if ( !mMDIFrame )
  93. {
  94. return false;
  95. }
  96. SetClassLong( mMDIFrame, GCL_HICON, ( LONG )LoadIcon( win32.hInstance, MAKEINTRESOURCE( IDI_GUIED ) ) );
  97. // Create the MDI window
  98. CLIENTCREATESTRUCT ccs;
  99. ccs.hWindowMenu = GetSubMenu ( GetMenu ( mMDIFrame ), 5 );
  100. ccs.idFirstChild = IDM_WINDOWCHILD;
  101. mMDIClient = CreateWindow ( "MDICLIENT", NULL,
  102. WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
  103. 0, 0, 1000, 1000,
  104. mMDIFrame, NULL,
  105. mInstance, &ccs );
  106. if ( !mMDIClient )
  107. {
  108. DestroyWindow ( mMDIFrame );
  109. return false;
  110. }
  111. // hide the doom window by default
  112. ::ShowWindow ( win32.hWnd, SW_HIDE );
  113. // Show both windows
  114. mOptions.GetWindowPlacement ( "mdiframe", mMDIFrame );
  115. ShowWindow ( mMDIFrame, SW_SHOW );
  116. UpdateWindow ( mMDIFrame );
  117. ShowWindow ( mMDIClient, SW_SHOW );
  118. UpdateWindow ( mMDIClient );
  119. return true;
  120. }
  121. /*
  122. ================
  123. rvGEApp::GetActiveWorkspace
  124. Retrieves the workspace pointer for the active workspace. If there is no active
  125. workspace then it will return NULL
  126. ================
  127. */
  128. rvGEWorkspace* rvGEApp::GetActiveWorkspace ( HWND* ret )
  129. {
  130. rvGEWorkspace* workspace;
  131. HWND active;
  132. workspace = NULL;
  133. active = (HWND)SendMessage ( mMDIClient, WM_MDIGETACTIVE, 0, NULL );
  134. // Return the window handle if requested
  135. if ( ret )
  136. {
  137. *ret = active;
  138. }
  139. if ( !active )
  140. {
  141. return NULL;
  142. }
  143. return rvGEWorkspace::GetWorkspace ( active );
  144. }
  145. /*
  146. ================
  147. rvGEApp::TranslateAccelerator
  148. Translate any accelerators destined for this window
  149. ================
  150. */
  151. bool rvGEApp::TranslateAccelerator ( LPMSG msg )
  152. {
  153. HWND focus;
  154. if ( msg->message == WM_SYSCHAR )
  155. {
  156. SetFocus ( GetMDIClient ( ) );
  157. msg->hwnd = GetMDIClient ( );
  158. }
  159. if ( mViewer )
  160. {
  161. return false;
  162. }
  163. focus = GetActiveWindow ( );
  164. // Only use accelerators when on the main window or navigator window
  165. if ( focus == mMDIClient || focus == mMDIFrame ||
  166. focus == GetNavigator().GetWindow ( ) )
  167. {
  168. if ( ::TranslateAccelerator ( mMDIFrame, mAccelerators, msg ) )
  169. {
  170. return true;
  171. }
  172. }
  173. if ( TranslateMDISysAccel ( mMDIClient, msg ) )
  174. {
  175. return true;
  176. }
  177. return false;
  178. }
  179. /*
  180. ================
  181. rvGEApp::RunFrame
  182. Runs the current frame which causes the active window to be redrawn
  183. ================
  184. */
  185. void rvGEApp::RunFrame ( void )
  186. {
  187. HWND wnd;
  188. rvGEWorkspace* workspace = GetActiveWorkspace ( &wnd );
  189. if ( workspace )
  190. {
  191. // Render the workspace using a temp DC
  192. HDC hDC = GetDC ( wnd );
  193. workspace->Render ( hDC );
  194. ReleaseDC ( wnd, hDC );
  195. if ( mViewer )
  196. {
  197. mViewer->RunFrame ( );
  198. }
  199. }
  200. }
  201. /*
  202. ================
  203. rvGEApp::FrameWndProc
  204. Main frame window procedure
  205. ================
  206. */
  207. LRESULT CALLBACK rvGEApp::FrameWndProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  208. {
  209. rvGEApp* app = (rvGEApp*) GetWindowLong ( hWnd, GWL_USERDATA );
  210. switch ( uMsg )
  211. {
  212. case WM_SIZE:
  213. {
  214. RECT rStatus;
  215. RECT rClient;
  216. // Tell the status bar to resize
  217. app->mStatusBar.Resize ( LOWORD(lParam), HIWORD(lParam) );
  218. // Calculate the new client window rectangle (minus the status bar)
  219. GetWindowRect ( app->mStatusBar.GetWindow ( ), &rStatus );
  220. GetClientRect ( hWnd, &rClient );
  221. if ( app->mOptions.GetStatusBarVisible ( ) )
  222. {
  223. rClient.bottom -= (rStatus.bottom-rStatus.top);
  224. }
  225. MoveWindow ( app->mMDIClient, 0, 0, rClient.right-rClient.left, rClient.bottom-rClient.top, FALSE );
  226. return 0;
  227. }
  228. case WM_ENABLE:
  229. {
  230. int i;
  231. // Synchronise all toolwindows to the same state.
  232. for(i = 0; i < app->mToolWindows.Num(); i++)
  233. {
  234. if(app->mToolWindows[i] != hWnd)
  235. {
  236. EnableWindow(app->mToolWindows[i], wParam);
  237. }
  238. }
  239. break;
  240. }
  241. case WM_NCACTIVATE:
  242. return app->ToolWindowActivate ( hWnd, uMsg, wParam, lParam );
  243. case WM_ACTIVATE:
  244. common->ActivateTool( LOWORD( wParam ) != WA_INACTIVE );
  245. break;
  246. case WM_INITMENUPOPUP:
  247. app->HandleInitMenu ( wParam, lParam );
  248. break;
  249. case WM_CLOSE:
  250. while ( app->mWorkspaces.Num ( ) )
  251. {
  252. SendMessage ( app->mWorkspaces[0]->GetWindow ( ), WM_CLOSE, 0, 0 );
  253. }
  254. break;
  255. case WM_DESTROY:
  256. app->mOptions.SetWindowPlacement ( "mdiframe", hWnd );
  257. app->mOptions.Save ( );
  258. ExitProcess(0);
  259. break;
  260. case WM_COMMAND:
  261. {
  262. int result;
  263. assert ( app );
  264. result = app->HandleCommand ( wParam, lParam );
  265. if ( -1 != result )
  266. {
  267. return result;
  268. }
  269. break;
  270. }
  271. case WM_CREATE:
  272. {
  273. LPCREATESTRUCT cs;
  274. cs = (LPCREATESTRUCT) lParam;
  275. app = (rvGEApp*)cs->lpCreateParams;
  276. assert ( app );
  277. SetWindowLong ( hWnd, GWL_USERDATA, (LONG)app );
  278. app->mMDIFrame = hWnd;
  279. app->InitRecentFiles ( );
  280. app->UpdateRecentFiles ( );
  281. app->mNavigator.Create ( hWnd, gApp.mOptions.GetNavigatorVisible ( ) );
  282. app->mTransformer.Create ( hWnd, gApp.mOptions.GetTransformerVisible ( ) );
  283. app->mStatusBar.Create ( hWnd, 9999, gApp.mOptions.GetStatusBarVisible ( ) );
  284. app->mProperties.Create ( hWnd, gApp.mOptions.GetPropertiesVisible ( ) );
  285. // add all the tool windows to the tool window array
  286. app->mToolWindows.Append ( app->mMDIFrame );
  287. app->mToolWindows.Append ( app->mNavigator.GetWindow ( ) );
  288. app->mToolWindows.Append ( app->mProperties.GetWindow ( ) );
  289. app->mToolWindows.Append ( app->mTransformer.GetWindow ( ) );
  290. SendMessage ( app->mNavigator.GetWindow ( ), WM_NCACTIVATE, true, (LONG)-1 );
  291. SendMessage ( app->mProperties.GetWindow ( ), WM_NCACTIVATE, true, (LONG)-1 );
  292. SendMessage ( app->mTransformer.GetWindow ( ), WM_NCACTIVATE, true, (LONG)-1 );
  293. break;
  294. }
  295. }
  296. return DefFrameProc ( hWnd, app?app->mMDIClient:NULL, uMsg, wParam, lParam );
  297. }
  298. /*
  299. ================
  300. rvGEApp::MDIChildProc
  301. MDI Child window procedure
  302. ================
  303. */
  304. LRESULT CALLBACK rvGEApp::MDIChildProc ( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  305. {
  306. rvGEWorkspace* workspace = (rvGEWorkspace*)GetWindowLong ( hWnd, GWL_USERDATA );
  307. // Give the active workspace a chance to play with it
  308. if ( workspace )
  309. {
  310. workspace->HandleMessage ( uMsg, wParam, lParam );
  311. }
  312. switch ( uMsg )
  313. {
  314. case WM_CLOSE:
  315. workspace->GetApplication ( )->mWorkspaces.Remove ( workspace );
  316. break;
  317. case WM_CREATE:
  318. {
  319. LPMDICREATESTRUCT mdics;
  320. LPCREATESTRUCT cs;
  321. // MDI windows have their creation params buried two levels deep, extract
  322. // that param since it is the workspace pointer
  323. cs = (LPCREATESTRUCT) lParam;
  324. mdics = (LPMDICREATESTRUCT) cs->lpCreateParams;
  325. // Attach the workspace to the window
  326. workspace = (rvGEWorkspace*) mdics->lParam;
  327. workspace->Attach ( hWnd );
  328. workspace->GetApplication ( )->mWorkspaces.Append ( workspace );
  329. break;
  330. }
  331. case WM_MDIACTIVATE:
  332. assert ( workspace );
  333. if ( (HWND)lParam == hWnd )
  334. {
  335. workspace->GetApplication ( )->GetNavigator().SetWorkspace(workspace);
  336. workspace->GetApplication ( )->GetTransformer().SetWorkspace(workspace);
  337. workspace->GetApplication ( )->GetProperties().SetWorkspace(workspace);
  338. gApp.GetStatusBar ( ).SetSimple ( false );
  339. }
  340. else if ( lParam == NULL )
  341. {
  342. gApp.GetStatusBar ( ).SetSimple ( true );
  343. }
  344. break;
  345. case WM_DESTROY:
  346. assert ( workspace );
  347. workspace->Detach ( );
  348. delete workspace;
  349. break;
  350. case WM_SETCURSOR:
  351. return 1;
  352. case WM_ERASEBKGND:
  353. return TRUE;
  354. case WM_PAINT:
  355. {
  356. HDC dc;
  357. PAINTSTRUCT ps;
  358. dc = BeginPaint(hWnd, &ps);
  359. if ( workspace )
  360. {
  361. workspace->Render ( dc );
  362. }
  363. EndPaint(hWnd, &ps);
  364. break;
  365. }
  366. }
  367. return DefMDIChildProc ( hWnd, uMsg, wParam, lParam );
  368. }
  369. /*
  370. ================
  371. rvGEApp::HandleCommandSave
  372. Handles the ID_GUIED_FILE_SAVE and ID_GUIED_FILE_SAVEAS commands
  373. ================
  374. */
  375. void rvGEApp::HandleCommandSave ( rvGEWorkspace* workspace, const char* filename )
  376. {
  377. idStr realFilename;
  378. // See if we need to browse for a filename
  379. if ( workspace->IsNew ( ) || filename == NULL )
  380. {
  381. OPENFILENAME ofn;
  382. char szFile[MAX_PATH];
  383. strcpy ( szFile, workspace->GetFilename ( ) );
  384. // Initialize OPENFILENAME
  385. ZeroMemory(&ofn, sizeof(OPENFILENAME));
  386. ofn.lStructSize = sizeof(OPENFILENAME);
  387. ofn.hwndOwner = mMDIFrame;
  388. ofn.lpstrFile = szFile;
  389. ofn.nMaxFile = sizeof(szFile);
  390. ofn.lpstrFilter = "GUI Files\0*.GUI\0All Files\0*.*\0";
  391. ofn.nFilterIndex = 1;
  392. ofn.Flags = OFN_PATHMUSTEXIST;
  393. // Display the save dialog box.
  394. if ( !GetSaveFileName(&ofn) )
  395. {
  396. return;
  397. }
  398. realFilename = ofn.lpstrFile;
  399. realFilename.StripFileExtension ( );
  400. realFilename.Append ( ".gui" );
  401. // If the file already exists then warn about overwriting it
  402. if ( _taccess ( realFilename, 0 ) == 0 )
  403. {
  404. if ( IDNO == MessageBox ( va("File '%s' already exists. Do you want to replace it?", realFilename.c_str()), MB_YESNO|MB_ICONQUESTION ) )
  405. {
  406. return;
  407. }
  408. }
  409. }
  410. else
  411. {
  412. realFilename = filename;
  413. }
  414. // Now performe the file save
  415. if ( workspace->SaveFile ( realFilename ) )
  416. {
  417. mOptions.AddRecentFile ( workspace->GetFilename ( ) );
  418. UpdateRecentFiles ( );
  419. }
  420. else
  421. {
  422. MessageBox ( va("Could not write file '%s'", workspace->GetFilename()), MB_OK|MB_ICONERROR );
  423. }
  424. }
  425. /*
  426. ================
  427. rvGEApp::HandleCommand
  428. Handles the WM_COMMAND message
  429. ================
  430. */
  431. int rvGEApp::HandleCommand ( WPARAM wParam, LPARAM lParam )
  432. {
  433. HWND active;
  434. rvGEWorkspace* workspace = GetActiveWorkspace ( &active );
  435. // The recent file list needs to be handled specially
  436. if ( LOWORD(wParam) >= ID_GUIED_FILE_MRU1 && LOWORD(wParam) < ID_GUIED_FILE_MRU1 + rvGEOptions::MAX_MRU_SIZE )
  437. {
  438. OpenFile ( mOptions.GetRecentFile ( mOptions.GetRecentFileCount() - (LOWORD(wParam)-ID_GUIED_FILE_MRU1) - 1 ) );
  439. return 0;
  440. }
  441. switch ( LOWORD ( wParam ) )
  442. {
  443. case ID_GUIED_SOURCECONTROL_CHECKIN:
  444. assert ( workspace );
  445. HandleCommandSave ( workspace, workspace->GetFilename ( ) );
  446. workspace->CheckIn ( );
  447. break;
  448. case ID_GUIED_SOURCECONTROL_CHECKOUT:
  449. assert ( workspace );
  450. workspace->CheckOut ( );
  451. break;
  452. case ID_GUIED_SOURCECONTROL_UNDOCHECKOUT:
  453. assert ( workspace );
  454. if ( IDYES == MessageBox ( va("Are you sure you want to undo the checkout of the file '%s'?",workspace->GetFilename()), MB_YESNO|MB_ICONQUESTION) )
  455. {
  456. workspace->UndoCheckout ( );
  457. }
  458. break;
  459. case ID_GUIED_TOOLS_RELOADMATERIALS:
  460. SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_WAIT) ) );
  461. cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reloadImages\n" );
  462. cmdSystem->BufferCommandText( CMD_EXEC_NOW, "reloadMaterials\n" );
  463. SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW) ) );
  464. break;
  465. case ID_GUIED_EDIT_COPY:
  466. assert ( workspace );
  467. workspace->Copy ( );
  468. break;
  469. case ID_GUIED_EDIT_PASTE:
  470. assert ( workspace );
  471. workspace->Paste ( );
  472. break;
  473. case ID_GUIED_HELP_ABOUT:
  474. DialogBox ( GetInstance(), MAKEINTRESOURCE(IDD_GUIED_ABOUT), mMDIFrame, AboutDlg_WndProc );
  475. break;
  476. case ID_GUIED_TOOLS_VIEWER:
  477. {
  478. if ( mViewer )
  479. {
  480. break;
  481. }
  482. mViewer = new rvGEViewer;
  483. if ( !mViewer->Create ( mMDIFrame ) )
  484. {
  485. delete mViewer;
  486. mViewer = NULL;
  487. }
  488. if ( workspace )
  489. {
  490. if ( !workspace->IsModified () || HandleCommand ( MAKELONG(ID_GUIED_FILE_SAVE,0), 0 ) )
  491. {
  492. mViewer->OpenFile ( workspace->GetFilename ( ) );
  493. }
  494. }
  495. SetActiveWindow ( mViewer->GetWindow ( ) );
  496. break;
  497. }
  498. case ID_GUIED_ITEM_MAKESAMESIZEWIDTH:
  499. assert ( workspace );
  500. workspace->MakeSelectedSameSize ( true, false );
  501. break;
  502. case ID_GUIED_ITEM_MAKESAMESIZEBOTH:
  503. assert ( workspace );
  504. workspace->MakeSelectedSameSize ( true, true );
  505. break;
  506. case ID_GUIED_ITEM_MAKESAMESIZEHEIGHT:
  507. assert ( workspace );
  508. workspace->MakeSelectedSameSize ( false, true );
  509. break;
  510. case ID_GUIED_ITEM_ALIGNLEFTS:
  511. assert ( workspace );
  512. workspace->AlignSelected ( rvGEWorkspace::ALIGN_LEFTS );
  513. break;
  514. case ID_GUIED_ITEM_ALIGNCENTERS:
  515. assert ( workspace );
  516. workspace->AlignSelected ( rvGEWorkspace::ALIGN_CENTERS );
  517. break;
  518. case ID_GUIED_ITEM_ALIGNRIGHTS:
  519. assert ( workspace );
  520. workspace->AlignSelected ( rvGEWorkspace::ALIGN_RIGHTS );
  521. break;
  522. case ID_GUIED_ITEM_ALIGNTOPS:
  523. assert ( workspace );
  524. workspace->AlignSelected ( rvGEWorkspace::ALIGN_TOPS );
  525. break;
  526. case ID_GUIED_ITEM_ALIGNMIDDLES:
  527. assert ( workspace );
  528. workspace->AlignSelected ( rvGEWorkspace::ALIGN_MIDDLES );
  529. break;
  530. case ID_GUIED_ITEM_ALIGNBOTTOMS:
  531. assert ( workspace );
  532. workspace->AlignSelected ( rvGEWorkspace::ALIGN_BOTTOMS );
  533. break;
  534. case ID_GUIED_ITEM_ARRANGESENDBACKWARD:
  535. assert ( workspace );
  536. workspace->SendSelectedBackward ( );
  537. break;
  538. case ID_GUIED_ITEM_ARRANGESENDTOBACK:
  539. assert ( workspace );
  540. workspace->SendSelectedToBack( );
  541. break;
  542. case ID_GUIED_ITEM_ARRANGEBRINGFORWARD:
  543. assert ( workspace );
  544. workspace->BringSelectedForward ( );
  545. break;
  546. case ID_GUIED_ITEM_ARRANGEBRINGTOFRONT:
  547. assert ( workspace );
  548. workspace->BringSelectedToFront ( );
  549. break;
  550. case ID_GUIED_ITEM_ARRANGEMAKECHILD:
  551. assert ( workspace );
  552. workspace->MakeSelectedAChild ( );
  553. break;
  554. case ID_GUIED_ITEM_PROPERTIES:
  555. assert ( workspace );
  556. workspace->EditSelectedProperties ( );
  557. break;
  558. case ID_GUIED_ITEM_SCRIPTS:
  559. assert ( workspace );
  560. workspace->EditSelectedScripts ( );
  561. break;
  562. case ID_GUIED_ITEM_NEWWINDOWDEF:
  563. assert ( workspace );
  564. workspace->AddWindow ( rvGEWindowWrapper::WT_NORMAL );
  565. break;
  566. case ID_GUIED_ITEM_NEWEDITDEF:
  567. assert ( workspace );
  568. workspace->AddWindow ( rvGEWindowWrapper::WT_EDIT );
  569. break;
  570. case ID_GUIED_ITEM_NEWHTMLDEF:
  571. assert ( workspace );
  572. workspace->AddWindow ( rvGEWindowWrapper::WT_HTML );
  573. break;
  574. case ID_GUIED_ITEM_NEWCHOICEDEF:
  575. assert ( workspace );
  576. workspace->AddWindow ( rvGEWindowWrapper::WT_CHOICE );
  577. break;
  578. case ID_GUIED_ITEM_NEWSLIDERDEF:
  579. assert ( workspace );
  580. workspace->AddWindow ( rvGEWindowWrapper::WT_SLIDER );
  581. break;
  582. case ID_GUIED_ITEM_NEWLISTDEF:
  583. assert ( workspace );
  584. workspace->AddWindow ( rvGEWindowWrapper::WT_LIST );
  585. break;
  586. case ID_GUIED_ITEM_NEWBINDDEF:
  587. assert ( workspace );
  588. workspace->AddWindow ( rvGEWindowWrapper::WT_BIND );
  589. break;
  590. case ID_GUIED_ITEM_NEWRENDERDEF:
  591. assert ( workspace );
  592. workspace->AddWindow ( rvGEWindowWrapper::WT_RENDER );
  593. break;
  594. case ID_GUIED_WINDOW_TILE:
  595. SendMessage ( mMDIClient, WM_MDITILE, 0, 0 );
  596. break;
  597. case ID_GUIED_WINDOW_CASCADE:
  598. SendMessage ( mMDIClient, WM_MDICASCADE, 0, 0 );
  599. break;
  600. case ID_GUIED_VIEW_STATUSBAR:
  601. {
  602. RECT rWindow;
  603. mStatusBar.Show ( mOptions.GetStatusBarVisible()?false:true );
  604. GetWindowRect ( mMDIFrame, &rWindow );
  605. SendMessage ( mMDIFrame, WM_SIZE, 0, MAKELONG ( rWindow.right-rWindow.left, rWindow.bottom-rWindow.top ) );
  606. break;
  607. }
  608. case ID_GUIED_WINDOW_SHOWNAVIGATOR:
  609. mNavigator.Show ( mOptions.GetNavigatorVisible()?false:true );
  610. break;
  611. case ID_GUIED_WINDOW_SHOWPROPERTIES:
  612. mProperties.Show ( mOptions.GetPropertiesVisible()?false:true );
  613. break;
  614. case ID_GUIED_WINDOW_SHOWTRANSFORMER:
  615. mTransformer.Show ( mOptions.GetTransformerVisible()?false:true );
  616. break;
  617. case ID_GUIED_EDIT_DELETE:
  618. assert ( workspace );
  619. workspace->DeleteSelected ( );
  620. break;
  621. case ID_GUIED_VIEW_HIDESELECTED:
  622. assert ( workspace );
  623. workspace->HideSelected ( );
  624. break;
  625. case ID_GUIED_VIEW_UNHIDESELECTED:
  626. assert ( workspace );
  627. workspace->UnhideSelected ( );
  628. break;
  629. case ID_GUIED_VIEW_SHOWHIDDEN:
  630. assert ( workspace );
  631. workspace->ShowHidden ( );
  632. break;
  633. case ID_GUIED_EDIT_UNDO:
  634. assert ( workspace );
  635. workspace->GetModifierStack().Undo ( );
  636. mNavigator.Update ( );
  637. mTransformer.Update ( );
  638. break;
  639. case ID_GUIED_EDIT_REDO:
  640. assert ( workspace );
  641. workspace->GetModifierStack().Redo ( );
  642. mNavigator.Update ( );
  643. mTransformer.Update ( );
  644. break;
  645. case ID_GUIED_VIEW_OPTIONS:
  646. GEOptionsDlg_DoModal ( mMDIFrame );
  647. break;
  648. case ID_GUIED_VIEW_SHOWGRID:
  649. mOptions.SetGridVisible ( mOptions.GetGridVisible()?false:true );
  650. break;
  651. case ID_GUIED_VIEW_SNAPTOGRID:
  652. mOptions.SetGridSnap ( mOptions.GetGridSnap ()?false:true );
  653. break;
  654. case ID_GUIED_VIEW_ZOOMIN:
  655. assert ( workspace );
  656. workspace->ZoomIn ( );
  657. break;
  658. case ID_GUIED_VIEW_ZOOMOUT:
  659. assert ( workspace );
  660. workspace->ZoomOut ( );
  661. break;
  662. case ID_GUIED_FILE_EXIT:
  663. DestroyWindow ( mMDIFrame );
  664. break;
  665. case ID_GUIED_FILE_CLOSE:
  666. if ( active )
  667. {
  668. assert ( workspace );
  669. SendMessage ( active, WM_CLOSE, 0, 0 );
  670. }
  671. break;
  672. case ID_GUIED_FILE_NEW:
  673. NewFile ( );
  674. break;
  675. case ID_GUIED_FILE_SAVE:
  676. assert ( workspace );
  677. HandleCommandSave ( workspace, workspace->GetFilename ( ) );
  678. break;
  679. case ID_GUIED_FILE_SAVEAS:
  680. assert ( workspace );
  681. HandleCommandSave ( workspace, NULL );
  682. break;
  683. case ID_GUIED_FILE_OPEN:
  684. {
  685. OPENFILENAME ofn;
  686. char szFile[MAX_PATH] = "";
  687. // Initialize OPENFILENAME
  688. ZeroMemory(&ofn, sizeof(OPENFILENAME));
  689. ofn.lStructSize = sizeof(OPENFILENAME);
  690. ofn.hwndOwner = mMDIFrame;
  691. ofn.lpstrFile = szFile;
  692. ofn.nMaxFile = sizeof(szFile);
  693. ofn.lpstrFilter = "GUI Files\0*.GUI\0All Files\0*.*\0";
  694. ofn.nFilterIndex = 1;
  695. ofn.lpstrFileTitle = NULL;
  696. ofn.nMaxFileTitle = 0;
  697. ofn.lpstrInitialDir = NULL;
  698. ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
  699. // Display the Open dialog box.
  700. if (GetOpenFileName(&ofn)==TRUE)
  701. {
  702. OpenFile ( ofn.lpstrFile );
  703. }
  704. break;
  705. }
  706. }
  707. return -1;
  708. }
  709. /*
  710. ================
  711. rvGEApp::HandleInitMenu
  712. Handles the initialization of the main menu
  713. ================
  714. */
  715. int rvGEApp::HandleInitMenu ( WPARAM wParam, LPARAM lParam )
  716. {
  717. int cMenuItems = GetMenuItemCount((HMENU)wParam);
  718. int nPos;
  719. int id;
  720. UINT flags;
  721. rvGEWorkspace* workspace;
  722. HMENU hmenu;
  723. hmenu = (HMENU) wParam;
  724. workspace = GetActiveWorkspace ( );
  725. // Run through all the menu items in the menu and see if any of them need
  726. // modification in any way
  727. for (nPos = 0; nPos < cMenuItems; nPos++)
  728. {
  729. id = GetMenuItemID(hmenu, nPos);
  730. flags = 0;
  731. // Handle popup menus too
  732. if ( id < 0 )
  733. {
  734. HMENU sub = GetSubMenu ( hmenu, nPos );
  735. if ( sub )
  736. {
  737. HandleInitMenu ( (WPARAM) sub, 0 );
  738. continue;
  739. }
  740. }
  741. // Menu items that are completely unrelated to the workspace
  742. switch ( id )
  743. {
  744. case ID_GUIED_VIEW_STATUSBAR:
  745. flags = MF_BYCOMMAND | (mOptions.GetStatusBarVisible()?MF_CHECKED:MF_UNCHECKED);
  746. CheckMenuItem ( hmenu, id, flags );
  747. break;
  748. case ID_GUIED_WINDOW_SHOWNAVIGATOR:
  749. flags = MF_BYCOMMAND | (mOptions.GetNavigatorVisible()?MF_CHECKED:MF_UNCHECKED);
  750. CheckMenuItem ( hmenu, id, flags );
  751. break;
  752. case ID_GUIED_WINDOW_SHOWPROPERTIES:
  753. flags = MF_BYCOMMAND | (mOptions.GetPropertiesVisible()?MF_CHECKED:MF_UNCHECKED);
  754. CheckMenuItem ( hmenu, id, flags );
  755. break;
  756. case ID_GUIED_WINDOW_SHOWTRANSFORMER:
  757. flags = MF_BYCOMMAND | (mOptions.GetTransformerVisible()?MF_CHECKED:MF_UNCHECKED);
  758. CheckMenuItem ( hmenu, id, flags );
  759. break;
  760. }
  761. // Handle the basic case where an item is disabled because
  762. // there is no workspace available
  763. if ( !workspace )
  764. {
  765. switch ( id )
  766. {
  767. case ID_GUIED_EDIT_UNDO:
  768. case ID_GUIED_EDIT_REDO:
  769. case ID_GUIED_VIEW_SHOWGRID:
  770. case ID_GUIED_VIEW_SNAPTOGRID:
  771. case ID_GUIED_VIEW_HIDESELECTED:
  772. case ID_GUIED_VIEW_UNHIDESELECTED:
  773. case ID_GUIED_EDIT_DELETE:
  774. case ID_GUIED_WINDOW_TILE:
  775. case ID_GUIED_WINDOW_CASCADE:
  776. case ID_GUIED_ITEM_NEWWINDOWDEF:
  777. case ID_GUIED_ITEM_NEWEDITDEF:
  778. case ID_GUIED_ITEM_NEWHTMLDEF:
  779. case ID_GUIED_ITEM_ARRANGEBRINGTOFRONT:
  780. case ID_GUIED_ITEM_ARRANGEBRINGFORWARD:
  781. case ID_GUIED_ITEM_ARRANGESENDTOBACK:
  782. case ID_GUIED_ITEM_ARRANGESENDBACKWARD:
  783. case ID_GUIED_ITEM_PROPERTIES:
  784. case ID_GUIED_ITEM_SCRIPTS:
  785. case ID_GUIED_VIEW_ZOOMIN:
  786. case ID_GUIED_VIEW_ZOOMOUT:
  787. case ID_GUIED_ITEM_ALIGNLEFTS:
  788. case ID_GUIED_ITEM_ALIGNCENTERS:
  789. case ID_GUIED_ITEM_ALIGNRIGHTS:
  790. case ID_GUIED_ITEM_ALIGNBOTTOMS:
  791. case ID_GUIED_ITEM_ALIGNMIDDLES:
  792. case ID_GUIED_ITEM_ALIGNTOPS:
  793. case ID_GUIED_ITEM_MAKESAMESIZEHEIGHT:
  794. case ID_GUIED_ITEM_MAKESAMESIZEWIDTH:
  795. case ID_GUIED_ITEM_MAKESAMESIZEBOTH:
  796. case ID_GUIED_FILE_SAVE:
  797. case ID_GUIED_FILE_SAVEAS:
  798. case ID_GUIED_EDIT_COPY:
  799. case ID_GUIED_EDIT_PASTE:
  800. case ID_GUIED_ITEM_ARRANGEMAKECHILD:
  801. case ID_GUIED_SOURCECONTROL_GETLATESTVERSION:
  802. case ID_GUIED_SOURCECONTROL_CHECKIN:
  803. case ID_GUIED_SOURCECONTROL_CHECKOUT:
  804. case ID_GUIED_SOURCECONTROL_UNDOCHECKOUT:
  805. case ID_GUIED_FILE_CLOSE:
  806. EnableMenuItem ( hmenu, nPos, MF_GRAYED|MF_BYPOSITION );
  807. break;
  808. }
  809. continue;
  810. }
  811. switch (id)
  812. {
  813. // Undo is greyed out when there is noting to undo and the text is
  814. // modified to include the name of the modifier that will be undone
  815. case ID_GUIED_EDIT_UNDO:
  816. {
  817. MENUITEMINFO info;
  818. idStr undo;
  819. info.cbSize = sizeof(info);
  820. info.fMask = MIIM_STATE|MIIM_TYPE;
  821. info.fType = MFT_STRING;
  822. if ( !workspace->GetModifierStack().CanUndo ( ) )
  823. {
  824. undo = "Undo\tCtrl+Z";
  825. info.fState = MFS_GRAYED;
  826. }
  827. else
  828. {
  829. undo = "Undo ";
  830. undo.Append ( workspace->GetModifierStack().GetUndoModifier()->GetName ( ) );
  831. undo.Append ( "\tCtrl+Z" );
  832. info.fState = MFS_ENABLED;
  833. }
  834. info.dwTypeData = (LPSTR)undo.c_str();
  835. info.cch = undo.Length ( );
  836. SetMenuItemInfo ( hmenu, id, FALSE, &info );
  837. break;
  838. }
  839. case ID_GUIED_EDIT_REDO:
  840. {
  841. MENUITEMINFO info;
  842. idStr undo;
  843. info.cbSize = sizeof(info);
  844. info.fMask = MIIM_STATE|MIIM_TYPE;
  845. info.fType = MFT_STRING;
  846. if ( !workspace || !workspace->GetModifierStack().CanRedo ( ) )
  847. {
  848. undo = "Redo\tCtrl+Y";
  849. info.fState = MFS_GRAYED;
  850. }
  851. else
  852. {
  853. undo = "Redo ";
  854. undo.Append ( workspace->GetModifierStack().GetRedoModifier()->GetName ( ) );
  855. undo.Append ( "\tCtrl+Y" );
  856. info.fState = MFS_ENABLED;
  857. }
  858. info.dwTypeData = (LPSTR)undo.c_str();
  859. info.cch = undo.Length ( );
  860. SetMenuItemInfo ( hmenu, id, FALSE, &info );
  861. break;
  862. }
  863. case ID_GUIED_VIEW_SHOWGRID:
  864. flags = MF_BYCOMMAND | (mOptions.GetGridVisible()?MF_CHECKED:MF_UNCHECKED);
  865. CheckMenuItem ( hmenu, id, flags );
  866. break;
  867. case ID_GUIED_VIEW_SNAPTOGRID:
  868. flags = MF_BYCOMMAND | (mOptions.GetGridSnap()?MF_CHECKED:MF_UNCHECKED);
  869. CheckMenuItem ( hmenu, id, flags );
  870. break;
  871. // All menu items that are greyed out when there is no workspace
  872. case ID_GUIED_WINDOW_TILE:
  873. case ID_GUIED_WINDOW_CASCADE:
  874. case ID_GUIED_ITEM_NEWWINDOWDEF:
  875. case ID_GUIED_ITEM_NEWEDITDEF:
  876. case ID_GUIED_ITEM_NEWHTMLDEF:
  877. case ID_GUIED_VIEW_ZOOMIN:
  878. case ID_GUIED_VIEW_ZOOMOUT:
  879. case ID_GUIED_FILE_SAVE:
  880. case ID_GUIED_FILE_SAVEAS:
  881. case ID_GUIED_FILE_CLOSE:
  882. EnableMenuItem ( hmenu, nPos, MF_ENABLED|MF_BYPOSITION);
  883. break;
  884. // All menu items that are greyed out unless an item is selected
  885. case ID_GUIED_VIEW_HIDESELECTED:
  886. case ID_GUIED_VIEW_UNHIDESELECTED:
  887. case ID_GUIED_EDIT_DELETE:
  888. case ID_GUIED_EDIT_COPY:
  889. EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetSelectionMgr().Num()>0?MF_ENABLED:MF_GRAYED) );
  890. break;
  891. // Enable paste if the clipboard has something in it
  892. case ID_GUIED_EDIT_PASTE:
  893. EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetClipboard().Num()>0?MF_ENABLED:MF_GRAYED) );
  894. break;
  895. // All menu items that are greyed out unless a single item is selected
  896. case ID_GUIED_ITEM_ARRANGEBRINGTOFRONT:
  897. case ID_GUIED_ITEM_ARRANGEBRINGFORWARD:
  898. case ID_GUIED_ITEM_ARRANGESENDTOBACK:
  899. case ID_GUIED_ITEM_ARRANGESENDBACKWARD:
  900. case ID_GUIED_ITEM_PROPERTIES:
  901. case ID_GUIED_ITEM_SCRIPTS:
  902. EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetSelectionMgr().Num()==1?MF_ENABLED:MF_GRAYED) );
  903. break;
  904. // All menu items that are greyed out unless multiple itmes are selected
  905. case ID_GUIED_ITEM_ALIGNLEFTS:
  906. case ID_GUIED_ITEM_ALIGNCENTERS:
  907. case ID_GUIED_ITEM_ALIGNRIGHTS:
  908. case ID_GUIED_ITEM_ALIGNBOTTOMS:
  909. case ID_GUIED_ITEM_ALIGNMIDDLES:
  910. case ID_GUIED_ITEM_ALIGNTOPS:
  911. case ID_GUIED_ITEM_MAKESAMESIZEHEIGHT:
  912. case ID_GUIED_ITEM_MAKESAMESIZEBOTH:
  913. case ID_GUIED_ITEM_MAKESAMESIZEWIDTH:
  914. case ID_GUIED_ITEM_ARRANGEMAKECHILD:
  915. EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|(workspace->GetSelectionMgr().Num()>1?MF_ENABLED:MF_GRAYED) );
  916. break;
  917. case ID_GUIED_SOURCECONTROL_CHECKIN:
  918. case ID_GUIED_SOURCECONTROL_UNDOCHECKOUT:
  919. EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|((workspace->GetSourceControlState()==rvGEWorkspace::SCS_CHECKEDOUT)?MF_ENABLED:MF_GRAYED) );
  920. break;
  921. case ID_GUIED_SOURCECONTROL_CHECKOUT:
  922. EnableMenuItem ( hmenu, nPos, MF_BYPOSITION|((workspace->GetSourceControlState()==rvGEWorkspace::SCS_CHECKEDIN)?MF_ENABLED:MF_GRAYED) );
  923. break;
  924. default:
  925. continue;
  926. }
  927. }
  928. return 0;
  929. }
  930. /*
  931. ================
  932. rvGEApp::NewFile
  933. Creates a new file and opens a window for it
  934. ================
  935. */
  936. bool rvGEApp::NewFile ( void )
  937. {
  938. rvGEWorkspace* workspace = new rvGEWorkspace ( this );
  939. if ( workspace->NewFile ( ) )
  940. {
  941. HWND child;
  942. child = CreateMDIWindow("QUAKE4_GUIEDITOR_CHILD_CLASS",
  943. "Untitled.gui",
  944. WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_HSCROLL|WS_VSCROLL|WS_MAXIMIZE,
  945. CW_USEDEFAULT,
  946. CW_USEDEFAULT,
  947. 640,
  948. 480,
  949. mMDIClient,
  950. mInstance,
  951. (LONG)workspace );
  952. ShowWindow ( child, SW_SHOW );
  953. }
  954. return true;
  955. }
  956. /*
  957. ================
  958. rvGEApp::OpenFile
  959. Opens the given file and will fail if its already open or could not
  960. be opened for some reason
  961. ================
  962. */
  963. bool rvGEApp::OpenFile ( const char* filename )
  964. {
  965. int i;
  966. bool result = false;
  967. idStr error;
  968. // See if the file is already open and if so just make it active
  969. for ( i = 0; i < mWorkspaces.Num(); i ++ )
  970. {
  971. if ( !idStr::Icmp ( mWorkspaces[i]->GetFilename(), filename ) )
  972. {
  973. SendMessage ( mMDIClient, WM_MDIACTIVATE, (WPARAM)mWorkspaces[i]->GetWindow ( ), 0 );
  974. return false;
  975. }
  976. }
  977. SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_WAIT ) ) );
  978. // Setup the default error.
  979. error = va("Failed to parse '%s'", filename );
  980. rvGEWorkspace* workspace = new rvGEWorkspace ( this );
  981. if ( workspace->LoadFile ( filename, &error ) )
  982. {
  983. HWND child;
  984. child = CreateMDIWindow("QUAKE4_GUIEDITOR_CHILD_CLASS",
  985. "Unamed.gui",
  986. WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_HSCROLL|WS_VSCROLL|WS_MAXIMIZE,
  987. CW_USEDEFAULT,
  988. CW_USEDEFAULT,
  989. 640,
  990. 480,
  991. mMDIClient,
  992. mInstance,
  993. (LONG)workspace );
  994. ShowWindow ( child, SW_SHOW );
  995. mOptions.AddRecentFile ( filename );
  996. UpdateRecentFiles ( );
  997. result = true;
  998. }
  999. else
  1000. {
  1001. MessageBox ( error, MB_OK|MB_ICONERROR );
  1002. }
  1003. SetCursor ( LoadCursor ( NULL, MAKEINTRESOURCE(IDC_ARROW ) ) );
  1004. return result;;
  1005. }
  1006. /*
  1007. ================
  1008. rvGEApp::InitRecentFiles
  1009. Finds the file menu and the location within it where the MRU should
  1010. be added.
  1011. ================
  1012. */
  1013. bool rvGEApp::InitRecentFiles ( void )
  1014. {
  1015. int i;
  1016. int count;
  1017. mRecentFileMenu = GetSubMenu ( GetMenu(mMDIFrame), 0 );
  1018. count = GetMenuItemCount ( mRecentFileMenu );
  1019. for ( i = 0; i < count; i ++ )
  1020. {
  1021. if ( GetMenuItemID ( mRecentFileMenu, i ) == ID_GUIED_FILE_MRU )
  1022. {
  1023. mRecentFileInsertPos = i;
  1024. DeleteMenu ( mRecentFileMenu, mRecentFileInsertPos, MF_BYPOSITION );
  1025. return true;
  1026. }
  1027. }
  1028. return false;
  1029. }
  1030. /*
  1031. ================
  1032. rvGEApp::UpdateRecentFiles
  1033. Updates the mru in the menu
  1034. ================
  1035. */
  1036. void rvGEApp::UpdateRecentFiles ( void )
  1037. {
  1038. int i;
  1039. int j;
  1040. // Make sure everything is initialized
  1041. if ( !mRecentFileMenu )
  1042. {
  1043. InitRecentFiles ( );
  1044. }
  1045. // Delete all the old recent files from the menu's
  1046. for ( i = 0; i < rvGEOptions::MAX_MRU_SIZE; i ++ )
  1047. {
  1048. DeleteMenu ( mRecentFileMenu, ID_GUIED_FILE_MRU1 + i, MF_BYCOMMAND );
  1049. }
  1050. // Make sure there is a separator after the recent files
  1051. if ( mOptions.GetRecentFileCount() )
  1052. {
  1053. MENUITEMINFO info;
  1054. ZeroMemory ( &info, sizeof(info) );
  1055. info.cbSize = sizeof(info);
  1056. info.fMask = MIIM_FTYPE;
  1057. GetMenuItemInfo ( mRecentFileMenu, mRecentFileInsertPos+1,TRUE, &info );
  1058. if ( !(info.fType & MFT_SEPARATOR ) )
  1059. {
  1060. InsertMenu ( mRecentFileMenu, mRecentFileInsertPos, MF_BYPOSITION|MF_SEPARATOR|MF_ENABLED, 0, NULL );
  1061. }
  1062. }
  1063. // Add the recent files to the menu now
  1064. for ( j = 0, i = mOptions.GetRecentFileCount ( ) - 1; i >= 0; i --, j++ )
  1065. {
  1066. UINT id = ID_GUIED_FILE_MRU1 + j;
  1067. idStr str = va("&%d ", j+1);
  1068. str.Append ( mOptions.GetRecentFile ( i ) );
  1069. InsertMenu ( mRecentFileMenu, mRecentFileInsertPos+j+1, MF_BYPOSITION|MF_STRING|MF_ENABLED, id, str );
  1070. }
  1071. }
  1072. /*
  1073. ================
  1074. rvGEApp::CloseViewer
  1075. Closes the gui viewer
  1076. ================
  1077. */
  1078. void rvGEApp::CloseViewer ( void )
  1079. {
  1080. if ( !mViewer )
  1081. {
  1082. return;
  1083. }
  1084. mViewer->Destroy ( );
  1085. delete mViewer;
  1086. mViewer = NULL;
  1087. }
  1088. /*
  1089. ================
  1090. rvGEApp::ToolWindowActivate
  1091. Handles the nc activate message for all tool windows
  1092. ================
  1093. */
  1094. int rvGEApp::ToolWindowActivate ( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
  1095. {
  1096. bool keepActive;
  1097. bool syncOthers;
  1098. int i;
  1099. keepActive = ( wParam != 0 );
  1100. syncOthers = true;
  1101. for ( i = 0; i < mToolWindows.Num (); i ++ )
  1102. {
  1103. if ( (HWND)lParam == mToolWindows[i] )
  1104. {
  1105. keepActive = true;
  1106. syncOthers = false;
  1107. break;
  1108. }
  1109. }
  1110. if ( lParam == -1 )
  1111. {
  1112. return DefWindowProc ( hwnd, WM_NCACTIVATE, keepActive, 0 );
  1113. }
  1114. if ( syncOthers )
  1115. {
  1116. for ( i = 0; i < mToolWindows.Num(); i ++ )
  1117. {
  1118. if ( mToolWindows[i] != hwnd && mToolWindows[i] != (HWND) lParam )
  1119. {
  1120. SendMessage ( mToolWindows[i], WM_NCACTIVATE, keepActive, (LONG)-1 );
  1121. }
  1122. }
  1123. }
  1124. return DefWindowProc ( hwnd, WM_NCACTIVATE, keepActive, lParam );
  1125. }
  1126. /*
  1127. ================
  1128. rvGEApp::MessageBox
  1129. Displays a modal message box
  1130. ================
  1131. */
  1132. int rvGEApp::MessageBox ( const char* text, int flags )
  1133. {
  1134. return ::MessageBox ( mMDIFrame, text, "Quake 4 GUI Editor", flags );
  1135. }