Files
UnrealEngineUWP/Engine/Source/Editor/ContentBrowser/Private/SPathPicker.cpp
Jamie Dale 55c3728d11 Added support for showing game and engine classes in the Content Browser
UE-7184 - Show game c++ classes and engine c++ classes in the content browser

The Content Browser now has extra entries for "Game C++ Classes" and "Engine C++ Classes" (with "Game" and "Engine" being renamed to "Game Content" and "Engine Content" respectively). These new folders serve as hosts for the list of available C++ modules, with each module internally mirroring the folder structure on disk.

For example:
- Game C++ Classes
    - ShooterGame
        - Classes
            - Bots
                - ShooterBot
                - ShooterAIController
                - [...]
            - [...]

The Content Browser allows you to navigate and search these classes like you can with assets, and provides convenient access to either edit an existing class, or create a new class (either within a selected folder, or derived from a selected class).

As the Content Browser only shows you known UClass types, any new classes need to be compiled into a loaded module before they will appear. This means that adding a new class will now automatically hot-reload your target module. Should you prefer to handle building and loading your modules manually, you can disable the automatic hot-reload via "Editor Settings" -> "Miscellaneous" -> "Hot Reload" -> "Automatically Hot Reload New Classes" (see UEditorUserSettings::bAutomaticallyHotReloadNewClasses).

[CL 2409386 by Jamie Dale in Main branch]
2015-01-16 15:39:47 -05:00

113 lines
3.7 KiB
C++

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "ContentBrowserPCH.h"
#define LOCTEXT_NAMESPACE "ContentBrowser"
void SPathPicker::Construct( const FArguments& InArgs )
{
for (auto DelegateIt = InArgs._PathPickerConfig.SetPathsDelegates.CreateConstIterator(); DelegateIt; ++DelegateIt)
{
if ((*DelegateIt) != NULL)
{
(**DelegateIt) = FSetPathPickerPathsDelegate::CreateSP(this, &SPathPicker::SetPaths);
}
}
ChildSlot
[
SAssignNew(PathViewPtr, SPathView)
.OnPathSelected(InArgs._PathPickerConfig.OnPathSelected)
.OnGetFolderContextMenu(this, &SPathPicker::GetFolderContextMenu)
.OnGetPathContextMenuExtender(InArgs._PathPickerConfig.OnGetPathContextMenuExtender)
.FocusSearchBoxWhenOpened(InArgs._PathPickerConfig.bFocusSearchBoxWhenOpened)
.AllowContextMenu(InArgs._PathPickerConfig.bAllowContextMenu)
.AllowClassesFolder(InArgs._PathPickerConfig.bAllowClassesFolder)
.SelectionMode(ESelectionMode::Single)
];
const FString& DefaultPath = InArgs._PathPickerConfig.DefaultPath;
if ( !DefaultPath.IsEmpty() )
{
if (InArgs._PathPickerConfig.bAddDefaultPath)
{
PathViewPtr->AddPath(DefaultPath, false);
}
TArray<FString> SelectedPaths;
SelectedPaths.Add(DefaultPath);
PathViewPtr->SetSelectedPaths(SelectedPaths);
}
}
TSharedPtr<SWidget> SPathPicker::GetFolderContextMenu(const TArray<FString>& SelectedPaths, FContentBrowserMenuExtender_SelectedPaths InMenuExtender, FOnCreateNewFolder InOnCreateNewFolder)
{
TSharedPtr<FExtender> Extender;
if (InMenuExtender.IsBound())
{
Extender = InMenuExtender.Execute(SelectedPaths);
}
const bool bInShouldCloseWindowAfterSelection = true;
const bool bCloseSelfOnly = true;
FMenuBuilder MenuBuilder(bInShouldCloseWindowAfterSelection, nullptr, Extender, bCloseSelfOnly);
// We can only create folders when we have a single path selected
const bool bCanCreateNewFolder = SelectedPaths.Num() == 1 && ContentBrowserUtils::IsValidPathToCreateNewFolder(SelectedPaths[0]);
FText NewFolderToolTip;
if(SelectedPaths.Num() == 1)
{
if(bCanCreateNewFolder)
{
NewFolderToolTip = FText::Format(LOCTEXT("NewFolderTooltip_CreateIn", "Create a new folder in {0}."), FText::FromString(SelectedPaths[0]));
}
else
{
NewFolderToolTip = FText::Format(LOCTEXT("NewFolderTooltip_InvalidPath", "Cannot create new folders in {0}."), FText::FromString(SelectedPaths[0]));
}
}
else
{
NewFolderToolTip = LOCTEXT("NewFolderTooltip_InvalidNumberOfPaths", "Can only create folders when there is a single path selected.");
}
// New Folder
MenuBuilder.AddMenuEntry(
LOCTEXT("NewFolder", "New Folder"),
NewFolderToolTip,
FSlateIcon(FEditorStyle::GetStyleSetName(), "ContentBrowser.NewFolderIcon"),
FUIAction(
FExecuteAction::CreateSP(this, &SPathPicker::CreateNewFolder, SelectedPaths.Num() > 0 ? SelectedPaths[0] : FString(), InOnCreateNewFolder),
FCanExecuteAction::CreateLambda( [bCanCreateNewFolder] { return bCanCreateNewFolder; } )
),
"NewFolder"
);
return MenuBuilder.MakeWidget();
}
void SPathPicker::CreateNewFolder(FString FolderPath, FOnCreateNewFolder InOnCreateNewFolder)
{
// Create a valid base name for this folder
FText DefaultFolderBaseName = LOCTEXT("DefaultFolderName", "NewFolder");
FText DefaultFolderName = DefaultFolderBaseName;
int32 NewFolderPostfix = 1;
while (ContentBrowserUtils::DoesFolderExist(FolderPath / DefaultFolderName.ToString()))
{
DefaultFolderName = FText::Format(LOCTEXT("DefaultFolderNamePattern", "{0}{1}"), DefaultFolderBaseName, FText::AsNumber(NewFolderPostfix));
NewFolderPostfix++;
}
InOnCreateNewFolder.ExecuteIfBound(DefaultFolderName.ToString(), FolderPath);
}
void SPathPicker::SetPaths(const TArray<FString>& NewPaths)
{
PathViewPtr->SetSelectedPaths(NewPaths);
}
#undef LOCTEXT_NAMESPACE