TSharedRef< SWidget > FLevelEditorToolBar::GenerateMatineeMenuContent( TSharedRef<FUICommandList> InCommandList, TWeakPtr<SLevelEditor> LevelEditorWeakPtr ) { #define LOCTEXT_NAMESPACE "LevelToolBarMatineeMenu" const bool bShouldCloseWindowAfterMenuSelection = true; FMenuBuilder MenuBuilder( bShouldCloseWindowAfterMenuSelection, InCommandList ); // We can't build a list of Matinees while the current World is a PIE world. FSceneOutlinerInitializationOptions InitOptions; { InitOptions.Mode = ESceneOutlinerMode::ActorPicker; // We hide the header row to keep the UI compact. // @todo: Might be useful to have this sometimes, actually. Ideally the user could summon it. InitOptions.bShowHeaderRow = false; // Only display Matinee actors InitOptions.ActorFilters = MakeShareable( new TFilterCollection< const AActor* const >() ); struct Local { static bool IsMatineeActor( const AActor* const Actor ) { return Actor->IsA( AMatineeActor::StaticClass() ); } }; InitOptions.ActorFilters->Add( MakeShareable( new TDelegateFilter< const AActor* const >( TDelegateFilter< const AActor* const >::FPredicate::CreateStatic( &Local::IsMatineeActor ) ) ) ); } // actor selector to allow the user to choose a Matinee actor FSceneOutlinerModule& SceneOutlinerModule = FModuleManager::LoadModuleChecked<FSceneOutlinerModule>( "SceneOutliner" ); TSharedRef< SWidget > MiniSceneOutliner = SNew( SVerticalBox ) +SVerticalBox::Slot() .AutoHeight() .MaxHeight(400.0f) [ SceneOutlinerModule.CreateSceneOutliner( InitOptions, FOnContextMenuOpening(), //no context menu allowed here FOnActorPicked::CreateStatic( &FLevelEditorToolBar::OnMatineeActorPicked ) ) ]; // Give the scene outliner a border and background const FSlateBrush* BackgroundBrush = FEditorStyle::GetBrush( "Menu.Background" ); TSharedRef< SBorder > RootBorder = SNew( SBorder ) .Padding(3) .BorderImage( BackgroundBrush ) .ForegroundColor( FEditorStyle::GetSlateColor("DefaultForeground") ) // Assign the box panel as the child [ SNew( SVerticalBox ) +SVerticalBox::Slot() .AutoHeight() .Padding( 5 ) .HAlign( HAlign_Center ) [ SNew( STextBlock ) .Text( LOCTEXT( "SelectMatineeActorToEdit", "Select a Matinee actor" ) ) ] +SVerticalBox::Slot() .AutoHeight() .Padding( 2 ) [ MiniSceneOutliner ] ] ; MenuBuilder.BeginSection("LevelEditorNewMatinee", LOCTEXT("MatineeMenuCombo_NewHeading", "New")); { MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().AddMatinee ); } MenuBuilder.EndSection(); bool bHasAnyMatineeActors = false; TActorIterator<AMatineeActor> MatineeIt( LevelEditorWeakPtr.Pin()->GetWorld() ); bHasAnyMatineeActors = MatineeIt; //Add a heading to separate the existing matinees from the 'Add New Matinee Actor' button MenuBuilder.BeginSection("LevelEditorExistingMatinee", LOCTEXT( "MatineeMenuCombo_ExistingHeading", "Edit Existing Matinee" ) ); { if( bHasAnyMatineeActors ) { MenuBuilder.AddWidget(MiniSceneOutliner, FText::GetEmpty(), false); } } MenuBuilder.EndSection(); #undef LOCTEXT_NAMESPACE return MenuBuilder.MakeWidget(); }
FText FLevelEditorToolBar::GetOpenGameModeBlueprintLabel(TWeakPtr< SLevelEditor > InLevelEditor) { #define LOCTEXT_NAMESPACE "LevelToolBarViewMenu" if(IsValidGameModeBlueprint(InLevelEditor)) { return FText::Format( LOCTEXT("GameModeEditBlueprint", "GameMode: Edit {GameModeName}"), FText::FromString(InLevelEditor.Pin()->GetWorld()->GetWorldSettings()->DefaultGameMode->ClassGeneratedBy->GetName())); } return LOCTEXT("GameModeCreateBlueprint", "GameMode: Create..."); #undef LOCTEXT_NAMESPACE }
bool FLevelEditorToolBar::IsValidGameModeBlueprint(TWeakPtr< SLevelEditor > InLevelEditor) { AWorldSettings* WorldSettings = InLevelEditor.Pin()->GetWorld()->GetWorldSettings(); return WorldSettings->DefaultGameMode && WorldSettings->DefaultGameMode->ClassGeneratedBy; }
TSharedRef< SWidget > FLevelEditorToolBar::GenerateOpenBlueprintMenuContent( TSharedRef<FUICommandList> InCommandList, TWeakPtr< SLevelEditor > InLevelEditor ) { #define LOCTEXT_NAMESPACE "LevelToolBarViewMenu" struct FBlueprintMenus { /** Generates a sub-level Blueprints sub-menu */ static void MakeSubLevelsMenu(FMenuBuilder& InMenuBuilder, TWeakPtr< SLevelEditor > InLvlEditor) { FSlateIcon EditBP(FEditorStyle::Get().GetStyleSetName(), TEXT("LevelEditor.OpenLevelBlueprint")); InMenuBuilder.BeginSection(NAME_None, LOCTEXT("SubLevelsHeading", "Sub-Level Blueprints")); { UWorld* World = InLvlEditor.Pin()->GetWorld(); for (int32 iLevel = 0; iLevel < World->GetNumLevels(); iLevel++) { ULevel* Level = World->GetLevel(iLevel); if (Level != NULL && Level->GetOutermost() != NULL) { if (!Level->IsPersistentLevel()) { FUIAction UIAction ( FExecuteAction::CreateStatic(&FLevelEditorToolBar::OnOpenSubLevelBlueprint, Level) ); FText DisplayName = FText::Format(LOCTEXT("SubLevelBlueprintItem", "Edit {LevelName}"), FText::FromString(FPaths::GetCleanFilename(Level->GetOutermost()->GetName()))); InMenuBuilder.AddMenuEntry(DisplayName, FText::GetEmpty(), EditBP, UIAction); } } } } InMenuBuilder.EndSection(); } /** Handle BP being selected from popup picker */ static void OnBPSelected(const class FAssetData& AssetData) { UBlueprint* SelectedBP = Cast<UBlueprint>(AssetData.GetAsset()); if(SelectedBP) { FAssetEditorManager::Get().OpenEditorForAsset(SelectedBP); } } /** Generates 'eopn blueprint' sub-menu */ static void MakeOpenClassBPMenu(FMenuBuilder& InMenuBuilder) { FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser")); // Configure filter for asset picker FAssetPickerConfig Config; Config.Filter.ClassNames.Add(UBlueprint::StaticClass()->GetFName()); Config.InitialAssetViewType = EAssetViewType::List; Config.ThumbnailScale = 0; // make thumbnails as small as possible Config.OnAssetSelected = FOnAssetSelected::CreateStatic(&FBlueprintMenus::OnBPSelected); Config.bAllowDragging = false; // Don't show stuff in Engine Config.Filter.PackagePaths.Add("/Game"); Config.Filter.bRecursivePaths = true; TSharedRef<SWidget> Widget = SNew(SBox) .WidthOverride(300.f) .HeightOverride(300.f) [ ContentBrowserModule.Get().CreateAssetPicker(Config) ]; InMenuBuilder.BeginSection(NAME_None, LOCTEXT("BrowseHeader", "Browse")); { InMenuBuilder.AddWidget(Widget, FText::GetEmpty()); } InMenuBuilder.EndSection(); } }; const bool bShouldCloseWindowAfterMenuSelection = true; FMenuBuilder MenuBuilder( bShouldCloseWindowAfterMenuSelection, InCommandList ); MenuBuilder.BeginSection(NAME_None, LOCTEXT("LevelScriptBlueprints", "Level Blueprints")); { MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenLevelBlueprint ); // If there are any sub-levels, display the sub-menu. A single level means there is only the persistent level UWorld* World = InLevelEditor.Pin()->GetWorld(); if(World->GetNumLevels() > 1) { MenuBuilder.AddSubMenu( LOCTEXT( "SubLevelsSubMenu", "Sub-Levels" ), LOCTEXT( "SubLevelsSubMenu_ToolTip", "Shows available sub-level Blueprints that can be edited." ), FNewMenuDelegate::CreateStatic( &FBlueprintMenus::MakeSubLevelsMenu, InLevelEditor ), FUIAction(), NAME_None, EUserInterfaceActionType::Button, false, FSlateIcon(FEditorStyle::Get().GetStyleSetName(), TEXT("LevelEditor.OpenLevelBlueprint")) ); } } MenuBuilder.EndSection(); MenuBuilder.BeginSection(NAME_None, LOCTEXT("GameBlueprints", "Game Blueprints")); { FSlateIcon EditBPIcon(FEditorStyle::Get().GetStyleSetName(), TEXT("PropertyWindow.Button_Edit")); FSlateIcon NewBPIcon(FEditorStyle::Get().GetStyleSetName(), TEXT("PropertyWindow.Button_AddToArray")); // Game Mode TAttribute<FText>::FGetter DynamicGameModeGetter; DynamicGameModeGetter.BindStatic(&FLevelEditorToolBar::GetOpenGameModeBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicGameModeLabel = TAttribute<FText>::Create(DynamicGameModeGetter); TAttribute<FText>::FGetter DynamicGameModeGetter_Tooltip; DynamicGameModeGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenGameModeBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicGameModeTooltip = TAttribute<FText>::Create(DynamicGameModeGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenGameModeBlueprint, NAME_None, DynamicGameModeLabel, DynamicGameModeTooltip, IsValidGameModeBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // Game State TAttribute<FText>::FGetter DynamicGameStateGetter; DynamicGameStateGetter.BindStatic(&FLevelEditorToolBar::GetOpenGameStateBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicGameStateLabel = TAttribute<FText>::Create(DynamicGameStateGetter); TAttribute<FText>::FGetter DynamicGameStateGetter_Tooltip; DynamicGameStateGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenGameStateBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicGameStateTooltip = TAttribute<FText>::Create(DynamicGameStateGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenGameStateBlueprint, NAME_None, DynamicGameStateLabel, DynamicGameStateTooltip, IsValidGameStateBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // Pawn TAttribute<FText>::FGetter DynamicDefaultPawnGetter; DynamicDefaultPawnGetter.BindStatic(&FLevelEditorToolBar::GetOpenPawnBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicDefaultPawnLabel = TAttribute<FText>::Create(DynamicDefaultPawnGetter); TAttribute<FText>::FGetter DynamicDefaultPawnGetter_Tooltip; DynamicDefaultPawnGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenPawnBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicDefaultPawnTooltip = TAttribute<FText>::Create(DynamicDefaultPawnGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenDefaultPawnBlueprint, NAME_None, DynamicDefaultPawnLabel, DynamicDefaultPawnTooltip, IsValidPawnBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // HUD TAttribute<FText>::FGetter DynamicHUDGetter; DynamicHUDGetter.BindStatic(&FLevelEditorToolBar::GetOpenHUDBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicHUDLabel = TAttribute<FText>::Create(DynamicHUDGetter); TAttribute<FText>::FGetter DynamicHUDGetter_Tooltip; DynamicHUDGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenHUDBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicHUDTooltip = TAttribute<FText>::Create(DynamicHUDGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenHUDBlueprint, NAME_None, DynamicHUDLabel, DynamicHUDTooltip, IsValidHUDBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // Player Controller TAttribute<FText>::FGetter DynamicPlayerControllerGetter; DynamicPlayerControllerGetter.BindStatic(&FLevelEditorToolBar::GetOpenPlayerControllerBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicPlayerControllerLabel = TAttribute<FText>::Create(DynamicPlayerControllerGetter); TAttribute<FText>::FGetter DynamicPlayerControllerGetter_Tooltip; DynamicPlayerControllerGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenPlayerControllerBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicPlayerControllerTooltip = TAttribute<FText>::Create(DynamicPlayerControllerGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenPlayerControllerBlueprint, NAME_None, DynamicPlayerControllerLabel, DynamicPlayerControllerTooltip, IsValidPlayerControllerBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); } MenuBuilder.EndSection(); MenuBuilder.BeginSection(NAME_None, LOCTEXT("ClassBlueprints", "Class Blueprints")); { // New Class Blueprint... MenuBuilder.AddMenuEntry(FLevelEditorCommands::Get().CreateClassBlueprint, NAME_None, LOCTEXT("NewClassBlueprint", "New Class Blueprint...")); // Open Class Blueprint... FSlateIcon OpenBPIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.OpenClassBlueprint"); MenuBuilder.AddSubMenu( LOCTEXT("OpenClassBlueprintSubMenu", "Open Class Blueprint..."), LOCTEXT("OpenClassBlueprintSubMenu_ToolTip", "Open an existing Class Blueprint in this project"), FNewMenuDelegate::CreateStatic(&FBlueprintMenus::MakeOpenClassBPMenu), false, OpenBPIcon ); } MenuBuilder.EndSection(); #undef LOCTEXT_NAMESPACE return MenuBuilder.MakeWidget(); }
/** * Construct this widget. Called by the SNew() Slate macro. * * @param InArgs Declaration used by the SNew() macro to construct this widget * @param Factory The factory this menu entry represents */ void Construct( const FArguments& InArgs, UFactory* Factory ) { const FName ClassThumbnailBrushOverride = Factory->GetNewAssetThumbnailOverride(); const FSlateBrush* ClassThumbnail = nullptr; if (ClassThumbnailBrushOverride.IsNone()) { ClassThumbnail = FClassIconFinder::FindThumbnailForClass(Factory->GetSupportedClass()); } else { // Instead of getting the override thumbnail directly from the editor style here get it from the // ClassIconFinder since it may have additional styles registered which can be searched by passing // it as a default with no class to search for. ClassThumbnail = FClassIconFinder::FindThumbnailForClass(nullptr, ClassThumbnailBrushOverride); } FAssetToolsModule& AssetToolsModule = FAssetToolsModule::GetModule(); TWeakPtr<IAssetTypeActions> AssetTypeActions = AssetToolsModule.Get().GetAssetTypeActionsForClass(Factory->GetSupportedClass()); FLinearColor AssetColor = FLinearColor::White; if ( AssetTypeActions.IsValid() ) { AssetColor = AssetTypeActions.Pin()->GetTypeColor(); } ChildSlot [ SNew( SHorizontalBox ) +SHorizontalBox::Slot() .Padding( 4, 0, 0, 0 ) .VAlign(VAlign_Center) .AutoWidth() [ SNew( SOverlay ) +SOverlay::Slot() [ SNew( SBox ) .WidthOverride( InArgs._Width + 4 ) .HeightOverride( InArgs._Height + 4 ) [ SNew( SBorder ) .BorderImage( FEditorStyle::GetBrush("AssetThumbnail.AssetBackground") ) .BorderBackgroundColor(AssetColor.CopyWithNewOpacity(0.3f)) .Padding( 2.0f ) .VAlign( VAlign_Center ) .HAlign( HAlign_Center ) [ SNew( SImage ) .Image( ClassThumbnail ) ] ] ] +SOverlay::Slot() .HAlign(HAlign_Fill) .VAlign(VAlign_Bottom) [ SNew( SBorder ) .BorderImage( FEditorStyle::GetBrush("WhiteBrush") ) .BorderBackgroundColor( AssetColor ) .Padding( FMargin(0, FMath::Max(FMath::CeilToFloat(InArgs._Width*0.025f), 3.0f), 0, 0) ) ] ] +SHorizontalBox::Slot() .VAlign(VAlign_Center) .Padding(4, 0, 4, 0) [ SNew( SVerticalBox ) +SVerticalBox::Slot() .Padding(0, 0, 0, 1) .AutoHeight() [ SNew(STextBlock) .Font( FEditorStyle::GetFontStyle("LevelViewportContextMenu.AssetLabel.Text.Font") ) .Text( Factory->GetDisplayName() ) ] ] ]; SetToolTip(IDocumentation::Get()->CreateToolTip(Factory->GetToolTip(), nullptr, Factory->GetToolTipDocumentationPage(), Factory->GetToolTipDocumentationExcerpt())); }
void STutorialRoot::LaunchTutorial(UEditorTutorial* InTutorial, IIntroTutorials::ETutorialStartType InStartType, TWeakPtr<SWindow> InNavigationWindow, FSimpleDelegate InOnTutorialClosed, FSimpleDelegate InOnTutorialExited) { if(InTutorial != nullptr) { CurrentTutorial = InTutorial; // we force a restart if this tutorial was completed if (GetDefault<UTutorialStateSettings>()->HaveCompletedTutorial(CurrentTutorial) && (InStartType == IIntroTutorials::ETutorialStartType::TST_CONTINUE)) { InStartType = IIntroTutorials::ETutorialStartType::TST_RESTART; } bool bHaveSeenTutorial = false; switch (InStartType) { case IIntroTutorials::ETutorialStartType::TST_RESTART: CurrentTutorialStage = 0; break; case IIntroTutorials::ETutorialStartType::TST_LASTSTAGE: CurrentTutorialStage = FMath::Max(0, (CurrentTutorial->Stages.Num() - 1)); break; default: case IIntroTutorials::ETutorialStartType::TST_CONTINUE: CurrentTutorialStage = GetDefault<UTutorialStateSettings>()->GetProgress(CurrentTutorial, bHaveSeenTutorial); break; } // check if we should be launching this tutorial for an asset editor if(InTutorial->AssetToUse.IsValid()) { TArray<FString> AssetPaths; AssetPaths.Add(InTutorial->AssetToUse.AssetLongPathname); FAssetEditorManager::Get().OpenEditorsForAssets(AssetPaths); UObject* Asset = InTutorial->AssetToUse.ResolveObject(); if(Asset != nullptr) { TSharedPtr<IToolkit> Toolkit = FToolkitManager::Get().FindEditorForAsset( Asset ); if(Toolkit.IsValid()) { InNavigationWindow = FSlateApplication::Get().FindWidgetWindow(Toolkit->GetToolkitHost()->GetParentWidget()); // make sure we have a valid tutorial overlay if(InNavigationWindow.IsValid()) { MaybeAddOverlay(InNavigationWindow.Pin().ToSharedRef()); } } } } CurrentTutorialStartTime = FPlatformTime::Seconds(); // launch tutorial for all windows we wrap - any tutorial can display over any window for(auto& TutorialWidget : TutorialWidgets) { if(TutorialWidget.Value.IsValid()) { bool bIsNavigationWindow = false; if (!InNavigationWindow.IsValid()) { bIsNavigationWindow = TutorialWidget.Value.Pin()->IsNavigationVisible(); } else { bIsNavigationWindow = (TutorialWidget.Value.Pin()->GetParentWindow() == InNavigationWindow.Pin()); } TutorialWidget.Value.Pin()->LaunchTutorial(bIsNavigationWindow, InOnTutorialClosed, InOnTutorialExited); } } if (CurrentTutorial != nullptr) { CurrentTutorial->HandleTutorialLaunched(); } if (CurrentTutorial != nullptr && CurrentTutorialStage < CurrentTutorial->Stages.Num()) { CurrentTutorial->HandleTutorialStageStarted(CurrentTutorial->Stages[CurrentTutorialStage].Name); } } }