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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user