EditorResourceBrowser.as 53 KB

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