EditorResourceBrowser.as 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604
  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. bool ToggleResourceBrowserWindow()
  448. {
  449. if (browserWindow.visible == false)
  450. ShowResourceBrowserWindow();
  451. else
  452. HideResourceBrowserWindow();
  453. return true;
  454. }
  455. void ShowResourceBrowserWindow()
  456. {
  457. browserWindow.visible = true;
  458. browserWindow.BringToFront();
  459. ui.focusElement = browserSearch;
  460. }
  461. void HideResourceBrowserWindow()
  462. {
  463. browserWindow.visible = false;
  464. }
  465. void ToggleResourceFilterWindow()
  466. {
  467. if (browserFilterWindow.visible)
  468. HideResourceFilterWindow();
  469. else
  470. ShowResourceFilterWindow();
  471. }
  472. void HideResourceFilterWindow()
  473. {
  474. browserFilterWindow.visible = false;
  475. }
  476. void ShowResourceFilterWindow()
  477. {
  478. int x = browserWindow.position.x + browserWindow.width - browserFilterWindow.width;
  479. int y = browserWindow.position.y - browserFilterWindow.height - 1;
  480. browserFilterWindow.position = IntVector2(x,y);
  481. browserFilterWindow.visible = true;
  482. browserFilterWindow.BringToFront();
  483. }
  484. void PopulateResourceDirFilters()
  485. {
  486. UIElement@ resourceDirs = browserFilterWindow.GetChild("DirFilters", true);
  487. resourceDirs.RemoveAllChildren();
  488. activeResourceDirFilters.Clear();
  489. for (uint i=0; i < cache.resourceDirs.length; ++i)
  490. {
  491. UIElement@ resourceDirHolder = UIElement();
  492. resourceDirs.AddChild(resourceDirHolder);
  493. resourceDirHolder.layoutMode = LM_HORIZONTAL;
  494. resourceDirHolder.layoutSpacing = 4;
  495. resourceDirHolder.SetFixedHeight(16);
  496. Text@ label = Text();
  497. label.style = "EditorAttributeText";
  498. label.text = cache.resourceDirs[i].Replaced(fileSystem.programDir, "");
  499. CheckBox@ checkbox = CheckBox();
  500. checkbox.name = i;
  501. checkbox.SetStyleAuto();
  502. checkbox.vars[TEXT_VAR_RESOURCE_DIR_ID] = i;
  503. checkbox.checked = true;
  504. SubscribeToEvent(checkbox, "Toggled", "HandleResourceDirFilterToggled");
  505. resourceDirHolder.AddChild(checkbox);
  506. resourceDirHolder.AddChild(label);
  507. }
  508. }
  509. void PopulateBrowserDirectories()
  510. {
  511. browserDirList.RemoveAllItems();
  512. CreateDirList(rootDir);
  513. browserDirList.selection = 0;
  514. }
  515. void PopulateResourceBrowserFilesByDirectory(BrowserDir@ dir)
  516. {
  517. @selectedBrowserDirectory = dir;
  518. browserFileList.RemoveAllItems();
  519. if (dir is null) return;
  520. Array<BrowserFile@> files;
  521. for(uint x=0; x < dir.files.length; x++)
  522. {
  523. BrowserFile@ file = dir.files[x];
  524. if (activeResourceTypeFilters.Find(file.resourceType) == -1)
  525. files.Push(file);
  526. }
  527. // Sort alphetically
  528. browserSearchSortMode = BROWSER_SORT_MODE_ALPHA;
  529. files.Sort();
  530. PopulateResourceBrowserResults(files);
  531. browserResultsMessage.text = localization.Get("Showing files: ") + files.length;
  532. }
  533. void PopulateResourceBrowserBySearch()
  534. {
  535. String query = browserSearch.text;
  536. Array<int> scores;
  537. Array<BrowserFile@> scored;
  538. Array<BrowserFile@> filtered;
  539. {
  540. BrowserFile@ file;
  541. for(uint x=0; x < browserFiles.length; x++)
  542. {
  543. @file = browserFiles[x];
  544. file.sortScore = -1;
  545. if (activeResourceTypeFilters.Find(file.resourceType) > -1)
  546. continue;
  547. if (activeResourceDirFilters.Find(file.resourceSourceIndex) > -1)
  548. continue;
  549. int find = file.fullname.Find(query, 0, false);
  550. if (find > -1)
  551. {
  552. int fudge = query.length - file.fullname.length;
  553. int score = find * int(Abs(fudge*2)) + int(Abs(fudge));
  554. file.sortScore = score;
  555. scored.Push(file);
  556. scores.Push(score);
  557. }
  558. }
  559. }
  560. // cut this down for a faster sort
  561. if (scored.length > BROWSER_SEARCH_LIMIT)
  562. {
  563. scores.Sort();
  564. int scoreThreshold = scores[BROWSER_SEARCH_LIMIT];
  565. BrowserFile@ file;
  566. for(uint x=0;x<scored.length;x++)
  567. {
  568. file = scored[x];
  569. if (file.sortScore <= scoreThreshold)
  570. filtered.Push(file);
  571. }
  572. }
  573. else
  574. filtered = scored;
  575. browserSearchSortMode = BROWSER_SORT_MODE_ALPHA;
  576. filtered.Sort();
  577. PopulateResourceBrowserResults(filtered);
  578. browserResultsMessage.text = "Showing top " + filtered.length + " of " + scored.length + " results";
  579. }
  580. void PopulateResourceBrowserResults(Array<BrowserFile@>@ files)
  581. {
  582. browserFileList.RemoveAllItems();
  583. for(uint i=0; i < files.length; ++i)
  584. CreateFileList(files[i]);
  585. }
  586. void RefreshBrowserResults()
  587. {
  588. if (browserSearch.text.empty)
  589. {
  590. browserDirList.visible = true;
  591. PopulateResourceBrowserFilesByDirectory(selectedBrowserDirectory);
  592. }
  593. else
  594. {
  595. browserDirList.visible = false;
  596. PopulateResourceBrowserBySearch();
  597. }
  598. }
  599. void HandleResourceTypeFilterToggleAllTypesToggled(StringHash eventType, VariantMap& eventData)
  600. {
  601. CheckBox@ checkbox = eventData["Element"].GetPtr();
  602. UIElement@ filterHolder = browserFilterWindow.GetChild("TypeFilters", true);
  603. Array<UIElement@> children = filterHolder.GetChildren(true);
  604. ignoreRefreshBrowserResults = true;
  605. for(uint i=0; i < children.length; ++i)
  606. {
  607. CheckBox@ filter = children[i];
  608. if (filter !is null)
  609. filter.checked = checkbox.checked;
  610. }
  611. ignoreRefreshBrowserResults = false;
  612. RefreshBrowserResults();
  613. }
  614. void HandleResourceTypeFilterToggled(StringHash eventType, VariantMap& eventData)
  615. {
  616. CheckBox@ checkbox = eventData["Element"].GetPtr();
  617. if (!checkbox.vars.Contains(TEXT_VAR_RESOURCE_TYPE))
  618. return;
  619. int resourceType = checkbox.GetVar(TEXT_VAR_RESOURCE_TYPE).GetInt();
  620. int find = activeResourceTypeFilters.Find(resourceType);
  621. if (checkbox.checked && find != -1)
  622. activeResourceTypeFilters.Erase(find);
  623. else if (!checkbox.checked && find == -1)
  624. activeResourceTypeFilters.Push(resourceType);
  625. if (ignoreRefreshBrowserResults == false)
  626. RefreshBrowserResults();
  627. }
  628. void HandleResourceDirFilterToggleAllTypesToggled(StringHash eventType, VariantMap& eventData)
  629. {
  630. CheckBox@ checkbox = eventData["Element"].GetPtr();
  631. UIElement@ filterHolder = browserFilterWindow.GetChild("DirFilters", true);
  632. Array<UIElement@> children = filterHolder.GetChildren(true);
  633. ignoreRefreshBrowserResults = true;
  634. for(uint i=0; i < children.length; ++i)
  635. {
  636. CheckBox@ filter = children[i];
  637. if (filter !is null)
  638. filter.checked = checkbox.checked;
  639. }
  640. ignoreRefreshBrowserResults = false;
  641. RebuildResourceDatabase();
  642. }
  643. void HandleResourceDirFilterToggled(StringHash eventType, VariantMap& eventData)
  644. {
  645. CheckBox@ checkbox = eventData["Element"].GetPtr();
  646. if (!checkbox.vars.Contains(TEXT_VAR_RESOURCE_DIR_ID))
  647. return;
  648. int resourceDir = checkbox.GetVar(TEXT_VAR_RESOURCE_DIR_ID).GetInt();
  649. int find = activeResourceDirFilters.Find(resourceDir);
  650. if (checkbox.checked && find != -1)
  651. activeResourceDirFilters.Erase(find);
  652. else if (!checkbox.checked && find == -1)
  653. activeResourceDirFilters.Push(resourceDir);
  654. if (ignoreRefreshBrowserResults == false)
  655. RebuildResourceDatabase();
  656. }
  657. void HandleRescanResourceBrowserClick(StringHash eventType, VariantMap& eventData)
  658. {
  659. RebuildResourceDatabase();
  660. }
  661. void HandleResourceBrowserDirListSelectionChange(StringHash eventType, VariantMap& eventData)
  662. {
  663. if (browserDirList.selection == M_MAX_UNSIGNED)
  664. return;
  665. UIElement@ uiElement = browserDirList.GetItems()[browserDirList.selection];
  666. BrowserDir@ dir = GetBrowserDir(uiElement.vars[TEXT_VAR_DIR_ID].GetString());
  667. if (dir is null)
  668. return;
  669. PopulateResourceBrowserFilesByDirectory(dir);
  670. }
  671. void HandleResourceBrowserFileListSelectionChange(StringHash eventType, VariantMap& eventData)
  672. {
  673. if (browserFileList.selection == M_MAX_UNSIGNED)
  674. return;
  675. UIElement@ uiElement = browserFileList.GetItems()[browserFileList.selection];
  676. BrowserFile@ file = GetBrowserFileFromUIElement(uiElement);
  677. if (file is null)
  678. return;
  679. if (resourcePreviewNode !is null)
  680. resourcePreviewNode.Remove();
  681. resourcePreviewNode = resourcePreviewScene.CreateChild("PreviewNodeContainer");
  682. CreateResourcePreview(file.GetFullPath(), resourcePreviewNode);
  683. if (resourcePreviewNode !is null)
  684. {
  685. Array<BoundingBox> boxes;
  686. Array<Component@> staticModels = resourcePreviewNode.GetComponents("StaticModel", true);
  687. Array<Component@> animatedModels = resourcePreviewNode.GetComponents("AnimatedModel", true);
  688. for (uint i = 0; i < staticModels.length; ++i)
  689. boxes.Push(cast<StaticModel>(staticModels[i]).worldBoundingBox);
  690. for (uint i = 0; i < animatedModels.length; ++i)
  691. boxes.Push(cast<AnimatedModel>(animatedModels[i]).worldBoundingBox);
  692. if (boxes.length > 0)
  693. {
  694. Vector3 camPosition = Vector3(0.0, 0.0, -1.2);
  695. BoundingBox biggestBox = boxes[0];
  696. for (uint i = 1; i < boxes.length; ++i)
  697. {
  698. if (boxes[i].size.length > biggestBox.size.length)
  699. biggestBox = boxes[i];
  700. }
  701. resourcePreviewCameraNode.position = biggestBox.center + camPosition * biggestBox.size.length;
  702. }
  703. resourcePreviewScene.AddChild(resourcePreviewNode);
  704. RefreshBrowserPreview();
  705. }
  706. }
  707. void HandleResourceBrowserSearchTextChange(StringHash eventType, VariantMap& eventData)
  708. {
  709. RefreshBrowserResults();
  710. }
  711. BrowserFile@ GetBrowserFileFromId(uint id)
  712. {
  713. if (id == 0)
  714. return null;
  715. BrowserFile@ file;
  716. for(uint i=0; i<browserFiles.length; ++i)
  717. {
  718. @file = @browserFiles[i];
  719. if (file.id == id) return file;
  720. }
  721. return null;
  722. }
  723. BrowserFile@ GetBrowserFileFromUIElement(UIElement@ element)
  724. {
  725. if (element is null || !element.vars.Contains(TEXT_VAR_FILE_ID))
  726. return null;
  727. return GetBrowserFileFromId(element.vars[TEXT_VAR_FILE_ID].GetUInt());
  728. }
  729. BrowserFile@ GetBrowserFileFromPath(String path)
  730. {
  731. for (uint i=0; i < browserFiles.length; ++i)
  732. {
  733. BrowserFile@ file = browserFiles[i];
  734. if (path == file.GetFullPath())
  735. return file;
  736. }
  737. return null;
  738. }
  739. void HandleBrowserEditResource(StringHash eventType, VariantMap& eventData)
  740. {
  741. UIElement@ element = eventData["Element"].GetPtr();
  742. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  743. if (file is null)
  744. return;
  745. if (file.resourceType == RESOURCE_TYPE_MATERIAL)
  746. {
  747. Material@ material = cache.GetResource("Material", file.resourceKey);
  748. if (material !is null)
  749. EditMaterial(material);
  750. }
  751. if (file.resourceType == RESOURCE_TYPE_PARTICLEEFFECT)
  752. {
  753. ParticleEffect@ particleEffect = cache.GetResource("ParticleEffect", file.resourceKey);
  754. if (particleEffect !is null)
  755. EditParticleEffect(particleEffect);
  756. }
  757. }
  758. void HandleBrowserOpenResource(StringHash eventType, VariantMap& eventData)
  759. {
  760. UIElement@ element = eventData["Element"].GetPtr();
  761. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  762. if (file !is null)
  763. OpenResource(file.resourceKey);
  764. }
  765. void HandleBrowserImportScene(StringHash eventType, VariantMap& eventData)
  766. {
  767. UIElement@ element = eventData["Element"].GetPtr();
  768. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  769. if (file !is null)
  770. ImportScene(file.GetFullPath());
  771. }
  772. void HandleBrowserImportModel(StringHash eventType, VariantMap& eventData)
  773. {
  774. UIElement@ element = eventData["Element"].GetPtr();
  775. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  776. if (file !is null)
  777. ImportModel(file.GetFullPath());
  778. }
  779. void HandleBrowserOpenUILayout(StringHash eventType, VariantMap& eventData)
  780. {
  781. UIElement@ element = eventData["Element"].GetPtr();
  782. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  783. if (file !is null)
  784. OpenUILayout(file.GetFullPath());
  785. }
  786. void HandleBrowserInstantiateStaticModel(StringHash eventType, VariantMap& eventData)
  787. {
  788. UIElement@ element = eventData["Element"].GetPtr();
  789. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  790. if (file !is null)
  791. CreateModelWithStaticModel(file.resourceKey, editNode);
  792. }
  793. void HandleBrowserInstantiateAnimatedModel(StringHash eventType, VariantMap& eventData)
  794. {
  795. UIElement@ element = eventData["Element"].GetPtr();
  796. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  797. if (file !is null)
  798. CreateModelWithAnimatedModel(file.resourceKey, editNode);
  799. }
  800. void HandleBrowserInstantiatePrefab(StringHash eventType, VariantMap& eventData)
  801. {
  802. UIElement@ element = eventData["Element"].GetPtr();
  803. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  804. if (file !is null)
  805. LoadNode(file.GetFullPath());
  806. }
  807. void HandleBrowserInstantiateInSpawnEditor(StringHash eventType, VariantMap& eventData)
  808. {
  809. UIElement@ element = eventData["Element"].GetPtr();
  810. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  811. if (file !is null)
  812. {
  813. spawnedObjectsNames.Resize(1);
  814. spawnedObjectsNames[0] = VerifySpawnedObjectFile(file.GetPath());
  815. RefreshPickedObjects();
  816. ShowSpawnEditor();
  817. }
  818. }
  819. void HandleBrowserLoadScene(StringHash eventType, VariantMap& eventData)
  820. {
  821. UIElement@ element = eventData["Element"].GetPtr();
  822. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  823. if (file !is null)
  824. LoadScene(file.GetFullPath());
  825. }
  826. void HandleBrowserRunScript(StringHash eventType, VariantMap& eventData)
  827. {
  828. UIElement@ element = eventData["Element"].GetPtr();
  829. BrowserFile@ file = GetBrowserFileFromUIElement(element);
  830. if (file !is null)
  831. ExecuteScript(ExtractFileName(eventData));
  832. }
  833. void HandleBrowserFileDragBegin(StringHash eventType, VariantMap& eventData)
  834. {
  835. UIElement@ uiElement = eventData["Element"].GetPtr();
  836. @browserDragFile = GetBrowserFileFromUIElement(uiElement);
  837. }
  838. void HandleBrowserFileDragEnd(StringHash eventType, VariantMap& eventData)
  839. {
  840. if (@browserDragFile is null)
  841. return;
  842. UIElement@ element = ui.GetElementAt(ui.cursor.screenPosition);
  843. if (element !is null)
  844. return;
  845. if (browserDragFile.resourceType == RESOURCE_TYPE_MATERIAL)
  846. {
  847. StaticModel@ model = cast<StaticModel>(GetDrawableAtMousePostion());
  848. if (model !is null)
  849. {
  850. AssignMaterial(model, browserDragFile.resourceKey);
  851. }
  852. }
  853. browserDragFile = null;
  854. browserDragComponent = null;
  855. browserDragNode = null;
  856. }
  857. void HandleFileChanged(StringHash eventType, VariantMap& eventData)
  858. {
  859. String filename = eventData["FileName"].GetString();
  860. BrowserFile@ file = GetBrowserFileFromPath(filename);
  861. if (file is null)
  862. {
  863. // TODO: new file logic when watchers are supported
  864. return;
  865. }
  866. else
  867. {
  868. file.FileChanged();
  869. }
  870. }
  871. Menu@ CreateBrowserFileActionMenu(String text, String handler, BrowserFile@ browserFile = null)
  872. {
  873. Menu@ menu = CreateContextMenuItem(text, handler);
  874. if (browserFile !is null)
  875. menu.vars[TEXT_VAR_FILE_ID] = browserFile.id;
  876. return menu;
  877. }
  878. int GetResourceType(String path)
  879. {
  880. StringHash fileType;
  881. return GetResourceType(path, fileType);
  882. }
  883. int GetResourceType(String path, StringHash &out fileType, bool useCache = false)
  884. {
  885. if (GetExtensionType(path, fileType) || GetBinaryType(path, fileType, useCache) || GetXmlType(path, fileType, useCache))
  886. return GetResourceType(fileType);
  887. return RESOURCE_TYPE_UNKNOWN;
  888. }
  889. int GetResourceType(StringHash fileType)
  890. {
  891. // binary fileTypes
  892. if (fileType == BINARY_TYPE_SCENE)
  893. return RESOURCE_TYPE_SCENE;
  894. else if (fileType == BINARY_TYPE_PACKAGE)
  895. return RESOURCE_TYPE_UNUSABLE;
  896. else if (fileType == BINARY_TYPE_COMPRESSED_PACKAGE)
  897. return RESOURCE_TYPE_UNUSABLE;
  898. else if (fileType == BINARY_TYPE_ANGLESCRIPT)
  899. return RESOURCE_TYPE_SCRIPTFILE;
  900. else if (fileType == BINARY_TYPE_MODEL)
  901. return RESOURCE_TYPE_MODEL;
  902. else if (fileType == BINARY_TYPE_SHADER)
  903. return RESOURCE_TYPE_UNUSABLE;
  904. else if (fileType == BINARY_TYPE_ANIMATION)
  905. return RESOURCE_TYPE_ANIMATION;
  906. // xml fileTypes
  907. else if (fileType == XML_TYPE_SCENE)
  908. return RESOURCE_TYPE_SCENE;
  909. else if (fileType == XML_TYPE_NODE)
  910. return RESOURCE_TYPE_PREFAB;
  911. else if(fileType == XML_TYPE_MATERIAL)
  912. return RESOURCE_TYPE_MATERIAL;
  913. else if(fileType == XML_TYPE_TECHNIQUE)
  914. return RESOURCE_TYPE_TECHNIQUE;
  915. else if(fileType == XML_TYPE_PARTICLEEFFECT)
  916. return RESOURCE_TYPE_PARTICLEEFFECT;
  917. else if(fileType == XML_TYPE_PARTICLEEMITTER)
  918. return RESOURCE_TYPE_PARTICLEEMITTER;
  919. else if(fileType == XML_TYPE_TEXTURE)
  920. return RESOURCE_TYPE_TEXTURE;
  921. else if(fileType == XML_TYPE_ELEMENT)
  922. return RESOURCE_TYPE_UIELEMENT;
  923. else if(fileType == XML_TYPE_ELEMENTS)
  924. return RESOURCE_TYPE_UIELEMENTS;
  925. else if (fileType == XML_TYPE_ANIMATION_SETTINGS)
  926. return RESOURCE_TYPE_ANIMATION_SETTINGS;
  927. else if (fileType == XML_TYPE_RENDERPATH)
  928. return RESOURCE_TYPE_RENDERPATH;
  929. else if (fileType == XML_TYPE_TEXTURE_ATLAS)
  930. return RESOURCE_TYPE_TEXTURE_ATLAS;
  931. else if (fileType == XML_TYPE_2D_PARTICLE_EFFECT)
  932. return RESOURCE_TYPE_2D_PARTICLE_EFFECT;
  933. else if (fileType == XML_TYPE_TEXTURE_3D)
  934. return RESOURCE_TYPE_TEXTURE_3D;
  935. else if (fileType == XML_TYPE_CUBEMAP)
  936. return RESOURCE_TYPE_CUBEMAP;
  937. else if (fileType == XML_TYPE_SPRITER_DATA)
  938. return RESOURCE_TYPE_2D_ANIMATION_SET;
  939. // extension fileTypes
  940. else if (fileType == EXTENSION_TYPE_TTF)
  941. return RESOURCE_TYPE_FONT;
  942. else if (fileType == EXTENSION_TYPE_OTF)
  943. return RESOURCE_TYPE_FONT;
  944. else if (fileType == EXTENSION_TYPE_OGG)
  945. return RESOURCE_TYPE_SOUND;
  946. else if(fileType == EXTENSION_TYPE_WAV)
  947. return RESOURCE_TYPE_SOUND;
  948. else if(fileType == EXTENSION_TYPE_DDS)
  949. return RESOURCE_TYPE_IMAGE;
  950. else if(fileType == EXTENSION_TYPE_PNG)
  951. return RESOURCE_TYPE_IMAGE;
  952. else if(fileType == EXTENSION_TYPE_JPG)
  953. return RESOURCE_TYPE_IMAGE;
  954. else if(fileType == EXTENSION_TYPE_JPEG)
  955. return RESOURCE_TYPE_IMAGE;
  956. else if(fileType == EXTENSION_TYPE_BMP)
  957. return RESOURCE_TYPE_IMAGE;
  958. else if(fileType == EXTENSION_TYPE_TGA)
  959. return RESOURCE_TYPE_IMAGE;
  960. else if(fileType == EXTENSION_TYPE_KTX)
  961. return RESOURCE_TYPE_IMAGE;
  962. else if(fileType == EXTENSION_TYPE_PVR)
  963. return RESOURCE_TYPE_IMAGE;
  964. else if(fileType == EXTENSION_TYPE_OBJ)
  965. return RESOURCE_TYPE_UNUSABLE;
  966. else if(fileType == EXTENSION_TYPE_FBX)
  967. return RESOURCE_TYPE_UNUSABLE;
  968. else if(fileType == EXTENSION_TYPE_COLLADA)
  969. return RESOURCE_TYPE_UNUSABLE;
  970. else if(fileType == EXTENSION_TYPE_BLEND)
  971. return RESOURCE_TYPE_UNUSABLE;
  972. else if(fileType == EXTENSION_TYPE_ANGELSCRIPT)
  973. return RESOURCE_TYPE_SCRIPTFILE;
  974. else if(fileType == EXTENSION_TYPE_LUASCRIPT)
  975. return RESOURCE_TYPE_SCRIPTFILE;
  976. else if(fileType == EXTENSION_TYPE_HLSL)
  977. return RESOURCE_TYPE_UNUSABLE;
  978. else if(fileType == EXTENSION_TYPE_GLSL)
  979. return RESOURCE_TYPE_UNUSABLE;
  980. else if(fileType == EXTENSION_TYPE_FRAGMENTSHADER)
  981. return RESOURCE_TYPE_UNUSABLE;
  982. else if(fileType == EXTENSION_TYPE_VERTEXSHADER)
  983. return RESOURCE_TYPE_UNUSABLE;
  984. else if(fileType == EXTENSION_TYPE_HTML)
  985. return RESOURCE_TYPE_UNUSABLE;
  986. return RESOURCE_TYPE_UNKNOWN;
  987. }
  988. bool GetExtensionType(String path, StringHash &out fileType)
  989. {
  990. StringHash type = StringHash(GetExtension(path));
  991. if (type == EXTENSION_TYPE_TTF)
  992. fileType = EXTENSION_TYPE_TTF;
  993. else if (type == EXTENSION_TYPE_OTF)
  994. fileType = EXTENSION_TYPE_OTF;
  995. else if (type == EXTENSION_TYPE_OGG)
  996. fileType = EXTENSION_TYPE_OGG;
  997. else if(type == EXTENSION_TYPE_WAV)
  998. fileType = EXTENSION_TYPE_WAV;
  999. else if(type == EXTENSION_TYPE_DDS)
  1000. fileType = EXTENSION_TYPE_DDS;
  1001. else if(type == EXTENSION_TYPE_PNG)
  1002. fileType = EXTENSION_TYPE_PNG;
  1003. else if(type == EXTENSION_TYPE_JPG)
  1004. fileType = EXTENSION_TYPE_JPG;
  1005. else if(type == EXTENSION_TYPE_JPEG)
  1006. fileType = EXTENSION_TYPE_JPEG;
  1007. else if(type == EXTENSION_TYPE_BMP)
  1008. fileType = EXTENSION_TYPE_BMP;
  1009. else if(type == EXTENSION_TYPE_TGA)
  1010. fileType = EXTENSION_TYPE_TGA;
  1011. else if(type == EXTENSION_TYPE_KTX)
  1012. fileType = EXTENSION_TYPE_KTX;
  1013. else if(type == EXTENSION_TYPE_PVR)
  1014. fileType = EXTENSION_TYPE_PVR;
  1015. else if(type == EXTENSION_TYPE_OBJ)
  1016. fileType = EXTENSION_TYPE_OBJ;
  1017. else if(type == EXTENSION_TYPE_FBX)
  1018. fileType = EXTENSION_TYPE_FBX;
  1019. else if(type == EXTENSION_TYPE_COLLADA)
  1020. fileType = EXTENSION_TYPE_COLLADA;
  1021. else if(type == EXTENSION_TYPE_BLEND)
  1022. fileType = EXTENSION_TYPE_BLEND;
  1023. else if(type == EXTENSION_TYPE_ANGELSCRIPT)
  1024. fileType = EXTENSION_TYPE_ANGELSCRIPT;
  1025. else if(type == EXTENSION_TYPE_LUASCRIPT)
  1026. fileType = EXTENSION_TYPE_LUASCRIPT;
  1027. else if(type == EXTENSION_TYPE_HLSL)
  1028. fileType = EXTENSION_TYPE_HLSL;
  1029. else if(type == EXTENSION_TYPE_GLSL)
  1030. fileType = EXTENSION_TYPE_GLSL;
  1031. else if(type == EXTENSION_TYPE_FRAGMENTSHADER)
  1032. fileType = EXTENSION_TYPE_FRAGMENTSHADER;
  1033. else if(type == EXTENSION_TYPE_VERTEXSHADER)
  1034. fileType = EXTENSION_TYPE_VERTEXSHADER;
  1035. else if(type == EXTENSION_TYPE_HTML)
  1036. fileType = EXTENSION_TYPE_HTML;
  1037. else
  1038. return false;
  1039. return true;
  1040. }
  1041. bool GetBinaryType(String path, StringHash &out fileType, bool useCache = false)
  1042. {
  1043. StringHash type;
  1044. if (useCache)
  1045. {
  1046. File@ file = cache.GetFile(path);
  1047. if (file is null)
  1048. return false;
  1049. if (file.size == 0)
  1050. return false;
  1051. type = StringHash(file.ReadFileID());
  1052. }
  1053. else
  1054. {
  1055. File@ file = File();
  1056. if (!file.Open(path))
  1057. return false;
  1058. if (file.size == 0)
  1059. return false;
  1060. type = StringHash(file.ReadFileID());
  1061. }
  1062. if (type == BINARY_TYPE_SCENE)
  1063. fileType = BINARY_TYPE_SCENE;
  1064. else if (type == BINARY_TYPE_PACKAGE)
  1065. fileType = BINARY_TYPE_PACKAGE;
  1066. else if (type == BINARY_TYPE_COMPRESSED_PACKAGE)
  1067. fileType = BINARY_TYPE_COMPRESSED_PACKAGE;
  1068. else if (type == BINARY_TYPE_ANGLESCRIPT)
  1069. fileType = BINARY_TYPE_ANGLESCRIPT;
  1070. else if (type == BINARY_TYPE_MODEL)
  1071. fileType = BINARY_TYPE_MODEL;
  1072. else if (type == BINARY_TYPE_SHADER)
  1073. fileType = BINARY_TYPE_SHADER;
  1074. else if (type == BINARY_TYPE_ANIMATION)
  1075. fileType = BINARY_TYPE_ANIMATION;
  1076. else
  1077. return false;
  1078. return true;
  1079. }
  1080. bool GetXmlType(String path, StringHash &out fileType, bool useCache = false)
  1081. {
  1082. String extension = GetExtension(path);
  1083. if (extension == ".txt" || extension == ".json" || extension == ".icns" || extension == ".atlas")
  1084. return false;
  1085. String name;
  1086. if (useCache)
  1087. {
  1088. XMLFile@ xml = cache.GetResource("XMLFile", path);
  1089. if (xml is null)
  1090. return false;
  1091. name = xml.root.name;
  1092. }
  1093. else
  1094. {
  1095. File@ file = File();
  1096. if (!file.Open(path))
  1097. return false;
  1098. if (file.size == 0)
  1099. return false;
  1100. XMLFile@ xml = XMLFile();
  1101. if (xml.Load(file))
  1102. name = xml.root.name;
  1103. else
  1104. return false;
  1105. }
  1106. bool found = false;
  1107. if (!name.empty)
  1108. {
  1109. found = true;
  1110. StringHash type = StringHash(name);
  1111. if (type == XML_TYPE_SCENE)
  1112. fileType = XML_TYPE_SCENE;
  1113. else if (type == XML_TYPE_NODE)
  1114. fileType = XML_TYPE_NODE;
  1115. else if(type == XML_TYPE_MATERIAL)
  1116. fileType = XML_TYPE_MATERIAL;
  1117. else if(type == XML_TYPE_TECHNIQUE)
  1118. fileType = XML_TYPE_TECHNIQUE;
  1119. else if(type == XML_TYPE_PARTICLEEFFECT)
  1120. fileType = XML_TYPE_PARTICLEEFFECT;
  1121. else if(type == XML_TYPE_PARTICLEEMITTER)
  1122. fileType = XML_TYPE_PARTICLEEMITTER;
  1123. else if(type == XML_TYPE_TEXTURE)
  1124. fileType = XML_TYPE_TEXTURE;
  1125. else if(type == XML_TYPE_ELEMENT)
  1126. fileType = XML_TYPE_ELEMENT;
  1127. else if(type == XML_TYPE_ELEMENTS)
  1128. fileType = XML_TYPE_ELEMENTS;
  1129. else if (type == XML_TYPE_ANIMATION_SETTINGS)
  1130. fileType = XML_TYPE_ANIMATION_SETTINGS;
  1131. else if (type == XML_TYPE_RENDERPATH)
  1132. fileType = XML_TYPE_RENDERPATH;
  1133. else if (type == XML_TYPE_TEXTURE_ATLAS)
  1134. fileType = XML_TYPE_TEXTURE_ATLAS;
  1135. else if (type == XML_TYPE_2D_PARTICLE_EFFECT)
  1136. fileType = XML_TYPE_2D_PARTICLE_EFFECT;
  1137. else if (type == XML_TYPE_TEXTURE_3D)
  1138. fileType = XML_TYPE_TEXTURE_3D;
  1139. else if (type == XML_TYPE_CUBEMAP)
  1140. fileType = XML_TYPE_CUBEMAP;
  1141. else if (type == XML_TYPE_SPRITER_DATA)
  1142. fileType = XML_TYPE_SPRITER_DATA;
  1143. else
  1144. found = false;
  1145. }
  1146. return found;
  1147. }
  1148. String ResourceTypeName(int resourceType)
  1149. {
  1150. if (resourceType == RESOURCE_TYPE_UNUSABLE)
  1151. return "Unusable";
  1152. else if (resourceType == RESOURCE_TYPE_UNKNOWN)
  1153. return "Unknown";
  1154. else if (resourceType == RESOURCE_TYPE_NOTSET)
  1155. return "Uninitialized";
  1156. else if (resourceType == RESOURCE_TYPE_SCENE)
  1157. return "Scene";
  1158. else if (resourceType == RESOURCE_TYPE_SCRIPTFILE)
  1159. return "Script File";
  1160. else if (resourceType == RESOURCE_TYPE_MODEL)
  1161. return "Model";
  1162. else if (resourceType == RESOURCE_TYPE_MATERIAL)
  1163. return "Material";
  1164. else if (resourceType == RESOURCE_TYPE_ANIMATION)
  1165. return "Animation";
  1166. else if (resourceType == RESOURCE_TYPE_IMAGE)
  1167. return "Image";
  1168. else if (resourceType == RESOURCE_TYPE_SOUND)
  1169. return "Sound";
  1170. else if (resourceType == RESOURCE_TYPE_TEXTURE)
  1171. return "Texture";
  1172. else if (resourceType == RESOURCE_TYPE_FONT)
  1173. return "Font";
  1174. else if (resourceType == RESOURCE_TYPE_PREFAB)
  1175. return "Prefab";
  1176. else if (resourceType == RESOURCE_TYPE_TECHNIQUE)
  1177. return "Render Technique";
  1178. else if (resourceType == RESOURCE_TYPE_PARTICLEEFFECT)
  1179. return "Particle Effect";
  1180. else if (resourceType == RESOURCE_TYPE_PARTICLEEMITTER)
  1181. return "Particle Emitter";
  1182. else if (resourceType == RESOURCE_TYPE_UIELEMENT)
  1183. return "UI Element";
  1184. else if (resourceType == RESOURCE_TYPE_UIELEMENTS)
  1185. return "UI Elements";
  1186. else if (resourceType == RESOURCE_TYPE_ANIMATION_SETTINGS)
  1187. return "Animation Settings";
  1188. else if (resourceType == RESOURCE_TYPE_RENDERPATH)
  1189. return "Render Path";
  1190. else if (resourceType == RESOURCE_TYPE_TEXTURE_ATLAS)
  1191. return "Texture Atlas";
  1192. else if (resourceType == RESOURCE_TYPE_2D_PARTICLE_EFFECT)
  1193. return "2D Particle Effect";
  1194. else if (resourceType == RESOURCE_TYPE_TEXTURE_3D)
  1195. return "Texture 3D";
  1196. else if (resourceType == RESOURCE_TYPE_CUBEMAP)
  1197. return "Cubemap";
  1198. else if (resourceType == RESOURCE_TYPE_2D_ANIMATION_SET)
  1199. return "2D Animation Set";
  1200. else
  1201. return "";
  1202. }
  1203. class BrowserDir
  1204. {
  1205. uint id;
  1206. String resourceKey;
  1207. String name;
  1208. Array<BrowserDir@> children;
  1209. Array<BrowserFile@> files;
  1210. BrowserDir(String path_)
  1211. {
  1212. resourceKey = path_;
  1213. String parent = GetParentPath(path_);
  1214. name = path_;
  1215. name.Replace(parent, "");
  1216. id = browserDirIndex++;
  1217. }
  1218. int opCmp(BrowserDir@ b)
  1219. {
  1220. return name.opCmp(b.name);
  1221. }
  1222. BrowserFile@ AddFile(String name, uint resourceSourceIndex, uint sourceType)
  1223. {
  1224. String path = resourceKey + "/" + name;
  1225. BrowserFile@ file = BrowserFile(path, resourceSourceIndex, sourceType);
  1226. files.Push(file);
  1227. return file;
  1228. }
  1229. }
  1230. class BrowserFile
  1231. {
  1232. uint id;
  1233. uint resourceSourceIndex;
  1234. String resourceKey;
  1235. String name;
  1236. String fullname;
  1237. String extension;
  1238. StringHash fileType;
  1239. int resourceType = 0;
  1240. int sourceType = 0;
  1241. int sortScore = 0;
  1242. WeakHandle browserFileListRow;
  1243. BrowserFile(String path_, uint resourceSourceIndex_, int sourceType_)
  1244. {
  1245. sourceType = sourceType_;
  1246. resourceSourceIndex = resourceSourceIndex_;
  1247. resourceKey = path_;
  1248. name = GetFileName(path_);
  1249. extension = GetExtension(path_);
  1250. fullname = GetFileNameAndExtension(path_);
  1251. id = browserFileIndex++;
  1252. }
  1253. int opCmp(BrowserFile@ b)
  1254. {
  1255. if (browserSearchSortMode == 1)
  1256. return fullname.opCmp(b.fullname);
  1257. else
  1258. return sortScore - b.sortScore;
  1259. }
  1260. String GetResourceSource()
  1261. {
  1262. if (sourceType == BROWSER_FILE_SOURCE_RESOURCE_DIR)
  1263. return cache.resourceDirs[resourceSourceIndex];
  1264. else
  1265. return "Unknown";
  1266. }
  1267. String GetFullPath()
  1268. {
  1269. return String(cache.resourceDirs[resourceSourceIndex] + resourceKey);
  1270. }
  1271. String GetPath()
  1272. {
  1273. return resourceKey;
  1274. }
  1275. void DetermainResourceType()
  1276. {
  1277. resourceType = GetResourceType(GetFullPath(), fileType, false);
  1278. Text@ browserFileListRow_ = browserFileListRow.Get();
  1279. if (browserFileListRow_ !is null)
  1280. {
  1281. InitializeBrowserFileListRow(browserFileListRow_, this);
  1282. }
  1283. }
  1284. String ResourceTypeName()
  1285. {
  1286. return ::ResourceTypeName(resourceType);
  1287. }
  1288. void FileChanged()
  1289. {
  1290. if (!fileSystem.FileExists(GetFullPath()))
  1291. {
  1292. }
  1293. else
  1294. {
  1295. }
  1296. }
  1297. }
  1298. void CreateResourcePreview(String path, Node@ previewNode)
  1299. {
  1300. resourceBrowserPreview.autoUpdate = false;
  1301. int resourceType = GetResourceType(path);
  1302. if (resourceType > 0)
  1303. {
  1304. File file;
  1305. file.Open(path);
  1306. if (resourceType == RESOURCE_TYPE_MODEL)
  1307. {
  1308. Model@ model = Model();
  1309. if (model.Load(file))
  1310. {
  1311. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1312. staticModel.model = model;
  1313. return;
  1314. }
  1315. }
  1316. else if (resourceType == RESOURCE_TYPE_MATERIAL)
  1317. {
  1318. Material@ material = Material();
  1319. if (material.Load(file))
  1320. {
  1321. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1322. staticModel.model = cache.GetResource("Model", "Models/Sphere.mdl");
  1323. staticModel.material = material;
  1324. return;
  1325. }
  1326. }
  1327. else if (resourceType == RESOURCE_TYPE_IMAGE)
  1328. {
  1329. Image@ image = Image();
  1330. if (image.Load(file))
  1331. {
  1332. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1333. staticModel.model = cache.GetResource("Model", "Models/Editor/ImagePlane.mdl");
  1334. Material@ material = cache.GetResource("Material", "Materials/Editor/TexturedUnlit.xml");
  1335. Texture2D@ texture = Texture2D();
  1336. texture.SetData(@image, true);
  1337. material.textures[0] = texture;
  1338. staticModel.material = material;
  1339. return;
  1340. }
  1341. }
  1342. else if (resourceType == RESOURCE_TYPE_PREFAB)
  1343. {
  1344. if (GetExtension(path) == ".xml")
  1345. {
  1346. XMLFile xmlFile;
  1347. if(xmlFile.Load(file))
  1348. if(previewNode.LoadXML(xmlFile.root, true) && (previewNode.GetComponents("StaticModel", true).length > 0 || previewNode.GetComponents("AnimatedModel", true).length > 0))
  1349. {
  1350. return;
  1351. }
  1352. }
  1353. else if(previewNode.Load(file, true) && (previewNode.GetComponents("StaticModel", true).length > 0 || previewNode.GetComponents("AnimatedModel", true).length > 0))
  1354. return;
  1355. previewNode.RemoveAllChildren();
  1356. previewNode.RemoveAllComponents();
  1357. }
  1358. else if (resourceType == RESOURCE_TYPE_PARTICLEEFFECT)
  1359. {
  1360. ParticleEffect@ particleEffect = ParticleEffect();
  1361. if (particleEffect.Load(file))
  1362. {
  1363. ParticleEmitter@ particleEmitter = previewNode.CreateComponent("ParticleEmitter");
  1364. particleEmitter.effect = particleEffect;
  1365. particleEffect.activeTime = 0.0;
  1366. particleEmitter.Reset();
  1367. resourceBrowserPreview.autoUpdate = true;
  1368. return;
  1369. }
  1370. }
  1371. }
  1372. StaticModel@ staticModel = previewNode.CreateComponent("StaticModel");
  1373. staticModel.model = cache.GetResource("Model", "Models/Editor/ImagePlane.mdl");
  1374. Material@ material = cache.GetResource("Material", "Materials/Editor/TexturedUnlit.xml");
  1375. Texture2D@ texture = Texture2D();
  1376. Image@ noPreviewImage = cache.GetResource("Image", "Textures/Editor/NoPreviewAvailable.png");
  1377. texture.SetData(noPreviewImage, false);
  1378. material.textures[0] = texture;
  1379. staticModel.material = material;
  1380. return;
  1381. }
  1382. void RotateResourceBrowserPreview(StringHash eventType, VariantMap& eventData)
  1383. {
  1384. int elemX = eventData["ElementX"].GetInt();
  1385. int elemY = eventData["ElementY"].GetInt();
  1386. if (resourceBrowserPreview.height > 0 && resourceBrowserPreview.width > 0)
  1387. {
  1388. float yaw = ((resourceBrowserPreview.height / 2) - elemY) * (90.0 / resourceBrowserPreview.height);
  1389. float pitch = ((resourceBrowserPreview.width / 2) - elemX) * (90.0 / resourceBrowserPreview.width);
  1390. resourcePreviewNode.rotation = resourcePreviewNode.rotation.Slerp(Quaternion(yaw, pitch, 0), 0.1);
  1391. RefreshBrowserPreview();
  1392. }
  1393. }
  1394. void RefreshBrowserPreview()
  1395. {
  1396. resourceBrowserPreview.QueueUpdate();
  1397. }
  1398. class ResourceType
  1399. {
  1400. int id;
  1401. String name;
  1402. ResourceType(int id_, String name_)
  1403. {
  1404. id = id_;
  1405. name = name_;
  1406. }
  1407. int opCmp(ResourceType@ b)
  1408. {
  1409. return name.opCmp(b.name);
  1410. }
  1411. }