void FLevelEditorContextMenu::SummonMenu( const TSharedRef< SLevelEditor >& LevelEditor, LevelEditorMenuContext ContextType ) { struct Local { static void ExtendMenu( FMenuBuilder& MenuBuilder ) { // one extra entry when summoning the menu this way MenuBuilder.BeginSection("ActorPreview", LOCTEXT("PreviewHeading", "Preview") ); { // Note: not using a command for play from here since it requires a mouse click FUIAction PlayFromHereAction( FExecuteAction::CreateStatic( &FPlayWorldCommandCallbacks::StartPlayFromHere ) ); const FText PlayFromHereLabel = GEditor->OnlyLoadEditorVisibleLevelsInPIE() ? LOCTEXT("PlayFromHereVisible", "Play From Here (visible levels)") : LOCTEXT("PlayFromHere", "Play From Here"); MenuBuilder.AddMenuEntry( PlayFromHereLabel, LOCTEXT("PlayFromHere_ToolTip", "Starts a game preview from the clicked location"),FSlateIcon(), PlayFromHereAction ); } MenuBuilder.EndSection(); } }; TSharedRef<FExtender> Extender = MakeShareable(new FExtender); Extender->AddMenuExtension("LevelViewportAttach", EExtensionHook::After, TSharedPtr< FUICommandList >(), FMenuExtensionDelegate::CreateStatic(&Local::ExtendMenu)); // Create the context menu! TSharedPtr<SWidget> MenuWidget = BuildMenuWidget( LevelEditor, ContextType, Extender ); if ( MenuWidget.IsValid() ) { // @todo: Should actually use the location from a click event instead! const FVector2D MouseCursorLocation = FSlateApplication::Get().GetCursorPos(); TWeakPtr< SWindow > ContextMenuWindow = FSlateApplication::Get().PushMenu( LevelEditor->GetActiveViewport().ToSharedRef(), MenuWidget.ToSharedRef(), MouseCursorLocation, FPopupTransitionEffect( FPopupTransitionEffect::ContextMenu ) ); } }
TSharedRef< SWidget > FMainMenu::MakeMainTabMenu( const TSharedPtr<FTabManager>& TabManager, const TSharedRef< FExtender > UserExtender ) { struct Local { static void FillProjectMenuItems( FMenuBuilder& MenuBuilder ) { MenuBuilder.BeginSection( "FileProject", LOCTEXT("ProjectHeading", "Project") ); { MenuBuilder.AddMenuEntry( FMainFrameCommands::Get().NewProject ); MenuBuilder.AddMenuEntry( FMainFrameCommands::Get().OpenProject ); const bool bUseShortIDEName = true; FText ShortIDEName = FSourceCodeNavigation::GetSuggestedSourceCodeIDE(bUseShortIDEName); MenuBuilder.AddMenuEntry( FMainFrameCommands::Get().AddCodeToProject, NAME_None, TAttribute<FText>(), FText::Format(LOCTEXT("AddCodeToProjectTooltip", "Adds C++ code to the project. The code can only be compiled if you have {0} installed."), ShortIDEName) ); MenuBuilder.AddSubMenu( LOCTEXT("PackageProjectSubMenuLabel", "Package Project"), LOCTEXT("PackageProjectSubMenuToolTip", "Compile, cook and package your project and its content for distribution"), FNewMenuDelegate::CreateStatic( &FPackageProjectMenu::MakeMenu ), false, FSlateIcon(FEditorStyle::GetStyleSetName(), "MainFrame.PackageProject") ); if (FPaths::FileExists(FModuleManager::Get().GetSolutionFilepath())) { MenuBuilder.AddMenuEntry( FMainFrameCommands::Get().RefreshCodeProject, NAME_None, FText::Format(LOCTEXT("RefreshCodeProjectLabel", "Refresh {0} Project"), ShortIDEName), FText::Format(LOCTEXT("RefreshCodeProjectTooltip", "Refreshes your C++ code project in {0}."), ShortIDEName) ); MenuBuilder.AddMenuEntry( FMainFrameCommands::Get().OpenIDE, NAME_None, FText::Format(LOCTEXT("OpenIDELabel", "Open {0}"), ShortIDEName), FText::Format(LOCTEXT("OpenIDETooltip", "Opens your C++ code in {0}."), ShortIDEName) ); } // @hack GDC: this should be moved somewhere else and be less hacky ITargetPlatform* RunningTargetPlatform = GetTargetPlatformManager()->GetRunningTargetPlatform(); if (RunningTargetPlatform != nullptr) { FString CookedPlatformName = RunningTargetPlatform->PlatformName() + TEXT("NoEditor"); FText CookedPlatformText = FText::FromString(RunningTargetPlatform->PlatformName()); FUIAction Action( FExecuteAction::CreateStatic(&FMainFrameActionCallbacks::CookContent, CookedPlatformName, CookedPlatformText), FCanExecuteAction::CreateStatic(&FMainFrameActionCallbacks::CookContentCanExecute, CookedPlatformName) ); MenuBuilder.AddMenuEntry( FText::Format(LOCTEXT("CookContentForPlatform", "Cook Content for {0}"), CookedPlatformText), FText::Format(LOCTEXT("CookContentForPlatformTooltip", "Cook your game content for debugging on the {0} platform"), CookedPlatformText), FSlateIcon(), Action ); } } MenuBuilder.EndSection(); } static void FillRecentFileAndExitMenuItems( FMenuBuilder& MenuBuilder ) { MenuBuilder.BeginSection( "FileRecentFiles" ); { if ( FMainFrameActionCallbacks::ProjectNames.Num() > 0 ) { MenuBuilder.AddSubMenu( LOCTEXT("SwitchProjectSubMenu", "Recent Projects"), LOCTEXT("SwitchProjectSubMenu_ToolTip", "Select a project to switch to"), FNewMenuDelegate::CreateStatic( &FRecentProjectsMenu::MakeMenu ), false, FSlateIcon(FEditorStyle::GetStyleSetName(), "MainFrame.RecentProjects") ); } } MenuBuilder.EndSection(); MenuBuilder.AddMenuSeparator(); MenuBuilder.AddMenuEntry( FMainFrameCommands::Get().Exit, "Exit" ); } }; FExtensibilityManager ExtensibilityManager; ExtensibilityManager.AddExtender( UserExtender ); { TSharedRef< FExtender > Extender( new FExtender() ); IMainFrameModule& MainFrameModule = FModuleManager::GetModuleChecked<IMainFrameModule>("MainFrame"); Extender->AddMenuExtension( "FileLoadAndSave", EExtensionHook::After, MainFrameModule.GetMainFrameCommandBindings(), FMenuExtensionDelegate::CreateStatic( &Local::FillProjectMenuItems ) ); Extender->AddMenuExtension( "FileLoadAndSave", EExtensionHook::After, MainFrameModule.GetMainFrameCommandBindings(), FMenuExtensionDelegate::CreateStatic( &Local::FillRecentFileAndExitMenuItems ) ); ExtensibilityManager.AddExtender( Extender ); } TSharedRef< SWidget > MenuBarWidget = FMainMenu::MakeMainMenu( TabManager, ExtensibilityManager.GetAllExtenders().ToSharedRef() ); return MenuBarWidget; }