Lua向C#逻辑迁移 一期 #13

将整个插件代码上传
This commit is contained in:
2025-10-26 21:48:39 +08:00
parent 56994b3927
commit 648386cd73
785 changed files with 53683 additions and 2 deletions

View File

@ -0,0 +1,307 @@
#include "CSNewProjectWizard.h"
#include "CSManager.h"
#include "DesktopPlatformModule.h"
#include "IDesktopPlatform.h"
#include "Interfaces/IPluginManager.h"
#include "Runtime/AppFramework/Public/Widgets/Workflow/SWizard.h"
#include "UnrealSharpEditor/UnrealSharpEditor.h"
#include "UnrealSharpProcHelper/CSProcHelper.h"
#define LOCTEXT_NAMESPACE "UnrealSharpEditor"
void SCSNewProjectDialog::Construct(const FArguments& InArgs)
{
static FName ProjectDestination(TEXT("<ProjectDestination>"));
const FString ScriptPath = FPaths::ConvertRelativePathToFull(FCSProcHelper::GetScriptFolderDirectory());
FText ProjectDestinationName = FText::FromString(FString::Printf(TEXT("%s (This Project)"), FApp::GetProjectName()));
ProjectDestinations.Add(MakeShared<FCSProjectDestination>(ProjectDestination, ProjectDestinationName, FApp::GetProjectName(), ScriptPath, 0));
IPluginManager& PluginManager = IPluginManager::Get();
TArray<TSharedRef<IPlugin>> EnabledPlugins = PluginManager.GetEnabledPlugins();
for (const TSharedRef<IPlugin>& Plugin : EnabledPlugins)
{
const FString PluginFilePath = FPaths::ConvertRelativePathToFull(Plugin->GetBaseDir());
if (!FPaths::IsUnderDirectory(PluginFilePath, FCSProcHelper::GetPluginsDirectory()) || Plugin->GetName() == UE_PLUGIN_NAME)
{
continue;
}
FString ScriptDirectory = PluginFilePath / "Script";
ProjectDestinations.Add(MakeShared<FCSProjectDestination>(FName(Plugin->GetName()),
FText::FromString(Plugin->GetFriendlyName()), Plugin->GetName(), ScriptDirectory, ProjectDestinations.Num(), Plugin));
}
SelectedProjectDestinationIndex = 0;
ChildSlot
[
SNew(SWizard)
.ShowPageList(false)
.FinishButtonText(LOCTEXT("CreateProject", "Create C# Project"))
.FinishButtonToolTip(LOCTEXT("CreateProjectTooltip", "Create a new C# project with the specified settings"))
.OnCanceled(this, &SCSNewProjectDialog::OnCancel)
.OnFinished(this, &SCSNewProjectDialog::OnFinish)
.CanFinish(this, &SCSNewProjectDialog::CanFinish)
+ SWizard::Page()
[
SNew(SOverlay)
+ SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot()
.Padding(0, 0, 0, 10)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
.Padding(0, 0, 10, 0)
[
SNew(STextBlock)
.Text(LOCTEXT("NewProjectName", "Name"))
]
+ SHorizontalBox::Slot()
.FillWidth(1)
[
SAssignNew(NameTextBox, SEditableTextBox)
]
]
+ SVerticalBox::Slot()
.Padding(0, 0, 0, 10)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
.Padding(0, 0, 10, 0)
[
SNew(STextBlock)
.Text(LOCTEXT("NewProjectOwner", "Owner"))
]
+ SHorizontalBox::Slot()
.FillWidth(1)
[
SAssignNew(ProjectDestinationComboBox, SComboBox<TSharedRef<FCSProjectDestination>>)
.OptionsSource(&ProjectDestinations)
.InitiallySelectedItem(ProjectDestinations[SelectedProjectDestinationIndex])
.OnSelectionChanged(this, &SCSNewProjectDialog::OnProjectDestinationChanged)
.OnGenerateWidget_Static(&SCSNewProjectDialog::OnGenerateProjectDestinationWidget)
.Content()
[
SNew(STextBlock).Text_Lambda([this]
{
if (SelectedProjectDestinationIndex == INDEX_NONE)
{
return FText();
}
return ProjectDestinations[SelectedProjectDestinationIndex]->GetDisplayName();
})
]
]
]
+ SVerticalBox::Slot()
.Padding(0, 0, 0, 10)
[
SNew(SHorizontalBox)
+ SHorizontalBox::Slot()
.AutoWidth()
.VAlign(VAlign_Center)
.Padding(0, 0, 10, 0)
[
SNew(STextBlock)
.Text(LOCTEXT("NewProjectLocation", "Location"))
]
+ SHorizontalBox::Slot()
.FillWidth(1)
[
SAssignNew(PathTextBox, SEditableTextBox)
.Text(FText::FromString(ScriptPath))
]
+ SHorizontalBox::Slot()
.AutoWidth()
[
SNew(SButton)
.VAlign(VAlign_Center)
.ButtonStyle(FAppStyle::Get(), "SimpleButton")
.OnClicked(this, &SCSNewProjectDialog::OnExplorerButtonClicked)
[
SNew(SImage)
.Image(FAppStyle::Get().GetBrush("Icons.FolderClosed"))
.ColorAndOpacity(FSlateColor::UseForeground())
]
]
]
]
]
];
OnProjectDestinationChanged(ProjectDestinations[SelectedProjectDestinationIndex], ESelectInfo::Direct);
}
void SCSNewProjectDialog::OnProjectDestinationChanged(TSharedPtr<FCSProjectDestination> NewProjectDestination, ESelectInfo::Type)
{
if (NewProjectDestination == nullptr)
{
SelectedProjectDestinationIndex = INDEX_NONE;
return;
}
SelectedProjectDestinationIndex = NewProjectDestination->GetIndex();
PathTextBox->SetText(FText::FromString(NewProjectDestination->GetPath()));
FString ManagedName = TEXT("Managed") + NewProjectDestination->GetName();
NameTextBox->SetText(FText::FromString(ManagedName));
}
TSharedRef<SWidget> SCSNewProjectDialog::OnGenerateProjectDestinationWidget(TSharedRef<FCSProjectDestination> Destination)
{
return SNew(STextBlock)
.Text(Destination->GetDisplayName());
}
void SCSNewProjectDialog::OnPathSelected(const FString& NewPath)
{
if (NewPath.IsEmpty())
{
return;
}
PathTextBox->SetText(FText::FromString(NewPath));
}
FReply SCSNewProjectDialog::OnExplorerButtonClicked()
{
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
if (!DesktopPlatform)
{
return FReply::Handled();
}
TSharedPtr<SWindow> ParentWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
void* ParentWindowWindowHandle = ParentWindow.IsValid() ? ParentWindow->GetNativeWindow()->GetOSWindowHandle() : nullptr;
FString FolderName;
const FString Title = TEXT("Choose a location for new project");
if (DesktopPlatform->OpenDirectoryDialog(ParentWindowWindowHandle, Title,FCSProcHelper::GetScriptFolderDirectory(), FolderName))
{
if (!FolderName.EndsWith(TEXT("/")) )
{
FolderName += TEXT("/");
}
}
if (FolderName.IsEmpty())
{
return FReply::Handled();
}
PathTextBox->SetText(FText::FromString(FolderName));
return FReply::Handled();
}
void SCSNewProjectDialog::OnCancel()
{
CloseWindow();
}
void SCSNewProjectDialog::OnFinish()
{
TMap<FString, FString> Arguments;
FString ModuleName = NameTextBox->GetText().ToString();
FString ProjectParentFolder = PathTextBox->GetText().ToString();
FString ProjectRoot;
FString GlueProjectLocation;
FString GlueProjectName;
auto MakeGlueNameAndLocation = [](FString& GlueLocation, FString& GlueName, const FString& PluginName, const FString& CsProjFolder)
{
GlueName = FString::Printf(TEXT("%s.Glue"), *PluginName);
GlueLocation = FPaths::Combine(CsProjFolder, FString::Printf(TEXT("%s.csproj"), *GlueName));
};
if (ProjectDestinations.IsValidIndex(SelectedProjectDestinationIndex) && SelectedProjectDestinationIndex > 0)
{
const TSharedRef<FCSProjectDestination>& Destination = ProjectDestinations[SelectedProjectDestinationIndex];
const TSharedPtr<IPlugin>& Plugin = Destination->GetPlugin();
ProjectRoot = Plugin->GetBaseDir();
MakeGlueNameAndLocation(GlueProjectLocation, GlueProjectName, Plugin->GetName(), FPaths::Combine(Destination->GetPath(), GlueProjectName));
}
else
{
ProjectRoot = FPaths::ProjectDir();
MakeGlueNameAndLocation(GlueProjectLocation, GlueProjectName, FApp::GetProjectName(), FCSProcHelper::GetProjectGlueFolderPath());
}
if (!FPaths::FileExists(GlueProjectLocation))
{
Arguments.Add(TEXT("SkipIncludeProjectGlue"), TEXT("true"));
}
Arguments.Add(TEXT("GlueProjectName"), GlueProjectName);
FUnrealSharpEditorModule::Get().AddNewProject(ModuleName, ProjectParentFolder, ProjectRoot, Arguments);
CloseWindow();
}
bool SCSNewProjectDialog::CanFinish() const
{
FString Name = NameTextBox->GetText().ToString();
FString Path = PathTextBox->GetText().ToString();
FString Filename = Name + ".csproj";
FString AbsolutePath = Path / Filename;
// Path can't be empty, name can't be empty, and path must contain the script path
if (Path.IsEmpty() || Name.IsEmpty() || SelectedProjectDestinationIndex == INDEX_NONE
|| !Path.Contains(ProjectDestinations[SelectedProjectDestinationIndex]->GetPath()))
{
return false;
}
// Name can't contain spaces
if (Name.Contains(TEXT(" ")))
{
return false;
}
// Path must be a valid directory
if (FPaths::DirectoryExists(Path / Name))
{
return false;
}
// File must not already exist
IFileManager& FileManager = IFileManager::Get();
TArray<FString> AssemblyPaths;
FileManager.FindFiles(AssemblyPaths, *Path, TEXT(".csproj"));
for (const FString& AssemblyPath : AssemblyPaths)
{
FString ProjectName = FPaths::GetBaseFilename(AssemblyPath);
if (ProjectName == Name)
{
return false;
}
}
return true;
}
void SCSNewProjectDialog::CloseWindow()
{
TSharedPtr<SWindow> ContainingWindow = FSlateApplication::Get().FindWidgetWindow(AsShared());
if (ContainingWindow.IsValid())
{
ContainingWindow->RequestDestroyWindow();
}
}
#undef LOCTEXT_NAMESPACE

View File

@ -0,0 +1,63 @@
#pragma once
struct FCSProjectDestination
{
FCSProjectDestination(const FName InKey, FText InDisplayName, FString InName, FString InPath, const int32 Index, TSharedPtr<IPlugin> Plugin = nullptr) :
Key(InKey), DisplayName(MoveTemp(InDisplayName)), Name(MoveTemp(InName)), Path(MoveTemp(InPath)), Index(Index), Plugin(MoveTemp(Plugin)) {}
FName GetKey() const { return Key; }
const FText& GetDisplayName() const { return DisplayName; }
const FString& GetName() const { return Name; }
const FString& GetPath() const { return Path; }
int32 GetIndex() const { return Index; }
const TSharedPtr<IPlugin>& GetPlugin() const { return Plugin; }
private:
FName Key;
FText DisplayName;
FString Name;
FString Path;
int32 Index;
TSharedPtr<IPlugin> Plugin;
friend uint32 GetTypeHash(const FCSProjectDestination& ProjectDestination)
{
return GetTypeHash(ProjectDestination.Key);
}
};
class SCSNewProjectDialog : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SCSNewProjectDialog) {}
SLATE_END_ARGS()
void Construct(const FArguments& InArgs);
private:
void OnProjectDestinationChanged(TSharedPtr<FCSProjectDestination> NewProjectDestination, ESelectInfo::Type SelectInfo);
static TSharedRef<SWidget> OnGenerateProjectDestinationWidget(TSharedRef<FCSProjectDestination> Destination);
void OnPathSelected(const FString& NewPath);
FReply OnExplorerButtonClicked();
void OnCancel();
void OnFinish();
bool CanFinish() const;
void CloseWindow();
private:
TSharedPtr<SEditableTextBox> PathTextBox;
TSharedPtr<SComboBox<TSharedRef<FCSProjectDestination>>> ProjectDestinationComboBox;
TSharedPtr<SEditableTextBox> NameTextBox;
FString SuggestedProjectName;
TArray<TSharedRef<FCSProjectDestination>> ProjectDestinations;
int32 SelectedProjectDestinationIndex = INDEX_NONE;
};