EditorResourceBrowser.as 53 KB

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