Add Recent Blueprint Plugin
This commit is contained in:
parent
a5e8a8db13
commit
b62d7d75de
@ -68,6 +68,11 @@
|
|||||||
"Name": "AsyncLoadingScreen",
|
"Name": "AsyncLoadingScreen",
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/01f39767dc6b4290877f38365787cbf8"
|
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/01f39767dc6b4290877f38365787cbf8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "RecentBlueprintMenu",
|
||||||
|
"Enabled": true,
|
||||||
|
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/484f72297c144cf9b5c35fea3359500c"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"FileVersion": 3,
|
||||||
|
"Version": 101,
|
||||||
|
"VersionName": "1.01",
|
||||||
|
"FriendlyName": "Recent Blueprints Menu",
|
||||||
|
"Description": "A simple but time saving plugin that adds a \"Recent Blueprints\" menu to the blueprint editor. Giving you one click access to blueprints recently opened, and avoid having to constantly search for them.",
|
||||||
|
"Category": "Blueprint Editor",
|
||||||
|
"CreatedBy": "The Tool Shed",
|
||||||
|
"CreatedByURL": "https://unrealengine.com/marketplace/en-US/profile/The%20Tool%20Shed",
|
||||||
|
"DocsURL": "https://docs.google.com/presentation/d/10Gp1y-EPkBW8myvR-Lzd3viMDU5xovd0fSzJLOFm4NI/edit?usp=sharing",
|
||||||
|
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/product/484f72297c144cf9b5c35fea3359500c",
|
||||||
|
"SupportURL": "https://forums.unrealengine.com/t/support-recent-blueprints-menu/532808",
|
||||||
|
"EngineVersion": "5.1.0",
|
||||||
|
"CanContainContent": false,
|
||||||
|
"Installed": true,
|
||||||
|
"Modules": [
|
||||||
|
{
|
||||||
|
"Name": "RecentBlueprintMenu",
|
||||||
|
"Type": "Editor",
|
||||||
|
"LoadingPhase": "PostEngineInit",
|
||||||
|
"PlatformAllowList": [
|
||||||
|
"Win64",
|
||||||
|
"Mac",
|
||||||
|
"Linux"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
EndlessVendetta/Plugins/RecentBlueprintMenu/Resources/Icon128.png
(Stored with Git LFS)
Normal file
BIN
EndlessVendetta/Plugins/RecentBlueprintMenu/Resources/Icon128.png
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -0,0 +1,83 @@
|
|||||||
|
// Copyright 2022 The Tool Shed (Chris Garnier)
|
||||||
|
|
||||||
|
#include "RecentBlueprintMenu.h"
|
||||||
|
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 24
|
||||||
|
#include "Toolkits/AssetEditorManager.h"
|
||||||
|
#endif
|
||||||
|
#include "BlueprintEditor.h"
|
||||||
|
#include "RecentBlueprintMenuUtils.h"
|
||||||
|
#include "RecentBlueprintMenuSettings.h"
|
||||||
|
#include "EditorStyleSet.h"
|
||||||
|
#include "Framework/MultiBox/MultiBoxBuilder.h"
|
||||||
|
#include "Engine/LevelScriptBlueprint.h"
|
||||||
|
|
||||||
|
#define LOCTEXT_NAMESPACE "FRecentBlueprintMenuModule"
|
||||||
|
|
||||||
|
void FRecentBlueprintMenuModule::StartupModule()
|
||||||
|
{
|
||||||
|
///ADD NEW BLUEPRINT MENU
|
||||||
|
FBlueprintEditorModule& BlueprintEditorModule = FModuleManager::LoadModuleChecked<FBlueprintEditorModule>("Kismet");
|
||||||
|
if (const TSharedPtr<FExtensibilityManager> MenuExtender = BlueprintEditorModule.GetMenuExtensibilityManager())
|
||||||
|
{
|
||||||
|
BlueprintMenuExtender = MakeShareable(new FExtender);
|
||||||
|
BlueprintMenuExtender->AddMenuExtension("FileBlueprint",
|
||||||
|
EExtensionHook::Before,
|
||||||
|
nullptr,
|
||||||
|
FMenuExtensionDelegate::CreateRaw(this, &FRecentBlueprintMenuModule::OnBuildBlueprintMenu));
|
||||||
|
MenuExtender->AddExtender(BlueprintMenuExtender);
|
||||||
|
}
|
||||||
|
|
||||||
|
//SUBSCRIBE TO BLUEPRINT OPEN EVENTS
|
||||||
|
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 24
|
||||||
|
FAssetEditorManager::Get().OnAssetEditorRequestedOpen().AddLambda([](UObject* Asset)
|
||||||
|
#else
|
||||||
|
GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->OnAssetEditorRequestedOpen().AddLambda([](UObject* Asset)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (Asset && Asset->GetClass() == UBlueprint::StaticClass() && Asset->GetClass() != ULevelScriptBlueprint::StaticClass())
|
||||||
|
{
|
||||||
|
FRecentBlueprintMenuUtils::OnBlueprintOpened(Asset->GetPathName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRecentBlueprintMenuModule::ShutdownModule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRecentBlueprintMenuModule::OnBuildBlueprintMenu(FMenuBuilder& MenuBuilder)
|
||||||
|
{
|
||||||
|
MenuBuilder.BeginSection("RecentBlueprintMenuSection", FText::FromString("Quick Access"));
|
||||||
|
MenuBuilder.AddSubMenu(FText::FromString("Recent Blueprints..."),
|
||||||
|
FText::FromString("Select a Blueprint to edit from a list of recently opened ones."),
|
||||||
|
FNewMenuDelegate::CreateRaw(this, &FRecentBlueprintMenuModule::OnBuildRecentSubMenu),
|
||||||
|
false,
|
||||||
|
FSlateIcon(FEditorStyle::GetStyleSetName(),"GraphEditor.Timeline_16x"));
|
||||||
|
MenuBuilder.EndSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRecentBlueprintMenuModule::OnBuildRecentSubMenu(FMenuBuilder& MenuBuilder)
|
||||||
|
{
|
||||||
|
//purge first to ensure we have a list with no bad assets
|
||||||
|
FRecentBlueprintMenuUtils::PurgeList();
|
||||||
|
|
||||||
|
TArray<FString> RecentList = GetDefault<URecentBlueprintMenuSettings>()->RecentBlueprints;
|
||||||
|
for (FString Entry : RecentList)
|
||||||
|
{
|
||||||
|
MenuBuilder.AddMenuEntry(FText::FromString(FPackageName::ObjectPathToObjectName(Entry)),
|
||||||
|
FText::FromString(FPackageName::ObjectPathToPackageName(Entry)),
|
||||||
|
FSlateIcon(),
|
||||||
|
FUIAction(FExecuteAction::CreateLambda([Entry]()
|
||||||
|
{
|
||||||
|
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 24
|
||||||
|
FAssetEditorManager::Get().OpenEditorForAsset(Entry);
|
||||||
|
#else
|
||||||
|
GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->OpenEditorForAsset(Entry);
|
||||||
|
#endif
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef LOCTEXT_NAMESPACE
|
||||||
|
|
||||||
|
IMPLEMENT_MODULE(FRecentBlueprintMenuModule, RecentBlueprintMenu)
|
@ -0,0 +1,57 @@
|
|||||||
|
// Copyright 2022 The Tool Shed (Chris Garnier)
|
||||||
|
|
||||||
|
|
||||||
|
#include "RecentBlueprintMenuUtils.h"
|
||||||
|
#include "RecentBlueprintMenuSettings.h"
|
||||||
|
|
||||||
|
void FRecentBlueprintMenuUtils::OnBlueprintOpened(FString BlueprintPath)
|
||||||
|
{
|
||||||
|
|
||||||
|
TArray<FString>& RecentList = GetMutableDefault<URecentBlueprintMenuSettings>()->RecentBlueprints;
|
||||||
|
const int32 Index = RecentList.Find(BlueprintPath);
|
||||||
|
if (Index != INDEX_NONE) //If it's already in the list we just need to move it to the top
|
||||||
|
{
|
||||||
|
if (Index == 0)
|
||||||
|
{
|
||||||
|
return; //already first
|
||||||
|
}
|
||||||
|
RecentList.RemoveAt(Index); //removes so we can re-add at the end
|
||||||
|
}
|
||||||
|
RecentList.EmplaceAt(0, BlueprintPath);
|
||||||
|
|
||||||
|
//Now that we've added, trim entries
|
||||||
|
const uint8 MaxBP = GetDefault<URecentBlueprintMenuSettings>()->MaxRecentBP;
|
||||||
|
if (RecentList.Num() > MaxBP)
|
||||||
|
{
|
||||||
|
TArray<FString> TrimmedList;
|
||||||
|
for (int i=0; i < RecentList.Num(); i++)
|
||||||
|
{
|
||||||
|
if (i < MaxBP)
|
||||||
|
{
|
||||||
|
TrimmedList.Add(RecentList[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RecentList = TrimmedList;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetMutableDefault<URecentBlueprintMenuSettings>()->SaveConfig();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void FRecentBlueprintMenuUtils::PurgeList()
|
||||||
|
{
|
||||||
|
TArray<FString>& List = GetMutableDefault<URecentBlueprintMenuSettings>()->RecentBlueprints;
|
||||||
|
|
||||||
|
TArray<FString> NewList;
|
||||||
|
|
||||||
|
for (int32 i = 0; i < List.Num(); i++)
|
||||||
|
{
|
||||||
|
if (FPackageName::DoesPackageExist(List[i]))
|
||||||
|
{
|
||||||
|
NewList.Add(List[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List = NewList;
|
||||||
|
GetMutableDefault<URecentBlueprintMenuSettings>()->SaveConfig();
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2022 The Tool Shed (Chris Garnier)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "Modules/ModuleManager.h"
|
||||||
|
|
||||||
|
class FMenuBuilder;
|
||||||
|
class FExtender;
|
||||||
|
|
||||||
|
class FRecentBlueprintMenuModule : public IModuleInterface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/** IModuleInterface implementation */
|
||||||
|
virtual void StartupModule() override;
|
||||||
|
virtual void ShutdownModule() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
//Delegate to generate new menu in BP
|
||||||
|
void OnBuildBlueprintMenu(FMenuBuilder&);
|
||||||
|
|
||||||
|
//Delegate to generate new menu in BP
|
||||||
|
void OnBuildRecentSubMenu(FMenuBuilder&);
|
||||||
|
|
||||||
|
//Pointer to the extender used for the new custom blueprint menu
|
||||||
|
TSharedPtr<FExtender> BlueprintMenuExtender;
|
||||||
|
};
|
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2022 The Tool Shed (Chris Garnier)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "UObject/Object.h"
|
||||||
|
#include "RecentBlueprintMenuSettings.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings class for RecentBlueprintMenu to save recent BPs and other info
|
||||||
|
*/
|
||||||
|
UCLASS(config=EditorPerProjectUserSettings)
|
||||||
|
class RECENTBLUEPRINTMENU_API URecentBlueprintMenuSettings : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
//List of blueprints that were recently open to show in the Recent menu
|
||||||
|
UPROPERTY(Config)
|
||||||
|
TArray<FString> RecentBlueprints;
|
||||||
|
|
||||||
|
//How many Blueprints to remember max
|
||||||
|
UPROPERTY(Config) //not presented in a menu but users can modify in ini
|
||||||
|
uint8 MaxRecentBP = 15;
|
||||||
|
};
|
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2022 The Tool Shed (Chris Garnier)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RecentBlueprintMenu class containing functions to use by the menus
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
class RECENTBLUEPRINTMENU_API FRecentBlueprintMenuUtils
|
||||||
|
{
|
||||||
|
friend class FRecentBlueprintMenuModule; //TODO: Only friend the necessary classes
|
||||||
|
|
||||||
|
private:
|
||||||
|
//Called when a blueprint opens, so it can get saved to the recent list
|
||||||
|
static void OnBlueprintOpened(FString BlueprintPath);
|
||||||
|
|
||||||
|
//Remove files that do not exist anymore
|
||||||
|
static void PurgeList();
|
||||||
|
|
||||||
|
};
|
@ -0,0 +1,55 @@
|
|||||||
|
// Copyright 2022 The Tool Shed (Chris Garnier)
|
||||||
|
|
||||||
|
using UnrealBuildTool;
|
||||||
|
|
||||||
|
public class RecentBlueprintMenu : ModuleRules
|
||||||
|
{
|
||||||
|
public RecentBlueprintMenu(ReadOnlyTargetRules Target) : base(Target)
|
||||||
|
{
|
||||||
|
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
|
PublicIncludePaths.AddRange(
|
||||||
|
new string[] {
|
||||||
|
// ... add public include paths required here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PrivateIncludePaths.AddRange(
|
||||||
|
new string[] {
|
||||||
|
// ... add other private include paths required here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PublicDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"Core",
|
||||||
|
// ... add other public dependencies that you statically link with here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
PrivateDependencyModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
"CoreUObject",
|
||||||
|
"Engine",
|
||||||
|
"Slate",
|
||||||
|
"SlateCore",
|
||||||
|
"UnrealEd",
|
||||||
|
"EditorStyle"
|
||||||
|
// ... add private dependencies that you statically link with here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
DynamicallyLoadedModuleNames.AddRange(
|
||||||
|
new string[]
|
||||||
|
{
|
||||||
|
// ... add any modules that your module loads dynamically here ...
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user