EditorResourceBrowser.as 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579
  1. UIElement@ browserWindow;
  2. Window@ browserFilterWindow;
  3. ListView@ browserDirList;
  4. ListView@ browserFileList;
  5. LineEdit@ browserSearch;
  6. BrowserFile@ browserDragFile;
  7. Node@ browserDragNode;
  8. Component@ browserDragComponent;
  9. View3D@ resourceBrowserPreview;
  10. Scene@ resourcePreviewScene;
  11. Node@ resourcePreviewNode;
  12. Node@ resourcePreviewCameraNode;
  13. Node@ resourcePreviewLightNode;
  14. Light@ resourcePreviewLight;
  15. int browserSearchSortMode = 0;
  16. BrowserDir@ rootDir;
  17. Array<BrowserFile@> browserFiles;
  18. Dictionary browserDirs;
  19. Array<int> activeResourceTypeFilters;
  20. Array<int> activeResourceDirFilters;
  21. Array<BrowserFile@> browserFilesToScan;
  22. const uint BROWSER_WORKER_ITEMS_PER_TICK = 10;
  23. const uint BROWSER_SEARCH_LIMIT = 50;
  24. const int BROWSER_SORT_MODE_ALPHA = 1;
  25. const int BROWSER_SORT_MODE_SEARCH = 2;
  26. const int RESOURCE_TYPE_UNUSABLE = -2;
  27. const int RESOURCE_TYPE_UNKNOWN = -1;
  28. const int RESOURCE_TYPE_NOTSET = 0;
  29. const int RESOURCE_TYPE_SCENE = 1;
  30. const int RESOURCE_TYPE_SCRIPTFILE = 2;
  31. const int RESOURCE_TYPE_MODEL = 3;
  32. const int RESOURCE_TYPE_MATERIAL = 4;
  33. const int RESOURCE_TYPE_ANIMATION = 5;
  34. const int RESOURCE_TYPE_IMAGE = 6;
  35. const int RESOURCE_TYPE_SOUND = 7;
  36. const int RESOURCE_TYPE_TEXTURE = 8;
  37. const int RESOURCE_TYPE_FONT = 9;
  38. const int RESOURCE_TYPE_PREFAB = 10;
  39. const int RESOURCE_TYPE_TECHNIQUE = 11;
  40. const int RESOURCE_TYPE_PARTICLEEFFECT = 12;
  41. const int RESOURCE_TYPE_UIELEMENT = 13;
  42. const int RESOURCE_TYPE_UIELEMENTS = 14;
  43. const int RESOURCE_TYPE_ANIMATION_SETTINGS = 15;
  44. const int RESOURCE_TYPE_RENDERPATH = 16;
  45. const int RESOURCE_TYPE_TEXTURE_ATLAS = 17;
  46. const int RESOURCE_TYPE_2D_PARTICLE_EFFECT = 18;
  47. const int RESOURCE_TYPE_TEXTURE_3D = 19;
  48. const int RESOURCE_TYPE_CUBEMAP = 20;
  49. const int RESOURCE_TYPE_PARTICLEEMITTER = 21;
  50. const int RESOURCE_TYPE_2D_ANIMATION_SET = 22;
  51. // any resource type > 0 is valid
  52. const int NUMBER_OF_VALID_RESOURCE_TYPES = 22;
  53. const StringHash XML_TYPE_SCENE("scene");
  54. const StringHash XML_TYPE_NODE("node");
  55. const StringHash XML_TYPE_MATERIAL("material");
  56. const StringHash XML_TYPE_TECHNIQUE("technique");
  57. const StringHash XML_TYPE_PARTICLEEFFECT("particleeffect");
  58. const StringHash XML_TYPE_PARTICLEEMITTER("particleemitter");
  59. const StringHash XML_TYPE_TEXTURE("texture");
  60. const StringHash XML_TYPE_ELEMENT("element");
  61. const StringHash XML_TYPE_ELEMENTS("elements");
  62. const StringHash XML_TYPE_ANIMATION_SETTINGS("animation");
  63. const StringHash XML_TYPE_RENDERPATH("renderpath");
  64. const StringHash XML_TYPE_TEXTURE_ATLAS("TextureAtlas");
  65. const StringHash XML_TYPE_2D_PARTICLE_EFFECT("particleEmitterConfig");
  66. const StringHash XML_TYPE_TEXTURE_3D("texture3d");
  67. const StringHash XML_TYPE_CUBEMAP("cubemap");
  68. const StringHash XML_TYPE_SPRITER_DATA("spriter_data");
  69. const StringHash BINARY_TYPE_SCENE("USCN");
  70. const StringHash BINARY_TYPE_PACKAGE("UPAK");
  71. const StringHash BINARY_TYPE_COMPRESSED_PACKAGE("ULZ4");
  72. const StringHash BINARY_TYPE_ANGLESCRIPT("ASBC");
  73. const StringHash BINARY_TYPE_MODEL("UMDL");
  74. const StringHash BINARY_TYPE_SHADER("USHD");
  75. const StringHash BINARY_TYPE_ANIMATION("UANI");
  76. const StringHash EXTENSION_TYPE_TTF(".ttf");
  77. const StringHash EXTENSION_TYPE_OTF(".otf");
  78. const StringHash EXTENSION_TYPE_OGG(".ogg");
  79. const StringHash EXTENSION_TYPE_WAV(".wav");
  80. const StringHash EXTENSION_TYPE_DDS(".dds");
  81. const StringHash EXTENSION_TYPE_PNG(".png");
  82. const StringHash EXTENSION_TYPE_JPG(".jpg");
  83. const StringHash EXTENSION_TYPE_JPEG(".jpeg");
  84. const StringHash EXTENSION_TYPE_TGA(".tga");
  85. const StringHash EXTENSION_TYPE_OBJ(".obj");
  86. const StringHash EXTENSION_TYPE_FBX(".fbx");
  87. const StringHash EXTENSION_TYPE_COLLADA(".dae");
  88. const StringHash EXTENSION_TYPE_BLEND(".blend");
  89. const StringHash EXTENSION_TYPE_ANGELSCRIPT(".as");
  90. const StringHash EXTENSION_TYPE_LUASCRIPT(".lua");
  91. const StringHash EXTENSION_TYPE_HLSL(".hlsl");
  92. const StringHash EXTENSION_TYPE_GLSL(".glsl");
  93. const StringHash EXTENSION_TYPE_FRAGMENTSHADER(".frag");
  94. const StringHash EXTENSION_TYPE_VERTEXSHADER(".vert");
  95. const StringHash EXTENSION_TYPE_HTML(".html");
  96. const StringHash TEXT_VAR_FILE_ID("browser_file_id");
  97. const StringHash TEXT_VAR_DIR_ID("browser_dir_id");
  98. const StringHash TEXT_VAR_RESOURCE_TYPE("resource_type");
  99. const StringHash TEXT_VAR_RESOURCE_DIR_ID("resource_dir_id");
  100. const int BROWSER_FILE_SOURCE_RESOURCE_DIR = 1;
  101. uint browserDirIndex = 1;
  102. uint browserFileIndex = 1;
  103. BrowserDir@ selectedBrowserDirectory;
  104. BrowserFile@ selectedBrowserFile;
  105. Text@ browserStatusMessage;
  106. Text@ browserResultsMessage;
  107. bool ignoreRefreshBrowserResults = false;
  108. String resourceDirsCache;
  109. void CreateResourceBrowser()
  110. {
  111. if (browserWindow !is null) return;
  112. CreateResourceBrowserUI();
  113. InitResourceBrowserPreview();
  114. RebuildResourceDatabase();
  115. }
  116. void RebuildResourceDatabase()
  117. {
  118. if (browserWindow is null)
  119. return;
  120. String newResourceDirsCache = Join(cache.resourceDirs, ';');
  121. ScanResourceDirectories();
  122. if (newResourceDirsCache != resourceDirsCache)
  123. {
  124. resourceDirsCache = newResourceDirsCache;
  125. PopulateResourceDirFilters();
  126. }
  127. PopulateBrowserDirectories();
  128. PopulateResourceBrowserFilesByDirectory(rootDir);
  129. }
  130. void ScanResourceDirectories()
  131. {
  132. browserDirs.Clear();
  133. browserFiles.Clear();
  134. browserFilesToScan.Clear();
  135. rootDir = BrowserDir("");
  136. browserDirs.Set("", @rootDir);
  137. // collect all of the items and sort them afterwards
  138. for(uint i=0; i < cache.resourceDirs.length; ++i)
  139. {
  140. if (activeResourceDirFilters.Find(i) > -1)
  141. continue;
  142. ScanResourceDir(i);
  143. }
  144. }
  145. // used to stop ui from blocking while determining file types
  146. void DoResourceBrowserWork()
  147. {
  148. if (browserFilesToScan.length == 0)
  149. return;
  150. int counter = 0;
  151. bool updateBrowserUI = false;
  152. BrowserFile@ scanItem = browserFilesToScan[0];
  153. while(counter < BROWSER_WORKER_ITEMS_PER_TICK)
  154. {
  155. scanItem.DetermainResourceType();
  156. // next
  157. browserFilesToScan.Erase(0);
  158. if (browserFilesToScan.length > 0)
  159. @scanItem = browserFilesToScan[0];
  160. else
  161. break;
  162. counter++;
  163. }
  164. if (browserFilesToScan.length > 0)
  165. browserStatusMessage.text = "Files left to scan: " + browserFilesToScan.length;
  166. else
  167. browserStatusMessage.text = "Scan complete";
  168. }
  169. void CreateResourceBrowserUI()
  170. {
  171. browserWindow = LoadEditorUI("UI/EditorResourceBrowser.xml");
  172. browserDirList = browserWindow.GetChild("DirectoryList", true);
  173. browserFileList = browserWindow.GetChild("FileList", true);
  174. browserSearch = browserWindow.GetChild("Search", true);
  175. browserStatusMessage = browserWindow.GetChild("StatusMessage", true);
  176. browserResultsMessage = browserWindow.GetChild("ResultsMessage", true);
  177. // browserWindow.visible = false;
  178. browserWindow.opacity = uiMaxOpacity;
  179. browserFilterWindow = LoadEditorUI("UI/EditorResourceFilterWindow.xml");
  180. CreateResourceFilterUI();
  181. HideResourceFilterWindow();
  182. int height = Min(ui.root.height / 4, 300);
  183. browserWindow.SetSize(900, height);
  184. browserWindow.SetPosition(35, ui.root.height - height - 25);
  185. CloseContextMenu();
  186. ui.root.AddChild(browserWindow);
  187. ui.root.AddChild(browserFilterWindow);
  188. SubscribeToEvent(browserWindow.GetChild("CloseButton", true), "Released", "HideResourceBrowserWindow");
  189. SubscribeToEvent(browserWindow.GetChild("RescanButton", true), "Released", "HandleRescanResourceBrowserClick");
  190. SubscribeToEvent(browserWindow.GetChild("FilterButton", true), "Released", "ToggleResourceFilterWindow");
  191. SubscribeToEvent(browserDirList, "SelectionChanged", "HandleResourceBrowserDirListSelectionChange");
  192. SubscribeToEvent(browserSearch, "TextChanged", "HandleResourceBrowserSearchTextChange");
  193. SubscribeToEvent(browserFileList, "ItemClicked", "HandleBrowserFileClick");
  194. SubscribeToEvent(browserFileList, "SelectionChanged", "HandleResourceBrowserFileListSelectionChange");
  195. SubscribeToEvent(cache, "FileChanged", "HandleFileChanged");
  196. }
  197. void CreateResourceFilterUI()
  198. {
  199. UIElement@ options = browserFilterWindow.GetChild("TypeOptions", true);
  200. CheckBox@ toggleAllTypes = browserFilterWindow.GetChild("ToggleAllTypes", true);
  201. CheckBox@ toggleAllResourceDirs = browserFilterWindow.GetChild("ToggleAllResourceDirs", true);
  202. SubscribeToEvent(toggleAllTypes, "Toggled", "HandleResourceTypeFilterToggleAllTypesToggled");
  203. SubscribeToEvent(toggleAllResourceDirs, "Toggled", "HandleResourceDirFilterToggleAllTypesToggled");
  204. SubscribeToEvent(browserFilterWindow.GetChild("CloseButton", true), "Released", "HideResourceFilterWindow");
  205. int columns = 2;
  206. UIElement@ col1 = browserFilterWindow.GetChild("TypeFilterColumn1", true);
  207. UIElement@ col2 = browserFilterWindow.GetChild("TypeFilterColumn2", true);
  208. // use array to get sort of items
  209. Array<ResourceType@> sorted;
  210. for (int i=1; i <= NUMBER_OF_VALID_RESOURCE_TYPES; ++i)
  211. sorted.Push(ResourceType(i, ResourceTypeName(i)));
  212. // 2 unknown types are reserved for the top, the rest are alphabetized
  213. sorted.Sort();
  214. sorted.Insert(0, ResourceType(RESOURCE_TYPE_UNKNOWN, ResourceTypeName(RESOURCE_TYPE_UNKNOWN)) );
  215. sorted.Insert(0, ResourceType(RESOURCE_TYPE_UNUSABLE, ResourceTypeName(RESOURCE_TYPE_UNUSABLE)) );
  216. int halfColumns = Ceil( float(sorted.length) / float(columns) );
  217. for (uint i = 0; i < sorted.length; ++i)
  218. {
  219. ResourceType@ type = sorted[i];
  220. UIElement@ resourceTypeHolder = UIElement();
  221. if (i < halfColumns)
  222. col1.AddChild(resourceTypeHolder);
  223. else
  224. col2.AddChild(resourceTypeHolder);
  225. resourceTypeHolder.layoutMode = LM_HORIZONTAL;
  226. resourceTypeHolder.layoutSpacing = 4;
  227. Text@ label = Text();
  228. label.style = "EditorAttributeText";
  229. label.text = type.name;
  230. CheckBox@ checkbox = CheckBox();
  231. checkbox.name = type.id;
  232. checkbox.SetStyleAuto();
  233. checkbox.vars[TEXT_VAR_RESOURCE_TYPE] = i;
  234. checkbox.checked = true;
  235. SubscribeToEvent(checkbox, "Toggled", "HandleResourceTypeFilterToggled");
  236. resourceTypeHolder.AddChild(checkbox);
  237. resourceTypeHolder.AddChild(label);
  238. }
  239. }
  240. void CreateDirList(BrowserDir@ dir, UIElement@ parentUI = null)
  241. {
  242. Text@ dirText = Text();
  243. browserDirList.InsertItem(browserDirList.numItems, dirText, parentUI);
  244. dirText.style = "FileSelectorListText";
  245. dirText.text = dir.resourceKey.empty ? "Root" : dir.name;
  246. dirText.name = dir.resourceKey;
  247. dirText.vars[TEXT_VAR_DIR_ID] = dir.resourceKey;
  248. // Sort directories alphetically
  249. browserSearchSortMode = BROWSER_SORT_MODE_ALPHA;
  250. dir.children.Sort();
  251. for(uint i=0; i<dir.children.length; ++i)
  252. CreateDirList(dir.children[i], dirText);
  253. }
  254. void CreateFileList(BrowserFile@ file)
  255. {
  256. Text@ fileText = Text();
  257. fileText.style = "FileSelectorListText";
  258. fileText.layoutMode = LM_HORIZONTAL;
  259. browserFileList.InsertItem(browserFileList.numItems, fileText);
  260. file.browserFileListRow = fileText;
  261. InitializeBrowserFileListRow(fileText, file);
  262. }
  263. void InitializeBrowserFileListRow(Text@ fileText, BrowserFile@ file)
  264. {
  265. fileText.RemoveAllChildren();
  266. VariantMap params = VariantMap();
  267. fileText.vars[TEXT_VAR_FILE_ID] = file.id;
  268. fileText.vars[TEXT_VAR_RESOURCE_TYPE] = file.resourceType;
  269. if (file.resourceType > 0)
  270. fileText.dragDropMode = DD_SOURCE;
  271. {
  272. Text@ text = Text();
  273. fileText.AddChild(text);
  274. text.style = "FileSelectorListText";
  275. text.text = file.fullname;
  276. text.name = file.resourceKey;
  277. }
  278. {
  279. Text@ text = Text();
  280. fileText.AddChild(text);
  281. text.style = "FileSelectorListText";
  282. text.text = file.ResourceTypeName();
  283. }
  284. if (file.resourceType == RESOURCE_TYPE_MATERIAL ||
  285. file.resourceType == RESOURCE_TYPE_MODEL ||
  286. file.resourceType == RESOURCE_TYPE_PARTICLEEFFECT ||
  287. file.resourceType == RESOURCE_TYPE_PREFAB
  288. )
  289. {
  290. SubscribeToEvent(fileText, "DragBegin", "HandleBrowserFileDragBegin");
  291. SubscribeToEvent(fileText, "DragEnd", "HandleBrowserFileDragEnd");
  292. }
  293. }
  294. void InitResourceBrowserPreview()
  295. {
  296. resourcePreviewScene = Scene("PreviewScene");
  297. resourcePreviewScene.CreateComponent("Octree");
  298. PhysicsWorld@ physicsWorld = resourcePreviewScene.CreateComponent("PhysicsWorld");
  299. physicsWorld.enabled = false;
  300. physicsWorld.gravity = Vector3(0.0, 0.0, 0.0);
  301. Node@ zoneNode = resourcePreviewScene.CreateChild("Zone");
  302. Zone@ zone = zoneNode.CreateComponent("Zone");
  303. zone.boundingBox = BoundingBox(-1000, 1000);
  304. zone.ambientColor = Color(0.15, 0.15, 0.15);
  305. zone.fogColor = Color(0, 0, 0);
  306. zone.fogStart = 10.0;
  307. zone.fogEnd = 100.0;
  308. resourcePreviewCameraNode = resourcePreviewScene.CreateChild("PreviewCamera");
  309. resourcePreviewCameraNode.position = Vector3(0, 0, -1.5);
  310. Camera@ camera = resourcePreviewCameraNode.CreateComponent("Camera");
  311. camera.nearClip = 0.1f;
  312. camera.farClip = 100.0f;
  313. resourcePreviewLightNode = resourcePreviewScene.CreateChild("PreviewLight");
  314. resourcePreviewLightNode.direction = Vector3(0.5, -0.5, 0.5);
  315. resourcePreviewLight = resourcePreviewLightNode.CreateComponent("Light");
  316. resourcePreviewLight.lightType = LIGHT_DIRECTIONAL;
  317. resourcePreviewLight.specularIntensity = 0.5;
  318. resourceBrowserPreview = browserWindow.GetChild("ResourceBrowserPreview", true);
  319. resourceBrowserPreview.SetFixedHeight(200);
  320. resourceBrowserPreview.SetFixedWidth(266);
  321. resourceBrowserPreview.SetView(resourcePreviewScene, camera);
  322. resourceBrowserPreview.autoUpdate = false;
  323. resourcePreviewNode = resourcePreviewScene.CreateChild("PreviewNodeContainer");
  324. SubscribeToEvent(resourceBrowserPreview, "DragMove", "RotateResourceBrowserPreview");
  325. RefreshBrowserPreview();
  326. }
  327. // Opens a contextual menu based on what resource item was actioned
  328. void HandleBrowserFileClick(StringHash eventType, VariantMap& eventData)
  329. {
  330. if (eventData["Button"].GetInt() != MOUSEB_RIGHT)
  331. return;
  332. UIElement@ uiElement = eventData["Item"].GetPtr();
  333. BrowserFile@ file = GetBrowserFileFromUIElement(uiElement);
  334. if (file is null)
  335. return;
  336. Array<UIElement@> actions;
  337. if (file.resourceType == RESOURCE_TYPE_MATERIAL)
  338. {
  339. actions.Push(CreateBrowserFileActionMenu("Edit", "HandleBrowserEditResource", file));
  340. }
  341. else if (file.resourceType == RESOURCE_TYPE_MODEL)
  342. {
  343. actions.Push(CreateBrowserFileActionMenu("Instance Animated Model", "HandleBrowserInstantiateAnimatedModel", file));
  344. actions.Push(CreateBrowserFileActionMenu("Instance Static Model", "HandleBrowserInstantiateStaticModel", file));
  345. }
  346. else if (file.resourceType == RESOURCE_TYPE_PREFAB)
  347. {
  348. actions.Push(CreateBrowserFileActionMenu("Instance Prefab", "HandleBrowserInstantiatePrefab", file));
  349. actions.Push(CreateBrowserFileActionMenu("Instance in Spawner", "HandleBrowserInstantiateInSpawnEditor", file));
  350. }
  351. else if (file.fileType == EXTENSION_TYPE_OBJ ||
  352. file.fileType == EXTENSION_TYPE_COLLADA ||
  353. file.fileType == EXTENSION_TYPE_FBX ||
  354. file.fileType == EXTENSION_TYPE_BLEND)
  355. {
  356. actions.Push(CreateBrowserFileActionMenu("Import Model", "HandleBrowserImportModel", file));
  357. actions.Push(CreateBrowserFileActionMenu("Import Scene", "HandleBrowserImportScene", file));
  358. }
  359. else if (file.resourceType == RESOURCE_TYPE_UIELEMENT)
  360. {
  361. actions.Push(CreateBrowserFileActionMenu("Open UI Layout", "HandleBrowserOpenUILayout", file));
  362. }
  363. else if (file.resourceType == RESOURCE_TYPE_SCENE)
  364. {
  365. actions.Push(CreateBrowserFileActionMenu("Load Scene", "HandleBrowserLoadScene", file));
  366. }
  367. else if (file.resourceType == RESOURCE_TYPE_SCRIPTFILE)
  368. {
  369. actions.Push(CreateBrowserFileActionMenu("Execute Script", "HandleBrowserRunScript", file));
  370. }
  371. else if (file.resourceType == RESOURCE_TYPE_PARTICLEEFFECT)
  372. {
  373. actions.Push(CreateBrowserFileActionMenu("Edit", "HandleBrowserEditResource", file));
  374. }
  375. actions.Push(CreateBrowserFileActionMenu("Open", "HandleBrowserOpenResource", file));
  376. ActivateContextMenu(actions);
  377. }
  378. BrowserDir@ GetBrowserDir(String path)
  379. {
  380. BrowserDir@ browserDir;
  381. browserDirs.Get(path, @browserDir);
  382. return browserDir;
  383. }
  384. // Makes sure the entire directory tree exists and new dir is linked to parent
  385. BrowserDir@ InitBrowserDir(String path)
  386. {
  387. BrowserDir@ browserDir;
  388. if (browserDirs.Get(path, @browserDir))
  389. return browserDir;
  390. Array<String> parts = path.Split('/');
  391. Array<String> finishedParts;
  392. if (parts.length > 0)
  393. {
  394. BrowserDir@ parent = rootDir;
  395. for( uint i = 0; i < parts.length; ++i )
  396. {
  397. finishedParts.Push(parts[i]);
  398. String currentPath = Join(finishedParts, "/");
  399. if (!browserDirs.Get(currentPath, @browserDir))
  400. {
  401. browserDir = BrowserDir(currentPath);
  402. browserDirs.Set(currentPath, @browserDir);
  403. parent.children.Push(browserDir);
  404. }
  405. @parent = browserDir;
  406. }
  407. return browserDir;
  408. }
  409. return null;
  410. }
  411. void ScanResourceDir(uint resourceDirIndex)
  412. {
  413. String resourceDir = cache.resourceDirs[resourceDirIndex];
  414. ScanResourceDirFiles("", resourceDirIndex);
  415. Array<String> dirs = fileSystem.ScanDir(resourceDir, "*", SCAN_DIRS, true);
  416. for (uint i=0; i < dirs.length; ++i)
  417. {
  418. String path = dirs[i];
  419. if (path.EndsWith("."))
  420. continue;
  421. InitBrowserDir(path);
  422. ScanResourceDirFiles(path, resourceDirIndex);
  423. }
  424. }
  425. void ScanResourceDirFiles(String path, uint resourceDirIndex)
  426. {
  427. String fullPath = cache.resourceDirs[resourceDirIndex] + path;
  428. if (!fileSystem.DirExists(fullPath))
  429. return;
  430. BrowserDir@ dir = GetBrowserDir(path);
  431. if (dir is null)
  432. return;
  433. // get files in directory
  434. Array<String> dirFiles = fileSystem.ScanDir(fullPath, "*.*", SCAN_FILES, false);
  435. // add new files
  436. for (uint x=0; x < dirFiles.length; x++)
  437. {
  438. String filename = dirFiles[x];
  439. BrowserFile@ browserFile = dir.AddFile(filename, resourceDirIndex, BROWSER_FILE_SOURCE_RESOURCE_DIR);
  440. browserFiles.Push(browserFile);
  441. browserFilesToScan.Push(browserFile);
  442. }
  443. }
  444. void HideResourceBrowserWindow()
  445. {
  446. browserWindow.visible = false;
  447. }
  448. bool ShowResourceBrowserWindow()
  449. {
  450. browserWindow.visible = true;
  451. browserWindow.BringToFront();
  452. ui.focusElement = browserSearch;
  453. return true;
  454. }
  455. void ToggleResourceFilterWindow()
  456. {
  457. if (browserFilterWindow.visible)
  458. HideResourceFilterWindow();
  459. else
  460. ShowResourceFilterWindow();
  461. }
  462. void HideResourceFilterWindow()
  463. {
  464. browserFilterWindow.visible = false;
  465. }
  466. void ShowResourceFilterWindow()
  467. {
  468. int x = browserWindow.position.x + browserWindow.width - browserFilterWindow.width;
  469. int y = browserWindow.position.y - browserFilterWindow.height - 1;
  470. browserFilterWindow.position = IntVector2(x,y);
  471. browserFilterWindow.visible = true;
  472. browserFilterWindow.BringToFront();
  473. }
  474. void PopulateResourceDirFilters()
  475. {
  476. UIElement@ resourceDirs = browserFilterWindow.GetChild("DirFilters", true);
  477. resourceDirs.RemoveAllChildren();
  478. activeResourceDirFilters.Clear();
  479. for (uint i=0; i < cache.resourceDirs.length; ++i)
  480. {
  481. UIElement@ resourceDirHolder = UIElement();
  482. resourceDirs.AddChild(resourceDirHolder);
  483. resourceDirHolder.layoutMode = LM_HORIZONTAL;
  484. resourceDirHolder.layoutSpacing = 4;
  485. resourceDirHolder.SetFixedHeight(16);
  486. Text@ label = Text();
  487. label.style = "EditorAttributeText";
  488. label.text = cache.resourceDirs[i].Replaced(fileSystem.programDir, "");
  489. CheckBox@ checkbox = CheckBox();
  490. checkbox.name = i;
  491. checkbox.SetStyleAuto();
  492. checkbox.vars[TEXT_VAR_RESOURCE_DIR_ID] = i;
  493. checkbox.checked = true;
  494. SubscribeToEvent(checkbox, "Toggled", "HandleResourceDirFilterToggled");
  495. resourceDirHolder.AddChild(checkbox);
  496. resourceDirHolder.AddChild(label);
  497. }
  498. }
  499. void PopulateBrowserDirectories()
  500. {
  501. browserDirList.RemoveAllItems();
  502. CreateDirList(rootDir);
  503. browserDirList.selection = 0;
  504. }
  505. void PopulateResourceBrowserFilesByDirectory(BrowserDir@ dir)
  506. {
  507. @selectedBrowserDirectory = dir;
  508. browserFileList.RemoveAllItems();
  509. if (dir is null) return;
  510. Array<BrowserFile@> files;
  511. for(uint x=0; x < dir.files.length; x++)
  512. {
  513. BrowserFile@ file = dir.files[x];
  514. if (activeResourceTypeFilters.Find(file.resourceType) == -1)
  515. files.Push(file);
  516. }
  517. // Sort alphetically
  518. browserSearchSortMode = BROWSER_SORT_MODE_ALPHA;
  519. files.Sort();
  520. PopulateResourceBrowserResults(files);
  521. browserResultsMessage.text = "Showing " + files.length + " files";
  522. }
  523. void PopulateResourceBrowserBySearch()
  524. {
  525. String query = browserSearch.text;
  526. Array<int> scores;
  527. Array<BrowserFile@> scored;
  528. Array<BrowserFile@> filtered;
  529. {
  530. BrowserFile@ file;
  531. for(uint x=0; x < browserFiles.length; x++)
  532. {
  533. @file = browserFiles[x];
  534. file.sortScore = -1;
  535. if (activeResourceTypeFilters.Find(file.resourceType) > -1)
  536. continue;
  537. if (activeResourceDirFilters.Find(file.resourceSourceIndex) > -1)
  538. continue;
  539. int find = file.fullname.Find(query, 0, false);
  540. if (find > -1)
  541. {
  542. int fudge = query.length - file.fullname.length;
  543. int score = find * int(Abs(fudge*2)) + int(Abs(fudge));
  544. file.sortScore = score;
  545. scored.Push(file);
  546. scores.Push(score);
  547. }
  548. }
  549. }
  550. // cut this down for a faster sort
  551. if (scored.length > BROWSER_SEARCH_LIMIT)
  552. {
  553. scores.Sort();
  554. int scoreThreshold = scores[BROWSER_SEARCH_LIMIT];
  555. BrowserFile@ file;
  556. for(uint x=0;x<scored.length;x++)
  557. {
  558. file = scored[x];
  559. if (file.sortScore <= scoreThreshold)
  560. filtered.Push(file);
  561. }
  562. }
  563. else
  564. filtered = scored;
  565. browserSearchSortMode = BROWSER_SORT_MODE_ALPHA;
  566. filtered.Sort();
  567. PopulateResourceBrowserResults(filtered);
  568. browserResultsMessage.text = "Showing top " + filtered.length + " of " + scored.length + " results";
  569. }
  570. void PopulateResourceBrowserResults(Array<BrowserFile@>@ files)
  571. {
  572. browserFileList.RemoveAllItems();
  573. for(uint i=0; i < files.length; ++i)
  574. CreateFileList(files[i]);
  575. }
  576. void RefreshBrowserResults()
  577. {
  578. if (browserSearch.text.empty)
  579. {
  580. browserDirList.visible = true;
  581. PopulateResourceBrowserFilesByDirectory(selectedBrowserDirectory);
  582. }
  583. else
  584. {
  585. browserDirList.visible = false;
  586. PopulateResourceBrowserBySearch();
  587. }
  588. }
  589. void HandleResourceTypeFilterToggleAllTypesToggled(StringHash eventType, VariantMap& eventData)
  590. {
  591. CheckBox@ checkbox = eventData["Element"].GetPtr();
  592. UIElement@ filterHolder = browserFilterWindow.GetChild("TypeFilters", true);
  593. Array<UIElement@> children = filterHolder.GetChildren(true);
  594. ignoreRefreshBrowserResults = true;
  595. for(uint i=0; i < children.length; ++i)
  596. {
  597. CheckBox@ filter = children[i];
  598. if (filter !is null)
  599. filter.checked = checkbox.checked;
  600. }
  601. ignoreRefreshBrowserResults = false;
  602. RefreshBrowserResults();
  603. }
  604. void HandleResourceTypeFilterToggled(StringHash eventType, VariantMap& eventData)
  605. {
  606. CheckBox@ checkbox = eventData["Element"].GetPtr();
  607. if (!checkbox.vars.Contains(TEXT_VAR_RESOURCE_TYPE))
  608. return;
  609. int resourceType = checkbox.GetVar(TEXT_VAR_RESOURCE_TYPE).GetInt();
  610. int find = activeResourceTypeFilters.Find(resourceType);
  611. if (checkbox.checked && find != -1)
  612. activeResourceTypeFilters.Erase(find);
  613. else if (!checkbox.checked && find == -1)
  614. activeResourceTypeFilters.Push(resourceType);
  615. if (ignoreRefreshBrowserResults == false)
  616. RefreshBrowserResults();
  617. }
  618. void HandleResourceDirFilterToggleAllTypesToggled(StringHash eventType, VariantMap& eventData)
  619. {
  620. CheckBox@ checkbox = eventData["Element"].GetPtr();
  621. UIElement@ filterHolder = browserFilterWindow.GetChild("DirFilters", true);
  622. Array<UIElement@> children = filterHolder.GetChildren(true);
  623. ignoreRefreshBrowserResults = true;
  624. for(uint i=0; i < children.length; ++i)
  625. {
  626. CheckBox@ filter = children[i];
  627. if (filter !is null)
  628. filter.checked = checkbox.checked;
  629. }
  630. ignoreRefreshBrowserResults = false;
  631. RebuildResourceDatabase();
  632. }
  633. void HandleResourceDirFilterToggled(StringHash eventType, VariantMap& eventData)
  634. {
  635. CheckBox@ checkbox = eventData["Element"].GetPtr();
  636. if (!checkbox.vars.Contains(TEXT_VAR_RESOURCE_DIR_ID))
  637. return;
  638. int resourceDir = checkbox.GetVar(TEXT_VAR_RESOURCE_DIR_ID).GetInt();
  639. int find = activeResourceDirFilters.Find(resourceDir);
  640. if (checkbox.checked && find != -1)
  641. activeResourceDirFilters.Erase(find);
  642. else if (!checkbox.checked && find == -1)
  643. activeResourceDirFilters.Push(resourceDir);
  644. if (ignoreRefreshBrowserResults == false)
  645. RebuildResourceDatabase();
  646. }
  647. void HandleRescanResourceBrowserClick(StringHash eventType, VariantMap& eventData)
  648. {
  649. RebuildResourceDatabase();
  650. }
  651. void HandleResourceBrowserDirListSelectionChange(StringHash eventType, VariantMap& eventData)
  652. {
  653. if (browserDirList.selection == M_MAX_UNSIGNED)
  654. return;
  655. UIElement@ uiElement = browserDirList.GetItems()[browserDirList.selection];
  656. BrowserDir@ dir = GetBrowserDir(uiElement.vars[TEXT_VAR_DIR_ID].GetString());
  657. if (dir is null)
  658. return;
  659. PopulateResourceBrowserFilesByDirectory(dir);
  660. }
  661. void HandleResourceBrowserFileListSelectionChange(StringHash eventType, VariantMap& eventData)
  662. {
  663. if (browserFileList.selection == M_MAX_UNSIGNED)
  664. return;
  665. UIElement@ uiElement = browserFileList.GetItems()[browserFileList.selection];
  666. BrowserFile@ file = GetBrowserFileFromUIElement(uiElement);
  667. if (file is null)
  668. return;
  669. if (resourcePreviewNode !is null)
  670. resourcePreviewNode.Remove();
  671. resourcePreviewNode = resourcePreviewScene.CreateChild("PreviewNodeContainer");
  672. CreateResourcePreview(file.GetFullPath(), resourcePreviewNode);
  673. if (resourcePreviewNode !is null)
  674. {
  675. Array<BoundingBox> boxes;
  676. Array<Component@> staticModels = resourcePreviewNode.GetComponents("StaticModel", true);
  677. Array<Component@> animatedModels = resourcePreviewNode.GetComponents("AnimatedModel", true);
  678. for (uint i = 0; i < staticModels.length; ++i)
  679. boxes.Push(cast<StaticModel>(staticModels[i]).worldBoundingBox);
  680. for (uint i = 0; i < animatedModels.length; ++i)
  681. boxes.Push(cast<AnimatedModel>(animatedModels[i]).worldBoundingBox);
  682. if (boxes.length > 0)
  683. {
  684. Vector3 camPosition = Vector3(0.0, 0.0, -1.2);
  685. BoundingBox biggestBox = boxes[0];
  686. for (uint i = 1; i < boxes.length; ++i)
  687. {
  688. if (boxes[i].size.length > biggestBox.size.length)
  689. biggestBox = boxes[i];
  690. }
  691. resourcePreviewCameraNode.position = biggestBox.center + camPosition * biggestBox.size.length;
  692. }
  693. resourcePreviewScene.AddChild(resourcePreviewNode);
  694. RefreshBrowserPreview();
  695. }
  696. }
  697. void HandleResourceBrowserSearchTextChange(StringHash eventType, VariantMap& eventData)
  698. {
  699. RefreshBrowserResults();
  700. }
  701. BrowserFile@ GetBrowserFileFromId(uint id)
  702. {
  703. if (id == 0)
  704. return null;
  705. BrowserFile@ file;
  706. for(uint i=0; i<browserFiles.length; ++i)
  707. {
  708. @file = @browserFiles[i];
  709. if (file.id == id) return file;
  710. }
  711. return null;
  712. }
  713. BrowserFile@ GetBrowserFileFromUIElement(UIElement@ element)
  714. {
  715. if (element is null || !element.vars.Contains(TEXT_VAR_FILE_ID))
  716. return null;
  717. return GetBrowserFileFromId(element.vars[TEXT_VAR_FILE_ID].GetUInt());
  718. }
  719. BrowserFile@ GetBrowserFileFromPath(String path)
  720. {
  721. for (uint i=0; i < browserFiles.length; ++i)
  722. {
  723. BrowserFile@ file = browserFiles[i];
  724. if (path == file.GetFullPath())
  725. return file;
  726. }
  727. return null;
  728. }
  729. void HandleBrowserEditResource(StringHash eventType, VariantMap& eventData)
  730. {
  731. UIElement@ element = eventData["Element"].GetPtr();
  732. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  733. if (file is null)
  734. return;
  735. if (file.resourceType == RESOURCE_TYPE_MATERIAL)
  736. {
  737. Material@ material = cache.GetResource("Material", file.resourceKey);
  738. if (material !is null)
  739. EditMaterial(material);
  740. }
  741. if (file.resourceType == RESOURCE_TYPE_PARTICLEEFFECT)
  742. {
  743. ParticleEffect@ particleEffect = cache.GetResource("ParticleEffect", file.resourceKey);
  744. if (particleEffect !is null)
  745. EditParticleEffect(particleEffect);
  746. }
  747. }
  748. void HandleBrowserOpenResource(StringHash eventType, VariantMap& eventData)
  749. {
  750. UIElement@ element = eventData["Element"].GetPtr();
  751. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  752. if (file !is null)
  753. OpenResource(file.resourceKey);
  754. }
  755. void HandleBrowserImportScene(StringHash eventType, VariantMap& eventData)
  756. {
  757. UIElement@ element = eventData["Element"].GetPtr();
  758. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  759. if (file !is null)
  760. ImportScene(file.GetFullPath());
  761. }
  762. void HandleBrowserImportModel(StringHash eventType, VariantMap& eventData)
  763. {
  764. UIElement@ element = eventData["Element"].GetPtr();
  765. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  766. if (file !is null)
  767. ImportModel(file.GetFullPath());
  768. }
  769. void HandleBrowserOpenUILayout(StringHash eventType, VariantMap& eventData)
  770. {
  771. UIElement@ element = eventData["Element"].GetPtr();
  772. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  773. if (file !is null)
  774. OpenUILayout(file.GetFullPath());
  775. }
  776. void HandleBrowserInstantiateStaticModel(StringHash eventType, VariantMap& eventData)
  777. {
  778. UIElement@ element = eventData["Element"].GetPtr();
  779. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  780. if (file !is null)
  781. CreateModelWithStaticModel(file.resourceKey, editNode);
  782. }
  783. void HandleBrowserInstantiateAnimatedModel(StringHash eventType, VariantMap& eventData)
  784. {
  785. UIElement@ element = eventData["Element"].GetPtr();
  786. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  787. if (file !is null)
  788. CreateModelWithAnimatedModel(file.resourceKey, editNode);
  789. }
  790. void HandleBrowserInstantiatePrefab(StringHash eventType, VariantMap& eventData)
  791. {
  792. UIElement@ element = eventData["Element"].GetPtr();
  793. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  794. if (file !is null)
  795. LoadNode(file.GetFullPath());
  796. }
  797. void HandleBrowserInstantiateInSpawnEditor(StringHash eventType, VariantMap& eventData)
  798. {
  799. UIElement@ element = eventData["Element"].GetPtr();
  800. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  801. if (file !is null)
  802. {
  803. spawnedObjectsNames.Resize(1);
  804. spawnedObjectsNames[0] = VerifySpawnedObjectFile(file.GetPath());
  805. RefreshPickedObjects();
  806. ShowSpawnEditor();
  807. }
  808. }
  809. void HandleBrowserLoadScene(StringHash eventType, VariantMap& eventData)
  810. {
  811. UIElement@ element = eventData["Element"].GetPtr();
  812. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  813. if (file !is null)
  814. LoadScene(file.GetFullPath());
  815. }
  816. void HandleBrowserRunScript(StringHash eventType, VariantMap& eventData)
  817. {
  818. UIElement@ element = eventData["Element"].GetPtr();
  819. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  820. if (file !is null)
  821. ExecuteScript(ExtractFileName(eventData));
  822. }
  823. void HandleBrowserFileDragBegin(StringHash eventType, VariantMap& eventData)
  824. {
  825. UIElement@ uiElement = eventData["Element"].GetPtr();
  826. @browserDragFile = GetBrowserFileFromUIElement(uiElement);
  827. }
  828. void HandleBrowserFileDragEnd(StringHash eventType, VariantMap& eventData)
  829. {
  830. if (@browserDragFile is null)
  831. return;
  832. UIElement@ element = ui.GetElementAt(ui.cursor.screenPosition);
  833. if (element !is null)
  834. return;
  835. if (browserDragFile.resourceType == RESOURCE_TYPE_MATERIAL)
  836. {
  837. StaticModel@ model = cast<StaticModel>(GetDrawableAtMousePostion());
  838. if (model !is null)
  839. {
  840. AssignMaterial(model, browserDragFile.resourceKey);
  841. }
  842. }
  843. browserDragFile = null;
  844. browserDragComponent = null;
  845. browserDragNode = null;
  846. }
  847. void HandleFileChanged(StringHash eventType, VariantMap& eventData)
  848. {
  849. String filename = eventData["FileName"].GetString();
  850. BrowserFile@ file = GetBrowserFileFromPath(filename);
  851. if (file is null)
  852. {
  853. // TODO: new file logic when watchers are supported
  854. return;
  855. }
  856. else
  857. {
  858. file.FileChanged();
  859. }
  860. }
  861. Menu@ CreateBrowserFileActionMenu(String text, String handler, BrowserFile@ browserFile = null)
  862. {
  863. Menu@ menu = CreateContextMenuItem(text, handler);
  864. if (browserFile !is null)
  865. menu.vars[TEXT_VAR_FILE_ID] = browserFile.id;
  866. return menu;
  867. }
  868. int GetResourceType(String path)
  869. {
  870. StringHash fileType;
  871. return GetResourceType(path, fileType);
  872. }
  873. int GetResourceType(String path, StringHash &out fileType, bool useCache = false)
  874. {
  875. if (GetExtensionType(path, fileType) || GetBinaryType(path, fileType, useCache) || GetXmlType(path, fileType, useCache))
  876. return GetResourceType(fileType);
  877. return RESOURCE_TYPE_UNKNOWN;
  878. }
  879. int GetResourceType(StringHash fileType)
  880. {
  881. // binary fileTypes
  882. if (fileType == BINARY_TYPE_SCENE)
  883. return RESOURCE_TYPE_SCENE;
  884. else if (fileType == BINARY_TYPE_PACKAGE)
  885. return RESOURCE_TYPE_UNUSABLE;
  886. else if (fileType == BINARY_TYPE_COMPRESSED_PACKAGE)
  887. return RESOURCE_TYPE_UNUSABLE;
  888. else if (fileType == BINARY_TYPE_ANGLESCRIPT)
  889. return RESOURCE_TYPE_SCRIPTFILE;
  890. else if (fileType == BINARY_TYPE_MODEL)
  891. return RESOURCE_TYPE_MODEL;
  892. else if (fileType == BINARY_TYPE_SHADER)
  893. return RESOURCE_TYPE_UNUSABLE;
  894. else if (fileType == BINARY_TYPE_ANIMATION)
  895. return RESOURCE_TYPE_ANIMATION;
  896. // xml fileTypes
  897. else if (fileType == XML_TYPE_SCENE)
  898. return RESOURCE_TYPE_SCENE;
  899. else if (fileType == XML_TYPE_NODE)
  900. return RESOURCE_TYPE_PREFAB;
  901. else if(fileType == XML_TYPE_MATERIAL)
  902. return RESOURCE_TYPE_MATERIAL;
  903. else if(fileType == XML_TYPE_TECHNIQUE)
  904. return RESOURCE_TYPE_TECHNIQUE;
  905. else if(fileType == XML_TYPE_PARTICLEEFFECT)
  906. return RESOURCE_TYPE_PARTICLEEFFECT;
  907. else if(fileType == XML_TYPE_PARTICLEEMITTER)
  908. return RESOURCE_TYPE_PARTICLEEMITTER;
  909. else if(fileType == XML_TYPE_TEXTURE)
  910. return RESOURCE_TYPE_TEXTURE;
  911. else if(fileType == XML_TYPE_ELEMENT)
  912. return RESOURCE_TYPE_UIELEMENT;
  913. else if(fileType == XML_TYPE_ELEMENTS)
  914. return RESOURCE_TYPE_UIELEMENTS;
  915. else if (fileType == XML_TYPE_ANIMATION_SETTINGS)
  916. return RESOURCE_TYPE_ANIMATION_SETTINGS;
  917. else if (fileType == XML_TYPE_RENDERPATH)
  918. return RESOURCE_TYPE_RENDERPATH;
  919. else if (fileType == XML_TYPE_TEXTURE_ATLAS)
  920. return RESOURCE_TYPE_TEXTURE_ATLAS;
  921. else if (fileType == XML_TYPE_2D_PARTICLE_EFFECT)
  922. return RESOURCE_TYPE_2D_PARTICLE_EFFECT;
  923. else if (fileType == XML_TYPE_TEXTURE_3D)
  924. return RESOURCE_TYPE_TEXTURE_3D;
  925. else if (fileType == XML_TYPE_CUBEMAP)
  926. return RESOURCE_TYPE_CUBEMAP;
  927. else if (fileType == XML_TYPE_SPRITER_DATA)
  928. return RESOURCE_TYPE_2D_ANIMATION_SET;
  929. // extension fileTypes
  930. else if (fileType == EXTENSION_TYPE_TTF)
  931. return RESOURCE_TYPE_FONT;
  932. else if (fileType == EXTENSION_TYPE_OTF)
  933. return RESOURCE_TYPE_FONT;
  934. else if (fileType == EXTENSION_TYPE_OGG)
  935. return RESOURCE_TYPE_SOUND;
  936. else if(fileType == EXTENSION_TYPE_WAV)
  937. return RESOURCE_TYPE_SOUND;
  938. else if(fileType == EXTENSION_TYPE_DDS)
  939. return RESOURCE_TYPE_IMAGE;
  940. else if(fileType == EXTENSION_TYPE_PNG)
  941. return RESOURCE_TYPE_IMAGE;
  942. else if(fileType == EXTENSION_TYPE_JPG)
  943. return RESOURCE_TYPE_IMAGE;
  944. else if(fileType == EXTENSION_TYPE_JPEG)
  945. return RESOURCE_TYPE_IMAGE;
  946. else if(fileType == EXTENSION_TYPE_TGA)
  947. return RESOURCE_TYPE_IMAGE;
  948. else if(fileType == EXTENSION_TYPE_OBJ)
  949. return RESOURCE_TYPE_UNUSABLE;
  950. else if(fileType == EXTENSION_TYPE_FBX)
  951. return RESOURCE_TYPE_UNUSABLE;
  952. else if(fileType == EXTENSION_TYPE_COLLADA)
  953. return RESOURCE_TYPE_UNUSABLE;
  954. else if(fileType == EXTENSION_TYPE_BLEND)
  955. return RESOURCE_TYPE_UNUSABLE;
  956. else if(fileType == EXTENSION_TYPE_ANGELSCRIPT)
  957. return RESOURCE_TYPE_SCRIPTFILE;
  958. else if(fileType == EXTENSION_TYPE_LUASCRIPT)
  959. return RESOURCE_TYPE_SCRIPTFILE;
  960. else if(fileType == EXTENSION_TYPE_HLSL)
  961. return RESOURCE_TYPE_UNUSABLE;
  962. else if(fileType == EXTENSION_TYPE_GLSL)
  963. return RESOURCE_TYPE_UNUSABLE;
  964. else if(fileType == EXTENSION_TYPE_FRAGMENTSHADER)
  965. return RESOURCE_TYPE_UNUSABLE;
  966. else if(fileType == EXTENSION_TYPE_VERTEXSHADER)
  967. return RESOURCE_TYPE_UNUSABLE;
  968. else if(fileType == EXTENSION_TYPE_HTML)
  969. return RESOURCE_TYPE_UNUSABLE;
  970. return RESOURCE_TYPE_UNKNOWN;
  971. }
  972. bool GetExtensionType(String path, StringHash &out fileType)
  973. {
  974. StringHash type = StringHash(GetExtension(path));
  975. if (type == EXTENSION_TYPE_TTF)
  976. fileType = EXTENSION_TYPE_TTF;
  977. else if (type == EXTENSION_TYPE_OGG)
  978. fileType = EXTENSION_TYPE_OGG;
  979. else if(type == EXTENSION_TYPE_WAV)
  980. fileType = EXTENSION_TYPE_WAV;
  981. else if(type == EXTENSION_TYPE_DDS)
  982. fileType = EXTENSION_TYPE_DDS;
  983. else if(type == EXTENSION_TYPE_PNG)
  984. fileType = EXTENSION_TYPE_PNG;
  985. else if(type == EXTENSION_TYPE_JPG)
  986. fileType = EXTENSION_TYPE_JPG;
  987. else if(type == EXTENSION_TYPE_JPEG)
  988. fileType = EXTENSION_TYPE_JPEG;
  989. else if(type == EXTENSION_TYPE_TGA)
  990. fileType = EXTENSION_TYPE_TGA;
  991. else if(type == EXTENSION_TYPE_OBJ)
  992. fileType = EXTENSION_TYPE_OBJ;
  993. else if(type == EXTENSION_TYPE_FBX)
  994. fileType = EXTENSION_TYPE_FBX;
  995. else if(type == EXTENSION_TYPE_COLLADA)
  996. fileType = EXTENSION_TYPE_COLLADA;
  997. else if(type == EXTENSION_TYPE_BLEND)
  998. fileType = EXTENSION_TYPE_BLEND;
  999. else if(type == EXTENSION_TYPE_ANGELSCRIPT)
  1000. fileType = EXTENSION_TYPE_ANGELSCRIPT;
  1001. else if(type == EXTENSION_TYPE_LUASCRIPT)
  1002. fileType = EXTENSION_TYPE_LUASCRIPT;
  1003. else if(type == EXTENSION_TYPE_HLSL)
  1004. fileType = EXTENSION_TYPE_HLSL;
  1005. else if(type == EXTENSION_TYPE_GLSL)
  1006. fileType = EXTENSION_TYPE_GLSL;
  1007. else if(type == EXTENSION_TYPE_FRAGMENTSHADER)
  1008. fileType = EXTENSION_TYPE_FRAGMENTSHADER;
  1009. else if(type == EXTENSION_TYPE_VERTEXSHADER)
  1010. fileType = EXTENSION_TYPE_VERTEXSHADER;
  1011. else if(type == EXTENSION_TYPE_HTML)
  1012. fileType = EXTENSION_TYPE_HTML;
  1013. else
  1014. return false;
  1015. return true;
  1016. }
  1017. bool GetBinaryType(String path, StringHash &out fileType, bool useCache = false)
  1018. {
  1019. StringHash type;
  1020. if (useCache)
  1021. {
  1022. File@ file = cache.GetFile(path);
  1023. if (file is null)
  1024. return false;
  1025. if (file.size == 0)
  1026. return false;
  1027. type = StringHash(file.ReadFileID());
  1028. }
  1029. else
  1030. {
  1031. File@ file = File();
  1032. if (!file.Open(path))
  1033. return false;
  1034. if (file.size == 0)
  1035. return false;
  1036. type = StringHash(file.ReadFileID());
  1037. }
  1038. if (type == BINARY_TYPE_SCENE)
  1039. fileType = BINARY_TYPE_SCENE;
  1040. else if (type == BINARY_TYPE_PACKAGE)
  1041. fileType = BINARY_TYPE_PACKAGE;
  1042. else if (type == BINARY_TYPE_COMPRESSED_PACKAGE)
  1043. fileType = BINARY_TYPE_COMPRESSED_PACKAGE;
  1044. else if (type == BINARY_TYPE_ANGLESCRIPT)
  1045. fileType = BINARY_TYPE_ANGLESCRIPT;
  1046. else if (type == BINARY_TYPE_MODEL)
  1047. fileType = BINARY_TYPE_MODEL;
  1048. else if (type == BINARY_TYPE_SHADER)
  1049. fileType = BINARY_TYPE_SHADER;
  1050. else if (type == BINARY_TYPE_ANIMATION)
  1051. fileType = BINARY_TYPE_ANIMATION;
  1052. else
  1053. return false;
  1054. return true;
  1055. }
  1056. bool GetXmlType(String path, StringHash &out fileType, bool useCache = false)
  1057. {
  1058. String extension = GetExtension(path);
  1059. if (extension == ".txt" || extension == ".json" || extension == ".icns")
  1060. return false;
  1061. String name;
  1062. if (useCache)
  1063. {
  1064. XMLFile@ xml = cache.GetResource("XMLFile", path);
  1065. if (xml is null)
  1066. return false;
  1067. name = xml.root.name;
  1068. }
  1069. else
  1070. {
  1071. File@ file = File();
  1072. if (!file.Open(path))
  1073. return false;
  1074. if (file.size == 0)
  1075. return false;
  1076. XMLFile@ xml = XMLFile();
  1077. if (xml.Load(file))
  1078. name = xml.root.name;
  1079. else
  1080. return false;
  1081. }
  1082. bool found = false;
  1083. if (!name.empty)
  1084. {
  1085. found = true;
  1086. StringHash type = StringHash(name);
  1087. if (type == XML_TYPE_SCENE)
  1088. fileType = XML_TYPE_SCENE;
  1089. else if (type == XML_TYPE_NODE)
  1090. fileType = XML_TYPE_NODE;
  1091. else if(type == XML_TYPE_MATERIAL)
  1092. fileType = XML_TYPE_MATERIAL;
  1093. else if(type == XML_TYPE_TECHNIQUE)
  1094. fileType = XML_TYPE_TECHNIQUE;
  1095. else if(type == XML_TYPE_PARTICLEEFFECT)
  1096. fileType = XML_TYPE_PARTICLEEFFECT;
  1097. else if(type == XML_TYPE_PARTICLEEMITTER)
  1098. fileType = XML_TYPE_PARTICLEEMITTER;
  1099. else if(type == XML_TYPE_TEXTURE)
  1100. fileType = XML_TYPE_TEXTURE;
  1101. else if(type == XML_TYPE_ELEMENT)
  1102. fileType = XML_TYPE_ELEMENT;
  1103. else if(type == XML_TYPE_ELEMENTS)
  1104. fileType = XML_TYPE_ELEMENTS;
  1105. else if (type == XML_TYPE_ANIMATION_SETTINGS)
  1106. fileType = XML_TYPE_ANIMATION_SETTINGS;
  1107. else if (type == XML_TYPE_RENDERPATH)
  1108. fileType = XML_TYPE_RENDERPATH;
  1109. else if (type == XML_TYPE_TEXTURE_ATLAS)
  1110. fileType = XML_TYPE_TEXTURE_ATLAS;
  1111. else if (type == XML_TYPE_2D_PARTICLE_EFFECT)
  1112. fileType = XML_TYPE_2D_PARTICLE_EFFECT;
  1113. else if (type == XML_TYPE_TEXTURE_3D)
  1114. fileType = XML_TYPE_TEXTURE_3D;
  1115. else if (type == XML_TYPE_CUBEMAP)
  1116. fileType = XML_TYPE_CUBEMAP;
  1117. else if (type == XML_TYPE_SPRITER_DATA)
  1118. fileType = XML_TYPE_SPRITER_DATA;
  1119. else
  1120. found = false;
  1121. }
  1122. return found;
  1123. }
  1124. String ResourceTypeName(int resourceType)
  1125. {
  1126. if (resourceType == RESOURCE_TYPE_UNUSABLE)
  1127. return "Unusable";
  1128. else if (resourceType == RESOURCE_TYPE_UNKNOWN)
  1129. return "Unknown";
  1130. else if (resourceType == RESOURCE_TYPE_NOTSET)
  1131. return "Uninitialized";
  1132. else if (resourceType == RESOURCE_TYPE_SCENE)
  1133. return "Scene";
  1134. else if (resourceType == RESOURCE_TYPE_SCRIPTFILE)
  1135. return "Script File";
  1136. else if (resourceType == RESOURCE_TYPE_MODEL)
  1137. return "Model";
  1138. else if (resourceType == RESOURCE_TYPE_MATERIAL)
  1139. return "Material";
  1140. else if (resourceType == RESOURCE_TYPE_ANIMATION)
  1141. return "Animation";
  1142. else if (resourceType == RESOURCE_TYPE_IMAGE)
  1143. return "Image";
  1144. else if (resourceType == RESOURCE_TYPE_SOUND)
  1145. return "Sound";
  1146. else if (resourceType == RESOURCE_TYPE_TEXTURE)
  1147. return "Texture";
  1148. else if (resourceType == RESOURCE_TYPE_FONT)
  1149. return "Font";
  1150. else if (resourceType == RESOURCE_TYPE_PREFAB)
  1151. return "Prefab";
  1152. else if (resourceType == RESOURCE_TYPE_TECHNIQUE)
  1153. return "Render Technique";
  1154. else if (resourceType == RESOURCE_TYPE_PARTICLEEFFECT)
  1155. return "Particle Effect";
  1156. else if (resourceType == RESOURCE_TYPE_PARTICLEEMITTER)
  1157. return "Particle Emitter";
  1158. else if (resourceType == RESOURCE_TYPE_UIELEMENT)
  1159. return "UI Element";
  1160. else if (resourceType == RESOURCE_TYPE_UIELEMENTS)
  1161. return "UI Elements";
  1162. else if (resourceType == RESOURCE_TYPE_ANIMATION_SETTINGS)
  1163. return "Animation Settings";
  1164. else if (resourceType == RESOURCE_TYPE_RENDERPATH)
  1165. return "Render Path";
  1166. else if (resourceType == RESOURCE_TYPE_TEXTURE_ATLAS)
  1167. return "Texture Atlas";
  1168. else if (resourceType == RESOURCE_TYPE_2D_PARTICLE_EFFECT)
  1169. return "2D Particle Effect";
  1170. else if (resourceType == RESOURCE_TYPE_TEXTURE_3D)
  1171. return "Texture 3D";
  1172. else if (resourceType == RESOURCE_TYPE_CUBEMAP)
  1173. return "Cubemap";
  1174. else if (resourceType == RESOURCE_TYPE_2D_ANIMATION_SET)
  1175. return "2D Animation Set";
  1176. else
  1177. return "";
  1178. }
  1179. class BrowserDir
  1180. {
  1181. uint id;
  1182. String resourceKey;
  1183. String name;
  1184. Array<BrowserDir@> children;
  1185. Array<BrowserFile@> files;
  1186. BrowserDir(String path_)
  1187. {
  1188. resourceKey = path_;
  1189. String parent = GetParentPath(path_);
  1190. name = path_;
  1191. name.Replace(parent, "");
  1192. id = browserDirIndex++;
  1193. }
  1194. int opCmp(BrowserDir@ b)
  1195. {
  1196. return name.opCmp(b.name);
  1197. }
  1198. BrowserFile@ AddFile(String name, uint resourceSourceIndex, uint sourceType)
  1199. {
  1200. String path = resourceKey + "/" + name;
  1201. BrowserFile@ file = BrowserFile(path, resourceSourceIndex, sourceType);
  1202. files.Push(file);
  1203. return file;
  1204. }
  1205. }
  1206. class BrowserFile
  1207. {
  1208. uint id;
  1209. uint resourceSourceIndex;
  1210. String resourceKey;
  1211. String name;
  1212. String fullname;
  1213. String extension;
  1214. StringHash fileType;
  1215. int resourceType = 0;
  1216. int sourceType = 0;
  1217. int sortScore = 0;
  1218. WeakHandle browserFileListRow;
  1219. BrowserFile(String path_, uint resourceSourceIndex_, int sourceType_)
  1220. {
  1221. sourceType = sourceType_;
  1222. resourceSourceIndex = resourceSourceIndex_;
  1223. resourceKey = path_;
  1224. name = GetFileName(path_);
  1225. extension = GetExtension(path_);
  1226. fullname = GetFileNameAndExtension(path_);
  1227. id = browserFileIndex++;
  1228. }
  1229. int opCmp(BrowserFile@ b)
  1230. {
  1231. if (browserSearchSortMode == 1)
  1232. return fullname.opCmp(b.fullname);
  1233. else
  1234. return sortScore - b.sortScore;
  1235. }
  1236. String GetResourceSource()
  1237. {
  1238. if (sourceType == BROWSER_FILE_SOURCE_RESOURCE_DIR)
  1239. return cache.resourceDirs[resourceSourceIndex];
  1240. else
  1241. return "Unknown";
  1242. }
  1243. String GetFullPath()
  1244. {
  1245. return String(cache.resourceDirs[resourceSourceIndex] + resourceKey);
  1246. }
  1247. String GetPath()
  1248. {
  1249. return resourceKey;
  1250. }
  1251. void DetermainResourceType()
  1252. {
  1253. resourceType = GetResourceType(GetFullPath(), fileType, false);
  1254. Text@ browserFileListRow_ = browserFileListRow.Get();
  1255. if (browserFileListRow_ !is null)
  1256. {
  1257. InitializeBrowserFileListRow(browserFileListRow_, this);
  1258. }
  1259. }
  1260. String ResourceTypeName()
  1261. {
  1262. return ::ResourceTypeName(resourceType);
  1263. }
  1264. void FileChanged()
  1265. {
  1266. if (!fileSystem.FileExists(GetFullPath()))
  1267. {
  1268. }
  1269. else
  1270. {
  1271. }
  1272. }
  1273. }
  1274. void CreateResourcePreview(String path, Node@ previewNode)
  1275. {
  1276. resourceBrowserPreview.autoUpdate = false;
  1277. int resourceType = GetResourceType(path);
  1278. if (resourceType > 0)
  1279. {
  1280. File file;
  1281. file.Open(path);
  1282. if (resourceType == RESOURCE_TYPE_MODEL)
  1283. {
  1284. Model@ model = Model();
  1285. if (model.Load(file))
  1286. {
  1287. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1288. staticModel.model = model;
  1289. return;
  1290. }
  1291. }
  1292. else if (resourceType == RESOURCE_TYPE_MATERIAL)
  1293. {
  1294. Material@ material = Material();
  1295. if (material.Load(file))
  1296. {
  1297. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1298. staticModel.model = cache.GetResource("Model", "Models/Sphere.mdl");
  1299. staticModel.material = material;
  1300. return;
  1301. }
  1302. }
  1303. else if (resourceType == RESOURCE_TYPE_IMAGE)
  1304. {
  1305. Image@ image = Image();
  1306. if (image.Load(file))
  1307. {
  1308. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1309. staticModel.model = cache.GetResource("Model", "Models/Editor/ImagePlane.mdl");
  1310. Material@ material = cache.GetResource("Material", "Materials/Editor/TexturedUnlit.xml");
  1311. Texture2D@ texture = Texture2D();
  1312. texture.SetData(@image, true);
  1313. material.textures[0] = texture;
  1314. staticModel.material = material;
  1315. return;
  1316. }
  1317. }
  1318. else if (resourceType == RESOURCE_TYPE_PREFAB)
  1319. {
  1320. if (GetExtension(path) == ".xml")
  1321. {
  1322. XMLFile xmlFile;
  1323. if(xmlFile.Load(file))
  1324. if(previewNode.LoadXML(xmlFile.root, true) && (previewNode.GetComponents("StaticModel", true).length > 0 || previewNode.GetComponents("AnimatedModel", true).length > 0))
  1325. {
  1326. return;
  1327. }
  1328. }
  1329. else if(previewNode.Load(file, true) && (previewNode.GetComponents("StaticModel", true).length > 0 || previewNode.GetComponents("AnimatedModel", true).length > 0))
  1330. return;
  1331. previewNode.RemoveAllChildren();
  1332. previewNode.RemoveAllComponents();
  1333. }
  1334. else if (resourceType == RESOURCE_TYPE_PARTICLEEFFECT)
  1335. {
  1336. ParticleEffect@ particleEffect = ParticleEffect();
  1337. if (particleEffect.Load(file))
  1338. {
  1339. ParticleEmitter@ particleEmitter = previewNode.CreateComponent("ParticleEmitter");
  1340. particleEmitter.effect = particleEffect;
  1341. particleEffect.activeTime = 0.0;
  1342. particleEmitter.Reset();
  1343. resourceBrowserPreview.autoUpdate = true;
  1344. return;
  1345. }
  1346. }
  1347. }
  1348. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1349. staticModel.model = cache.GetResource("Model", "Models/Editor/ImagePlane.mdl");
  1350. Material@ material = cache.GetResource("Material", "Materials/Editor/TexturedUnlit.xml");
  1351. Texture2D@ texture = Texture2D();
  1352. Image@ noPreviewImage = cache.GetResource("Image", "Textures/Editor/NoPreviewAvailable.png");
  1353. texture.SetData(noPreviewImage, false);
  1354. material.textures[0] = texture;
  1355. staticModel.material = material;
  1356. return;
  1357. }
  1358. void RotateResourceBrowserPreview(StringHash eventType, VariantMap& eventData)
  1359. {
  1360. int elemX = eventData["ElementX"].GetInt();
  1361. int elemY = eventData["ElementY"].GetInt();
  1362. if (resourceBrowserPreview.height > 0 && resourceBrowserPreview.width > 0)
  1363. {
  1364. float yaw = ((resourceBrowserPreview.height / 2) - elemY) * (90.0 / resourceBrowserPreview.height);
  1365. float pitch = ((resourceBrowserPreview.width / 2) - elemX) * (90.0 / resourceBrowserPreview.width);
  1366. resourcePreviewNode.rotation = resourcePreviewNode.rotation.Slerp(Quaternion(yaw, pitch, 0), 0.1);
  1367. RefreshBrowserPreview();
  1368. }
  1369. }
  1370. void RefreshBrowserPreview()
  1371. {
  1372. resourceBrowserPreview.QueueUpdate();
  1373. }
  1374. class ResourceType
  1375. {
  1376. int id;
  1377. String name;
  1378. ResourceType(int id_, String name_)
  1379. {
  1380. id = id_;
  1381. name = name_;
  1382. }
  1383. int opCmp(ResourceType@ b)
  1384. {
  1385. return name.opCmp(b.name);
  1386. }
  1387. }