PresetsLibForm.cpp 88 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. // PresetsForm.cpp : implementation file
  19. //
  20. #include "stdafx.h"
  21. #include "leveledit.h"
  22. #include "presetslibform.h"
  23. #include "utils.h"
  24. #include "filemgr.h"
  25. #include "definitionfactorymgr.h"
  26. #include "definitionclassids.h"
  27. #include "definitionfactory.h"
  28. #include "definitionmgr.h"
  29. #include "definition.h"
  30. #include "icons.h"
  31. #include "terraindefinition.h"
  32. #include "preset.h"
  33. #include "presetmgr.h"
  34. #include "sceneeditor.h"
  35. #include "saveload.h"
  36. #include "rawfile.h"
  37. #include "chunkio.h"
  38. #include "filelocations.h"
  39. #include "nodecategories.h"
  40. #include "editorchunkids.h"
  41. #include "regkeys.h"
  42. #include "nodemgr.h"
  43. #include "LevelEditView.h"
  44. #include "PlaySoundDialog.h"
  45. #include "AudibleSound.h"
  46. #include "UpdatePresetDialog.h"
  47. #include "definitionutils.h"
  48. #include "presetlogger.h"
  49. #include "rendobj.h"
  50. #include "phys.h"
  51. #include "textfile.h"
  52. #include "node.h"
  53. #include "ramfile.h"
  54. #include "editorbuild.h"
  55. #ifdef _DEBUG
  56. #define new DEBUG_NEW
  57. #undef THIS_FILE
  58. static char THIS_FILE[] = __FILE__;
  59. #endif
  60. ///////////////////////////////////////////////////////////////////////
  61. //
  62. // Helper objects
  63. //
  64. ///////////////////////////////////////////////////////////////////////
  65. class SelectionCaptureClass
  66. {
  67. public:
  68. SelectionCaptureClass (PresetsFormClass *preset_form)
  69. {
  70. m_PresetForm = preset_form;
  71. HTREEITEM tree_item = m_PresetForm->m_TreeCtrl.GetSelectedItem ();
  72. PresetClass *preset = m_PresetForm->Get_Item_Preset (tree_item);
  73. DefinitionFactoryClass *factory = m_PresetForm->Get_Item_Factory (tree_item);
  74. if (preset != NULL) {
  75. m_ID = preset->Get_ID ();
  76. m_IsFactory = false;
  77. } else {
  78. m_ID = factory->Get_Class_ID ();
  79. m_IsFactory = true;
  80. }
  81. return ;
  82. }
  83. void Restore (void)
  84. {
  85. m_PresetForm->Reselect_Item (m_ID, m_IsFactory);
  86. return ;
  87. }
  88. private:
  89. PresetsFormClass * m_PresetForm;
  90. int m_ID;
  91. bool m_IsFactory;
  92. };
  93. ///////////////////////////////////////////////////////////////////////
  94. //
  95. // Macros
  96. //
  97. ///////////////////////////////////////////////////////////////////////
  98. #ifndef TreeView_SetOverlay
  99. #define TreeView_SetOverlay(hwndLV, i, overlay) \
  100. { \
  101. TVITEMEX item_info = { TVIF_STATE, i, INDEXTOOVERLAYMASK(overlay), TVIS_OVERLAYMASK, 0 }; \
  102. TreeView_SetItem(hwndLV, &item_info); \
  103. }
  104. #endif
  105. ///////////////////////////////////////////////////////////////////////
  106. //
  107. // Constants
  108. //
  109. ///////////////////////////////////////////////////////////////////////
  110. typedef enum
  111. {
  112. TYPE_FACTORY,
  113. TYPE_PRESET,
  114. } ITEM_TYPE;
  115. typedef struct
  116. {
  117. ITEM_TYPE type;
  118. union
  119. {
  120. DefinitionFactoryClass *factory;
  121. PresetClass *preset;
  122. };
  123. } ITEM_DATA;
  124. static const int TOOLBAR_HEIGHT = 36;
  125. static const int TOOLBAR_V_SPACING = 5;
  126. static const int TOOLBAR_V_BORDER = TOOLBAR_V_SPACING * 2;
  127. static const int TOOLBAR_H_SPACING = 5;
  128. static const int TOOLBAR_H_BORDER = TOOLBAR_H_SPACING * 2;
  129. /////////////////////////////////////////////////////////////////////////////
  130. //
  131. // PresetsFormClass
  132. //
  133. /////////////////////////////////////////////////////////////////////////////
  134. PresetsFormClass::PresetsFormClass(CWnd *parent_wnd)
  135. : m_DragItem (NULL),
  136. m_IsDragging (false),
  137. m_DragImageList (NULL),
  138. CDialog(PresetsFormClass::IDD)
  139. {
  140. //{{AFX_DATA_INIT(PresetsFormClass)
  141. // NOTE: the ClassWizard will add member initialization here
  142. //}}AFX_DATA_INIT
  143. Create (PresetsFormClass::IDD, parent_wnd);
  144. return ;
  145. }
  146. PresetsFormClass::~PresetsFormClass()
  147. {
  148. return ;
  149. }
  150. void PresetsFormClass::DoDataExchange(CDataExchange* pDX)
  151. {
  152. CDialog::DoDataExchange(pDX);
  153. //{{AFX_DATA_MAP(PresetsFormClass)
  154. DDX_Control(pDX, IDC_PRESETS_TREE, m_TreeCtrl);
  155. //}}AFX_DATA_MAP
  156. }
  157. BEGIN_MESSAGE_MAP(PresetsFormClass, CDialog)
  158. //{{AFX_MSG_MAP(PresetsFormClass)
  159. ON_WM_SIZE()
  160. ON_COMMAND(IDC_ADD, OnAdd)
  161. ON_NOTIFY(TVN_DELETEITEM, IDC_PRESETS_TREE, OnDeleteitemPresetsTree)
  162. ON_COMMAND(IDC_MODIFY, OnModify)
  163. ON_COMMAND(IDC_MAKE, OnMake)
  164. ON_COMMAND(IDC_ADD_TEMP, OnAddTemp)
  165. ON_COMMAND(IDC_DELETE, OnDelete)
  166. ON_NOTIFY(TVN_SELCHANGED, IDC_PRESETS_TREE, OnSelchangedPresetsTree)
  167. ON_COMMAND(IDC_PLAY, OnPlay)
  168. ON_COMMAND(IDC_INFO, OnInfo)
  169. ON_COMMAND(IDC_EXTRA, OnExtra)
  170. ON_UPDATE_COMMAND_UI(IDC_CONVERT, OnUpdateConvert)
  171. ON_UPDATE_COMMAND_UI(IDC_INFO, OnUpdateInfo)
  172. ON_UPDATE_COMMAND_UI(IDC_PLAY, OnUpdatePlay)
  173. ON_UPDATE_COMMAND_UI(IDC_UPDATE_VSS, OnUpdateUpdateVss)
  174. ON_WM_DRAWITEM()
  175. ON_WM_MEASUREITEM()
  176. ON_COMMAND(IDC_CONVERT, OnConvert)
  177. ON_COMMAND(IDC_UPDATE_VSS, OnUpdateVss)
  178. ON_COMMAND(IDM_BATCH_IMPORT_TERRAIN, OnBatchImportTerrain)
  179. ON_COMMAND(IDM_UPDATE_EMBEDDED_NODE_LIST, OnBuildEmbedNodeList)
  180. ON_COMMAND(IDM_CLEAR_EMBEDDED_NODE_LIST, OnClearEmbeddedNodeList)
  181. ON_UPDATE_COMMAND_UI(IDM_BATCH_IMPORT_TERRAIN, OnUpdateBatchImportTerrain)
  182. ON_UPDATE_COMMAND_UI(IDM_UPDATE_EMBEDDED_NODE_LIST, OnUpdateEmbeddedNodeList)
  183. ON_UPDATE_COMMAND_UI(IDM_CLEAR_EMBEDDED_NODE_LIST, OnUpdateClearEmbeddedNodeList)
  184. ON_NOTIFY(TVN_BEGINDRAG, IDC_PRESETS_TREE, OnBegindragPresetsTree)
  185. ON_WM_LBUTTONUP()
  186. ON_WM_MOUSEMOVE()
  187. ON_WM_DESTROY()
  188. //}}AFX_MSG_MAP
  189. END_MESSAGE_MAP()
  190. /////////////////////////////////////////////////////////////////////////////
  191. // PresetsFormClass diagnostics
  192. #ifdef _DEBUG
  193. void PresetsFormClass::AssertValid() const
  194. {
  195. CDialog::AssertValid();
  196. }
  197. void PresetsFormClass::Dump(CDumpContext& dc) const
  198. {
  199. CDialog::Dump(dc);
  200. }
  201. #endif //_DEBUG
  202. /////////////////////////////////////////////////////////////////////////////
  203. //
  204. // OnSize
  205. //
  206. /////////////////////////////////////////////////////////////////////////////
  207. void
  208. PresetsFormClass::OnSize
  209. (
  210. UINT nType,
  211. int cx,
  212. int cy
  213. )
  214. {
  215. CDialog::OnSize(nType, cx, cy);
  216. if (::IsWindow (m_TreeCtrl) && (cx > 0) && (cy > 0)) {
  217. // Get the bounding rectangle of the form window
  218. CRect parentrect;
  219. GetWindowRect (&parentrect);
  220. // Get the bounding rectangle of the toolbar
  221. CRect toolbar_rect;
  222. m_Toolbar.GetWindowRect (&toolbar_rect);
  223. ScreenToClient (&toolbar_rect);
  224. // Move the toolbar so it is in its correct position
  225. m_Toolbar.SetWindowPos (NULL,
  226. TOOLBAR_H_SPACING,
  227. (cy - TOOLBAR_V_SPACING) - toolbar_rect.Height (),
  228. cx - TOOLBAR_H_BORDER,
  229. toolbar_rect.Height (),
  230. SWP_NOZORDER);
  231. // Get the bounding rectnagle of the list ctrl
  232. RECT list_rect;
  233. m_TreeCtrl.GetWindowRect (&list_rect);
  234. CRect client_rect = list_rect;
  235. ScreenToClient (&client_rect);
  236. int list_height = ((cy - TOOLBAR_V_BORDER) - toolbar_rect.Height ()) - client_rect.top;
  237. //
  238. // Resize the tab control to fill the empty contents of the client area
  239. //
  240. m_TreeCtrl.SetWindowPos ( NULL,
  241. 0,
  242. 0,
  243. cx-((list_rect.left-parentrect.left) << 1),
  244. list_height,
  245. SWP_NOZORDER | SWP_NOMOVE);
  246. }
  247. return ;
  248. }
  249. /////////////////////////////////////////////////////////////////////////////
  250. //
  251. // OnInitDialog
  252. //
  253. /////////////////////////////////////////////////////////////////////////////
  254. BOOL
  255. PresetsFormClass::OnInitDialog (void)
  256. {
  257. CDialog::OnInitDialog ();
  258. CRect rect;
  259. GetClientRect (&rect);
  260. m_Toolbar.CreateEx (this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_ALIGN_TOP, CRect(0, 0, 0, 0), 101);
  261. m_Toolbar.SetOwner (this);
  262. m_Toolbar.LoadToolBar (IDR_PRESET_TOOLBAR1);
  263. m_Toolbar.SetBarStyle (m_Toolbar.GetBarStyle () | CBRS_TOOLTIPS | CBRS_FLYBY);
  264. m_Toolbar.GetToolBarCtrl ().SetExtendedStyle (TBSTYLE_EX_DRAWDDARROWS);
  265. TBBUTTONINFO button_info = { sizeof (TBBUTTONINFO), TBIF_STYLE, 0 };
  266. int index = m_Toolbar.CommandToIndex (IDC_EXTRA);
  267. m_Toolbar.GetToolBarCtrl ().GetButtonInfo (IDC_EXTRA, &button_info);
  268. button_info.fsStyle |= TBSTYLE_DROPDOWN;
  269. m_Toolbar.GetToolBarCtrl ().SetButtonInfo (IDC_EXTRA, &button_info);
  270. //
  271. // Get the bounding rectangle of the form window
  272. //
  273. CRect parentrect;
  274. GetWindowRect (&parentrect);
  275. m_Toolbar.SetWindowPos (NULL, 0, 0, parentrect.Width () - TOOLBAR_H_BORDER, TOOLBAR_HEIGHT, SWP_NOZORDER | SWP_NOMOVE);
  276. m_Toolbar.Enable_Button (IDC_ADD, Enable_Button (IDC_ADD));
  277. m_Toolbar.Enable_Button (IDC_DELETE, Enable_Button (IDC_DELETE));
  278. //
  279. // Pass the general use imagelist onto the tree control
  280. //
  281. m_TreeCtrl.SetImageList (::Get_Global_Image_List (), TVSIL_NORMAL);
  282. Reload_Presets ();
  283. //
  284. // Select the first item in the tree control
  285. //
  286. HTREEITEM first_item = m_TreeCtrl.GetNextItem (NULL, TVGN_CHILD);
  287. if (first_item != NULL) {
  288. m_TreeCtrl.SelectItem (first_item);
  289. }
  290. SetProp (m_TreeCtrl, "TRANS_ACCS", (HANDLE)1);
  291. SetProp (m_hWnd, "TRANS_ACCS", (HANDLE)1);
  292. return TRUE;
  293. }
  294. /////////////////////////////////////////////////////////////////////////////
  295. //
  296. // Reload_Presets
  297. //
  298. /////////////////////////////////////////////////////////////////////////////
  299. void
  300. PresetsFormClass::Reload_Presets (void)
  301. {
  302. m_TreeCtrl.SetRedraw (FALSE);
  303. m_TreeCtrl.SelectItem (NULL);
  304. m_TreeCtrl.DeleteAllItems ();
  305. //
  306. // Loop through and add all the registered definition factories to
  307. // the tree control
  308. //
  309. for (int index = 0; index < PRESET_CATEGORY_COUNT; index ++) {
  310. //
  311. // Add this factory to the tree
  312. //
  313. HTREEITEM tree_item = m_TreeCtrl.InsertItem (PRESET_CATEGORIES[index].name, FOLDER_ICON, FOLDER_ICON);
  314. //
  315. // Is there a factory to create this class of defintion?
  316. //
  317. DefinitionFactoryClass *factory = DefinitionFactoryMgrClass::Find_Factory (PRESET_CATEGORIES[index].clsid);
  318. if (factory != NULL) {
  319. //
  320. // Add all presets for this factory into the tree
  321. //
  322. if (factory->Is_Displayed ()) {
  323. Set_Item_Data (tree_item, factory);
  324. Fill_In_Presets (tree_item);
  325. }
  326. } else {
  327. //
  328. // Find all the sub-factories
  329. //
  330. for ( factory = DefinitionFactoryMgrClass::Get_First (PRESET_CATEGORIES[index].clsid);
  331. factory != NULL;
  332. factory = DefinitionFactoryMgrClass::Get_Next (factory, PRESET_CATEGORIES[index].clsid))
  333. {
  334. //
  335. // Add this sub-factory and all its definitions to the tree
  336. //
  337. if (factory->Is_Displayed ()) {
  338. LPCTSTR name = factory->Get_Name ();
  339. HTREEITEM child_item = m_TreeCtrl.InsertItem (factory->Get_Name (), FOLDER_ICON, FOLDER_ICON, tree_item);
  340. Set_Item_Data (child_item, factory);
  341. Fill_In_Presets (child_item);
  342. }
  343. }
  344. }
  345. }
  346. Sort_Nodes (TVI_ROOT);
  347. m_TreeCtrl.SetRedraw (TRUE);
  348. return ;
  349. }
  350. /////////////////////////////////////////////////////////////////////////////
  351. //
  352. // Fill_In_Presets
  353. //
  354. /////////////////////////////////////////////////////////////////////////////
  355. void
  356. PresetsFormClass::Fill_In_Presets (HTREEITEM root_item)
  357. {
  358. DefinitionFactoryClass *factory = Get_Item_Factory (root_item);
  359. if (factory != NULL && factory->Is_Displayed ()) {
  360. uint32 class_id = factory->Get_Class_ID ();
  361. //
  362. // Find all the presets that belong to this class
  363. //
  364. PresetClass *preset = NULL;
  365. for ( preset = PresetMgrClass::Get_First (class_id, PresetMgrClass::ID_CLASS);
  366. preset != NULL;
  367. preset = PresetMgrClass::Get_Next (preset, class_id, PresetMgrClass::ID_CLASS))
  368. {
  369. //
  370. // Add this preset to the tree
  371. //
  372. if (preset->Get_Parent () == NULL) {
  373. HTREEITEM tree_item = Insert_Preset (root_item, preset);
  374. if (tree_item != NULL) {
  375. //
  376. // Recursively fill in this definition's 'children'
  377. //
  378. Fill_In_Preset_Children (tree_item, preset->Get_ID ());
  379. }
  380. }
  381. }
  382. }
  383. return ;
  384. }
  385. /////////////////////////////////////////////////////////////////////////////
  386. //
  387. // Fill_In_Preset_Children
  388. //
  389. /////////////////////////////////////////////////////////////////////////////
  390. void
  391. PresetsFormClass::Fill_In_Preset_Children
  392. (
  393. HTREEITEM root_item,
  394. uint32 parent_id
  395. )
  396. {
  397. //
  398. // Lookup the parent preset
  399. //
  400. PresetClass *parent_preset = PresetMgrClass::Find_Preset (parent_id);
  401. if (parent_preset == NULL) {
  402. return ;
  403. }
  404. //
  405. // Loop over all the children of this preset
  406. //
  407. int count = parent_preset->Get_Child_Preset_Count ();
  408. for (int index = 0; index < count; index ++) {
  409. PresetClass *child_preset = parent_preset->Get_Child_Preset (index);
  410. if (child_preset != NULL) {
  411. //
  412. // Check to make sure we have no recursive links
  413. //
  414. PresetClass *parent = child_preset->Get_Parent ();
  415. if (parent == child_preset || parent->Get_ID () == child_preset->Get_ID ()) {
  416. CString message;
  417. message.Format ("Preset '%s' is recursively linked to itself.\r\n", child_preset->Get_Name ());
  418. MessageBox (message, "Preset Error", MB_ICONERROR | MB_OK | MB_SETFOREGROUND);
  419. continue ;
  420. }
  421. //
  422. // Check to make sure the parent is correct
  423. //
  424. if (parent != NULL && child_preset->Get_Class_ID () != parent->Get_Class_ID ()) {
  425. CString message;
  426. message.Format ("Preset '%s' is incorrectly linked as a child of '%s'.\r\n", child_preset->Get_Name (), parent->Get_Name ());
  427. MessageBox (message, "Preset Error", MB_ICONERROR | MB_OK | MB_SETFOREGROUND);
  428. }
  429. //
  430. // Add this preset to the tree
  431. //
  432. HTREEITEM tree_item = Insert_Preset (root_item, child_preset);
  433. if (tree_item != NULL) {
  434. //
  435. // Recursively fill in this definition's 'children'
  436. //
  437. Fill_In_Preset_Children (tree_item, child_preset->Get_ID ());
  438. }
  439. }
  440. }
  441. return ;
  442. }
  443. /////////////////////////////////////////////////////////////////////////////
  444. //
  445. // Find_Preset
  446. //
  447. /////////////////////////////////////////////////////////////////////////////
  448. HTREEITEM
  449. PresetsFormClass::Find_Preset (HTREEITEM root_item, uint32 id)
  450. {
  451. HTREEITEM preset_item = NULL;
  452. //
  453. // Look for the preset in this item's children (recursive)
  454. //
  455. for ( HTREEITEM tree_item = m_TreeCtrl.GetChildItem (root_item);
  456. (tree_item != NULL) && (preset_item == NULL);
  457. tree_item = m_TreeCtrl.GetNextSiblingItem (tree_item))
  458. {
  459. DefinitionClass *definition = Get_Item_Definition (tree_item);
  460. //
  461. // Is this the preset we were looking for?
  462. //
  463. if ((definition != NULL) && (definition->Get_ID () == id)) {
  464. preset_item = tree_item;
  465. } else if (m_TreeCtrl.ItemHasChildren (tree_item)) {
  466. //
  467. // Recursively call this method for all sub-folders in this tree
  468. //
  469. preset_item = Find_Preset (tree_item, id);
  470. }
  471. }
  472. return preset_item;
  473. }
  474. /////////////////////////////////////////////////////////////////////////////
  475. //
  476. // Find_Factory
  477. //
  478. /////////////////////////////////////////////////////////////////////////////
  479. HTREEITEM
  480. PresetsFormClass::Find_Factory (HTREEITEM root_item, uint32 id)
  481. {
  482. HTREEITEM factory_item = NULL;
  483. //
  484. // Look for the preset in this item's children (recursive)
  485. //
  486. for ( HTREEITEM tree_item = m_TreeCtrl.GetChildItem (root_item);
  487. (tree_item != NULL) && (factory_item == NULL);
  488. tree_item = m_TreeCtrl.GetNextSiblingItem (tree_item))
  489. {
  490. DefinitionFactoryClass *factory = Get_Item_Factory (tree_item);
  491. //
  492. // Is this the factory we were looking for?
  493. //
  494. if ((factory != NULL) && (factory->Get_Class_ID () == id)) {
  495. factory_item = tree_item;
  496. } else if (m_TreeCtrl.ItemHasChildren (tree_item)) {
  497. //
  498. // Recursively call this method for all sub-folders in this tree
  499. //
  500. factory_item = Find_Factory (tree_item, id);
  501. }
  502. }
  503. return factory_item;
  504. }
  505. /////////////////////////////////////////////////////////////////////////////
  506. //
  507. // Get_Selected_Factory
  508. //
  509. /////////////////////////////////////////////////////////////////////////////
  510. DefinitionFactoryClass *
  511. PresetsFormClass::Get_Selected_Factory (void)
  512. {
  513. HTREEITEM curr_item = m_TreeCtrl.GetSelectedItem ();
  514. DefinitionFactoryClass *factory = Get_Item_Factory (curr_item);
  515. // Does this item represent a definition?
  516. if (factory == NULL) {
  517. //
  518. // Find the defintion's factory (if possible)
  519. //
  520. DefinitionClass *definition = Get_Item_Definition (curr_item);
  521. if (definition != NULL) {
  522. uint32 class_id = definition->Get_Class_ID ();
  523. factory = DefinitionFactoryMgrClass::Find_Factory (class_id);
  524. }
  525. }
  526. return factory;
  527. }
  528. /////////////////////////////////////////////////////////////////////////////
  529. //
  530. // Set_Item_Data
  531. //
  532. /////////////////////////////////////////////////////////////////////////////
  533. void
  534. PresetsFormClass::Set_Item_Data (HTREEITEM item, DefinitionFactoryClass *factory)
  535. {
  536. //
  537. // Allocate a new wrapper if we need to
  538. //
  539. ITEM_DATA *item_data = (ITEM_DATA *)m_TreeCtrl.GetItemData (item);
  540. if (item_data == NULL) {
  541. item_data = new ITEM_DATA;
  542. }
  543. //
  544. // Set a flag in the wrapper so we know what kind of data
  545. // this tree item contains.
  546. //
  547. item_data->type = TYPE_FACTORY;
  548. item_data->factory = factory;
  549. m_TreeCtrl.SetItemData (item, (DWORD)item_data);
  550. return ;
  551. }
  552. /////////////////////////////////////////////////////////////////////////////
  553. //
  554. // Set_Item_Data
  555. //
  556. /////////////////////////////////////////////////////////////////////////////
  557. void
  558. PresetsFormClass::Set_Item_Data (HTREEITEM item, PresetClass *preset)
  559. {
  560. //
  561. // Allocate a new wrapper if we need to
  562. //
  563. ITEM_DATA *item_data = (ITEM_DATA *)m_TreeCtrl.GetItemData (item);
  564. if (item_data == NULL) {
  565. item_data = new ITEM_DATA;
  566. }
  567. //
  568. // Set a flag in the wrapper so we know what kind of data
  569. // this tree item contains.
  570. //
  571. item_data->type = TYPE_PRESET;
  572. item_data->preset = preset;
  573. m_TreeCtrl.SetItemData (item, (DWORD)item_data);
  574. return ;
  575. }
  576. /////////////////////////////////////////////////////////////////////////////
  577. //
  578. // Get_Item_Factory
  579. //
  580. /////////////////////////////////////////////////////////////////////////////
  581. DefinitionFactoryClass *
  582. PresetsFormClass::Get_Item_Factory (HTREEITEM item)
  583. {
  584. DefinitionFactoryClass *factory = NULL;
  585. if (item != NULL) {
  586. //
  587. // If this item represents a factory, then return the factory
  588. // pointer to the caller.
  589. //
  590. ITEM_DATA *item_data = (ITEM_DATA *)m_TreeCtrl.GetItemData (item);
  591. if ((item_data != NULL) && (item_data->type == TYPE_FACTORY)) {
  592. factory = item_data->factory;
  593. }
  594. }
  595. return factory;
  596. }
  597. /////////////////////////////////////////////////////////////////////////////
  598. //
  599. // Get_Item_Definition
  600. //
  601. /////////////////////////////////////////////////////////////////////////////
  602. DefinitionClass *
  603. PresetsFormClass::Get_Item_Definition (HTREEITEM item)
  604. {
  605. DefinitionClass *definition = NULL;
  606. if (item != NULL) {
  607. //
  608. // Get the definition from the preset this item
  609. // represents
  610. //
  611. PresetClass *preset = Get_Item_Preset (item);
  612. if (preset != NULL) {
  613. definition = preset->Get_Definition ();
  614. }
  615. }
  616. return definition;
  617. }
  618. /////////////////////////////////////////////////////////////////////////////
  619. //
  620. // Get_Item_Preset
  621. //
  622. /////////////////////////////////////////////////////////////////////////////
  623. PresetClass *
  624. PresetsFormClass::Get_Item_Preset (HTREEITEM item)
  625. {
  626. PresetClass *preset = NULL;
  627. if (item != NULL) {
  628. //
  629. // If this item represents a definition, then return the definition
  630. // pointer to the caller.
  631. //
  632. ITEM_DATA *item_data = (ITEM_DATA *)m_TreeCtrl.GetItemData (item);
  633. if ((item_data != NULL) && (item_data->type == TYPE_PRESET)) {
  634. preset = item_data->preset;
  635. }
  636. }
  637. return preset;
  638. }
  639. /////////////////////////////////////////////////////////////////////////////
  640. //
  641. // Get_Icon
  642. //
  643. /////////////////////////////////////////////////////////////////////////////
  644. int
  645. PresetsFormClass::Get_Icon (PresetClass *preset)
  646. {
  647. int icon = FOLDER_ICON;
  648. DefinitionClass *definition = preset->Get_Definition ();
  649. if (definition != NULL) {
  650. int class_id = definition->Get_Class_ID ();
  651. int superclass_id = ::SuperClassID_From_ClassID (class_id);
  652. switch (superclass_id) {
  653. case CLASSID_TERRAIN:
  654. icon = TERRAIN_ICON;
  655. break;
  656. case CLASSID_TILE:
  657. icon = TILE_ICON;
  658. break;
  659. case CLASSID_GAME_OBJECTS:
  660. case CLASSID_MUNITIONS:
  661. case CLASSID_DUMMY_OBJECTS:
  662. if (class_id == CLASSID_GAME_OBJECT_DEF_BUILDING) {
  663. icon = BUILDING_ICON;
  664. } else {
  665. icon = OBJECT_ICON;
  666. }
  667. break;
  668. case CLASSID_LIGHT:
  669. icon = LIGHT_ICON;
  670. break;
  671. case CLASSID_SOUND:
  672. icon = SOUND_ICON;
  673. break;
  674. case CLASSID_WAYPATH:
  675. icon = WAYPATH_ICON;
  676. break;
  677. case CLASSID_ZONE:
  678. icon = ZONE_ICON;
  679. break;
  680. case CLASSID_TRANSITION:
  681. icon = TRANSITION_ICON;
  682. break;
  683. case CLASSID_TWIDDLERS:
  684. icon = RAND_ICON;
  685. break;
  686. case CLASSID_BUILDINGS:
  687. icon = BUILDING_ICON;
  688. break;
  689. case CLASSID_EDITOR_OBJECTS:
  690. if (class_id == CLASSID_VIS_POINT_DEF) {
  691. icon = VIS_ICON;
  692. } else if (class_id == CLASSID_PATHFIND_START_DEF) {
  693. icon = PATHFIND_ICON;
  694. }
  695. break;
  696. case CLASSID_GLOBAL_SETTINGS:
  697. icon = FILE_ICON;
  698. break;
  699. }
  700. }
  701. if (preset->Get_IsTemporary ()) {
  702. icon = TEMP_ICON;
  703. }
  704. return icon;
  705. }
  706. /////////////////////////////////////////////////////////////////////////////
  707. //
  708. // Insert_Preset
  709. //
  710. /////////////////////////////////////////////////////////////////////////////
  711. HTREEITEM
  712. PresetsFormClass::Insert_Preset
  713. (
  714. HTREEITEM root_item,
  715. PresetClass * preset
  716. )
  717. {
  718. int icon = Get_Icon (preset);
  719. //
  720. // Insert a new node into the tree to represent this item
  721. //
  722. HTREEITEM tree_item = m_TreeCtrl.InsertItem (preset->Get_Name (), icon, icon, root_item);
  723. if (tree_item != NULL) {
  724. Set_Item_Data (tree_item, preset);
  725. bool needs_overlay = (preset->Get_Node_List ().Count () > 0);
  726. TreeView_SetOverlay (m_TreeCtrl, tree_item, needs_overlay);
  727. }
  728. return tree_item;
  729. }
  730. /////////////////////////////////////////////////////////////////////////////
  731. //
  732. // OnDeleteitemPresetsTree
  733. //
  734. /////////////////////////////////////////////////////////////////////////////
  735. void
  736. PresetsFormClass::OnDeleteitemPresetsTree
  737. (
  738. NMHDR * pNMHDR,
  739. LRESULT *pResult
  740. )
  741. {
  742. NM_TREEVIEW *pNMTreeView = (NM_TREEVIEW *)pNMHDR;
  743. (*pResult) = 0;
  744. //
  745. // Free the wrapper we installed around this item
  746. //
  747. ITEM_DATA *item_data = (ITEM_DATA *)m_TreeCtrl.GetItemData (pNMTreeView->itemOld.hItem);
  748. SAFE_DELETE (item_data);
  749. m_TreeCtrl.SetItemData (pNMTreeView->itemOld.hItem, 0L);
  750. return ;
  751. }
  752. /////////////////////////////////////////////////////////////////////////////
  753. //
  754. // OnModify
  755. //
  756. /////////////////////////////////////////////////////////////////////////////
  757. bool
  758. PresetsFormClass::Modify_Preset (void)
  759. {
  760. bool retval = false;
  761. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  762. PresetClass *preset = Get_Item_Preset (current_item);
  763. if (preset != NULL) {
  764. StringClass old_name = preset->Get_Name ();
  765. //
  766. // Show the properties dialog for this preset
  767. //
  768. if (preset->Show_Properties ()) {
  769. //
  770. // Check to see if the user has renamed the preset
  771. //
  772. StringClass new_name = preset->Get_Name ();
  773. if (::lstrcmp (old_name, new_name) != 0) {
  774. //
  775. // Rename the item in the tree
  776. //
  777. m_TreeCtrl.SetRedraw (FALSE);
  778. m_TreeCtrl.SetItemText (current_item, preset->Get_Name ());
  779. m_TreeCtrl.SetRedraw (TRUE);
  780. m_TreeCtrl.InvalidateRect (NULL, TRUE);
  781. //
  782. // Log the rename operation
  783. //
  784. if (preset->Get_IsTemporary () == false) {
  785. PresetLoggerClass::Log_Renamed (old_name, new_name);
  786. }
  787. }
  788. retval = true;
  789. }
  790. }
  791. return retval;
  792. }
  793. /////////////////////////////////////////////////////////////////////////////
  794. //
  795. // OnModify
  796. //
  797. /////////////////////////////////////////////////////////////////////////////
  798. void
  799. PresetsFormClass::OnModify (void)
  800. {
  801. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  802. PresetClass *preset = Get_Item_Preset (current_item);
  803. if (preset != NULL) {
  804. if (preset->Get_IsTemporary () == false) {
  805. //
  806. // Check out the definition database
  807. //
  808. SelectionCaptureClass sel_capture (this);
  809. bool undo_on_err = false;
  810. uint32 class_id = preset->Get_Class_ID ();
  811. if (PresetMgrClass::Check_Out_Database (class_id, &undo_on_err)) {
  812. sel_capture.Restore ();
  813. //
  814. // Re-get the preset (its pointer has changed, the
  815. // old one is crap).
  816. //
  817. current_item = m_TreeCtrl.GetSelectedItem ();
  818. preset = Get_Item_Preset (current_item);
  819. if (preset != NULL) {
  820. //
  821. // Show the preset settings
  822. //
  823. if (Modify_Preset ()) {
  824. Save_Global_Presets (class_id);
  825. PresetMgrClass::Add_Dirty_Preset (preset->Get_ID ());
  826. } else if (undo_on_err) {
  827. PresetMgrClass::Undo_Database_Check_Out (class_id);
  828. }
  829. }
  830. }
  831. } else {
  832. //
  833. // Show the preset settings
  834. //
  835. if (Modify_Preset ()) {
  836. Save_Temp_Presets ();
  837. }
  838. }
  839. NodeMgrClass::Reload_Nodes (preset);
  840. }
  841. return ;
  842. }
  843. /////////////////////////////////////////////////////////////////////////////
  844. //
  845. // Load_Databases
  846. //
  847. /////////////////////////////////////////////////////////////////////////////
  848. bool
  849. PresetsFormClass::Load_Databases (void)
  850. {
  851. // Start fresh
  852. PresetMgrClass::Free_Presets ();
  853. DefinitionMgrClass::Free_Definitions ();
  854. bool retval = false;
  855. #ifdef PUBLIC_EDITOR_VER
  856. //
  857. // Reload the presets
  858. //
  859. retval = Old_Load_Presets ();
  860. retval &= Load_Temp_Presets ();
  861. #else
  862. //
  863. // Reload the presets
  864. //
  865. retval = Load_Preset_Libraries ();
  866. retval &= Load_Temp_Presets ();
  867. #endif //PUBLIC_EDITOR_VER
  868. return retval;
  869. }
  870. /////////////////////////////////////////////////////////////////////////////
  871. //
  872. // Load_Preset_Libraries
  873. //
  874. /////////////////////////////////////////////////////////////////////////////
  875. bool
  876. PresetsFormClass::Load_Preset_Libraries (void)
  877. {
  878. //
  879. // Try to load the library for each factory
  880. //
  881. DefinitionFactoryClass *factory = NULL;
  882. for ( factory = DefinitionFactoryMgrClass::Get_First ();
  883. factory != NULL;
  884. factory = DefinitionFactoryMgrClass::Get_Next (factory))
  885. {
  886. if (factory->Is_Displayed ()) {
  887. Load_Presets (factory->Get_Class_ID ());
  888. }
  889. }
  890. return true;
  891. }
  892. /////////////////////////////////////////////////////////////////////////////
  893. //
  894. // Load_Presets
  895. //
  896. /////////////////////////////////////////////////////////////////////////////
  897. bool
  898. PresetsFormClass::Load_Presets (uint32 class_id)
  899. {
  900. //
  901. // Build a filename for the presets library
  902. //
  903. CString path;
  904. ::Get_File_Mgr ()->Get_Preset_Library_Path (class_id, false, path);
  905. //
  906. // Open the file
  907. //
  908. HANDLE file = ::CreateFile ( path,
  909. GENERIC_READ,
  910. FILE_SHARE_READ,
  911. NULL,
  912. OPEN_EXISTING,
  913. 0L,
  914. NULL);
  915. if (file != INVALID_HANDLE_VALUE) {
  916. //
  917. // Determine how large the file is
  918. //
  919. int file_size = ::GetFileSize (file, NULL);
  920. if (file_size > 0 && file_size < 99999999)
  921. {
  922. //
  923. // Read the file into memory
  924. //
  925. unsigned char *buffer = new unsigned char[file_size];
  926. DWORD bytes_read = 0;
  927. ::ReadFile (file, buffer, file_size, &bytes_read, NULL);
  928. //
  929. // Close the file
  930. //
  931. ::CloseHandle (file);
  932. file = INVALID_HANDLE_VALUE;
  933. //
  934. // Use a RAM file for the loading
  935. //
  936. RAMFileClass file_obj (buffer, file_size);
  937. file_obj.Open (FileClass::READ);
  938. ChunkLoadClass chunk_load (&file_obj);
  939. //
  940. // Load the file
  941. //
  942. SaveLoadSystemClass::Load (chunk_load);
  943. //
  944. // Free the buffer
  945. //
  946. delete [] buffer;
  947. buffer = NULL;
  948. }
  949. }
  950. return true;
  951. }
  952. /////////////////////////////////////////////////////////////////////////////
  953. //
  954. // Old_Load_Presets
  955. //
  956. /////////////////////////////////////////////////////////////////////////////
  957. bool
  958. PresetsFormClass::Old_Load_Presets (void)
  959. {
  960. CString path = ::Get_File_Mgr ()->Make_Full_Path (OBJECTS_DDB_PATH);
  961. //
  962. // Open the file
  963. //
  964. HANDLE file = ::CreateFile (path,
  965. GENERIC_READ,
  966. FILE_SHARE_READ,
  967. NULL,
  968. OPEN_EXISTING,
  969. 0L,
  970. NULL);
  971. if (file != INVALID_HANDLE_VALUE) {
  972. //
  973. // Determine how large the file is
  974. //
  975. int file_size = ::GetFileSize (file, NULL);
  976. if (file_size > 0 && file_size < 99999999)
  977. {
  978. //
  979. // Read the file into memory
  980. //
  981. unsigned char *buffer = new unsigned char[file_size];
  982. DWORD bytes_read = 0;
  983. ::ReadFile (file, buffer, file_size, &bytes_read, NULL);
  984. //
  985. // Close the file
  986. //
  987. ::CloseHandle (file);
  988. file = INVALID_HANDLE_VALUE;
  989. //
  990. // Use a RAM file for the loading
  991. //
  992. RAMFileClass file_obj (buffer, file_size);
  993. file_obj.Open (FileClass::READ);
  994. ChunkLoadClass chunk_load (&file_obj);
  995. //
  996. // Load the file
  997. //
  998. SaveLoadSystemClass::Load (chunk_load);
  999. //
  1000. // Free the buffer
  1001. //
  1002. delete [] buffer;
  1003. buffer = NULL;
  1004. }
  1005. }
  1006. return true;
  1007. }
  1008. /////////////////////////////////////////////////////////////////////////////
  1009. //
  1010. // Load_Temp_Presets
  1011. //
  1012. /////////////////////////////////////////////////////////////////////////////
  1013. bool
  1014. PresetsFormClass::Load_Temp_Presets (void)
  1015. {
  1016. CString path = ::Get_File_Mgr ()->Make_Full_Path (TEMP_DB_PATH);
  1017. //
  1018. // Open the file
  1019. //
  1020. HANDLE hfile = ::CreateFile (path,
  1021. GENERIC_READ,
  1022. FILE_SHARE_READ,
  1023. NULL,
  1024. OPEN_EXISTING,
  1025. 0L,
  1026. NULL);
  1027. if (hfile != INVALID_HANDLE_VALUE) {
  1028. RawFileClass file_obj;
  1029. file_obj.Attach (hfile);
  1030. ChunkLoadClass chunk_load (&file_obj);
  1031. //
  1032. // Load the file
  1033. //
  1034. SaveLoadSystemClass::Load (chunk_load);
  1035. }
  1036. return true;
  1037. }
  1038. /////////////////////////////////////////////////////////////////////////////
  1039. //
  1040. // Save_Temp_Presets
  1041. //
  1042. /////////////////////////////////////////////////////////////////////////////
  1043. bool
  1044. PresetsFormClass::Save_Temp_Presets (void)
  1045. {
  1046. Save_Presets (0, true);
  1047. return true;
  1048. }
  1049. /////////////////////////////////////////////////////////////////////////////
  1050. //
  1051. // Save_Global_Presets
  1052. //
  1053. /////////////////////////////////////////////////////////////////////////////
  1054. bool
  1055. PresetsFormClass::Save_Global_Presets (uint32 class_id)
  1056. {
  1057. #ifndef PUBLIC_EDITOR_VER
  1058. Save_Presets (class_id, false);
  1059. #endif //PUBLIC_EDITOR_VER
  1060. return true;
  1061. }
  1062. /////////////////////////////////////////////////////////////////////////////
  1063. //
  1064. // Build_DDB_File_List
  1065. //
  1066. /////////////////////////////////////////////////////////////////////////////
  1067. void
  1068. PresetsFormClass::Build_DDB_File_List
  1069. (
  1070. DynamicVectorClass<CString> & file_list,
  1071. HTREEITEM parent_item
  1072. )
  1073. {
  1074. //
  1075. // Loop over all the immediate children
  1076. //
  1077. for ( HTREEITEM child_item = m_TreeCtrl.GetChildItem (parent_item);
  1078. child_item != NULL;
  1079. child_item = m_TreeCtrl.GetNextSiblingItem (child_item))
  1080. {
  1081. //
  1082. // If this tree item represents a definition factory, then
  1083. // we should have a preset library to match
  1084. //
  1085. DefinitionFactoryClass *factory = Get_Item_Factory (child_item);
  1086. if (factory != NULL) {
  1087. //
  1088. // Build a filename for this preset library
  1089. //
  1090. CString path;
  1091. ::Get_File_Mgr ()->Get_Preset_Library_Path (factory->Get_Class_ID (), false, path);
  1092. //
  1093. // Add this preset library to the list
  1094. //
  1095. file_list.Add (path);
  1096. } else if (m_TreeCtrl.ItemHasChildren (child_item)) {
  1097. //
  1098. // Recursively call this method for all sub-folders in this tree
  1099. //
  1100. Build_DDB_File_List (file_list, child_item);
  1101. }
  1102. }
  1103. return ;
  1104. }
  1105. /////////////////////////////////////////////////////////////////////////////
  1106. //
  1107. // Save_Preset_Libraries
  1108. //
  1109. /////////////////////////////////////////////////////////////////////////////
  1110. void
  1111. PresetsFormClass::Save_Preset_Libraries (HTREEITEM parent_item)
  1112. {
  1113. #ifdef PUBLIC_EDITOR_VER
  1114. //
  1115. // Simply save the presets together in one file
  1116. //
  1117. CString path = ::Get_File_Mgr ()->Make_Full_Path (OBJECTS_DDB_PATH);
  1118. Save_Presets (path, 0, false, false);
  1119. #else
  1120. //
  1121. // Loop over all the immediate children
  1122. //
  1123. for ( HTREEITEM child_item = m_TreeCtrl.GetChildItem (parent_item);
  1124. child_item != NULL;
  1125. child_item = m_TreeCtrl.GetNextSiblingItem (child_item))
  1126. {
  1127. //
  1128. // If this tree item represents a definition factory, then save
  1129. // a preset library for all presets of this class ID
  1130. //
  1131. DefinitionFactoryClass *factory = Get_Item_Factory (child_item);
  1132. if (factory != NULL) {
  1133. Save_Global_Presets (factory->Get_Class_ID ());
  1134. } else if (m_TreeCtrl.ItemHasChildren (child_item)) {
  1135. //
  1136. // Recursively call this method for all sub-folders in this tree
  1137. //
  1138. Save_Preset_Libraries (child_item);
  1139. }
  1140. }
  1141. #endif //PUBLIC_EDITOR_VER
  1142. return ;
  1143. }
  1144. /////////////////////////////////////////////////////////////////////////////
  1145. //
  1146. // Save_Presets
  1147. //
  1148. /////////////////////////////////////////////////////////////////////////////
  1149. bool
  1150. PresetsFormClass::Save_Presets
  1151. (
  1152. LPCTSTR path,
  1153. uint32 class_id,
  1154. bool class_id_matters,
  1155. bool temps_only
  1156. )
  1157. {
  1158. ///
  1159. // Delete the file if it already exists
  1160. //
  1161. if (::GetFileAttributes (path) != 0xFFFFFFFF) {
  1162. DWORD attributes = ::GetFileAttributes (path);
  1163. ::SetFileAttributes (path, attributes & (~FILE_ATTRIBUTE_READONLY));
  1164. ::DeleteFile (path);
  1165. }
  1166. //
  1167. // Create the file at the specified location
  1168. //
  1169. HANDLE file = ::CreateFile ( path,
  1170. GENERIC_WRITE,
  1171. 0,
  1172. NULL,
  1173. CREATE_ALWAYS,
  1174. 0L,
  1175. NULL);
  1176. ASSERT (file != INVALID_HANDLE_VALUE);
  1177. if (file != INVALID_HANDLE_VALUE) {
  1178. //
  1179. // Now write the presets and definitions out to this file
  1180. //
  1181. Save_Presets (file, class_id, class_id_matters, temps_only);
  1182. } else {
  1183. //
  1184. // Warn the user
  1185. //
  1186. DWORD last_error = ::GetLastError ();
  1187. CString message;
  1188. message.Format ("Unable to create database file.\nPath:%s\nError Code:%d", path, last_error);
  1189. ::MessageBox (::AfxGetMainWnd ()->m_hWnd, message, "File I/O Error", MB_ICONERROR | MB_OK);
  1190. }
  1191. return true;
  1192. }
  1193. /////////////////////////////////////////////////////////////////////////////
  1194. //
  1195. // Save_Presets
  1196. //
  1197. /////////////////////////////////////////////////////////////////////////////
  1198. bool
  1199. PresetsFormClass::Save_Presets (uint32 class_id, bool temps_only)
  1200. {
  1201. //
  1202. // Build a filename for the presets library
  1203. //
  1204. CString path;
  1205. ::Get_File_Mgr ()->Get_Preset_Library_Path (class_id, temps_only, path);
  1206. //
  1207. // Now save the presets to this file
  1208. //
  1209. return Save_Presets (path, class_id, !temps_only, temps_only);
  1210. }
  1211. /////////////////////////////////////////////////////////////////////////////
  1212. //
  1213. // Save_Presets
  1214. //
  1215. /////////////////////////////////////////////////////////////////////////////
  1216. void
  1217. PresetsFormClass::Save_Presets (HANDLE file, uint32 class_id, bool class_id_matters, bool temps_only)
  1218. {
  1219. //
  1220. // Create a chunk IO object that we can use to save our subsystems
  1221. //
  1222. RawFileClass file_obj;
  1223. file_obj.Attach (file);
  1224. ChunkSaveClass chunk_save (&file_obj);
  1225. //
  1226. // Remove all the presets that don't match our criteria
  1227. //
  1228. PRESET_LIST preset_list;
  1229. preset_list.Set_Growth_Step (2000);
  1230. PresetMgrClass::Remove_Non_Matching_Presets (class_id, class_id_matters, temps_only, preset_list);
  1231. //
  1232. // Turn saving off for all definitions
  1233. //
  1234. DefinitionClass *definition = NULL;
  1235. for ( definition = DefinitionMgrClass::Get_First ();
  1236. definition != NULL;
  1237. definition = DefinitionMgrClass::Get_Next (definition))
  1238. {
  1239. definition->Enable_Save (false);
  1240. }
  1241. //
  1242. // Now turn saving on for all definitions that are needed by
  1243. // one of the presets.
  1244. //
  1245. DEFINITION_LIST defs_to_save;
  1246. PresetClass *preset = NULL;
  1247. for ( preset = PresetMgrClass::Get_First ();
  1248. preset != NULL;
  1249. preset = PresetMgrClass::Get_Next (preset))
  1250. {
  1251. //
  1252. // Build a list of definitions this preset depends on
  1253. //
  1254. DEFINITION_LIST curr_defs;
  1255. preset->Collect_Definitions (curr_defs);
  1256. //
  1257. // Turn saving on for all these definitions
  1258. //
  1259. for (int index = 0; index < curr_defs.Count (); index ++) {
  1260. DefinitionClass *definition = curr_defs[index];
  1261. if (definition != NULL) {
  1262. definition->Enable_Save (true);
  1263. }
  1264. }
  1265. }
  1266. //
  1267. // The definition database consists of the definitions (global)
  1268. // and the presets (editor only).
  1269. //
  1270. SaveLoadSystemClass::Save (chunk_save, _TheDefinitionMgr);
  1271. SaveLoadSystemClass::Save (chunk_save, _ThePresetMgr);
  1272. //
  1273. // Turn saving back on for all definitions
  1274. //
  1275. for ( definition = DefinitionMgrClass::Get_First ();
  1276. definition != NULL;
  1277. definition = DefinitionMgrClass::Get_Next (definition))
  1278. {
  1279. definition->Enable_Save (true);
  1280. }
  1281. //
  1282. // Now add back all the presets we removed
  1283. //
  1284. PresetMgrClass::Put_Presets_Back (preset_list);
  1285. return ;
  1286. }
  1287. /////////////////////////////////////////////////////////////////////////////
  1288. //
  1289. // Reselect_Item
  1290. //
  1291. /////////////////////////////////////////////////////////////////////////////
  1292. void
  1293. PresetsFormClass::Reselect_Item (int id, bool is_factory)
  1294. {
  1295. HTREEITEM tree_item = NULL;
  1296. if (is_factory) {
  1297. tree_item = Find_Factory (TVI_ROOT, id);
  1298. } else {
  1299. tree_item = Find_Preset (TVI_ROOT, id);
  1300. }
  1301. m_TreeCtrl.Select (tree_item, TVGN_FIRSTVISIBLE);
  1302. m_TreeCtrl.SelectItem (tree_item);
  1303. return ;
  1304. }
  1305. /////////////////////////////////////////////////////////////////////////////
  1306. //
  1307. // OnAddTemp
  1308. //
  1309. /////////////////////////////////////////////////////////////////////////////
  1310. void
  1311. PresetsFormClass::OnAddTemp (void)
  1312. {
  1313. DefinitionFactoryClass *factory = Get_Selected_Factory ();
  1314. if (factory != NULL) {
  1315. if (Add_New_Preset (NULL, true) != NULL) {
  1316. Save_Temp_Presets ();
  1317. }
  1318. }
  1319. return ;
  1320. }
  1321. /////////////////////////////////////////////////////////////////////////////
  1322. //
  1323. // OnAdd
  1324. //
  1325. /////////////////////////////////////////////////////////////////////////////
  1326. void
  1327. PresetsFormClass::OnAdd (void)
  1328. {
  1329. DefinitionFactoryClass *factory = Get_Selected_Factory ();
  1330. if (factory != NULL) {
  1331. //
  1332. // Check out the definition database
  1333. //
  1334. SelectionCaptureClass sel_capture (this);
  1335. bool undo_check_out = false;
  1336. if (PresetMgrClass::Check_Out_Database (factory->Get_Class_ID (), &undo_check_out)) {
  1337. sel_capture.Restore ();
  1338. //
  1339. // Create a new preset
  1340. //
  1341. PresetClass *preset = Add_New_Preset (NULL);
  1342. if (preset != NULL) {
  1343. //
  1344. // Log creation
  1345. //
  1346. PresetLoggerClass::Log_Created (preset);
  1347. //
  1348. // Register this new preset for check-in
  1349. //
  1350. Save_Global_Presets (factory->Get_Class_ID ());
  1351. PresetMgrClass::Add_Dirty_Preset (preset->Get_ID ());
  1352. } else if (undo_check_out) {
  1353. PresetMgrClass::Undo_Database_Check_Out (factory->Get_Class_ID ());
  1354. }
  1355. }
  1356. }
  1357. return ;
  1358. }
  1359. /////////////////////////////////////////////////////////////////////////////
  1360. //
  1361. // OnMake
  1362. //
  1363. /////////////////////////////////////////////////////////////////////////////
  1364. void
  1365. PresetsFormClass::OnMake (void)
  1366. {
  1367. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  1368. PresetClass *preset = Get_Item_Preset (current_item);
  1369. if (preset != NULL) {
  1370. ::Get_Scene_Editor ()->Create_Node (preset);
  1371. //
  1372. // Repartition the scene if the user placed a terrain
  1373. //
  1374. if (preset->Get_Class_ID () == CLASSID_TERRAIN) {
  1375. ::Get_Scene_Editor ()->Re_Partition_Static_Projectors ();
  1376. ::Get_Scene_Editor ()->Re_Partition_Static_Lights ();
  1377. ::Get_Scene_Editor ()->Re_Partition_Static_Objects ();
  1378. }
  1379. ::Refresh_Main_View ();
  1380. }
  1381. return ;
  1382. }
  1383. /////////////////////////////////////////////////////////////////////////////
  1384. //
  1385. // Add_New_Preset
  1386. //
  1387. /////////////////////////////////////////////////////////////////////////////
  1388. PresetClass *
  1389. PresetsFormClass::Add_New_Preset (LPCTSTR name, bool is_temp, bool sel_new)
  1390. {
  1391. PresetClass *new_preset = NULL;
  1392. DefinitionFactoryClass *factory = Get_Selected_Factory ();
  1393. if (factory != NULL) {
  1394. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  1395. PresetClass *parent_preset = Get_Item_Preset (current_item);
  1396. //
  1397. // Create a new preset
  1398. //
  1399. new_preset = PresetMgrClass::Create_Preset (factory->Get_Class_ID (), name, is_temp);
  1400. new_preset->Set_Parent (parent_preset);
  1401. //
  1402. // Give the new preset its parent's values by default
  1403. //
  1404. if (parent_preset != NULL) {
  1405. new_preset->Copy_Properties (*parent_preset);
  1406. }
  1407. //
  1408. // Edit the preset's properties
  1409. //
  1410. if (name != NULL || new_preset->Show_Properties ()) {
  1411. //
  1412. // Add this preset to the framework
  1413. //
  1414. HTREEITEM new_item = Insert_Preset (current_item, new_preset);
  1415. PresetMgrClass::Add_Preset (new_preset);
  1416. DefinitionMgrClass::Register_Definition (new_preset->Get_Definition ());
  1417. if (parent_preset != NULL) {
  1418. parent_preset->Add_Child_Preset (new_preset->Get_ID ());
  1419. }
  1420. //
  1421. // Select the new entry
  1422. //
  1423. if (sel_new) {
  1424. m_TreeCtrl.Select (new_item, TVGN_FIRSTVISIBLE);
  1425. m_TreeCtrl.SelectItem (new_item);
  1426. }
  1427. m_TreeCtrl.SortChildren (current_item);
  1428. m_TreeCtrl.InvalidateRect (NULL, TRUE);
  1429. } else {
  1430. DefinitionClass *definition = new_preset->Get_Definition ();
  1431. SAFE_DELETE (definition);
  1432. SAFE_DELETE (new_preset);
  1433. }
  1434. }
  1435. return new_preset;
  1436. }
  1437. /////////////////////////////////////////////////////////////////////////////
  1438. //
  1439. // OnDelete
  1440. //
  1441. /////////////////////////////////////////////////////////////////////////////
  1442. void
  1443. PresetsFormClass::OnDelete (void)
  1444. {
  1445. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  1446. PresetClass *preset = Get_Item_Preset (current_item);
  1447. if (preset != NULL) {
  1448. //
  1449. // Make sure the user really wants to do this
  1450. //
  1451. if (::Message_Box ( m_hWnd,
  1452. IDS_DELETE_PRESET_MSG,
  1453. IDS_DELETE_PRESET_TITLE,
  1454. MB_ICONQUESTION | MB_YESNO) == IDYES )
  1455. {
  1456. CWaitCursor wait_cursor;
  1457. //
  1458. // Check out the definition database (unless its a temp)
  1459. //
  1460. SelectionCaptureClass sel_capture (this);
  1461. bool undo_on_err = false;
  1462. bool was_temp = preset->Get_IsTemporary ();;
  1463. if (was_temp || PresetMgrClass::Check_Out_Database (preset->Get_Class_ID (), &undo_on_err)) {
  1464. sel_capture.Restore ();
  1465. //
  1466. // Re-get the preset (its pointer has changed, the
  1467. // old one is crap).
  1468. //
  1469. current_item = m_TreeCtrl.GetSelectedItem ();
  1470. preset = Get_Item_Preset (current_item);
  1471. if (preset != NULL) {
  1472. //
  1473. // Log the delete operation
  1474. //
  1475. if (preset->Get_IsTemporary () == false) {
  1476. PresetLoggerClass::Log_Deleted (preset->Get_Name ());
  1477. }
  1478. //
  1479. // Build a list of all the sub-items that are affected by this operation
  1480. //
  1481. DynamicVectorClass<HTREEITEM> tree_item_list;
  1482. tree_item_list.Add (current_item);
  1483. Build_Child_List (current_item, tree_item_list);
  1484. //
  1485. // Determine what class-id's these presets belong to (they all belong
  1486. // to the same class)
  1487. //
  1488. uint32 class_id = 0;
  1489. DefinitionClass *definition = preset->Get_Definition ();
  1490. if (definition != NULL) {
  1491. class_id = definition->Get_Class_ID ();
  1492. }
  1493. //
  1494. // Free all the nodes in the scene that use any of these presets.
  1495. // Also unregister the preset and its definition
  1496. //
  1497. bool save_temp_lib = was_temp;
  1498. for (int index = 0; index < tree_item_list.Count (); index ++) {
  1499. PresetClass *preset = Get_Item_Preset (tree_item_list[index]);
  1500. if (preset != NULL) {
  1501. ::Get_Scene_Editor ()->Delete_Nodes (preset);
  1502. PresetMgrClass::Remove_Preset (preset);
  1503. //
  1504. // Determine if we need to save the temporary preset
  1505. // library later or not.
  1506. //
  1507. if (preset->Get_IsTemporary ()) {
  1508. save_temp_lib = true;
  1509. }
  1510. //
  1511. // Unlink the definition
  1512. //
  1513. preset->Set_Definition (NULL);
  1514. //
  1515. // Free the definition
  1516. //
  1517. DefinitionClass *definition = preset->Get_Definition ();
  1518. if (definition != NULL) {
  1519. DefinitionMgrClass::Unregister_Definition (definition);
  1520. preset->Set_Definition (NULL);
  1521. SAFE_DELETE (definition);
  1522. }
  1523. //
  1524. // Free the preset
  1525. //
  1526. SAFE_DELETE (preset);
  1527. }
  1528. }
  1529. //
  1530. // Save the temporary presets library if necessary.
  1531. //
  1532. if (save_temp_lib) {
  1533. Save_Temp_Presets ();
  1534. }
  1535. //
  1536. // Save the global presets library if necessary
  1537. //
  1538. if (was_temp == false) {
  1539. Save_Global_Presets (class_id);
  1540. if (PresetMgrClass::Get_Immediate_Check_In_Mode ()) {
  1541. PresetMgrClass::Check_In_Presets ();
  1542. } else {
  1543. PresetMgrClass::Set_Presets_Dirty ();
  1544. }
  1545. }
  1546. m_TreeCtrl.DeleteItem (current_item);
  1547. ::Refresh_Main_View ();
  1548. }
  1549. }
  1550. }
  1551. }
  1552. return ;
  1553. }
  1554. ////////////////////////////////////////////////////////////////////////////
  1555. //
  1556. // Sort_Nodes
  1557. //
  1558. ////////////////////////////////////////////////////////////////////////////
  1559. void
  1560. PresetsFormClass::Sort_Nodes (HTREEITEM root_item, bool recursive)
  1561. {
  1562. for ( HTREEITEM tree_item = m_TreeCtrl.GetChildItem (root_item);
  1563. tree_item != NULL;
  1564. tree_item = m_TreeCtrl.GetNextSiblingItem (tree_item))
  1565. {
  1566. //
  1567. // Sort the children
  1568. //
  1569. m_TreeCtrl.SortChildren (tree_item);
  1570. //
  1571. // Recurse through the hierarchy
  1572. //
  1573. if (recursive && m_TreeCtrl.ItemHasChildren (tree_item)) {
  1574. Sort_Nodes (tree_item);
  1575. }
  1576. }
  1577. return ;
  1578. }
  1579. ////////////////////////////////////////////////////////////////////////////
  1580. //
  1581. // Create_Preset
  1582. //
  1583. ////////////////////////////////////////////////////////////////////////////
  1584. PresetClass *
  1585. PresetsFormClass::Create_Preset (DefinitionFactoryClass *factory, bool is_temp)
  1586. {
  1587. //
  1588. // Create a new definition for the preset
  1589. //
  1590. DefinitionClass *definition = factory->Create ();
  1591. //
  1592. // Assign the definition a new ID
  1593. //
  1594. if (is_temp) {
  1595. definition->Set_ID (::Get_Next_Temp_ID ());
  1596. } else {
  1597. definition->Set_ID (DefinitionMgrClass::Get_New_ID (definition->Get_Class_ID ()));
  1598. }
  1599. //
  1600. // Create the new preset
  1601. //
  1602. PresetClass *new_preset = new PresetClass;
  1603. new_preset->Set_Definition (definition);
  1604. new_preset->Set_IsTemporary (is_temp);
  1605. return new_preset;
  1606. }
  1607. ////////////////////////////////////////////////////////////////////////////
  1608. //
  1609. // Build_Child_List
  1610. //
  1611. ////////////////////////////////////////////////////////////////////////////
  1612. void
  1613. PresetsFormClass::Build_Child_List
  1614. (
  1615. HTREEITEM parent_item,
  1616. DynamicVectorClass<HTREEITEM> & list
  1617. )
  1618. {
  1619. //
  1620. // Loop over all the immediate children
  1621. //
  1622. for ( HTREEITEM child_item = m_TreeCtrl.GetChildItem (parent_item);
  1623. child_item != NULL;
  1624. child_item = m_TreeCtrl.GetNextSiblingItem (child_item))
  1625. {
  1626. list.Add (child_item);
  1627. if (m_TreeCtrl.ItemHasChildren (child_item)) {
  1628. //
  1629. // Recursively call this method for all sub-folders in this tree
  1630. //
  1631. Build_Child_List (child_item, list);
  1632. }
  1633. }
  1634. return ;
  1635. }
  1636. ////////////////////////////////////////////////////////////////////////////
  1637. //
  1638. // Enable_Button
  1639. //
  1640. ////////////////////////////////////////////////////////////////////////////
  1641. bool
  1642. PresetsFormClass::Enable_Button (int cmd_id)
  1643. {
  1644. bool retval = false;
  1645. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  1646. if (current_item != NULL) {
  1647. PresetClass *preset = Get_Item_Preset (current_item);
  1648. DefinitionFactoryClass *factory = Get_Item_Factory (current_item);
  1649. bool read_only = ::Get_File_Mgr()->Is_VSS_Read_Only ();
  1650. bool temp = (preset != NULL && preset->Get_IsTemporary ()) ? true : false;
  1651. bool is_proxy_test_folder = false;
  1652. //
  1653. // Determine if this is the proxy-test folder or not (special rules
  1654. // apply to this folder).
  1655. //
  1656. if (preset != NULL) {
  1657. is_proxy_test_folder = preset->Is_A_Parent (PROXY_TESTS_FOLDER);
  1658. }
  1659. //
  1660. // Change the read_only state depending on the user class
  1661. //
  1662. if (read_only == false && ::Get_File_Mgr ()->Is_Special_User ()) {
  1663. read_only = true;
  1664. if (preset != NULL) {
  1665. if (preset->Is_A_Parent (SPECIAL_USER_FOLDER)) {
  1666. read_only = false;
  1667. //
  1668. // Don't let special users modify the folder itself (just sub-folders)
  1669. //
  1670. if ( ::lstrcmpi (preset->Get_Name (), SPECIAL_USER_FOLDER) == 0 &&
  1671. (cmd_id == IDC_MODIFY || cmd_id == IDC_DELETE))
  1672. {
  1673. read_only = true;
  1674. }
  1675. }
  1676. }
  1677. }
  1678. //
  1679. // What operation is this?
  1680. //
  1681. switch (cmd_id)
  1682. {
  1683. case IDC_ADD:
  1684. retval = ((preset || factory) && !read_only && !temp && !is_proxy_test_folder);
  1685. break;
  1686. case IDC_ADD_TEMP:
  1687. retval = (preset || factory);
  1688. break;
  1689. case IDC_MAKE:
  1690. retval = (preset != NULL);
  1691. break;
  1692. case IDC_MODIFY:
  1693. retval = (preset && (!read_only || temp));
  1694. break;
  1695. case IDC_DELETE:
  1696. retval = (preset && (!read_only || temp));
  1697. break;
  1698. case IDC_PLAY:
  1699. retval = (preset != NULL && preset->Is_Valid_Sound_Preset ()) ? true : false;
  1700. break;
  1701. case IDC_UPDATE_VSS:
  1702. retval = ((preset != NULL) && !read_only);
  1703. break;
  1704. case IDC_INFO:
  1705. retval = (preset != NULL);
  1706. break;
  1707. case IDC_CONVERT:
  1708. retval = ((preset != NULL) && temp && !read_only && !is_proxy_test_folder);
  1709. if ( preset != NULL &&
  1710. preset->Get_Parent () != NULL &&
  1711. preset->Get_Parent ()->Get_IsTemporary ())
  1712. {
  1713. retval = false;
  1714. }
  1715. break;
  1716. case IDM_BATCH_IMPORT_TERRAIN:
  1717. {
  1718. if (preset != NULL && preset->Get_Class_ID () == CLASSID_TERRAIN) {
  1719. retval = true;
  1720. }
  1721. }
  1722. break;
  1723. case IDM_CLEAR_EMBEDDED_NODE_LIST:
  1724. {
  1725. retval = (preset && (!read_only || temp));
  1726. if (preset != NULL && preset->Get_Node_List ().Count () == 0) {
  1727. retval = false;
  1728. }
  1729. }
  1730. break;
  1731. case IDM_UPDATE_EMBEDDED_NODE_LIST:
  1732. retval = (preset && (!read_only || temp));
  1733. //
  1734. // Only allow this option for terrain and tile presets
  1735. //
  1736. if (preset != NULL) {
  1737. if ( preset->Get_Class_ID () != CLASSID_TERRAIN &&
  1738. preset->Get_Class_ID () != CLASSID_TILE)
  1739. {
  1740. retval = false;
  1741. }
  1742. }
  1743. break;
  1744. }
  1745. }
  1746. return retval;
  1747. }
  1748. ////////////////////////////////////////////////////////////////////////////
  1749. //
  1750. // OnSelchangedPresetsTree
  1751. //
  1752. ////////////////////////////////////////////////////////////////////////////
  1753. void
  1754. PresetsFormClass::OnSelchangedPresetsTree (NMHDR *pNMHDR, LRESULT *pResult)
  1755. {
  1756. NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  1757. (*pResult) = 0;
  1758. //
  1759. // Enable/disable the toolbar buttons
  1760. //
  1761. m_Toolbar.Enable_Button (IDC_ADD, Enable_Button (IDC_ADD));
  1762. m_Toolbar.Enable_Button (IDC_ADD_TEMP, Enable_Button (IDC_ADD_TEMP));
  1763. m_Toolbar.Enable_Button (IDC_MAKE, Enable_Button (IDC_MAKE));
  1764. m_Toolbar.Enable_Button (IDC_MODIFY, Enable_Button (IDC_MODIFY));
  1765. m_Toolbar.Enable_Button (IDC_DELETE, Enable_Button (IDC_DELETE));
  1766. return ;
  1767. }
  1768. ////////////////////////////////////////////////////////////////////////////
  1769. //
  1770. // Propagate_Changes
  1771. //
  1772. ////////////////////////////////////////////////////////////////////////////
  1773. void
  1774. PresetsFormClass::Propagate_Changes
  1775. (
  1776. HTREEITEM modified_item,
  1777. DERIVED_PARAM_LIST & list
  1778. )
  1779. {
  1780. CWaitCursor wait_cursor;
  1781. CLevelEditView::Allow_Repaint (false);
  1782. PresetClass *preset = Get_Item_Preset (modified_item);
  1783. DefinitionClass *definition = preset->Get_Definition ();
  1784. //
  1785. // Loop over the list of derived parameters that need to
  1786. // be updated with the new values.
  1787. //
  1788. for (int index = 0; index < list.Count (); index ++) {
  1789. DERIVED_PARAM_INFO &info = list[index];
  1790. //
  1791. // Copy all the inherited parameter values from the parent preset
  1792. //
  1793. int list_count = info.base_param_list.Count ();
  1794. for (int list_index = 0; list_index < list_count; list_index ++) {
  1795. //int param_index = info.inherited_param_list[list_index];
  1796. ParameterClass *parameter = info.base_param_list[list_index];
  1797. ParameterClass *curr_parameter = info.derived_param_list[list_index];
  1798. ASSERT (parameter != NULL);
  1799. ASSERT (curr_parameter != NULL);
  1800. //
  1801. // Copy the parameter value from the parent.
  1802. //
  1803. curr_parameter->Copy_Value (*parameter);
  1804. //
  1805. // Release the parameter pointers
  1806. //
  1807. //definition->Unlock_Parameter (param_index);
  1808. //curr_definition->Unlock_Parameter (param_index);
  1809. }
  1810. //
  1811. // Now reload any nodes in the scene that refer to the
  1812. // changed preset.
  1813. //
  1814. if (info.preset != NULL) {
  1815. NodeMgrClass::Reload_Nodes (info.preset);
  1816. }
  1817. }
  1818. //
  1819. // Now reload any nodes in the scene that refer to the
  1820. // changed preset.
  1821. //
  1822. NodeMgrClass::Reload_Nodes (preset);
  1823. CLevelEditView::Allow_Repaint (true);
  1824. return ;
  1825. }
  1826. ////////////////////////////////////////////////////////////////////////////
  1827. //
  1828. // Compare_Derived_Parameters
  1829. //
  1830. ////////////////////////////////////////////////////////////////////////////
  1831. void
  1832. PresetsFormClass::Compare_Derived_Parameters
  1833. (
  1834. PresetClass * curr_preset,
  1835. DefinitionClass * base_def,
  1836. DefinitionClass * derived_def,
  1837. DERIVED_PARAM_LIST & list
  1838. )
  1839. {
  1840. DERIVED_PARAM_INFO info;
  1841. info.preset = curr_preset;
  1842. //
  1843. // Compare all the parameters with this derived definition to
  1844. // find any that are not overridden.
  1845. //
  1846. int param_count = base_def->Get_Parameter_Count ();
  1847. for (int param_index = 0; param_index < param_count; param_index ++) {
  1848. ParameterClass *parameter = base_def->Lock_Parameter (param_index);
  1849. ParameterClass *curr_parameter = derived_def->Lock_Parameter (param_index);
  1850. ASSERT (parameter != NULL);
  1851. ASSERT (curr_parameter != NULL);
  1852. //
  1853. // If the parameter values are exactly the same, then
  1854. // we will assume this parameter is derived and not overridden
  1855. //
  1856. if (*curr_parameter == *parameter) {
  1857. info.base_param_list.Add (parameter);
  1858. info.derived_param_list.Add (curr_parameter);
  1859. } else if (parameter->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  1860. //
  1861. // Lookup the definitions that these parameters reference
  1862. //
  1863. int base_id = ((ModelDefParameterClass *)parameter)->Get_Value ();
  1864. int derived_id = ((ModelDefParameterClass *)curr_parameter)->Get_Value ();
  1865. DefinitionClass *base_model_def = DefinitionMgrClass::Find_Definition (base_id, false);
  1866. DefinitionClass *derived_model_def = DefinitionMgrClass::Find_Definition (derived_id, false);
  1867. //
  1868. // Recursively add parameters from these definitions to the list
  1869. //
  1870. if ( base_model_def != NULL && derived_model_def != NULL &&
  1871. base_model_def->Get_Class_ID () == derived_model_def->Get_Class_ID ())
  1872. {
  1873. Compare_Derived_Parameters (NULL, base_model_def, derived_model_def, list);
  1874. }
  1875. }
  1876. //
  1877. // Release the parameter pointers
  1878. //
  1879. base_def->Unlock_Parameter (param_index);
  1880. derived_def->Unlock_Parameter (param_index);
  1881. }
  1882. //
  1883. // If this preset contains at least one derived (not overridden) value,
  1884. // then add it to the list.
  1885. //
  1886. if (info.base_param_list.Count () > 0) {
  1887. list.Add (info);
  1888. }
  1889. return ;
  1890. }
  1891. ////////////////////////////////////////////////////////////////////////////
  1892. //
  1893. // Build_Inherited_Param_List
  1894. //
  1895. ////////////////////////////////////////////////////////////////////////////
  1896. void
  1897. PresetsFormClass::Build_Inherited_Param_List
  1898. (
  1899. HTREEITEM parent_item,
  1900. DERIVED_PARAM_LIST & list
  1901. )
  1902. {
  1903. PresetClass *preset = Get_Item_Preset (parent_item);
  1904. DefinitionClass *definition = preset->Get_Definition ();
  1905. //
  1906. // Build a list of children (derived presets)
  1907. //
  1908. DynamicVectorClass<HTREEITEM> child_list;
  1909. Build_Child_List (parent_item, child_list);
  1910. //
  1911. // Loop over all the derived presets and build up the list
  1912. // of non-overridden parameter values
  1913. //
  1914. for (int index = 0; index < child_list.Count (); index ++) {
  1915. HTREEITEM tree_item = child_list[index];
  1916. PresetClass *curr_preset = Get_Item_Preset (tree_item);
  1917. DefinitionClass *curr_definition = curr_preset->Get_Definition ();
  1918. ASSERT (curr_definition->Get_Class_ID () == definition->Get_Class_ID ());
  1919. //
  1920. // Build the list of parameters that are the same as the base
  1921. //
  1922. Compare_Derived_Parameters (curr_preset, definition, curr_definition, list);
  1923. }
  1924. return ;
  1925. }
  1926. ////////////////////////////////////////////////////////////////////////////
  1927. //
  1928. // OnPlay
  1929. //
  1930. ////////////////////////////////////////////////////////////////////////////
  1931. void
  1932. PresetsFormClass::OnPlay (void)
  1933. {
  1934. HTREEITEM tree_item = m_TreeCtrl.GetSelectedItem ();
  1935. PresetClass *preset = Get_Item_Preset (tree_item);
  1936. if (preset != NULL && preset->Get_Definition () != NULL) {
  1937. AudibleSoundDefinitionClass *definition = NULL;
  1938. definition = (AudibleSoundDefinitionClass *)preset->Get_Definition ();
  1939. //
  1940. // Make sure we have a local copy of this sound
  1941. //
  1942. CString filename = definition->Get_Filename ();
  1943. if (::Get_File_Mgr ()->Does_File_Exist (filename, true)) {
  1944. //
  1945. // Pass the sound filename onto the dialog
  1946. //
  1947. PlaySoundDialogClass dialog (filename, this);
  1948. dialog.DoModal ();
  1949. }
  1950. }
  1951. return ;
  1952. }
  1953. ////////////////////////////////////////////////////////////////////////////
  1954. //
  1955. // OnInfo
  1956. //
  1957. ////////////////////////////////////////////////////////////////////////////
  1958. void
  1959. PresetsFormClass::OnInfo (void)
  1960. {
  1961. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  1962. PresetClass *preset = Get_Item_Preset (current_item);
  1963. if (preset != NULL) {
  1964. //
  1965. // Show the (read-only) properties dialog for this preset
  1966. //
  1967. preset->Show_Properties (true);
  1968. }
  1969. return ;
  1970. }
  1971. ////////////////////////////////////////////////////////////////////////////
  1972. //
  1973. // OnExtra
  1974. //
  1975. ////////////////////////////////////////////////////////////////////////////
  1976. void
  1977. PresetsFormClass::OnExtra (void)
  1978. {
  1979. //
  1980. // Determine the screen coords of the toolbar button
  1981. //
  1982. CRect rect;
  1983. m_Toolbar.GetItemRect (m_Toolbar.CommandToIndex (IDC_EXTRA), &rect);
  1984. m_Toolbar.ClientToScreen (&rect);
  1985. //
  1986. // Load the menu we want to display
  1987. //
  1988. HMENU main_menu = ::LoadMenu (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDR_XTRA_POPUP));
  1989. HMENU menu = ::GetSubMenu (main_menu, 0);
  1990. //
  1991. // Make the menu commands owner-draw so we can paint icons next to them
  1992. //
  1993. ::ModifyMenu (menu, IDC_PLAY, MF_BYCOMMAND | MF_OWNERDRAW, IDC_PLAY, NULL);
  1994. ::ModifyMenu (menu, IDC_CONVERT, MF_BYCOMMAND | MF_OWNERDRAW, IDC_CONVERT, NULL);
  1995. ::ModifyMenu (menu, IDC_UPDATE_VSS, MF_BYCOMMAND | MF_OWNERDRAW, IDC_UPDATE_VSS, NULL);
  1996. ::ModifyMenu (menu, IDM_BATCH_IMPORT_TERRAIN, MF_BYCOMMAND | MF_OWNERDRAW, IDM_BATCH_IMPORT_TERRAIN, NULL);
  1997. ::ModifyMenu (menu, IDM_UPDATE_EMBEDDED_NODE_LIST, MF_BYCOMMAND | MF_OWNERDRAW, IDM_UPDATE_EMBEDDED_NODE_LIST, NULL);
  1998. ::ModifyMenu (menu, IDM_CLEAR_EMBEDDED_NODE_LIST, MF_BYCOMMAND | MF_OWNERDRAW, IDM_CLEAR_EMBEDDED_NODE_LIST, NULL);
  1999. //
  2000. // Disable any buttons if necessary
  2001. //
  2002. if (Enable_Button (IDC_PLAY) == false) {
  2003. ::EnableMenuItem (menu, IDC_PLAY, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2004. }
  2005. if (Enable_Button (IDC_CONVERT) == false) {
  2006. ::EnableMenuItem (menu, IDC_CONVERT, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2007. }
  2008. if (Enable_Button (IDC_UPDATE_VSS) == false) {
  2009. ::EnableMenuItem (menu, IDC_UPDATE_VSS, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2010. }
  2011. if (Enable_Button (IDM_BATCH_IMPORT_TERRAIN) == false) {
  2012. ::EnableMenuItem (menu, IDM_BATCH_IMPORT_TERRAIN, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2013. }
  2014. if (Enable_Button (IDM_UPDATE_EMBEDDED_NODE_LIST) == false) {
  2015. ::EnableMenuItem (menu, IDM_UPDATE_EMBEDDED_NODE_LIST, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2016. }
  2017. if (Enable_Button (IDM_CLEAR_EMBEDDED_NODE_LIST) == false) {
  2018. ::EnableMenuItem (menu, IDM_CLEAR_EMBEDDED_NODE_LIST, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED);
  2019. }
  2020. //
  2021. // Display the menu
  2022. //
  2023. ::TrackPopupMenu (menu, TPM_LEFTALIGN | TPM_TOPALIGN, rect.left, rect.bottom, 0, m_hWnd, NULL);
  2024. //
  2025. // Cleanup
  2026. //
  2027. ::DestroyMenu (main_menu);
  2028. return ;
  2029. }
  2030. ////////////////////////////////////////////////////////////////////////////
  2031. //
  2032. // OnNotify
  2033. //
  2034. ////////////////////////////////////////////////////////////////////////////
  2035. BOOL
  2036. PresetsFormClass::OnNotify
  2037. (
  2038. WPARAM wParam,
  2039. LPARAM lParam,
  2040. LRESULT* pResult
  2041. )
  2042. {
  2043. if (((NMHDR *)lParam)->code == TBN_DROPDOWN) {
  2044. OnExtra ();
  2045. (*pResult) = TBDDRET_DEFAULT;
  2046. return TRUE;
  2047. }
  2048. return CDialog::OnNotify(wParam, lParam, pResult);
  2049. }
  2050. ////////////////////////////////////////////////////////////////////////////
  2051. //
  2052. // OnUpdateConvert
  2053. //
  2054. ////////////////////////////////////////////////////////////////////////////
  2055. void
  2056. PresetsFormClass::OnUpdateConvert (CCmdUI *pCmdUI)
  2057. {
  2058. pCmdUI->Enable (Enable_Button (IDC_CONVERT));
  2059. return ;
  2060. }
  2061. ////////////////////////////////////////////////////////////////////////////
  2062. //
  2063. // OnUpdateInfo
  2064. //
  2065. ////////////////////////////////////////////////////////////////////////////
  2066. void
  2067. PresetsFormClass::OnUpdateInfo (CCmdUI *pCmdUI)
  2068. {
  2069. pCmdUI->Enable (Enable_Button (IDC_INFO));
  2070. return ;
  2071. }
  2072. ////////////////////////////////////////////////////////////////////////////
  2073. //
  2074. // OnUpdatePlay
  2075. //
  2076. ////////////////////////////////////////////////////////////////////////////
  2077. void
  2078. PresetsFormClass::OnUpdatePlay (CCmdUI *pCmdUI)
  2079. {
  2080. pCmdUI->Enable (Enable_Button (IDC_PLAY));
  2081. return ;
  2082. }
  2083. ////////////////////////////////////////////////////////////////////////////
  2084. //
  2085. // OnUpdateUpdateVss
  2086. //
  2087. ////////////////////////////////////////////////////////////////////////////
  2088. void
  2089. PresetsFormClass::OnUpdateUpdateVss (CCmdUI *pCmdUI)
  2090. {
  2091. pCmdUI->Enable (Enable_Button (IDC_UPDATE_VSS));
  2092. return ;
  2093. }
  2094. ////////////////////////////////////////////////////////////////////////////
  2095. //
  2096. // Get_Menu_Text
  2097. //
  2098. ////////////////////////////////////////////////////////////////////////////
  2099. void
  2100. PresetsFormClass::Get_Menu_Text (int menu_id, CString &text)
  2101. {
  2102. switch (menu_id)
  2103. {
  2104. case IDC_PLAY:
  2105. text = "Play...";
  2106. break;
  2107. case IDC_CONVERT:
  2108. text = "Convert Temp...";
  2109. break;
  2110. case IDC_UPDATE_VSS:
  2111. text = "Update VSS...";
  2112. break;
  2113. case IDM_BATCH_IMPORT_TERRAIN:
  2114. text = "Batch Import Terrain...";
  2115. break;
  2116. case IDM_CLEAR_EMBEDDED_NODE_LIST:
  2117. text = "Clear Embedded Node List";
  2118. break;
  2119. case IDM_UPDATE_EMBEDDED_NODE_LIST:
  2120. text = "Embed Nodes...";
  2121. break;
  2122. }
  2123. return ;
  2124. }
  2125. ////////////////////////////////////////////////////////////////////////////
  2126. //
  2127. // OnDrawItem
  2128. //
  2129. ////////////////////////////////////////////////////////////////////////////
  2130. void
  2131. PresetsFormClass::OnDrawItem
  2132. (
  2133. int nIDCtl,
  2134. LPDRAWITEMSTRUCT lpDrawItemStruct
  2135. )
  2136. {
  2137. HICON icon = NULL;
  2138. CString text;
  2139. Get_Menu_Text (lpDrawItemStruct->itemID, text);
  2140. switch (lpDrawItemStruct->itemID)
  2141. {
  2142. case IDC_PLAY:
  2143. icon = (HICON)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_PLAY), IMAGE_ICON, 16, 16, LR_SHARED);
  2144. break;
  2145. case IDC_CONVERT:
  2146. icon = (HICON)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_CONVERT), IMAGE_ICON, 16, 16, LR_SHARED);
  2147. break;
  2148. case IDC_UPDATE_VSS:
  2149. icon = (HICON)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_UPDATE), IMAGE_ICON, 16, 16, LR_SHARED);
  2150. break;
  2151. case IDM_BATCH_IMPORT_TERRAIN:
  2152. icon = (HICON)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_TERRAIN), IMAGE_ICON, 16, 16, LR_SHARED);
  2153. break;
  2154. case IDM_UPDATE_EMBEDDED_NODE_LIST:
  2155. icon = (HICON)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_OBJECT), IMAGE_ICON, 16, 16, LR_SHARED);
  2156. break;
  2157. case IDM_CLEAR_EMBEDDED_NODE_LIST:
  2158. icon = (HICON)::LoadImage (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDI_DELETE), IMAGE_ICON, 16, 16, LR_SHARED);
  2159. break;
  2160. }
  2161. CRect rect = lpDrawItemStruct->rcItem;
  2162. int dss_state = DSS_NORMAL;
  2163. UINT bk_color = 0;
  2164. //
  2165. // Deteremine what background and text color to use
  2166. //
  2167. if (lpDrawItemStruct->itemState & ODS_GRAYED) {
  2168. bk_color = COLOR_MENU;
  2169. ::SetBkColor (lpDrawItemStruct->hDC, ::GetSysColor (COLOR_MENU));
  2170. ::SetTextColor (lpDrawItemStruct->hDC, ::GetSysColor (COLOR_GRAYTEXT));
  2171. dss_state = DSS_DISABLED;
  2172. } else if (lpDrawItemStruct->itemState & ODS_SELECTED) {
  2173. bk_color = COLOR_HIGHLIGHT;
  2174. ::SetBkColor (lpDrawItemStruct->hDC, ::GetSysColor (COLOR_HIGHLIGHT));
  2175. ::SetTextColor (lpDrawItemStruct->hDC, ::GetSysColor (COLOR_HIGHLIGHTTEXT));
  2176. } else {
  2177. bk_color = COLOR_MENU;
  2178. ::SetBkColor (lpDrawItemStruct->hDC, ::GetSysColor (COLOR_MENU));
  2179. ::SetTextColor (lpDrawItemStruct->hDC, ::GetSysColor (COLOR_MENUTEXT));
  2180. }
  2181. //
  2182. // Determine the height of the text
  2183. //
  2184. CSize text_size;
  2185. ::GetTextExtentPoint32 (lpDrawItemStruct->hDC, text, text.GetLength (), &text_size);
  2186. //
  2187. // Render the text
  2188. //
  2189. rect.top += 2;
  2190. rect.bottom -= 2;
  2191. ::FillRect (lpDrawItemStruct->hDC, &rect, (HBRUSH) (bk_color+1));
  2192. ::SetBkMode (lpDrawItemStruct->hDC, TRANSPARENT);
  2193. ::DrawState ( lpDrawItemStruct->hDC,
  2194. NULL,
  2195. NULL,
  2196. (LPARAM)(LPCTSTR)text,
  2197. 0,
  2198. rect.left + 24,
  2199. rect.top + (rect.Height () >> 1) - (text_size.cy >> 1),
  2200. 0, 0, DST_TEXT | dss_state);
  2201. //
  2202. // Draw the associated icon (if necessary)
  2203. //
  2204. if (icon != NULL) {
  2205. ::DrawState ( lpDrawItemStruct->hDC, NULL, NULL, (LPARAM)icon, 0, rect.left + 4, rect.top + 4, 16, 16, DST_ICON | dss_state);
  2206. }
  2207. CDialog::OnDrawItem (nIDCtl, lpDrawItemStruct);
  2208. return ;
  2209. }
  2210. ////////////////////////////////////////////////////////////////////////////
  2211. //
  2212. // OnMeasureItem
  2213. //
  2214. ////////////////////////////////////////////////////////////////////////////
  2215. void
  2216. PresetsFormClass::OnMeasureItem
  2217. (
  2218. int nIDCtl,
  2219. LPMEASUREITEMSTRUCT lpMeasureItemStruct
  2220. )
  2221. {
  2222. CString text;
  2223. Get_Menu_Text (lpMeasureItemStruct->itemID, text);
  2224. NONCLIENTMETRICS metrics = { sizeof (NONCLIENTMETRICS), 0 };
  2225. ::SystemParametersInfo (SPI_GETNONCLIENTMETRICS, 0, &metrics, FALSE);
  2226. HDC mem_dc = ::CreateCompatibleDC (NULL);
  2227. HFONT font = ::CreateFontIndirect (&metrics.lfMenuFont);
  2228. HFONT old_font = (HFONT)::SelectObject (mem_dc, font);
  2229. CSize text_size;
  2230. ::GetTextExtentPoint32 (mem_dc, text, text.GetLength (), &text_size);
  2231. ::SelectObject (mem_dc, old_font);
  2232. ::DeleteObject (font);
  2233. ::DeleteDC (mem_dc);
  2234. lpMeasureItemStruct->itemWidth = text_size.cx + 24;
  2235. lpMeasureItemStruct->itemHeight = 24;
  2236. return ;
  2237. }
  2238. ////////////////////////////////////////////////////////////////////////////
  2239. //
  2240. // OnConvert
  2241. //
  2242. ////////////////////////////////////////////////////////////////////////////
  2243. void
  2244. PresetsFormClass::OnConvert (void)
  2245. {
  2246. HTREEITEM item = m_TreeCtrl.GetSelectedItem ();
  2247. PresetClass *preset = Get_Item_Preset (item);
  2248. if (preset != NULL) {
  2249. //
  2250. // Make sure the user really wants to do this...
  2251. //
  2252. CString message;
  2253. message.Format ("Are you sure you wish to convert '%s' from a temporary preset to a shared preset?", preset->Get_Name ());
  2254. if (MessageBox (message, "Preset Convert", MB_ICONQUESTION | MB_YESNO) == IDYES) {
  2255. CWaitCursor wait_cursor;
  2256. //
  2257. // Check out the definition database
  2258. //
  2259. SelectionCaptureClass sel_capture (this);
  2260. bool undo_check_out = false;
  2261. uint32 class_id = preset->Get_Class_ID ();
  2262. if (PresetMgrClass::Check_Out_Database (class_id, &undo_check_out)) {
  2263. sel_capture.Restore ();
  2264. item = m_TreeCtrl.GetSelectedItem ();
  2265. PresetClass *preset = Get_Item_Preset (item);
  2266. if (preset != NULL) {
  2267. //
  2268. // Change the preset's ID from temp-range to normal-range
  2269. //
  2270. preset->Set_IsTemporary (false);
  2271. preset->Set_ID (DefinitionMgrClass::Get_New_ID (preset->Get_Class_ID ()));
  2272. //
  2273. // Now change the IDs of any embedded definition objects
  2274. //
  2275. Fix_Embedded_Definition_IDs (preset->Get_Definition ());
  2276. //
  2277. // Now save-out the databases (they have both changed)
  2278. //
  2279. Save_Global_Presets (class_id);
  2280. PresetMgrClass::Add_Dirty_Preset (preset->Get_ID ());
  2281. Save_Temp_Presets ();
  2282. //
  2283. // Finally change the preset's icon
  2284. //
  2285. int icon = Get_Icon (preset);
  2286. m_TreeCtrl.SetItemImage (item, icon, icon);
  2287. //
  2288. // Force a re-paint
  2289. //
  2290. m_TreeCtrl.SelectItem (item);
  2291. m_TreeCtrl.InvalidateRect (NULL, TRUE);
  2292. } else if (undo_check_out) {
  2293. MessageBox ("Unable to find preset.", "Preset Error", MB_ICONERROR | MB_OK);
  2294. PresetMgrClass::Undo_Database_Check_Out (class_id);
  2295. }
  2296. }
  2297. }
  2298. }
  2299. return ;
  2300. }
  2301. ////////////////////////////////////////////////////////////////////////////
  2302. //
  2303. // OnUpdateVss
  2304. //
  2305. ////////////////////////////////////////////////////////////////////////////
  2306. void
  2307. PresetsFormClass::OnUpdateVss (void)
  2308. {
  2309. HTREEITEM item = m_TreeCtrl.GetSelectedItem ();
  2310. PresetClass *preset = Get_Item_Preset (item);
  2311. if (preset != NULL) {
  2312. //
  2313. // Show the update-preset dialog
  2314. //
  2315. UpdatePresetDialogClass dialog (preset, this);
  2316. dialog.DoModal ();
  2317. }
  2318. return ;
  2319. }
  2320. ////////////////////////////////////////////////////////////////////////////
  2321. //
  2322. // OnClearEmbeddedNodeList
  2323. //
  2324. ////////////////////////////////////////////////////////////////////////////
  2325. void
  2326. PresetsFormClass::OnClearEmbeddedNodeList (void)
  2327. {
  2328. CWaitCursor wait_cursor;
  2329. //
  2330. // Get the currently selected preset
  2331. //
  2332. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  2333. PresetClass *preset = Get_Item_Preset (current_item);
  2334. if (preset != NULL) {
  2335. if (preset->Get_IsTemporary () == false) {
  2336. //
  2337. // Check out the definition database
  2338. //
  2339. SelectionCaptureClass sel_capture (this);
  2340. bool undo_on_err = false;
  2341. uint32 class_id = preset->Get_Class_ID ();
  2342. if (PresetMgrClass::Check_Out_Database (class_id, &undo_on_err)) {
  2343. sel_capture.Restore ();
  2344. //
  2345. // Re-get the preset (its pointer has changed, the
  2346. // old one is crap).
  2347. //
  2348. current_item = m_TreeCtrl.GetSelectedItem ();
  2349. preset = Get_Item_Preset (current_item);
  2350. //
  2351. // Now, free the embedded nodes
  2352. //
  2353. if (preset != NULL) {
  2354. preset->Free_Node_List ();
  2355. Save_Global_Presets (preset->Get_Class_ID ());
  2356. PresetMgrClass::Add_Dirty_Preset (preset->Get_ID ());
  2357. }
  2358. }
  2359. } else {
  2360. //
  2361. // Free the embedded nodes
  2362. //
  2363. preset->Free_Node_List ();
  2364. Save_Temp_Presets ();
  2365. }
  2366. Reset_Embedded_Node_Instances (preset);
  2367. NodeMgrClass::Reload_Nodes (preset);
  2368. if (preset != NULL) {
  2369. //
  2370. // Update the overlay icon on the preset
  2371. //
  2372. bool needs_overlay = (preset->Get_Node_List ().Count () > 0);
  2373. TreeView_SetOverlay (m_TreeCtrl, current_item, needs_overlay);
  2374. }
  2375. }
  2376. return ;
  2377. }
  2378. ////////////////////////////////////////////////////////////////////////////
  2379. //
  2380. // Reset_Embedded_Node_Instances
  2381. //
  2382. ////////////////////////////////////////////////////////////////////////////
  2383. void
  2384. PresetsFormClass::Reset_Embedded_Node_Instances (PresetClass *preset)
  2385. {
  2386. if (preset == NULL) {
  2387. return ;
  2388. }
  2389. //
  2390. // Loop over all the nodes in the scene
  2391. //
  2392. for ( NodeClass *node = NodeMgrClass::Get_First ();
  2393. node != NULL;
  2394. node = NodeMgrClass::Get_Next (node))
  2395. {
  2396. //
  2397. // If this was an embedded node, then convert it to
  2398. // a "normal" node.
  2399. //
  2400. if (node->Get_Container_Preset_ID () == preset->Get_ID ()) {
  2401. node->Set_Is_Proxied (false);
  2402. node->Set_Needs_Save (true);
  2403. node->Set_Container_Preset_ID (0);
  2404. }
  2405. }
  2406. return ;
  2407. }
  2408. ////////////////////////////////////////////////////////////////////////////
  2409. //
  2410. // OnBuildEmbedNodeList
  2411. //
  2412. ////////////////////////////////////////////////////////////////////////////
  2413. void
  2414. PresetsFormClass::OnBuildEmbedNodeList (void)
  2415. {
  2416. //
  2417. // Prompt the user
  2418. //
  2419. if (::MessageBox (m_hWnd,
  2420. "This operation will embed a copy of all the nodes in scene into this preset. Are you sure you wish to continue?",
  2421. "Embed Nodes", MB_ICONQUESTION | MB_YESNO) == IDNO)
  2422. {
  2423. return ;
  2424. }
  2425. CWaitCursor wait_cursor;
  2426. //
  2427. // Get the currently selected preset
  2428. //
  2429. HTREEITEM current_item = m_TreeCtrl.GetSelectedItem ();
  2430. PresetClass *preset = Get_Item_Preset (current_item);
  2431. if (preset != NULL) {
  2432. if (preset->Get_IsTemporary () == false) {
  2433. //
  2434. // Check out the definition database
  2435. //
  2436. SelectionCaptureClass sel_capture (this);
  2437. bool undo_on_err = false;
  2438. uint32 class_id = preset->Get_Class_ID ();
  2439. if (PresetMgrClass::Check_Out_Database (class_id, &undo_on_err)) {
  2440. sel_capture.Restore ();
  2441. //
  2442. // Re-get the preset (its pointer has changed, the
  2443. // old one is crap).
  2444. //
  2445. current_item = m_TreeCtrl.GetSelectedItem ();
  2446. preset = Get_Item_Preset (current_item);
  2447. //
  2448. // Now, update the embedded node information for this preset
  2449. //
  2450. if (preset != NULL) {
  2451. Update_Embedded_Nodes (preset);
  2452. Save_Global_Presets (preset->Get_Class_ID ());
  2453. PresetMgrClass::Add_Dirty_Preset (preset->Get_ID ());
  2454. }
  2455. }
  2456. } else {
  2457. //
  2458. // Update the embedded node information for this preset
  2459. //
  2460. Update_Embedded_Nodes (preset);
  2461. Save_Temp_Presets ();
  2462. }
  2463. NodeMgrClass::Reload_Nodes (preset);
  2464. //
  2465. // Update the overlay icon on the preset
  2466. //
  2467. if (preset != NULL) {
  2468. bool needs_overlay = (preset->Get_Node_List ().Count () > 0);
  2469. TreeView_SetOverlay (m_TreeCtrl, current_item, needs_overlay);
  2470. }
  2471. }
  2472. return ;
  2473. }
  2474. ////////////////////////////////////////////////////////////////////////////
  2475. //
  2476. // Update_Embedded_Nodes
  2477. //
  2478. ////////////////////////////////////////////////////////////////////////////
  2479. void
  2480. PresetsFormClass::Update_Embedded_Nodes (PresetClass *preset)
  2481. {
  2482. Reset_Embedded_Node_Instances (preset);
  2483. //
  2484. // Loop over all the nodes in the scene
  2485. //
  2486. for ( NodeClass *node = NodeMgrClass::Get_First ();
  2487. node != NULL;
  2488. node = NodeMgrClass::Get_Next (node))
  2489. {
  2490. //
  2491. // Just find the first node that came from this preset
  2492. //
  2493. if (node->Get_Preset () == preset) {
  2494. break;
  2495. }
  2496. }
  2497. //
  2498. // Generate the node list
  2499. //
  2500. if (node != NULL) {
  2501. preset->Build_Node_List (node);
  2502. }
  2503. return ;
  2504. }
  2505. ////////////////////////////////////////////////////////////////////////////
  2506. //
  2507. // OnBatchImportTerrain
  2508. //
  2509. ////////////////////////////////////////////////////////////////////////////
  2510. void
  2511. PresetsFormClass::OnBatchImportTerrain (void)
  2512. {
  2513. CFileDialog dialog ( TRUE,
  2514. ".w3d",
  2515. NULL,
  2516. OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_ALLOWMULTISELECT | OFN_EXPLORER,
  2517. "Westwood 3D Files (*.w3d)|*.w3d||",
  2518. this);
  2519. TCHAR filename_list[MAX_PATH*20] = { 0 };
  2520. dialog.m_ofn.lpstrFile = filename_list;
  2521. dialog.m_ofn.nMaxFile = sizeof (filename_list);
  2522. //
  2523. // Ask the user what files they wish to import
  2524. //
  2525. if (dialog.DoModal () == IDOK) {
  2526. //
  2527. // Loop through all the selected files
  2528. //
  2529. POSITION pos = dialog.GetStartPosition ();
  2530. while (pos != NULL) {
  2531. //
  2532. // Add this preset to the tree
  2533. //
  2534. Add_Terrain_Preset (dialog.GetNextPathName (pos));
  2535. }
  2536. //
  2537. // Save the temp presets lib
  2538. //
  2539. Save_Temp_Presets ();
  2540. }
  2541. return ;
  2542. }
  2543. ////////////////////////////////////////////////////////////////////////////
  2544. //
  2545. // OnUpdateClearEmbeddedNodeList
  2546. //
  2547. ////////////////////////////////////////////////////////////////////////////
  2548. void
  2549. PresetsFormClass::OnUpdateClearEmbeddedNodeList (CCmdUI *pCmdUI)
  2550. {
  2551. pCmdUI->Enable (Enable_Button (IDM_CLEAR_EMBEDDED_NODE_LIST));
  2552. return ;
  2553. }
  2554. ////////////////////////////////////////////////////////////////////////////
  2555. //
  2556. // OnUpdateEmbeddedNodeList
  2557. //
  2558. ////////////////////////////////////////////////////////////////////////////
  2559. void
  2560. PresetsFormClass::OnUpdateEmbeddedNodeList (CCmdUI *pCmdUI)
  2561. {
  2562. pCmdUI->Enable (Enable_Button (IDM_UPDATE_EMBEDDED_NODE_LIST));
  2563. return ;
  2564. }
  2565. ////////////////////////////////////////////////////////////////////////////
  2566. //
  2567. // OnUpdateBatchImportTerrain
  2568. //
  2569. ////////////////////////////////////////////////////////////////////////////
  2570. void
  2571. PresetsFormClass::OnUpdateBatchImportTerrain (CCmdUI *pCmdUI)
  2572. {
  2573. pCmdUI->Enable (Enable_Button (IDM_BATCH_IMPORT_TERRAIN));
  2574. return ;
  2575. }
  2576. ////////////////////////////////////////////////////////////////////////////
  2577. //
  2578. // Add_Terrain_Preset
  2579. //
  2580. ////////////////////////////////////////////////////////////////////////////
  2581. void
  2582. PresetsFormClass::Add_Terrain_Preset (LPCTSTR filename)
  2583. {
  2584. if (::Is_W3D_Filename (filename)) {
  2585. //
  2586. // Make an asset name from the filename
  2587. //
  2588. CString preset_name = ::Asset_Name_From_Filename (filename);
  2589. if (preset_name.GetLength () > 0) {
  2590. //
  2591. // Add the new preset
  2592. //
  2593. PresetClass *preset = Add_New_Preset (preset_name, true, false);
  2594. if (preset != NULL && preset->Get_Class_ID () == CLASSID_TERRAIN) {
  2595. //
  2596. // Configure the preset
  2597. //
  2598. TerrainDefinitionClass *definition = (TerrainDefinitionClass *)preset->Get_Definition ();
  2599. definition->Set_Model_Name (::Get_File_Mgr ()->Make_Relative_Path (filename));
  2600. }
  2601. }
  2602. }
  2603. return ;
  2604. }
  2605. ////////////////////////////////////////////////////////////////////////////
  2606. //
  2607. // OnBegindragPresetsTree
  2608. //
  2609. ////////////////////////////////////////////////////////////////////////////
  2610. void
  2611. PresetsFormClass::OnBegindragPresetsTree
  2612. (
  2613. NMHDR * pNMHDR,
  2614. LRESULT *pResult
  2615. )
  2616. {
  2617. NM_TREEVIEW *tv_info = (NM_TREEVIEW *)pNMHDR;
  2618. (*pResult) = 0;
  2619. if (Is_Drag_OK (tv_info->itemNew.hItem)) {
  2620. //
  2621. // Set-up for our drag operation
  2622. //
  2623. m_DragItem = tv_info->itemNew.hItem;
  2624. if (m_DragItem != NULL) {
  2625. m_DragImageList = m_TreeCtrl.CreateDragImage (m_DragItem);
  2626. m_DragImageList->BeginDrag (0, CPoint (-20, -20));
  2627. m_IsDragging = true;
  2628. SetCapture ();
  2629. }
  2630. }
  2631. return ;
  2632. }
  2633. ////////////////////////////////////////////////////////////////////////////
  2634. //
  2635. // OnLButtonUp
  2636. //
  2637. ////////////////////////////////////////////////////////////////////////////
  2638. void
  2639. PresetsFormClass::OnLButtonUp (UINT nFlags, CPoint point)
  2640. {
  2641. if (m_IsDragging) {
  2642. //
  2643. // Convert the tab mouse-position to the tree's mouse-position
  2644. //
  2645. CPoint tree_pt = point;
  2646. ClientToScreen (&tree_pt);
  2647. m_TreeCtrl.ScreenToClient (&tree_pt);
  2648. //
  2649. // Reset the state of the tree
  2650. //
  2651. CImageList::EndDrag ();
  2652. ReleaseCapture ();
  2653. m_TreeCtrl.SelectDropTarget (NULL);
  2654. m_TreeCtrl.SelectItem (m_DragItem);
  2655. //
  2656. // Check to ensure its OK to move the preset
  2657. //
  2658. UINT flags = TVHT_ONITEM;
  2659. HTREEITEM drop_target = m_TreeCtrl.HitTest (tree_pt, &flags);
  2660. if (Is_Drop_OK (drop_target)) {
  2661. //
  2662. // Perform the move operation
  2663. //
  2664. m_TreeCtrl.SelectItem (drop_target);
  2665. Do_Drop (m_DragItem, drop_target);
  2666. }
  2667. m_DragItem = NULL;
  2668. m_IsDragging = false;
  2669. }
  2670. CDialog::OnLButtonUp (nFlags, point);
  2671. return ;
  2672. }
  2673. ////////////////////////////////////////////////////////////////////////////
  2674. //
  2675. // OnMouseMove
  2676. //
  2677. ////////////////////////////////////////////////////////////////////////////
  2678. void
  2679. PresetsFormClass::OnMouseMove (UINT nFlags, CPoint point)
  2680. {
  2681. if (m_IsDragging) {
  2682. //
  2683. // Convert the tab mouse-position to the tree's mouse-position
  2684. //
  2685. CPoint tree_pt = point;
  2686. ClientToScreen (&tree_pt);
  2687. m_TreeCtrl.ScreenToClient (&tree_pt);
  2688. //
  2689. // Draw the outline of the drag operation
  2690. //
  2691. CImageList::DragMove (tree_pt);
  2692. m_DragImageList->DragLeave (&m_TreeCtrl);
  2693. //
  2694. // Determine if we should hilight one of the entries in the tree control
  2695. //
  2696. UINT flags = TVHT_ONITEM;
  2697. HTREEITEM drop_target = m_TreeCtrl.HitTest (tree_pt, &flags);
  2698. if (drop_target != NULL) {
  2699. m_TreeCtrl.SelectDropTarget (drop_target);
  2700. }
  2701. m_DragImageList->DragEnter (&m_TreeCtrl, tree_pt);
  2702. //
  2703. // Choose a cursor
  2704. //
  2705. if (drop_target == NULL || Is_Drop_OK (drop_target) == false) {
  2706. SetCursor (::LoadCursor (::AfxGetResourceHandle (), MAKEINTRESOURCE (IDC_NODROP)));
  2707. } else {
  2708. SetCursor (::LoadCursor (NULL, IDC_ARROW));
  2709. }
  2710. }
  2711. CDialog::OnMouseMove (nFlags, point);
  2712. return ;
  2713. }
  2714. ////////////////////////////////////////////////////////////////////////////
  2715. //
  2716. // Is_Drag_OK
  2717. //
  2718. ////////////////////////////////////////////////////////////////////////////
  2719. bool
  2720. PresetsFormClass::Is_Drag_OK (HTREEITEM drag_item)
  2721. {
  2722. bool retval = false;
  2723. PresetClass *preset = Get_Item_Preset (drag_item);
  2724. bool read_only = ::Get_File_Mgr()->Is_VSS_Read_Only ();
  2725. bool temp = (preset != NULL && preset->Get_IsTemporary ()) ? true : false;
  2726. //
  2727. // We allow the user to drag a preset if its a temp or they have write
  2728. // access to the database.
  2729. //
  2730. if (preset != NULL && (read_only == false || temp == true)) {
  2731. retval = true;
  2732. }
  2733. return retval;
  2734. }
  2735. ////////////////////////////////////////////////////////////////////////////
  2736. //
  2737. // Is_Drop_OK
  2738. //
  2739. ////////////////////////////////////////////////////////////////////////////
  2740. bool
  2741. PresetsFormClass::Is_Drop_OK (HTREEITEM drop_item)
  2742. {
  2743. bool retval = false;
  2744. if (m_DragItem != NULL && drop_item != NULL) {
  2745. PresetClass *drag_preset = Get_Item_Preset (m_DragItem);
  2746. PresetClass *drop_preset = Get_Item_Preset (drop_item);
  2747. DefinitionFactoryClass *factory = Get_Item_Factory (drop_item);
  2748. if (drag_preset != NULL && (drop_preset != NULL || factory != NULL)) {
  2749. //
  2750. // Check to make sure we don't try to move a preset to one of its children
  2751. //
  2752. if (drop_preset == NULL || drop_preset->Is_A_Parent (drag_preset) == false) {
  2753. //
  2754. // Get information about what 'type' of presets these are
  2755. //
  2756. int drag_classid = drag_preset->Get_Class_ID ();
  2757. int drop_classid = 0;
  2758. if (drop_preset != NULL) {
  2759. drop_classid = drop_preset->Get_Class_ID ();
  2760. } else {
  2761. drop_classid = factory->Get_Class_ID ();
  2762. }
  2763. //
  2764. // Are the preset's factories the same?
  2765. //
  2766. if (drag_classid == drop_classid) {
  2767. bool is_drop_temp = (drop_preset != NULL && drop_preset->Get_IsTemporary ()) ? true : false;
  2768. bool is_drag_temp = (drag_preset != NULL && drag_preset->Get_IsTemporary ()) ? true : false;
  2769. //
  2770. // We allow the drop if the target is a factory, or both the drag and drops are non-temp
  2771. //
  2772. if (factory != NULL || is_drag_temp || is_drop_temp == false) {
  2773. retval = true;
  2774. }
  2775. }
  2776. }
  2777. }
  2778. }
  2779. return retval;
  2780. }
  2781. ////////////////////////////////////////////////////////////////////////////
  2782. //
  2783. // Do_Drop
  2784. //
  2785. ////////////////////////////////////////////////////////////////////////////
  2786. void
  2787. PresetsFormClass::Do_Drop (HTREEITEM drag_item, HTREEITEM drop_item)
  2788. {
  2789. CWaitCursor wait_cursor;
  2790. PresetClass *drag_preset = Get_Item_Preset (drag_item);
  2791. bool is_drag_temp = (drag_preset != NULL && drag_preset->Get_IsTemporary ()) ? true : false;
  2792. //
  2793. // Does this operation affect only shared presets or only temps?
  2794. //
  2795. if (is_drag_temp == false) {
  2796. uint32 drag_preset_id = drag_preset->Get_Definition ()->Get_ID ();
  2797. //
  2798. // Check out the definition database
  2799. //
  2800. SelectionCaptureClass sel_capture (this);
  2801. bool undo_on_err = false;
  2802. uint32 class_id = drag_preset->Get_Class_ID ();
  2803. if (PresetMgrClass::Check_Out_Database (class_id, &undo_on_err)) {
  2804. sel_capture.Restore ();
  2805. //
  2806. // Look-up the preset tree items
  2807. //
  2808. drag_item = Find_Preset (TVI_ROOT, drag_preset_id);
  2809. drop_item = m_TreeCtrl.GetSelectedItem ();
  2810. drag_preset = Get_Item_Preset (drag_item);
  2811. //
  2812. // Are the drag and drop locations still valid?
  2813. //
  2814. if ( drag_preset != NULL &&
  2815. drag_preset->Get_Definition ()->Get_ID () == drag_preset_id &&
  2816. drag_item != NULL && drop_item != NULL && drag_item != drop_item)
  2817. {
  2818. //
  2819. // Perform the operation and save the presets...
  2820. //
  2821. Move_Preset (drag_item, drop_item);
  2822. Save_Global_Presets (class_id);
  2823. PresetMgrClass::Add_Dirty_Preset (drag_preset->Get_ID ());
  2824. } else {
  2825. //
  2826. // Inform the user that something has changed...
  2827. //
  2828. ::MessageBox ( NULL,
  2829. "Either the drag source or the drop target no longer exists, please try again.",
  2830. "Drag/Drop Error",
  2831. MB_OK | MB_ICONERROR);
  2832. if (undo_on_err) {
  2833. PresetMgrClass::Undo_Database_Check_Out (class_id);
  2834. }
  2835. }
  2836. }
  2837. } else {
  2838. //
  2839. // Simply move the preset and save the temp library
  2840. //
  2841. Move_Preset (drag_item, drop_item);
  2842. if (drag_preset != NULL) {
  2843. Save_Temp_Presets ();
  2844. }
  2845. }
  2846. return ;
  2847. }
  2848. ////////////////////////////////////////////////////////////////////////////
  2849. //
  2850. // Move_Preset
  2851. //
  2852. ////////////////////////////////////////////////////////////////////////////
  2853. void
  2854. PresetsFormClass::Move_Preset (HTREEITEM preset_item, HTREEITEM parent_item)
  2855. {
  2856. ASSERT (preset_item != NULL);
  2857. ASSERT (parent_item != NULL);
  2858. PresetClass *preset = Get_Item_Preset (preset_item);
  2859. if (preset != NULL) {
  2860. //
  2861. // Let the preset know who its new parent is
  2862. //
  2863. PresetClass *parent_preset = Get_Item_Preset (parent_item);
  2864. preset->Set_Parent (parent_preset);
  2865. if (parent_preset != NULL) {
  2866. parent_preset->Add_Child_Preset (preset->Get_ID ());
  2867. }
  2868. //
  2869. // Make a log entry about the new parent
  2870. //
  2871. if (preset->Get_IsTemporary () == false) {
  2872. //
  2873. // Get the name of the new parent
  2874. //
  2875. const char *parent_name = NULL;
  2876. if (parent_preset != NULL) {
  2877. parent_name = parent_preset->Get_Name ();
  2878. }
  2879. //
  2880. // Log the operation
  2881. //
  2882. PresetLoggerClass::Log_Moved (preset, parent_name);
  2883. }
  2884. //
  2885. // Move the tree item (and all its children)
  2886. //
  2887. m_TreeCtrl.SetRedraw (false);
  2888. Copy_Preset_Items (preset_item, parent_item);
  2889. m_TreeCtrl.DeleteItem (preset_item);
  2890. m_TreeCtrl.SetRedraw (true);
  2891. }
  2892. return ;
  2893. }
  2894. ////////////////////////////////////////////////////////////////////////////
  2895. //
  2896. // Copy_Preset_Items
  2897. //
  2898. ////////////////////////////////////////////////////////////////////////////
  2899. void
  2900. PresetsFormClass::Copy_Preset_Items (HTREEITEM preset_item, HTREEITEM parent_item)
  2901. {
  2902. //
  2903. // Copy the preset to its new parent
  2904. //
  2905. PresetClass *preset = Get_Item_Preset (preset_item);
  2906. HTREEITEM new_item = Insert_Preset (parent_item, preset);
  2907. //
  2908. // Recursive copy all child items
  2909. //
  2910. for ( HTREEITEM child_item = m_TreeCtrl.GetChildItem (preset_item);
  2911. child_item != NULL;
  2912. child_item = m_TreeCtrl.GetNextSiblingItem (child_item))
  2913. {
  2914. Copy_Preset_Items (child_item, new_item);
  2915. }
  2916. // Ensure the entries are sorted correctly
  2917. m_TreeCtrl.SortChildren (parent_item);
  2918. return ;
  2919. }
  2920. ////////////////////////////////////////////////////////////////////////////
  2921. //
  2922. // OnDestroy
  2923. //
  2924. ////////////////////////////////////////////////////////////////////////////
  2925. void
  2926. PresetsFormClass::OnDestroy (void)
  2927. {
  2928. ::RemoveProp (m_TreeCtrl, "TRANS_ACCS");
  2929. ::RemoveProp (m_hWnd, "TRANS_ACCS");
  2930. CDialog::OnDestroy ();
  2931. return ;
  2932. }
  2933. ////////////////////////////////////////////////////////////////////////////
  2934. //
  2935. // Export_File_Dependencies
  2936. //
  2937. ////////////////////////////////////////////////////////////////////////////
  2938. void
  2939. PresetsFormClass::Export_File_Dependencies (const char *filename)
  2940. {
  2941. //
  2942. // Create the file
  2943. //
  2944. TextFileClass file (filename);
  2945. if (file.Open (RawFileClass::WRITE)) {
  2946. //
  2947. // Build a list of all the entries in the tree
  2948. //
  2949. DynamicVectorClass<HTREEITEM> entry_list;
  2950. Build_Child_List (TVI_ROOT, entry_list);
  2951. //
  2952. // Loop over all the presets in the list
  2953. //
  2954. for (int index = 0; index < entry_list.Count (); index ++) {
  2955. PresetClass *preset = Get_Item_Preset (entry_list[index]);
  2956. if (preset != NULL) {
  2957. DefinitionClass *definition = preset->Get_Definition ();
  2958. if (definition != NULL) {
  2959. //
  2960. // Generate the list of file's that this preset is dependent on
  2961. //
  2962. DynamicVectorClass<StringClass> file_list;
  2963. Build_File_Dependencies_For_Definition (file_list, definition);
  2964. //
  2965. // If the list wasn't empty, then export the filenames to the text file.
  2966. //
  2967. if (file_list.Count () > 0) {
  2968. //
  2969. // Start the entry off with the name of the preset
  2970. //
  2971. StringClass entry;
  2972. entry.Format ("%s\t", (const char *)definition->Get_Name ());
  2973. //
  2974. // Now, spit out the list of files
  2975. //
  2976. for (int index = 0; index < file_list.Count (); index ++) {
  2977. entry += file_list[index];
  2978. entry += "\t";
  2979. }
  2980. //
  2981. // Add the entry to the text file
  2982. //
  2983. file.Write_Line (entry);
  2984. }
  2985. }
  2986. }
  2987. }
  2988. //
  2989. // Close the file
  2990. //
  2991. file.Close ();
  2992. }
  2993. return ;
  2994. }
  2995. ////////////////////////////////////////////////////////////////////////////
  2996. //
  2997. // Build_File_Dependencies_For_Definition
  2998. //
  2999. ////////////////////////////////////////////////////////////////////////////
  3000. void
  3001. PresetsFormClass::Build_File_Dependencies_For_Definition
  3002. (
  3003. DynamicVectorClass<StringClass> & file_list,
  3004. DefinitionClass * definition
  3005. )
  3006. {
  3007. //
  3008. // Loop over all the parameters of this definition
  3009. //
  3010. int count = definition->Get_Parameter_Count ();
  3011. for (int index = 0; index < count; index ++) {
  3012. ParameterClass *parameter = definition->Lock_Parameter (index);
  3013. //
  3014. // Handle the different file types
  3015. //
  3016. if (parameter->Is_Type (ParameterClass::TYPE_FILENAME)) {
  3017. FilenameParameterClass *filename_param = reinterpret_cast<FilenameParameterClass *> (parameter);
  3018. //
  3019. // Add the filename to the list if its not empty
  3020. //
  3021. StringClass filename = filename_param->Get_String ();
  3022. if (filename.Get_Length () > 0) {
  3023. file_list.Add (filename);
  3024. }
  3025. } else if (parameter->Get_Type () == ParameterClass::TYPE_MODELDEFINITIONID) {
  3026. int def_id = ((ModelDefParameterClass *)parameter)->Get_Value ();
  3027. //
  3028. // Recurse into the model's definition (if necessary)
  3029. //
  3030. DefinitionClass *model_definition = DefinitionMgrClass::Find_Definition (def_id, false);
  3031. if (model_definition != NULL) {
  3032. Build_File_Dependencies_For_Definition (file_list, model_definition);
  3033. }
  3034. } else if (parameter->Get_Type () == ParameterClass::TYPE_PHYSDEFINITIONID) {
  3035. int def_id = ((PhysDefParameterClass *)parameter)->Get_Value ();
  3036. //
  3037. // Recurse into the physic object's definition (if necessary)
  3038. //
  3039. DefinitionClass *phys_definition = DefinitionMgrClass::Find_Definition (def_id, false);
  3040. if (phys_definition != NULL) {
  3041. Build_File_Dependencies_For_Definition (file_list, phys_definition);
  3042. }
  3043. }
  3044. definition->Unlock_Parameter (index);
  3045. }
  3046. return ;
  3047. }
  3048. ////////////////////////////////////////////////////////////////////////////
  3049. //
  3050. // Add_Preset
  3051. //
  3052. ////////////////////////////////////////////////////////////////////////////
  3053. void
  3054. PresetsFormClass::Add_Preset (PresetClass *preset)
  3055. {
  3056. uint32 class_id = preset->Get_Class_ID ();
  3057. //
  3058. // Find the root item
  3059. //
  3060. HTREEITEM root_item = Find_Factory (TVI_ROOT, class_id);
  3061. if (root_item != NULL) {
  3062. //
  3063. // Add the preset to the tree
  3064. //
  3065. Insert_Preset (root_item, preset);
  3066. }
  3067. return ;
  3068. }
  3069. ////////////////////////////////////////////////////////////////////////////
  3070. //
  3071. // Sort_Items
  3072. //
  3073. ////////////////////////////////////////////////////////////////////////////
  3074. void
  3075. PresetsFormClass::Sort_Items (uint32 class_id)
  3076. {
  3077. //
  3078. // Find the root item
  3079. //
  3080. HTREEITEM root_item = Find_Factory (TVI_ROOT, class_id);
  3081. if (root_item != NULL) {
  3082. //
  3083. // Sort all items under this root
  3084. //
  3085. m_TreeCtrl.SetRedraw (FALSE);
  3086. Sort_Nodes (root_item);
  3087. m_TreeCtrl.SetRedraw (TRUE);
  3088. }
  3089. return ;
  3090. }