diff --git a/ActorInteractionPlugin.uplugin b/ActorInteractionPlugin.uplugin index 93e3b46..77eb7b0 100644 --- a/ActorInteractionPlugin.uplugin +++ b/ActorInteractionPlugin.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, "Version": 1, - "VersionName": "3.0.1.0", + "VersionName": "3.0.1.1", "FriendlyName": "Actor Interaction Plugin", "Description": "Actor Interaction Plugin is an Open-source Mountea Framework components-based simple framework providing utilities for smart Actor Interaction with other Actors. Developed with Game Developers in mind to allow as easy as possible implementation while maintaining high scalability and diverse options to tweak everything.", "Category": "Mountea Framework", diff --git a/Resources/HelpIcon.png b/Resources/HelpIcon.png new file mode 100644 index 0000000..740189e Binary files /dev/null and b/Resources/HelpIcon.png differ diff --git a/Resources/Mountea_Logo.png b/Resources/Mountea_Logo.png new file mode 100644 index 0000000..885f2d9 Binary files /dev/null and b/Resources/Mountea_Logo.png differ diff --git a/Source/ActorInteractionPluginEditor/ActorInteractionPluginEditor.Build.cs b/Source/ActorInteractionPluginEditor/ActorInteractionPluginEditor.Build.cs index ef0d802..4e1e20e 100644 --- a/Source/ActorInteractionPluginEditor/ActorInteractionPluginEditor.Build.cs +++ b/Source/ActorInteractionPluginEditor/ActorInteractionPluginEditor.Build.cs @@ -46,7 +46,11 @@ public ActorInteractionPluginEditor(ReadOnlyTargetRules Target) : base(Target) "WebBrowser", "EditorStyle", - "DeveloperSettings" + "DeveloperSettings", + + "MainFrame", + "ToolMenus", + "InputCore" } ); diff --git a/Source/ActorInteractionPluginEditor/Private/ActorInteractionPluginEditor.cpp b/Source/ActorInteractionPluginEditor/Private/ActorInteractionPluginEditor.cpp index a4c28c2..58c928c 100644 --- a/Source/ActorInteractionPluginEditor/Private/ActorInteractionPluginEditor.cpp +++ b/Source/ActorInteractionPluginEditor/Private/ActorInteractionPluginEditor.cpp @@ -13,13 +13,20 @@ #include "AssetActions/InteractableComponentAssetActions.h" #include "AssetToolsModule.h" +#include "HelpButton/AIntPCommands.h" +#include "HelpButton/AIntPHelpStyle.h" #include "Kismet2/KismetEditorUtilities.h" #include "Popup/AIntPPopup.h" #include "Utilities/ActorInteractionEditorUtilities.h" +#include "ToolMenus.h" + +#include "Interfaces/IMainFrameModule.h" DEFINE_LOG_CATEGORY(ActorInteractionPluginEditor); +static const FName AIntPHelpTabName("MounteaFramework"); + #define LOCTEXT_NAMESPACE "FActorInteractionPluginEditor" void FActorInteractionPluginEditor::StartupModule() @@ -112,10 +119,28 @@ void FActorInteractionPluginEditor::StartupModule() // Register popup { - - AIntPPopup::Register(); } + + // Register Help Button + { + FAIntPHelpStyle::Initialize(); + FAIntPHelpStyle::ReloadTextures(); + + FAIntPCommands::Register(); + + PluginCommands = MakeShareable(new FUICommandList); + + PluginCommands->MapAction( + FAIntPCommands::Get().PluginAction, + FExecuteAction::CreateRaw(this, &FActorInteractionPluginEditor::PluginButtonClicked), + FCanExecuteAction()); + + IMainFrameModule& mainFrame = FModuleManager::Get().LoadModuleChecked("MainFrame"); + mainFrame.GetMainFrameCommandBindings()->Append(PluginCommands.ToSharedRef()); + + UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FActorInteractionPluginEditor::RegisterMenus)); + } } void FActorInteractionPluginEditor::ShutdownModule() @@ -135,6 +160,17 @@ void FActorInteractionPluginEditor::ShutdownModule() } } + // Help Button Cleanup + { + UToolMenus::UnRegisterStartupCallback(this); + + UToolMenus::UnregisterOwner(this); + + FAIntPHelpStyle::Shutdown(); + + FAIntPCommands::Unregister(); + } + UE_LOG(ActorInteractionPluginEditor, Warning, TEXT("ActorInteractionPluginEditor module has been unloaded")); } @@ -182,6 +218,56 @@ void FActorInteractionPluginEditor::HandleNewInteractableBlueprintCreated(UBluep Blueprint->BlueprintCategory = FString("Interaction"); } +void FActorInteractionPluginEditor::PluginButtonClicked() +{ + const FString URL = "https://discord.gg/2vXWEEN"; + + if (!URL.IsEmpty()) + { + FPlatformProcess::LaunchURL(*URL, nullptr, nullptr); + } +} + +void FActorInteractionPluginEditor::RegisterMenus() +{ + // Owner will be used for cleanup in call to UToolMenus::UnregisterOwner + FToolMenuOwnerScoped OwnerScoped(this); + + // Register in Window tab + { + UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Help"); + { + FToolMenuSection& Section = Menu->FindOrAddSection("MounteaFramework"); + Section.Label = FText::FromString(TEXT("Mountea Framework")); + + FToolMenuEntry Entry = Section.AddMenuEntryWithCommandList + ( + FAIntPCommands::Get().PluginAction, + PluginCommands, + NSLOCTEXT("MounteaSupport", "TabTitle", "Mountea Support"), + NSLOCTEXT("MounteaSupport", "TooltipText", "Opens Mountea Framework Support channel"), + FSlateIcon(FAIntPHelpStyle::GetStyleSetName(), "AIntPSupport.PluginAction.small") + ); + } + } + + // Register in Level Editor Toolbar + { + UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar.PlayToolBar"); + { + FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("MounteaFramework"); + { + Section.Label = FText::FromString(TEXT("Mountea Framework")); + + FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FAIntPCommands::Get().PluginAction)); + Entry.SetCommandList(PluginCommands); + + Entry.InsertPosition.Position = EToolMenuInsertType::First; + } + } + } +} + #undef LOCTEXT_NAMESPACE IMPLEMENT_MODULE(FActorInteractionPluginEditor, ActorInteractionPluginEditor); \ No newline at end of file diff --git a/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.cpp b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.cpp new file mode 100644 index 0000000..adbc69f --- /dev/null +++ b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.cpp @@ -0,0 +1,13 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AIntPCommands.h" + +#define LOCTEXT_NAMESPACE "ActorInteractionPluginEditorModule" + +void FAIntPCommands::RegisterCommands() +{ + UI_COMMAND(PluginAction, "Support", "Opens Mountea Framework Support channel", EUserInterfaceActionType::Button, FInputChord(EModifierKey::Control|EModifierKey::Shift|EModifierKey::Alt, EKeys::X)); +} + +#undef LOCTEXT_NAMESPACE \ No newline at end of file diff --git a/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.h b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.h new file mode 100644 index 0000000..115e5ed --- /dev/null +++ b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPCommands.h @@ -0,0 +1,24 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "AIntPHelpStyle.h" + + +class FAIntPCommands : public TCommands +{ +public: + + FAIntPCommands() + : TCommands(TEXT("AIntPSupport"), NSLOCTEXT("Contexts", "Support", "ActorInteraction Plugin"), NAME_None, FAIntPHelpStyle::GetStyleSetName()) + { + } + + // TCommands<> interface + virtual void RegisterCommands() override; + +public: + + TSharedPtr< FUICommandInfo > PluginAction; +}; diff --git a/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.cpp b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.cpp new file mode 100644 index 0000000..ae3e45c --- /dev/null +++ b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.cpp @@ -0,0 +1,72 @@ +// Fill out your copyright notice in the Description page of Project Settings. + + +#include "AIntPHelpStyle.h" +#include "Framework/Application/SlateApplication.h" +#include "Styling/SlateStyleRegistry.h" +#include "Slate/SlateGameResources.h" +#include "Interfaces/IPluginManager.h" + +TSharedPtr< FSlateStyleSet > FAIntPHelpStyle::StyleInstance = nullptr; + +void FAIntPHelpStyle::Initialize() +{ + if (!StyleInstance.IsValid()) + { + StyleInstance = Create(); + FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); + } +} + +void FAIntPHelpStyle::Shutdown() +{ + FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); + ensure(StyleInstance.IsUnique()); + StyleInstance.Reset(); +} + +void FAIntPHelpStyle::ReloadTextures() +{ + if (FSlateApplication::IsInitialized()) + { + FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); + } +} + +const ISlateStyle& FAIntPHelpStyle::Get() +{ + return *StyleInstance; +} + +FName FAIntPHelpStyle::GetStyleSetName() +{ + static FName StyleSetName(TEXT("AIntPHelpStyle")); + return StyleSetName; +} + +#define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) +#define TTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) +#define OTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) + +const FVector2D Icon16x16(16.0f, 16.0f); +const FVector2D Icon20x20(20.0f, 20.0f); +const FVector2D Icon40x40(40.0f, 40.0f); + +TSharedRef FAIntPHelpStyle::Create() +{ + TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("AIntPHelpStyle")); + Style->SetContentRoot(IPluginManager::Get().FindPlugin("ActorInteractionPlugin")->GetBaseDir() / TEXT("Resources")); + + Style->Set("AIntPSupport.PluginAction", new IMAGE_BRUSH(TEXT("Mountea_Logo"), Icon40x40)); + Style->Set("AIntPSupport.PluginAction.small", new IMAGE_BRUSH(TEXT("HelpIcon"), Icon20x20)); + + return Style; +} + +#undef IMAGE_BRUSH +#undef BOX_BRUSH +#undef BORDER_BRUSH +#undef TTF_FONT +#undef OTF_FONT \ No newline at end of file diff --git a/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.h b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.h new file mode 100644 index 0000000..17becd3 --- /dev/null +++ b/Source/ActorInteractionPluginEditor/Private/HelpButton/AIntPHelpStyle.h @@ -0,0 +1,31 @@ +// Fill out your copyright notice in the Description page of Project Settings. + +#pragma once + +#include "CoreMinimal.h" +#include "Styling/SlateStyle.h" + +class FAIntPHelpStyle +{ +public: + + static void Initialize(); + + static void Shutdown(); + + /** reloads textures used by slate renderer */ + static void ReloadTextures(); + + /** @return The Slate style set for the Actor Interaction Plugin Help Button */ + static const ISlateStyle& Get(); + + static FName GetStyleSetName(); + +private: + + static TSharedRef< class FSlateStyleSet > Create(); + +private: + + static TSharedPtr< class FSlateStyleSet > StyleInstance; +}; diff --git a/Source/ActorInteractionPluginEditor/Public/ActorInteractionPluginEditor.h b/Source/ActorInteractionPluginEditor/Public/ActorInteractionPluginEditor.h index 447430d..d9ec0a6 100644 --- a/Source/ActorInteractionPluginEditor/Public/ActorInteractionPluginEditor.h +++ b/Source/ActorInteractionPluginEditor/Public/ActorInteractionPluginEditor.h @@ -29,4 +29,17 @@ class FActorInteractionPluginEditor : public IModuleInterface TSharedPtr InteractorComponentAssetActions; TSharedPtr InteractableComponentAssetActions; + +public: + + /** This function will be bound to Command. */ + void PluginButtonClicked(); + +private: + + void RegisterMenus(); + +private: + + TSharedPtr PluginCommands; };