EditorResourceBrowser.as 50 KB

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