Browse Source

Feature: Editor now displays texture preview as icons in the Library window

BearishSun 7 years ago
parent
commit
1e251e1aa3

+ 73 - 3
Source/EditorCore/Library/BsProjectLibrary.cpp

@@ -16,13 +16,75 @@
 #include "Resources/BsResource.h"
 #include "BsEditorApplication.h"
 #include "Material/BsShader.h"
+#include "Image/BsTexture.h"
 #include "String/BsUnicode.h"
+#include "CoreThread/BsCoreThread.h"
 #include <regex>
 
 using namespace std::placeholders;
 
 namespace bs
 {
+	ProjectResourceIcons generatePreviewIcons(Resource& resource)
+	{
+		ProjectResourceIcons icons;
+
+		const UINT32 typeId = resource.getTypeId();
+		if(typeId == TID_Texture)
+		{
+			Texture& texture = static_cast<Texture&>(resource);
+
+			const TextureProperties& props = texture.getProperties();
+
+			const SPtr<PixelData> srcData = props.allocBuffer(0, 0);
+			AsyncOp readOp = texture.readData(srcData);
+			gCoreThread().submitAll(true);
+
+			// 256
+			const SPtr<PixelData> data256 = PixelData::create(256, 256, 1, props.getFormat());
+			PixelUtil::scale(*srcData, *data256);
+
+			// 192
+			const SPtr<PixelData> data192 = PixelData::create(192, 192, 1, props.getFormat());
+			PixelUtil::scale(*data256, *data192);
+
+			// 128
+			const SPtr<PixelData> data128 = PixelData::create(128, 128, 1, props.getFormat());
+			PixelUtil::scale(*data192, *data128);
+
+			// 96
+			const SPtr<PixelData> data96 = PixelData::create(96, 96, 1, props.getFormat());
+			PixelUtil::scale(*data128, *data96);
+
+			// 64
+			const SPtr<PixelData> data64 = PixelData::create(64, 64, 1, props.getFormat());
+			PixelUtil::scale(*data96, *data64);
+
+			// 48
+			const SPtr<PixelData> data48 = PixelData::create(48, 48, 1, props.getFormat());
+			PixelUtil::scale(*data64, *data48);
+
+			// 32
+			const SPtr<PixelData> data32 = PixelData::create(32, 32, 1, props.getFormat());
+			PixelUtil::scale(*data48, *data32);
+
+			// 16
+			const SPtr<PixelData> data16 = PixelData::create(16, 16, 1, props.getFormat());
+			PixelUtil::scale(*data32, *data16);
+
+			icons.icon16 = Texture::create(data16);
+			icons.icon32 = Texture::create(data32);
+			icons.icon48 = Texture::create(data48);
+			icons.icon64 = Texture::create(data64);
+			icons.icon96 = Texture::create(data96);
+			icons.icon128 = Texture::create(data128);
+			icons.icon192 = Texture::create(data192);
+			icons.icon256 = Texture::create(data256);
+		}
+
+		return icons;
+	}
+
 	const Path ProjectLibrary::RESOURCES_DIR = "Resources/";
 	const Path ProjectLibrary::INTERNAL_RESOURCES_DIR = PROJECT_INTERNAL_DIR + GAME_RESOURCES_FOLDER_NAME;
 	const char* ProjectLibrary::LIBRARY_ENTRIES_FILENAME = "ProjectLibrary.asset";
@@ -441,11 +503,14 @@ namespace bs
 					const UUID& UUID = entry.value.getUUID();
 					Path::stripInvalid(entry.name);
 
-					SPtr<ProjectResourceMeta> resMeta = ProjectResourceMeta::create(entry.name, UUID, typeId, subMeta);
+					const ProjectResourceIcons icons = generatePreviewIcons(*entry.value);
+
+					SPtr<ProjectResourceMeta> resMeta = ProjectResourceMeta::create(entry.name, UUID, typeId, icons, 
+						subMeta);
 					fileEntry->meta->add(resMeta);
 				}
 
-				if(importedResources.size() > 0)
+				if(!importedResources.empty())
 				{
 					HResource primary = importedResources[0].value;
 
@@ -476,6 +541,8 @@ namespace bs
 					{
 						Path::stripInvalid(resEntry.name);
 
+						const ProjectResourceIcons icons = generatePreviewIcons(*resEntry.value);
+
 						bool foundMeta = false;
 						for (auto iter = existingResourceMetas.begin(); iter != existingResourceMetas.end(); ++iter)
 						{
@@ -487,6 +554,8 @@ namespace bs
 								gResources().update(importedResource, resEntry.value);
 
 								importedResources.push_back({ resEntry.name, importedResource });
+
+								metaEntry->setPreviewIcons(icons);
 								fileEntry->meta->add(metaEntry);
 
 								existingResourceMetas.erase(iter);
@@ -504,7 +573,8 @@ namespace bs
 							UINT32 typeId = resEntry.value->getTypeId();
 							const UUID& UUID = importedResource.getUUID();
 
-							SPtr<ProjectResourceMeta> resMeta = ProjectResourceMeta::create(resEntry.name, UUID, typeId, subMeta);
+							SPtr<ProjectResourceMeta> resMeta = ProjectResourceMeta::create(resEntry.name, UUID, typeId, 
+								icons, subMeta);
 							fileEntry->meta->add(resMeta);
 						}
 					}

+ 2 - 2
Source/EditorCore/Library/BsProjectResourceMeta.cpp

@@ -7,7 +7,6 @@
 namespace bs
 {
 	ProjectResourceMeta::ProjectResourceMeta(const ConstructPrivately& dummy)
-		:mTypeId(0)
 	{
 
 	}
@@ -18,12 +17,13 @@ namespace bs
 	}
 
 	SPtr<ProjectResourceMeta> ProjectResourceMeta::create(const String& name, const UUID& uuid, UINT32 typeId,
-		const SPtr<ResourceMetaData>& resourceMetaData)
+		const ProjectResourceIcons& previewIcons, const SPtr<ResourceMetaData>& resourceMetaData)
 	{
 		SPtr<ProjectResourceMeta> meta = bs_shared_ptr_new<ProjectResourceMeta>(ConstructPrivately());
 		meta->mName = UTF8::toWide(name); // Using wide string internally to keep compatibility with older versions
 		meta->mUUID = uuid;
 		meta->mTypeId = typeId;
+		meta->mPreviewIcons = previewIcons;
 		meta->mResourceMeta = resourceMetaData;
 
 		return meta;

+ 23 - 2
Source/EditorCore/Library/BsProjectResourceMeta.h

@@ -11,6 +11,19 @@ namespace bs
 	 *  @{
 	 */
 
+	/** Different icon sizes for project resource preview icons. */
+	struct BS_SCRIPT_EXPORT(pl:true,ed:true) ProjectResourceIcons
+	{
+		HTexture icon16;
+		HTexture icon32;
+		HTexture icon48;
+		HTexture icon64;
+		HTexture icon96;
+		HTexture icon128; 
+		HTexture icon192;
+		HTexture icon256;
+	};
+
 	/**	Contains meta-data for a resource stored in the ProjectLibrary. */
 	class BS_ED_EXPORT ProjectResourceMeta : public IReflectable
 	{
@@ -26,11 +39,12 @@ namespace bs
 		 * @param[in]	name				Name of the resource, unique within the file containing the resource.
 		 * @param[in]	uuid				UUID of the resource.
 		 * @param[in]	typeId				RTTI type id of the resource.
+		 * @param[in]	previewIcons		A set of icons used for displaying a preview of the resource's contents.
 		 * @param[in]	resourceMetaData	Non-project library specific meta-data.
 		 * @return							New project library resource meta data instance.
 		 */
 		static SPtr<ProjectResourceMeta> create(const String& name, const UUID& uuid, UINT32 typeId, 
-			const SPtr<ResourceMetaData>& resourceMetaData);
+			const ProjectResourceIcons& previewIcons, const SPtr<ResourceMetaData>& resourceMetaData);
 
 		/** Returns the name of the resource, unique within the file containing the resource. */
 		String getUniqueName() const;
@@ -44,6 +58,12 @@ namespace bs
 		/**	Returns the RTTI type ID of the resource this object is referencing. */
 		UINT32 getTypeID() const { return mTypeId; }
 
+		/** @copydoc setPreviewIcons() */
+		const ProjectResourceIcons& getPreviewIcons() const { return mPreviewIcons; }
+
+		/* A set of icons used for displaying a preview of the resource's contents. */
+		void setPreviewIcons(const ProjectResourceIcons& icons) { mPreviewIcons = icons; }
+
 		/** 
 		 * Returns additional data attached to the resource meta by the user. This is non-specific data and can contain
 		 * anything the user requires. 
@@ -56,7 +76,8 @@ namespace bs
 		WString mName;
 		UUID mUUID;
 		SPtr<ResourceMetaData> mResourceMeta;
-		UINT32 mTypeId;
+		UINT32 mTypeId = 0;
+		ProjectResourceIcons mPreviewIcons;
 		SPtr<IReflectable> mUserData;
 
 		/************************************************************************/

+ 47 - 7
Source/EditorCore/RTTI/BsProjectResourceMetaRTTI.h

@@ -7,6 +7,8 @@
 #include "Library/BsProjectResourceMeta.h"
 #include "Resources/BsResourceMetaData.h"
 #include "Importer/BsImportOptions.h"
+#include "Resources/BsResources.h"
+#include "Image/BsTexture.h"
 
 namespace bs
 {
@@ -25,10 +27,52 @@ namespace bs
 			BS_RTTI_MEMBER_REFLPTR(mResourceMeta, 3)
 			BS_RTTI_MEMBER_REFLPTR(mUserData, 4)
 		BS_END_RTTI_MEMBERS
+
+		// We want to store textures directly in this object rather than referencing them externally, so we need to strip
+		// away resource handles before saving them, and restore afterwards
+#define GETTER_SETTER_ICON(icon)																						\
+		SPtr<Texture> get##icon(ProjectResourceMeta* obj)																\
+		{																												\
+			if(obj->mPreviewIcons.icon.isLoaded(false))																	\
+				return obj->mPreviewIcons.icon.getInternalPtr();														\
+																														\
+			return nullptr;																								\
+		}																												\
+																														\
+			void set##icon(ProjectResourceMeta* obj, SPtr<Texture> data)												\
+		{																												\
+			obj->mPreviewIcons.icon = static_resource_cast<Texture>(gResources()._createResourceHandle(data));			\
+		}																												\
+
+		GETTER_SETTER_ICON(icon16)
+		GETTER_SETTER_ICON(icon32)
+		GETTER_SETTER_ICON(icon48)
+		GETTER_SETTER_ICON(icon64)
+		GETTER_SETTER_ICON(icon96)
+		GETTER_SETTER_ICON(icon128)
+		GETTER_SETTER_ICON(icon192)
+		GETTER_SETTER_ICON(icon256)
+
 	public:
 		ProjectResourceMetaRTTI()
-			:mInitMembers(this)
-		{ }
+		{
+			addReflectablePtrField("mPreviewIcon16", 5, 
+				&ProjectResourceMetaRTTI::geticon16, &ProjectResourceMetaRTTI::seticon16, RTTI_Flag_SkipInReferenceSearch);
+			addReflectablePtrField("mPreviewIcon32", 6, 
+				&ProjectResourceMetaRTTI::geticon32, &ProjectResourceMetaRTTI::seticon32, RTTI_Flag_SkipInReferenceSearch);
+			addReflectablePtrField("mPreviewIcon48", 7, 
+				&ProjectResourceMetaRTTI::geticon48, &ProjectResourceMetaRTTI::seticon48, RTTI_Flag_SkipInReferenceSearch);
+			addReflectablePtrField("mPreviewIcon64", 8, 
+				&ProjectResourceMetaRTTI::geticon64, &ProjectResourceMetaRTTI::seticon64, RTTI_Flag_SkipInReferenceSearch);
+			addReflectablePtrField("mPreviewIcon96", 9, 
+				&ProjectResourceMetaRTTI::geticon96, &ProjectResourceMetaRTTI::seticon96, RTTI_Flag_SkipInReferenceSearch);
+			addReflectablePtrField("mPreviewIcon128", 10, 
+				&ProjectResourceMetaRTTI::geticon128, &ProjectResourceMetaRTTI::seticon128, RTTI_Flag_SkipInReferenceSearch);
+			addReflectablePtrField("mPreviewIcon192", 11, 
+				&ProjectResourceMetaRTTI::geticon192, &ProjectResourceMetaRTTI::seticon192, RTTI_Flag_SkipInReferenceSearch);
+			addReflectablePtrField("mPreviewIcon256", 12, 
+				&ProjectResourceMetaRTTI::geticon256, &ProjectResourceMetaRTTI::seticon256, RTTI_Flag_SkipInReferenceSearch);
+		}
 
 		const String& getRTTIName() override
 		{
@@ -58,10 +102,6 @@ namespace bs
 		BS_END_RTTI_MEMBERS
 
 	public:
-		ProjectFileMetaRTTI()
-			:mInitMembers(this)
-		{ }
-
 		const String& getRTTIName() override
 		{
 			static String name = "ProjectFileMeta";
@@ -81,4 +121,4 @@ namespace bs
 
 	/** @} */
 	/** @endcond */
-}
+}

+ 21 - 0
Source/Scripting/MBansheeEditor/Generated/ProjectResourceIcons.generated.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using BansheeEngine;
+
+namespace BansheeEditor
+{
+	/// <summary>Different icon sizes for project resource preview icons.</summary>
+	[StructLayout(LayoutKind.Sequential), SerializeObject]
+	public partial struct ProjectResourceIcons
+	{
+		public Texture icon16;
+		public Texture icon32;
+		public Texture icon48;
+		public Texture icon64;
+		public Texture icon96;
+		public Texture icon128;
+		public Texture icon192;
+		public Texture icon256;
+	}
+}

+ 15 - 0
Source/Scripting/MBansheeEditor/Windows/Library/LibraryGUIEntry.cs

@@ -456,6 +456,21 @@ namespace BansheeEditor
             else
             {
                 ResourceMeta meta = ProjectLibrary.GetMeta(path);
+                ProjectResourceIcons icons = meta.Icons;
+
+                Texture icon;
+                if (size <= 16)
+                    icon = icons.icon16;
+                else if (size <= 32)
+                    icon = icons.icon32;
+                else if (size <= 48)
+                    icon = icons.icon48;
+                else
+                    icon = icons.icon64;
+
+                if(icon != null)
+                    return new SpriteTexture(icon);
+
                 switch (meta.ResType)
                 {
                     case ResourceType.Font:

+ 12 - 3
Source/Scripting/MBansheeEditor/Windows/Library/ProjectLibrary.cs

@@ -575,9 +575,18 @@ namespace BansheeEditor
         public string SubresourceName { get { return Internal_GetSubresourceName(mCachedPtr); } }
 
         /// <summary>
-        /// Custom icon for the resource to display in the editor, if the resource has one.
+        /// Custom icons for the resource to display in the editor, if the resource has them.
         /// </summary>
-        public Texture Icon { get { return Internal_GetIcon(mCachedPtr); } }
+        public ProjectResourceIcons Icons
+        {
+            get
+            {
+                ProjectResourceIcons output;
+                Internal_GetPreviewIcons(mCachedPtr, out output);
+
+                return output;
+            }
+        }
 
         /// <summary>
         /// Type of the resource referenced by this entry.
@@ -601,7 +610,7 @@ namespace BansheeEditor
         private static extern string Internal_GetSubresourceName(IntPtr thisPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern Texture Internal_GetIcon(IntPtr thisPtr);
+        private static extern void Internal_GetPreviewIcons(IntPtr thisPtr, out ProjectResourceIcons icons);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern ResourceType Internal_GetResourceType(IntPtr thisPtr);

+ 153 - 0
Source/Scripting/SBansheeEditor/Generated/BsScriptProjectResourceIcons.generated.cpp

@@ -0,0 +1,153 @@
+#include "BsScriptProjectResourceIcons.generated.h"
+#include "BsMonoMethod.h"
+#include "BsMonoClass.h"
+#include "BsMonoUtil.h"
+#include "BsScriptResourceManager.h"
+#include "BsScriptTexture.generated.h"
+
+namespace bs
+{
+	ScriptProjectResourceIcons::ScriptProjectResourceIcons(MonoObject* managedInstance)
+		:ScriptObject(managedInstance)
+	{ }
+
+	void ScriptProjectResourceIcons::initRuntimeData()
+	{ }
+
+	MonoObject*ScriptProjectResourceIcons::box(const __ProjectResourceIconsInterop& value)
+	{
+		return MonoUtil::box(metaData.scriptClass->_getInternalClass(), (void*)&value);
+	}
+
+	__ProjectResourceIconsInterop ScriptProjectResourceIcons::unbox(MonoObject* value)
+	{
+		return *(__ProjectResourceIconsInterop*)MonoUtil::unbox(value);
+	}
+
+	ProjectResourceIcons ScriptProjectResourceIcons::fromInterop(const __ProjectResourceIconsInterop& value)
+	{
+		ProjectResourceIcons output;
+		ResourceHandle<Texture> tmpicon16;
+		ScriptTexture* scripticon16;
+		scripticon16 = ScriptTexture::toNative(value.icon16);
+		if(scripticon16 != nullptr)
+			tmpicon16 = scripticon16->getHandle();
+		output.icon16 = tmpicon16;
+		ResourceHandle<Texture> tmpicon32;
+		ScriptTexture* scripticon32;
+		scripticon32 = ScriptTexture::toNative(value.icon32);
+		if(scripticon32 != nullptr)
+			tmpicon32 = scripticon32->getHandle();
+		output.icon32 = tmpicon32;
+		ResourceHandle<Texture> tmpicon48;
+		ScriptTexture* scripticon48;
+		scripticon48 = ScriptTexture::toNative(value.icon48);
+		if(scripticon48 != nullptr)
+			tmpicon48 = scripticon48->getHandle();
+		output.icon48 = tmpicon48;
+		ResourceHandle<Texture> tmpicon64;
+		ScriptTexture* scripticon64;
+		scripticon64 = ScriptTexture::toNative(value.icon64);
+		if(scripticon64 != nullptr)
+			tmpicon64 = scripticon64->getHandle();
+		output.icon64 = tmpicon64;
+		ResourceHandle<Texture> tmpicon96;
+		ScriptTexture* scripticon96;
+		scripticon96 = ScriptTexture::toNative(value.icon96);
+		if(scripticon96 != nullptr)
+			tmpicon96 = scripticon96->getHandle();
+		output.icon96 = tmpicon96;
+		ResourceHandle<Texture> tmpicon128;
+		ScriptTexture* scripticon128;
+		scripticon128 = ScriptTexture::toNative(value.icon128);
+		if(scripticon128 != nullptr)
+			tmpicon128 = scripticon128->getHandle();
+		output.icon128 = tmpicon128;
+		ResourceHandle<Texture> tmpicon192;
+		ScriptTexture* scripticon192;
+		scripticon192 = ScriptTexture::toNative(value.icon192);
+		if(scripticon192 != nullptr)
+			tmpicon192 = scripticon192->getHandle();
+		output.icon192 = tmpicon192;
+		ResourceHandle<Texture> tmpicon256;
+		ScriptTexture* scripticon256;
+		scripticon256 = ScriptTexture::toNative(value.icon256);
+		if(scripticon256 != nullptr)
+			tmpicon256 = scripticon256->getHandle();
+		output.icon256 = tmpicon256;
+
+		return output;
+	}
+
+	__ProjectResourceIconsInterop ScriptProjectResourceIcons::toInterop(const ProjectResourceIcons& value)
+	{
+		__ProjectResourceIconsInterop output;
+		ScriptResourceBase* scripticon16;
+		scripticon16 = ScriptResourceManager::instance().getScriptResource(value.icon16, true);
+		MonoObject* tmpicon16;
+		if(scripticon16 != nullptr)
+			tmpicon16 = scripticon16->getManagedInstance();
+		else
+			tmpicon16 = nullptr;
+		output.icon16 = tmpicon16;
+		ScriptResourceBase* scripticon32;
+		scripticon32 = ScriptResourceManager::instance().getScriptResource(value.icon32, true);
+		MonoObject* tmpicon32;
+		if(scripticon32 != nullptr)
+			tmpicon32 = scripticon32->getManagedInstance();
+		else
+			tmpicon32 = nullptr;
+		output.icon32 = tmpicon32;
+		ScriptResourceBase* scripticon48;
+		scripticon48 = ScriptResourceManager::instance().getScriptResource(value.icon48, true);
+		MonoObject* tmpicon48;
+		if(scripticon48 != nullptr)
+			tmpicon48 = scripticon48->getManagedInstance();
+		else
+			tmpicon48 = nullptr;
+		output.icon48 = tmpicon48;
+		ScriptResourceBase* scripticon64;
+		scripticon64 = ScriptResourceManager::instance().getScriptResource(value.icon64, true);
+		MonoObject* tmpicon64;
+		if(scripticon64 != nullptr)
+			tmpicon64 = scripticon64->getManagedInstance();
+		else
+			tmpicon64 = nullptr;
+		output.icon64 = tmpicon64;
+		ScriptResourceBase* scripticon96;
+		scripticon96 = ScriptResourceManager::instance().getScriptResource(value.icon96, true);
+		MonoObject* tmpicon96;
+		if(scripticon96 != nullptr)
+			tmpicon96 = scripticon96->getManagedInstance();
+		else
+			tmpicon96 = nullptr;
+		output.icon96 = tmpicon96;
+		ScriptResourceBase* scripticon128;
+		scripticon128 = ScriptResourceManager::instance().getScriptResource(value.icon128, true);
+		MonoObject* tmpicon128;
+		if(scripticon128 != nullptr)
+			tmpicon128 = scripticon128->getManagedInstance();
+		else
+			tmpicon128 = nullptr;
+		output.icon128 = tmpicon128;
+		ScriptResourceBase* scripticon192;
+		scripticon192 = ScriptResourceManager::instance().getScriptResource(value.icon192, true);
+		MonoObject* tmpicon192;
+		if(scripticon192 != nullptr)
+			tmpicon192 = scripticon192->getManagedInstance();
+		else
+			tmpicon192 = nullptr;
+		output.icon192 = tmpicon192;
+		ScriptResourceBase* scripticon256;
+		scripticon256 = ScriptResourceManager::instance().getScriptResource(value.icon256, true);
+		MonoObject* tmpicon256;
+		if(scripticon256 != nullptr)
+			tmpicon256 = scripticon256->getManagedInstance();
+		else
+			tmpicon256 = nullptr;
+		output.icon256 = tmpicon256;
+
+		return output;
+	}
+
+}

+ 35 - 0
Source/Scripting/SBansheeEditor/Generated/BsScriptProjectResourceIcons.generated.h

@@ -0,0 +1,35 @@
+#pragma once
+
+#include "BsScriptEditorPrerequisites.h"
+#include "BsScriptObject.h"
+#include "../../../EditorCore/Library/BsProjectResourceMeta.h"
+
+namespace bs
+{
+	struct __ProjectResourceIconsInterop
+	{
+		MonoObject* icon16;
+		MonoObject* icon32;
+		MonoObject* icon48;
+		MonoObject* icon64;
+		MonoObject* icon96;
+		MonoObject* icon128;
+		MonoObject* icon192;
+		MonoObject* icon256;
+	};
+
+	class BS_SCR_BED_EXPORT ScriptProjectResourceIcons : public ScriptObject<ScriptProjectResourceIcons>
+	{
+	public:
+		SCRIPT_OBJ(EDITOR_ASSEMBLY, "BansheeEditor", "ProjectResourceIcons")
+
+		static MonoObject* box(const __ProjectResourceIconsInterop& value);
+		static __ProjectResourceIconsInterop unbox(MonoObject* value);
+		static ProjectResourceIcons fromInterop(const __ProjectResourceIconsInterop& value);
+		static __ProjectResourceIconsInterop toInterop(const ProjectResourceIcons& value);
+
+	private:
+		ScriptProjectResourceIcons(MonoObject* managedInstance);
+
+	};
+}

+ 5 - 4
Source/Scripting/SBansheeEditor/Wrappers/BsScriptProjectLibrary.cpp

@@ -16,6 +16,8 @@
 #include "Reflection/BsRTTIType.h"
 #include "BsManagedResourceMetaData.h"
 
+#include "BsScriptProjectResourceIcons.generated.h"
+
 using namespace std::placeholders;
 
 namespace bs
@@ -514,7 +516,7 @@ namespace bs
 	{
 		metaData.scriptClass->addInternalCall("Internal_GetUUID", (void*)&ScriptResourceMeta::internal_GetUUID);
 		metaData.scriptClass->addInternalCall("Internal_GetSubresourceName", (void*)&ScriptResourceMeta::internal_GetSubresourceName);
-		metaData.scriptClass->addInternalCall("Internal_GetIcon", (void*)&ScriptResourceMeta::internal_GetIcon);
+		metaData.scriptClass->addInternalCall("Internal_GetPreviewIcons", (void*)&ScriptResourceMeta::internal_GetPreviewIcons);
 		metaData.scriptClass->addInternalCall("Internal_GetResourceType", (void*)&ScriptResourceMeta::internal_GetResourceType);
 		metaData.scriptClass->addInternalCall("Internal_GetType", (void*)&ScriptResourceMeta::internal_GetType);
 		metaData.scriptClass->addInternalCall("Internal_GetEditorData", (void*)&ScriptResourceMeta::internal_GetEditorData);
@@ -530,10 +532,9 @@ namespace bs
 		return MonoUtil::stringToMono(thisPtr->mMeta->getUniqueName());
 	}
 
-	MonoObject* ScriptResourceMeta::internal_GetIcon(ScriptResourceMeta* thisPtr)
+	void ScriptResourceMeta::internal_GetPreviewIcons(ScriptResourceMeta* thisPtr, __ProjectResourceIconsInterop* output)
 	{
-		// TODO - Icons not supported yet
-		return nullptr;
+		*output = ScriptProjectResourceIcons::toInterop(thisPtr->mMeta->getPreviewIcons());
 	}
 
 	ScriptResourceType ScriptResourceMeta::internal_GetResourceType(ScriptResourceMeta* thisPtr)

+ 4 - 2
Source/Scripting/SBansheeEditor/Wrappers/BsScriptProjectLibrary.h

@@ -9,6 +9,8 @@
 
 namespace bs
 {
+	struct __ProjectResourceIconsInterop;
+
 	/** @addtogroup ScriptInteropEditor
 	 *  @{
 	 */
@@ -173,11 +175,11 @@ namespace bs
 		/************************************************************************/
 		static void internal_GetUUID(ScriptResourceMeta* thisPtr, UUID* uuid);
 		static MonoString* internal_GetSubresourceName(ScriptResourceMeta* thisPtr);
-		static MonoObject* internal_GetIcon(ScriptResourceMeta* thisPtr);
+		static void internal_GetPreviewIcons(ScriptResourceMeta* thisPtr, __ProjectResourceIconsInterop* output);
 		static ScriptResourceType internal_GetResourceType(ScriptResourceMeta* thisPtr);
 		static MonoReflectionType* internal_GetType(ScriptResourceMeta* thisPtr);
 		static MonoObject* internal_GetEditorData(ScriptResourceMeta* thisPtr);
 	};
 
 	/** @} */
-}
+}