FSlateStyleSet

Add custom Icons and Thumbnails for assets and specific classes

Updated over 2 years ago Edit Page Revisions

Its possible to assign custom Thumbnails and Icons for specific classes using FSlateStyleSet. Its relatively straight forward with only a few minor difficulties to overcome. In this example we will set it up all in a plugin.

Go ahead an initilize a new plugin then the first thing we need to add is the "Projects" module to the Build.cs file:

// Build.cs
PrivateDependencyModuleNames.AddRange(new string[]
{
    "Engine",
    "CoreUObject",
    "Slate",
    "SlateCore",
    "Projects" // <-- The Module for using FSlateStyleSet
});

Usually you would have 2 Modules in a plugin, the first module being plugin itself and a Editor module that then assigns the icons to the first modules classes by finding that module and getting the directory for the images.

Up next go to your plugin module Header and CPP and prepare it like below:

// HEADER
#pragma once

// Core Includes
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"

// Additional Includes
#include "Styling/SlateStyle.h"
#include "Styling/SlateStyleRegistry.h"

// Module
class FYourPluginModule : public IModuleInterface
{
public:

	// Style of the plugin
	TSharedPtr<FSlateStyleSet> Style;
	
	/** IModuleInterface implementation */
	virtual void StartupModule() override;
	virtual void ShutdownModule() override;
	/** IModuleInterface implementation */

private:

	// Was the Style implement correctly?
	bool StyleWasImplemented;

	// Applies the Icons for the plugins asset.
	bool SetupStyle();
};

Find all possible properties to assign images to, sofar I have been unable to find a good resource except engine source code to find stuiable properties.

// CPP
#include "FYourPluginModule.h"

#define LOCTEXT_NAMESPACE "FYourPluginModule"

/**
* This macro just makes it easier to write.
* Another way of doing this is like this for example:
* @note Style->Set("ClassIcon.SomeClass", new FSlateImageBrush(Style->RootToContentDir(TEXT("Resources/SomeImage.png")), FVector2D(16,16)));
*/
#define IMAGE_BRUSH(RelativePath, ...) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ )

void FYourPluginModule::StartupModule()
{
	StyleWasImplemented = SetupStyle();
	
	if (StyleWasImplemented)
	{
		FSlateStyleRegistry::RegisterSlateStyle(*Style);
	}
}

void FYourPluginModule::ShutdownModule()
{
	if (StyleWasImplemented)
	{
		FSlateStyleRegistry::UnRegisterSlateStyle(Style->GetStyleSetName());
	}
}

bool FYourPluginModule::SetupStyle()
{
	FString RootDirectory;
	
	/**
	* Instead of using the IPluginManager to get the content directory in a second editor module its often easier to
	* to just find the directory in the most obvious places and check if its present. This is by no way a good solution in my opinion but it works.
	*/
	auto ProjectPluginDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(FPaths::ProjectPluginsDir() + "YourPluginName"));
	auto EnginePluginDir = FPaths::ConvertRelativePathToFull(FPaths::Combine(FPaths::EnginePluginsDir() + TEXT("Marketplace/YourPluginName")));
	
	// Is it in the project plugin folder?
	if (FPaths::DirectoryExists(ProjectPluginDir))
	{
		RootDirectory = ProjectPluginDir;
	}
	// Is it in the engines marketplace folder ?
	else if(FPaths::DirectoryExists(EnginePluginDir))
	{
		RootDirectory = EnginePluginDir;
	}
	// No valid directory found, therefor no style will be registered or implemented
	else return false;
	
	// Create a new style set
	Style = MakeShareable(new FSlateStyleSet("YourPluginModuleStyle"));
		
	// Set the content Root directory of our plugin in order to access the images
	Style->SetContentRoot(RootDirectory);

	// Common sizes for icons and thumbnails
	const FVector2D Icon64x64(64.f, 64.f);
	const FVector2D Icon16x16(16.0f, 16.0f);

	// Set the Images of the properties to be equal of our new images, finding the property names can be a bit tricky however.
	Style->Set("ClassThumbnail.SomeClassName", new IMAGE_BRUSH(TEXT("Resources/Icon_64"), Icon64x64));
	Style->Set("ClassIcon.SomeClassName", new IMAGE_BRUSH(TEXT("Resources/Icon_16"), Icon16x16));

        // Continue to add styles below...

	return true;
}

#undef IMAGE_BRUSH
#undef LOCTEXT_NAMESPACE

IMPLEMENT_MODULE(FYourPluginModule, YourPlugin)

In the end you will just have to compile everything and when you lauch the editor create the asset of that class and it should appear with the Image, I recommend you try it out with a simple actor class first for practice.