commit 35ea4db981ad3f54279ab8cb6ee7f1d274d1cf39 Author: Lucas Peter Date: Tue Sep 17 17:50:37 2024 +0200 Initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ef6465 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Intermediate +Binaries diff --git a/Resources/Icon128.png b/Resources/Icon128.png new file mode 100644 index 0000000..fc6eae4 Binary files /dev/null and b/Resources/Icon128.png differ diff --git a/Resources/PlaceholderButtonIcon.svg b/Resources/PlaceholderButtonIcon.svg new file mode 100644 index 0000000..7302447 --- /dev/null +++ b/Resources/PlaceholderButtonIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/SkyPortal.uplugin b/SkyPortal.uplugin new file mode 100644 index 0000000..03b10d3 --- /dev/null +++ b/SkyPortal.uplugin @@ -0,0 +1,25 @@ +{ + "FileVersion": 3, + "Version": 1, + "VersionName": "1.0", + "FriendlyName": "Skylanders Portal", + "Description": "Enable skylanders portal input.", + "Category": "Input Devices", + "CreatedBy": "lucastucious", + "CreatedByURL": "", + "DocsURL": "", + "MarketplaceURL": "", + "SupportURL": "", + "CanContainContent": false, + "IsBetaVersion": true, + "Installed": false, + "Modules": [ + { + "Name": "SkyPortal", + "Type": "Runtime", + "LoadingPhase": "Default" + } + ], + "IsExperimentalVersion": false, + "Sealed": true +} \ No newline at end of file diff --git a/Source/SkyPortal/Private/SkyPortal.cpp b/Source/SkyPortal/Private/SkyPortal.cpp new file mode 100644 index 0000000..4aadb3e --- /dev/null +++ b/Source/SkyPortal/Private/SkyPortal.cpp @@ -0,0 +1,109 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "SkyPortal.h" +#include "SkyPortalStyle.h" +#include "SkyPortalCommands.h" +#include "LevelEditor.h" +#include "Widgets/Docking/SDockTab.h" +#include "Widgets/Layout/SBox.h" +#include "Widgets/Text/STextBlock.h" +#include "ToolMenus.h" + +static const FName SkyPortalTabName("SkyPortal"); + +#define LOCTEXT_NAMESPACE "FSkyPortalModule" + +void FSkyPortalModule::StartupModule() +{ + // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module + + FSkyPortalStyle::Initialize(); + FSkyPortalStyle::ReloadTextures(); + + FSkyPortalCommands::Register(); + + PluginCommands = MakeShareable(new FUICommandList); + + PluginCommands->MapAction( + FSkyPortalCommands::Get().OpenPluginWindow, + FExecuteAction::CreateRaw(this, &FSkyPortalModule::PluginButtonClicked), + FCanExecuteAction()); + + UToolMenus::RegisterStartupCallback(FSimpleMulticastDelegate::FDelegate::CreateRaw(this, &FSkyPortalModule::RegisterMenus)); + + FGlobalTabmanager::Get()->RegisterNomadTabSpawner(SkyPortalTabName, FOnSpawnTab::CreateRaw(this, &FSkyPortalModule::OnSpawnPluginTab)) + .SetDisplayName(LOCTEXT("FSkyPortalTabTitle", "SkyPortal")) + .SetMenuType(ETabSpawnerMenuType::Hidden); +} + +void FSkyPortalModule::ShutdownModule() +{ + // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, + // we call this function before unloading the module. + + UToolMenus::UnRegisterStartupCallback(this); + + UToolMenus::UnregisterOwner(this); + + FSkyPortalStyle::Shutdown(); + + FSkyPortalCommands::Unregister(); + + FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(SkyPortalTabName); +} + +TSharedRef FSkyPortalModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs) +{ + FText WidgetText = FText::Format( + LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"), + FText::FromString(TEXT("FSkyPortalModule::OnSpawnPluginTab")), + FText::FromString(TEXT("SkyPortal.cpp")) + ); + + return SNew(SDockTab) + .TabRole(ETabRole::NomadTab) + [ + // Put your tab content here! + SNew(SBox) + .HAlign(HAlign_Center) + .VAlign(VAlign_Center) + [ + SNew(STextBlock) + .Text(WidgetText) + ] + ]; +} + +void FSkyPortalModule::PluginButtonClicked() +{ + FGlobalTabmanager::Get()->TryInvokeTab(SkyPortalTabName); +} + +void FSkyPortalModule::RegisterMenus() +{ + // Owner will be used for cleanup in call to UToolMenus::UnregisterOwner + FToolMenuOwnerScoped OwnerScoped(this); + + { + UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window"); + { + FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout"); + Section.AddMenuEntryWithCommandList(FSkyPortalCommands::Get().OpenPluginWindow, PluginCommands); + } + } + + { + UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar"); + { + FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("Settings"); + { + FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FSkyPortalCommands::Get().OpenPluginWindow)); + Entry.SetCommandList(PluginCommands); + } + } + } +} + +#undef LOCTEXT_NAMESPACE + +IMPLEMENT_MODULE(FSkyPortalModule, SkyPortal) diff --git a/Source/SkyPortal/Private/SkyPortalCommands.cpp b/Source/SkyPortal/Private/SkyPortalCommands.cpp new file mode 100644 index 0000000..e9fc874 --- /dev/null +++ b/Source/SkyPortal/Private/SkyPortalCommands.cpp @@ -0,0 +1,12 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "SkyPortalCommands.h" + +#define LOCTEXT_NAMESPACE "FSkyPortalModule" + +void FSkyPortalCommands::RegisterCommands() +{ + UI_COMMAND(OpenPluginWindow, "SkyPortal", "Bring up SkyPortal window", EUserInterfaceActionType::Button, FInputChord()); +} + +#undef LOCTEXT_NAMESPACE diff --git a/Source/SkyPortal/Private/SkyPortalStyle.cpp b/Source/SkyPortal/Private/SkyPortalStyle.cpp new file mode 100644 index 0000000..095d525 --- /dev/null +++ b/Source/SkyPortal/Private/SkyPortalStyle.cpp @@ -0,0 +1,60 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "SkyPortalStyle.h" +#include "Styling/SlateStyleRegistry.h" +#include "Framework/Application/SlateApplication.h" +#include "Slate/SlateGameResources.h" +#include "Interfaces/IPluginManager.h" +#include "Styling/SlateStyleMacros.h" + +#define RootToContentDir Style->RootToContentDir + +TSharedPtr FSkyPortalStyle::StyleInstance = nullptr; + +void FSkyPortalStyle::Initialize() +{ + if (!StyleInstance.IsValid()) + { + StyleInstance = Create(); + FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); + } +} + +void FSkyPortalStyle::Shutdown() +{ + FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); + ensure(StyleInstance.IsUnique()); + StyleInstance.Reset(); +} + +FName FSkyPortalStyle::GetStyleSetName() +{ + static FName StyleSetName(TEXT("SkyPortalStyle")); + return StyleSetName; +} + +const FVector2D Icon16x16(16.0f, 16.0f); +const FVector2D Icon20x20(20.0f, 20.0f); + +TSharedRef< FSlateStyleSet > FSkyPortalStyle::Create() +{ + TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("SkyPortalStyle")); + Style->SetContentRoot(IPluginManager::Get().FindPlugin("SkyPortal")->GetBaseDir() / TEXT("Resources")); + + Style->Set("SkyPortal.OpenPluginWindow", new IMAGE_BRUSH_SVG(TEXT("PlaceholderButtonIcon"), Icon20x20)); + + return Style; +} + +void FSkyPortalStyle::ReloadTextures() +{ + if (FSlateApplication::IsInitialized()) + { + FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); + } +} + +const ISlateStyle& FSkyPortalStyle::Get() +{ + return *StyleInstance; +} diff --git a/Source/SkyPortal/Public/SkyPortal.h b/Source/SkyPortal/Public/SkyPortal.h new file mode 100644 index 0000000..9405618 --- /dev/null +++ b/Source/SkyPortal/Public/SkyPortal.h @@ -0,0 +1,30 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Modules/ModuleManager.h" + +class FToolBarBuilder; +class FMenuBuilder; + +class FSkyPortalModule : public IModuleInterface +{ +public: + + /** IModuleInterface implementation */ + virtual void StartupModule() override; + virtual void ShutdownModule() override; + + /** This function will be bound to Command (by default it will bring up plugin window) */ + void PluginButtonClicked(); + +private: + + void RegisterMenus(); + + TSharedRef OnSpawnPluginTab(const class FSpawnTabArgs& SpawnTabArgs); + +private: + TSharedPtr PluginCommands; +}; diff --git a/Source/SkyPortal/Public/SkyPortalCommands.h b/Source/SkyPortal/Public/SkyPortalCommands.h new file mode 100644 index 0000000..4d054c3 --- /dev/null +++ b/Source/SkyPortal/Public/SkyPortalCommands.h @@ -0,0 +1,23 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Framework/Commands/Commands.h" +#include "SkyPortalStyle.h" + +class FSkyPortalCommands : public TCommands +{ +public: + + FSkyPortalCommands() + : TCommands(TEXT("SkyPortal"), NSLOCTEXT("Contexts", "SkyPortal", "SkyPortal Plugin"), NAME_None, FSkyPortalStyle::GetStyleSetName()) + { + } + + // TCommands<> interface + virtual void RegisterCommands() override; + +public: + TSharedPtr< FUICommandInfo > OpenPluginWindow; +}; diff --git a/Source/SkyPortal/Public/SkyPortalStyle.h b/Source/SkyPortal/Public/SkyPortalStyle.h new file mode 100644 index 0000000..52e3194 --- /dev/null +++ b/Source/SkyPortal/Public/SkyPortalStyle.h @@ -0,0 +1,32 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "CoreMinimal.h" +#include "Styling/SlateStyle.h" + +/** */ +class FSkyPortalStyle +{ +public: + + static void Initialize(); + + static void Shutdown(); + + /** reloads textures used by slate renderer */ + static void ReloadTextures(); + + /** @return The Slate style set for the Shooter game */ + static const ISlateStyle& Get(); + + static FName GetStyleSetName(); + +private: + + static TSharedRef< class FSlateStyleSet > Create(); + +private: + + static TSharedPtr< class FSlateStyleSet > StyleInstance; +}; diff --git a/Source/SkyPortal/SkyPortal.Build.cs b/Source/SkyPortal/SkyPortal.Build.cs new file mode 100644 index 0000000..84a0dce --- /dev/null +++ b/Source/SkyPortal/SkyPortal.Build.cs @@ -0,0 +1,58 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +using UnrealBuildTool; + +public class SkyPortal : ModuleRules +{ + public SkyPortal(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[] + { + "Projects", + "InputCore", + "EditorFramework", + "UnrealEd", + "ToolMenus", + "CoreUObject", + "Engine", + "Slate", + "SlateCore", + // ... add private dependencies that you statically link with here ... + } + ); + + + DynamicallyLoadedModuleNames.AddRange( + new string[] + { + // ... add any modules that your module loads dynamically here ... + } + ); + } +}