void SGraphEditor::ConstructImplementation( const FArguments& InArgs ) { FGraphEditorModule& GraphEdModule = FModuleManager::LoadModuleChecked<FGraphEditorModule>(TEXT("GraphEditor")); // Construct the implementation and make it the contents of this widget. Implementation = GraphEdModule.PRIVATE_MakeGraphEditor( InArgs._AdditionalCommands, InArgs._IsEditable, InArgs._DisplayAsReadOnly, InArgs._IsEmpty, InArgs._Appearance, InArgs._TitleBar, InArgs._GraphToEdit, InArgs._GraphEvents, InArgs._AutoExpandActionMenu, InArgs._GraphToDiff, InArgs._OnNavigateHistoryBack, InArgs._OnNavigateHistoryForward, InArgs._ShowGraphStateOverlay ); this->ChildSlot [ SNew( SBox ) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("GraphEditorPanel"))) [ Implementation.ToSharedRef() ] ]; }
TSharedRef<SWidget> FWidgetBlueprintEditor::CreateSequencerWidget() { TSharedRef<SOverlay> SequencerOverlayRef = SNew(SOverlay) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("Sequencer"))); SequencerOverlay = SequencerOverlayRef; TSharedRef<STextBlock> NoAnimationTextBlockRef = SNew(STextBlock) .TextStyle(FEditorStyle::Get(), "UMGEditor.NoAnimationFont") .Text(LOCTEXT("NoAnimationSelected", "No Animation Selected")); NoAnimationTextBlock = NoAnimationTextBlockRef; SequencerOverlayRef->AddSlot(0) [ GetSequencer()->GetSequencerWidget() ]; SequencerOverlayRef->AddSlot(1) .HAlign(HAlign_Center) .VAlign(VAlign_Center) [ NoAnimationTextBlockRef ]; return SequencerOverlayRef; }
TSharedRef<SWidget> FHierarchyTabSummoner::CreateTabBody(const FWorkflowTabSpawnInfo& Info) const { TSharedPtr<FWidgetBlueprintEditor> BlueprintEditorPtr = StaticCastSharedPtr<FWidgetBlueprintEditor>(BlueprintEditor.Pin()); return SNew(SHierarchyView, BlueprintEditorPtr, BlueprintEditorPtr->GetBlueprintObj()->SimpleConstructionScript) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("Hierarchy"))); }
TSharedRef<SWidget> FDesignerTabSummoner::CreateTabBody(const FWorkflowTabSpawnInfo& Info) const { return SNew(SScissorRectBox) [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .FillWidth(1) [ SNew(SDesignerView, BlueprintEditor.Pin()) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("Designer"))) ] ]; }
void FToolBarBuilder::AddWidget( TSharedRef<SWidget> InWidget, FName InTutorialHighlightName, bool bSearchable ) { ApplySectionBeginning(); // If tutorial name specified, wrap in tutorial wrapper const FName WrapperName = GenerateTutorialIdentfierName(InTutorialHighlightName, NAME_None, nullptr, MultiBox->GetBlocks().Num()); TSharedRef<SWidget> ChildWidget = InWidget; InWidget = SNew( SBox ) .AddMetaData<FTagMetaData>(FTagMetaData(InTutorialHighlightName)) [ ChildWidget ]; TSharedRef< FWidgetBlock > NewWidgetBlock( new FWidgetBlock( InWidget, FText::GetEmpty(), true ) ); MultiBox->AddMultiBlock( NewWidgetBlock ); NewWidgetBlock->SetSearchable(bSearchable); }
void SAssetPicker::Construct( const FArguments& InArgs ) { BindCommands(); OnAssetsActivated = InArgs._AssetPickerConfig.OnAssetsActivated; OnAssetSelected = InArgs._AssetPickerConfig.OnAssetSelected; OnAssetDoubleClicked = InArgs._AssetPickerConfig.OnAssetDoubleClicked; OnAssetEnterPressed = InArgs._AssetPickerConfig.OnAssetEnterPressed; bPendingFocusNextFrame = InArgs._AssetPickerConfig.bFocusSearchBoxWhenOpened; DefaultFilterMenuExpansion = InArgs._AssetPickerConfig.DefaultFilterMenuExpansion; SaveSettingsName = InArgs._AssetPickerConfig.SaveSettingsName; OnFolderEnteredDelegate = InArgs._AssetPickerConfig.OnFolderEntered; if ( InArgs._AssetPickerConfig.bFocusSearchBoxWhenOpened ) { RegisterActiveTimer( 0.f, FWidgetActiveTimerDelegate::CreateSP( this, &SAssetPicker::SetFocusPostConstruct ) ); } for (auto DelegateIt = InArgs._AssetPickerConfig.GetCurrentSelectionDelegates.CreateConstIterator(); DelegateIt; ++DelegateIt) { if ((*DelegateIt) != NULL) { (**DelegateIt) = FGetCurrentSelectionDelegate::CreateSP(this, &SAssetPicker::GetCurrentSelection); } } for(auto DelegateIt = InArgs._AssetPickerConfig.SyncToAssetsDelegates.CreateConstIterator(); DelegateIt; ++DelegateIt) { if((*DelegateIt) != NULL) { (**DelegateIt) = FSyncToAssetsDelegate::CreateSP(this, &SAssetPicker::SyncToAssets); } } for (auto DelegateIt = InArgs._AssetPickerConfig.SetFilterDelegates.CreateConstIterator(); DelegateIt; ++DelegateIt) { if ((*DelegateIt) != NULL) { (**DelegateIt) = FSetARFilterDelegate::CreateSP(this, &SAssetPicker::SetNewBackendFilter); } } TSharedRef<SVerticalBox> VerticalBox = SNew(SVerticalBox); ChildSlot [ VerticalBox ]; TAttribute< FText > HighlightText; EThumbnailLabel::Type ThumbnailLabel = InArgs._AssetPickerConfig.ThumbnailLabel; FrontendFilters = MakeShareable(new FAssetFilterCollectionType()); // Search box if (!InArgs._AssetPickerConfig.bAutohideSearchBar) { TextFilter = MakeShareable( new FFrontendFilter_Text() ); TextFilter->SetIncludeClassName(InArgs._AssetPickerConfig.Filter.ClassNames.Num() != 1); HighlightText = TAttribute< FText >( this, &SAssetPicker::GetHighlightedText ); OtherDevelopersFilter = MakeShareable( new FFrontendFilter_ShowOtherDevelopers(nullptr) ); FrontendFilters->Add( OtherDevelopersFilter ); TSharedRef<SHorizontalBox> HorizontalBox = SNew(SHorizontalBox); if(InArgs._AssetPickerConfig.bAddFilterUI) { // Filter HorizontalBox->AddSlot() .AutoWidth() [ SNew( SComboButton ) .ComboButtonStyle( FEditorStyle::Get(), "ContentBrowser.Filters.Style" ) .ForegroundColor(FLinearColor::White) .ToolTipText( LOCTEXT( "AddFilterToolTip", "Add an asset filter." ) ) .OnGetMenuContent( this, &SAssetPicker::MakeAddFilterMenu ) .HasDownArrow( true ) .ContentPadding( FMargin( 1, 0 ) ) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ContentBrowserFiltersCombo"))) .ButtonContent() [ SNew( STextBlock ) .TextStyle( FEditorStyle::Get(), "ContentBrowser.Filters.Text" ) .Text( LOCTEXT( "Filters", "Filters" ) ) ] ]; } HorizontalBox->AddSlot() .FillWidth(1.0f) [ SAssignNew( SearchBoxPtr, SAssetSearchBox ) .HintText(NSLOCTEXT( "ContentBrowser", "SearchBoxHint", "Search Assets" )) .OnTextChanged( this, &SAssetPicker::OnSearchBoxChanged ) .OnTextCommitted( this, &SAssetPicker::OnSearchBoxCommitted ) .DelayChangeNotificationsWhileTyping( true ) ]; HorizontalBox->AddSlot() .AutoWidth() [ SNew( SCheckBox ) .Style( FEditorStyle::Get(), "ToggleButtonCheckbox" ) .ToolTipText( this, &SAssetPicker::GetShowOtherDevelopersToolTip ) .OnCheckStateChanged( this, &SAssetPicker::HandleShowOtherDevelopersCheckStateChanged ) .IsChecked( this, &SAssetPicker::GetShowOtherDevelopersCheckState ) [ SNew( SImage ) .Image( FEditorStyle::GetBrush("ContentBrowser.ColumnViewDeveloperFolderIcon") ) ] ]; VerticalBox->AddSlot() .AutoHeight() .Padding( 0, 0, 0, 1 ) [ HorizontalBox ]; } // "None" button if (InArgs._AssetPickerConfig.bAllowNullSelection) { VerticalBox->AddSlot() .AutoHeight() [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() [ SNew(SButton) .ButtonStyle( FEditorStyle::Get(), "ContentBrowser.NoneButton" ) .TextStyle( FEditorStyle::Get(), "ContentBrowser.NoneButtonText" ) .Text( LOCTEXT("NoneButtonText", "( None )") ) .ToolTipText( LOCTEXT("NoneButtonTooltip", "Clears the asset selection.") ) .HAlign(HAlign_Center) .VAlign(VAlign_Center) .OnClicked(this, &SAssetPicker::OnNoneButtonClicked) ] // Trailing separator + SVerticalBox::Slot() .AutoHeight() .Padding(0, 0, 0, 4) [ SNew(SSeparator) .Orientation(Orient_Horizontal) ] ]; } // Asset view // Break up the incoming filter into a sources data and backend filter. CurrentSourcesData.PackagePaths = InArgs._AssetPickerConfig.Filter.PackagePaths; CurrentSourcesData.Collections = InArgs._AssetPickerConfig.Collections; CurrentBackendFilter = InArgs._AssetPickerConfig.Filter; CurrentBackendFilter.PackagePaths.Empty(); if(InArgs._AssetPickerConfig.bAddFilterUI) { // Filters TArray<UClass*> FilterClassList; for(auto Iter = CurrentBackendFilter.ClassNames.CreateIterator(); Iter; ++Iter) { FName ClassName = (*Iter); UClass* FilterClass = FindObject<UClass>(ANY_PACKAGE, *ClassName.ToString()); if(FilterClass) { FilterClassList.AddUnique(FilterClass); } } VerticalBox->AddSlot() .AutoHeight() [ SAssignNew(FilterListPtr, SFilterList) .OnFilterChanged(this, &SAssetPicker::OnFilterChanged) .FrontendFilters(FrontendFilters) .InitialClassFilters(FilterClassList) .ExtraFrontendFilters(InArgs._AssetPickerConfig.ExtraFrontendFilters) ]; } VerticalBox->AddSlot() .FillHeight(1.f) [ SAssignNew(AssetViewPtr, SAssetView) .SelectionMode( InArgs._AssetPickerConfig.SelectionMode ) .OnShouldFilterAsset(InArgs._AssetPickerConfig.OnShouldFilterAsset) .OnAssetSelected(InArgs._AssetPickerConfig.OnAssetSelected) .OnAssetsActivated(this, &SAssetPicker::HandleAssetsActivated) .OnGetAssetContextMenu(InArgs._AssetPickerConfig.OnGetAssetContextMenu) .OnGetCustomAssetToolTip(InArgs._AssetPickerConfig.OnGetCustomAssetToolTip) .OnVisualizeAssetToolTip(InArgs._AssetPickerConfig.OnVisualizeAssetToolTip) .OnAssetToolTipClosing(InArgs._AssetPickerConfig.OnAssetToolTipClosing) .AreRealTimeThumbnailsAllowed(this, &SAssetPicker::IsHovered) .FrontendFilters(FrontendFilters) .InitialSourcesData(CurrentSourcesData) .InitialBackendFilter(CurrentBackendFilter) .InitialViewType(InArgs._AssetPickerConfig.InitialAssetViewType) .InitialAssetSelection(InArgs._AssetPickerConfig.InitialAssetSelection) .ThumbnailScale(InArgs._AssetPickerConfig.ThumbnailScale) .ShowBottomToolbar(InArgs._AssetPickerConfig.bShowBottomToolbar) .OnAssetTagWantsToBeDisplayed(InArgs._AssetPickerConfig.OnAssetTagWantsToBeDisplayed) .AllowDragging( InArgs._AssetPickerConfig.bAllowDragging ) .CanShowClasses( InArgs._AssetPickerConfig.bCanShowClasses ) .CanShowFolders( InArgs._AssetPickerConfig.bCanShowFolders ) .FilterRecursivelyWithBackendFilter( false ) .CanShowRealTimeThumbnails( InArgs._AssetPickerConfig.bCanShowRealTimeThumbnails ) .CanShowDevelopersFolder( InArgs._AssetPickerConfig.bCanShowDevelopersFolder ) .PreloadAssetsForContextMenu( InArgs._AssetPickerConfig.bPreloadAssetsForContextMenu ) .HighlightedText( HighlightText ) .ThumbnailLabel( ThumbnailLabel ) .AssetShowWarningText( InArgs._AssetPickerConfig.AssetShowWarningText) .AllowFocusOnSync(false) // Stop the asset view from stealing focus (we're in control of that) .OnPathSelected(this, &SAssetPicker::FolderEntered) ]; LoadSettings(); AssetViewPtr->RequestSlowFullListRefresh(); }
/** * Builds this MultiBlock widget up from the MultiBlock associated with it */ void SToolBarButtonBlock::BuildMultiBlockWidget(const ISlateStyle* StyleSet, const FName& StyleName) { struct Local { /** Appends the key binding to the end of the provided ToolTip */ static FText AppendKeyBindingToToolTip( const TAttribute<FText> ToolTip, TWeakPtr< const FUICommandInfo> Command ) { TSharedPtr<const FUICommandInfo> CommandPtr = Command.Pin(); if( CommandPtr.IsValid() && CommandPtr->GetActiveChord()->IsValidChord() ) { FFormatNamedArguments Args; Args.Add( TEXT("ToolTipDescription"), ToolTip.Get() ); Args.Add( TEXT("Keybinding"), CommandPtr->GetInputText() ); return FText::Format( NSLOCTEXT("ToolBar", "ToolTip + Keybinding", "{ToolTipDescription} ({Keybinding})"), Args ); } else { return ToolTip.Get(); } } }; TSharedRef< const FMultiBox > MultiBox( OwnerMultiBoxWidget.Pin()->GetMultiBox() ); TSharedRef< const FToolBarButtonBlock > ToolBarButtonBlock = StaticCastSharedRef< const FToolBarButtonBlock >( MultiBlock.ToSharedRef() ); // Allow the block to override the action's label and tool tip string, if desired TAttribute<FText> ActualLabel; if (ToolBarButtonBlock->LabelOverride.IsSet()) { ActualLabel = ToolBarButtonBlock->LabelOverride; } else { ActualLabel = ToolBarButtonBlock->GetAction()->GetLabel(); } // Add this widget to the search list of the multibox if (MultiBlock->GetSearchable()) OwnerMultiBoxWidget.Pin()->AddSearchElement(this->AsWidget(), ActualLabel.Get()); TAttribute<FText> ActualToolTip; if (ToolBarButtonBlock->ToolTipOverride.IsSet()) { ActualToolTip = ToolBarButtonBlock->ToolTipOverride; } else { ActualToolTip = ToolBarButtonBlock->GetAction()->GetDescription(); } // If a key is bound to the command, append it to the tooltip text. TWeakPtr<const FUICommandInfo> Action = ToolBarButtonBlock->GetAction(); ActualToolTip = TAttribute< FText >::Create( TAttribute< FText >::FGetter::CreateStatic( &Local::AppendKeyBindingToToolTip, ActualToolTip, Action ) ); // If we were supplied an image than go ahead and use that, otherwise we use a null widget TSharedRef< SWidget > IconWidget = SNew( SImage ) .Visibility( this, &SToolBarButtonBlock::GetIconVisibility, false ) .Image( this, &SToolBarButtonBlock::GetIconBrush ); TSharedRef< SWidget > SmallIconWidget = SNew( SImage ) .Visibility( this, &SToolBarButtonBlock::GetIconVisibility, true ) .Image( this, &SToolBarButtonBlock::GetSmallIconBrush ); // Create the content for our button TSharedRef< SWidget > ButtonContent = SNew(SHorizontalBox) .AddMetaData<FTagMetaData>(FTagMetaData(TutorialHighlightName)) + SHorizontalBox::Slot() .FillWidth(1) .VAlign(VAlign_Center) [ SNew( SVerticalBox ) // Icon image + SVerticalBox::Slot() .AutoHeight() .HAlign( HAlign_Center ) // Center the icon horizontally, so that large labels don't stretch out the artwork [ IconWidget ] + SVerticalBox::Slot().AutoHeight() .HAlign( HAlign_Center ) [ SmallIconWidget ] // Label text + SVerticalBox::Slot().AutoHeight() .HAlign( HAlign_Center ) // Center the label text horizontally [ SNew( STextBlock ) .Visibility( LabelVisibility ) .Text( ActualLabel ) .TextStyle( StyleSet, ISlateStyle::Join( StyleName, ".Label" ) ) // Smaller font for tool tip labels .ShadowOffset( FVector2D::UnitVector ) ] ]; EMultiBlockLocation::Type BlockLocation = GetMultiBlockLocation(); // What type of UI should we create for this block? EUserInterfaceActionType::Type UserInterfaceType = ToolBarButtonBlock->UserInterfaceActionType; if ( Action.IsValid() ) { // If we have a UICommand, then this is specified in the command. UserInterfaceType = Action.Pin()->GetUserInterfaceType(); } if( UserInterfaceType == EUserInterfaceActionType::Button ) { FName BlockStyle = EMultiBlockLocation::ToName(ISlateStyle::Join( StyleName, ".Button" ), BlockLocation); ChildSlot [ // Create a button SNew( SButton ) .ContentPadding(0) // Use the tool bar item style for this button .ButtonStyle( StyleSet, BlockStyle ) .ForegroundColor( FSlateColor::UseForeground() ) .IsFocusable(bIsFocusable) [ ButtonContent ] // Bind the button's "on clicked" event to our object's method for this .OnClicked( this, &SToolBarButtonBlock::OnClicked ) // Pass along the block's tool-tip string .ToolTip( FMultiBoxSettings::ToolTipConstructor.Execute( ActualToolTip, nullptr, Action.Pin() ) ) ]; } else if( ensure( UserInterfaceType == EUserInterfaceActionType::ToggleButton || UserInterfaceType == EUserInterfaceActionType::RadioButton ) ) { FName BlockStyle = EMultiBlockLocation::ToName(ISlateStyle::Join( StyleName, ".ToggleButton" ), BlockLocation); FName CheckboxStyle = ISlateStyle::Join( StyleName, ".SToolBarButtonBlock.CheckBox.Padding" ); ChildSlot [ // Create a check box SNew( SCheckBox ) // Use the tool bar style for this check box .Style( StyleSet, BlockStyle ) // User will have set the focusable attribute for the block, honor it .IsFocusable( bIsFocusable ) // Pass along the block's tool-tip string .ToolTip( FMultiBoxSettings::ToolTipConstructor.Execute( ActualToolTip, nullptr, Action.Pin() ) ) [ ButtonContent ] // Bind the button's "on checked" event to our object's method for this .OnCheckStateChanged( this, &SToolBarButtonBlock::OnCheckStateChanged ) // Bind the check box's "checked" state to our user interface action .IsChecked( this, &SToolBarButtonBlock::OnIsChecked ) .Padding( StyleSet->GetMargin(CheckboxStyle) ) ]; } ChildSlot.Padding(StyleSet->GetMargin(ISlateStyle::Join( StyleName, ".SToolBarButtonBlock.Padding" ))); // Bind our widget's enabled state to whether or not our action can execute SetEnabled( TAttribute< bool >( this, &SToolBarButtonBlock::IsEnabled ) ); // Bind our widget's visible state to whether or not the button should be visible SetVisibility( TAttribute<EVisibility>(this, &SToolBarButtonBlock::GetBlockVisibility) ); }
void STreeThemePreview3DViewportToolbar::Construct(const FArguments& InArgs) { Viewport = InArgs._Viewport; TSharedRef<STreeThemePreview3DViewport> ViewportRef = Viewport.Pin().ToSharedRef(); FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked<FLevelEditorModule>("LevelEditor"); const FMargin ToolbarSlotPadding(2.0f, 2.0f); const FMargin ToolbarButtonPadding(2.0f, 0.0f); static const FName DefaultForegroundName("DefaultForeground"); ChildSlot [ SNew(SBorder) .BorderImage(FEditorStyle::GetBrush("NoBorder")) // Color and opacity is changed based on whether or not the mouse cursor is hovering over the toolbar area .ColorAndOpacity(this, &SViewportToolBar::OnGetColorAndOpacity) .ForegroundColor(FEditorStyle::GetSlateColor(DefaultForegroundName)) [ SNew(SVerticalBox) + SVerticalBox::Slot() .AutoHeight() [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() .Padding(ToolbarSlotPadding) [ SNew(SEditorViewportToolbarMenu) .Label(LOCTEXT("ShowMenuTitle", "Properties")) .Cursor(EMouseCursor::Default) .ParentToolBar(SharedThis(this)) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("EditorViewportToolBar.ShowMenu"))) .OnGetMenuContent(this, &STreeThemePreview3DViewportToolbar::GeneratePropertiesMenu) ] + SHorizontalBox::Slot() .AutoWidth() .Padding(ToolbarSlotPadding) [ SNew(SEditorViewportToolbarMenu) .Label(LOCTEXT("ShowCamMenuTitle", "Camera")) .Cursor(EMouseCursor::Default) .ParentToolBar(SharedThis(this)) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("EditorViewportToolBar.CameraMenu"))) .OnGetMenuContent(this, &STreeThemePreview3DViewportToolbar::GenerateCameraMenu) ] + SHorizontalBox::Slot() .AutoWidth() .Padding(ToolbarSlotPadding) [ SNew(SEditorViewportViewMenu, ViewportRef, SharedThis(this)) .Cursor(EMouseCursor::Default) .MenuExtenders(GetViewMenuExtender()) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ViewMenuButton"))) ] ] ] ]; SViewportToolBar::Construct(SViewportToolBar::FArguments()); }
/** * Constructs the widget * * @param InArgs Declaration from which to construct this widget. */ void SDetailsView::Construct(const FArguments& InArgs) { DetailsViewArgs = InArgs._DetailsViewArgs; bViewingClassDefaultObject = false; PropertyUtilities = MakeShareable( new FPropertyDetailsUtilities( *this ) ); ColumnSizeData.LeftColumnWidth = TAttribute<float>( this, &SDetailsView::OnGetLeftColumnWidth ); ColumnSizeData.RightColumnWidth = TAttribute<float>( this, &SDetailsView::OnGetRightColumnWidth ); ColumnSizeData.OnWidthChanged = SSplitter::FOnSlotResized::CreateSP( this, &SDetailsView::OnSetColumnWidth ); // We want the scrollbar to always be visible when objects are selected, but not when there is no selection - however: // - We can't use AlwaysShowScrollbar for this, as this will also show the scrollbar when nothing is selected // - We can't use the Visibility construction parameter, as it gets translated into user visibility and can hide the scrollbar even when objects are selected // We instead have to explicitly set the visibility after the scrollbar has been constructed to get the exact behavior we want TSharedRef<SScrollBar> ExternalScrollbar = SNew(SScrollBar); ExternalScrollbar->SetVisibility( TAttribute<EVisibility>( this, &SDetailsView::GetScrollBarVisibility ) ); FMenuBuilder DetailViewOptions( true, nullptr); if (DetailsViewArgs.bShowModifiedPropertiesOption) { DetailViewOptions.AddMenuEntry( LOCTEXT("ShowOnlyModified", "Show Only Modified Properties"), LOCTEXT("ShowOnlyModified_ToolTip", "Displays only properties which have been changed from their default"), FSlateIcon(), FUIAction( FExecuteAction::CreateSP( this, &SDetailsView::OnShowOnlyModifiedClicked ), FCanExecuteAction(), FIsActionChecked::CreateSP( this, &SDetailsView::IsShowOnlyModifiedChecked ) ), NAME_None, EUserInterfaceActionType::ToggleButton ); } if( DetailsViewArgs.bShowDifferingPropertiesOption ) { DetailViewOptions.AddMenuEntry( LOCTEXT("ShowOnlyDiffering", "Show Only Differing Properties"), LOCTEXT("ShowOnlyDiffering_ToolTip", "Displays only properties in this instance which have been changed or added from the instance being compared"), FSlateIcon(), FUIAction( FExecuteAction::CreateSP(this, &SDetailsView::OnShowOnlyDifferingClicked), FCanExecuteAction(), FIsActionChecked::CreateSP(this, &SDetailsView::IsShowOnlyDifferingChecked) ), NAME_None, EUserInterfaceActionType::ToggleButton ); } DetailViewOptions.AddMenuEntry( LOCTEXT("ShowAllAdvanced", "Show All Advanced Details"), LOCTEXT("ShowAllAdvanced_ToolTip", "Shows all advanced detail sections in each category"), FSlateIcon(), FUIAction( FExecuteAction::CreateSP( this, &SDetailsView::OnShowAllAdvancedClicked ), FCanExecuteAction(), FIsActionChecked::CreateSP( this, &SDetailsView::IsShowAllAdvancedChecked ) ), NAME_None, EUserInterfaceActionType::ToggleButton ); DetailViewOptions.AddMenuEntry( LOCTEXT("ShowAllChildrenIfCategoryMatches", "Show Child On Category Match"), LOCTEXT("ShowAllChildrenIfCategoryMatches_ToolTip", "Shows children if their category matches the search criteria"), FSlateIcon(), FUIAction( FExecuteAction::CreateSP( this, &SDetailsView::OnShowAllChildrenIfCategoryMatchesClicked ), FCanExecuteAction(), FIsActionChecked::CreateSP( this, &SDetailsView::IsShowAllChildrenIfCategoryMatchesChecked ) ), NAME_None, EUserInterfaceActionType::ToggleButton ); DetailViewOptions.AddMenuEntry( LOCTEXT("CollapseAll", "Collapse All Categories"), LOCTEXT("CollapseAll_ToolTip", "Collapses all root level categories"), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(this, &SDetailsView::SetRootExpansionStates, /*bExpanded=*/false, /*bRecurse=*/false ))); DetailViewOptions.AddMenuEntry( LOCTEXT("ExpandAll", "Expand All Categories"), LOCTEXT("ExpandAll_ToolTip", "Expands all root level categories"), FSlateIcon(), FUIAction(FExecuteAction::CreateSP(this, &SDetailsView::SetRootExpansionStates, /*bExpanded=*/true, /*bRecurse=*/false ))); FilterRow = SNew( SHorizontalBox ) .Visibility( this, &SDetailsView::GetFilterBoxVisibility ) +SHorizontalBox::Slot() .FillWidth( 1 ) .VAlign( VAlign_Center ) [ // Create the search box SAssignNew( SearchBox, SSearchBox ) .OnTextChanged( this, &SDetailsView::OnFilterTextChanged ) .AddMetaData<FTagMetaData>(TEXT("Details.Search")) ] +SHorizontalBox::Slot() .Padding( 4.0f, 0.0f, 0.0f, 0.0f ) .AutoWidth() [ // Create the search box SNew( SButton ) .OnClicked( this, &SDetailsView::OnOpenRawPropertyEditorClicked ) .IsEnabled( this, &SDetailsView::IsPropertyEditingEnabled ) .ToolTipText( LOCTEXT("RawPropertyEditorButtonLabel", "Open Selection in Property Matrix") ) [ SNew( SImage ) .Image( FEditorStyle::GetBrush("DetailsView.EditRawProperties") ) ] ]; if (DetailsViewArgs.bShowOptions) { FilterRow->AddSlot() .HAlign(HAlign_Right) .AutoWidth() [ SNew( SComboButton ) .ContentPadding(0) .ForegroundColor( FSlateColor::UseForeground() ) .ButtonStyle( FEditorStyle::Get(), "ToggleButton" ) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("ViewOptions"))) .MenuContent() [ DetailViewOptions.MakeWidget() ] .ButtonContent() [ SNew(SImage) .Image( FEditorStyle::GetBrush("GenericViewButton") ) ] ]; } // Create the name area which does not change when selection changes SAssignNew(NameArea, SDetailNameArea, &SelectedObjects) // the name area is only for actors .Visibility(this, &SDetailsView::GetActorNameAreaVisibility) .OnLockButtonClicked(this, &SDetailsView::OnLockButtonClicked) .IsLocked(this, &SDetailsView::IsLocked) .ShowLockButton(DetailsViewArgs.bLockable) .ShowActorLabel(DetailsViewArgs.bShowActorLabel) // only show the selection tip if we're not selecting objects .SelectionTip(!DetailsViewArgs.bHideSelectionTip); TSharedRef<SVerticalBox> VerticalBox = SNew(SVerticalBox); if( !DetailsViewArgs.bCustomNameAreaLocation ) { VerticalBox->AddSlot() .AutoHeight() .Padding(0.0f, 0.0f, 0.0f, 4.0f) [ NameArea.ToSharedRef() ]; } if( !DetailsViewArgs.bCustomFilterAreaLocation ) { VerticalBox->AddSlot() .AutoHeight() .Padding(0.0f, 0.0f, 0.0f, 2.0f) [ FilterRow.ToSharedRef() ]; } VerticalBox->AddSlot() .FillHeight(1) .Padding(0) [ SNew(SOverlay) + SOverlay::Slot() [ ConstructTreeView(ExternalScrollbar) ] + SOverlay::Slot() .HAlign(HAlign_Right) [ SNew(SBox) .WidthOverride(16.0f) [ ExternalScrollbar ] ] ]; ChildSlot [ VerticalBox ]; }
void SKismetInspector::Construct(const FArguments& InArgs) { bShowInspectorPropertyView = true; PublicViewState = ECheckBoxState::Unchecked; bComponenetDetailsCustomizationEnabled = false; bRefreshOnTick = false; BlueprintEditorPtr = InArgs._Kismet2; bShowPublicView = InArgs._ShowPublicViewControl; bShowTitleArea = InArgs._ShowTitleArea; TSharedPtr<FBlueprintEditor> Kismet2 = BlueprintEditorPtr.Pin(); // Create a property view FPropertyEditorModule& EditModule = FModuleManager::Get().GetModuleChecked<FPropertyEditorModule>("PropertyEditor"); FNotifyHook* NotifyHook = NULL; if(InArgs._SetNotifyHook) { NotifyHook = Kismet2.Get(); } FDetailsViewArgs::ENameAreaSettings NameAreaSettings = InArgs._HideNameArea ? FDetailsViewArgs::HideNameArea : FDetailsViewArgs::ObjectsUseNameArea; FDetailsViewArgs DetailsViewArgs( /*bUpdateFromSelection=*/ false, /*bLockable=*/ false, /*bAllowSearch=*/ true, NameAreaSettings, /*bHideSelectionTip=*/ true, /*InNotifyHook=*/ NotifyHook, /*InSearchInitialKeyFocus=*/ false, /*InViewIdentifier=*/ InArgs._ViewIdentifier ); PropertyView = EditModule.CreateDetailView( DetailsViewArgs ); //@TODO: .IsEnabled( FSlateApplication::Get().GetNormalExecutionAttribute() ); PropertyView->SetIsPropertyVisibleDelegate( FIsPropertyVisible::CreateSP(this, &SKismetInspector::IsPropertyVisible) ); PropertyView->SetIsPropertyEditingEnabledDelegate(InArgs._IsPropertyEditingEnabledDelegate); UserOnFinishedChangingProperties = InArgs._OnFinishedChangingProperties; TWeakPtr<SMyBlueprint> MyBlueprint = Kismet2.IsValid() ? Kismet2->GetMyBlueprintWidget() : InArgs._MyBlueprintWidget; if( MyBlueprint.IsValid() ) { FOnGetDetailCustomizationInstance LayoutDelegateDetails = FOnGetDetailCustomizationInstance::CreateStatic(&FBlueprintDelegateActionDetails::MakeInstance, MyBlueprint); PropertyView->RegisterInstancedCustomPropertyLayout(UMulticastDelegateProperty::StaticClass(), LayoutDelegateDetails); // Register function and variable details customization FOnGetDetailCustomizationInstance LayoutGraphDetails = FOnGetDetailCustomizationInstance::CreateStatic(&FBlueprintGraphActionDetails::MakeInstance, MyBlueprint); PropertyView->RegisterInstancedCustomPropertyLayout(UEdGraph::StaticClass(), LayoutGraphDetails); PropertyView->RegisterInstancedCustomPropertyLayout(UK2Node_EditablePinBase::StaticClass(), LayoutGraphDetails); PropertyView->RegisterInstancedCustomPropertyLayout(UK2Node_CallFunction::StaticClass(), LayoutGraphDetails); FOnGetDetailCustomizationInstance LayoutVariableDetails = FOnGetDetailCustomizationInstance::CreateStatic(&FBlueprintVarActionDetails::MakeInstance, MyBlueprint); PropertyView->RegisterInstancedCustomPropertyLayout(UProperty::StaticClass(), LayoutVariableDetails); PropertyView->RegisterInstancedCustomPropertyLayout(UK2Node_VariableGet::StaticClass(), LayoutVariableDetails); PropertyView->RegisterInstancedCustomPropertyLayout(UK2Node_VariableSet::StaticClass(), LayoutVariableDetails); } if (Kismet2.IsValid() && Kismet2->IsEditingSingleBlueprint()) { FOnGetDetailCustomizationInstance LayoutOptionDetails = FOnGetDetailCustomizationInstance::CreateStatic(&FBlueprintGlobalOptionsDetails::MakeInstance, BlueprintEditorPtr); PropertyView->RegisterInstancedCustomPropertyLayout(UBlueprint::StaticClass(), LayoutOptionDetails); FOnGetDetailCustomizationInstance LayoutFormatTextDetails = FOnGetDetailCustomizationInstance::CreateStatic(&FFormatTextDetails::MakeInstance); PropertyView->RegisterInstancedCustomPropertyLayout(UK2Node_FormatText::StaticClass(), LayoutFormatTextDetails); FOnGetDetailCustomizationInstance LayoutDocumentationDetails = FOnGetDetailCustomizationInstance::CreateStatic(&FBlueprintDocumentationDetails::MakeInstance, BlueprintEditorPtr); PropertyView->RegisterInstancedCustomPropertyLayout(UEdGraphNode_Documentation::StaticClass(), LayoutDocumentationDetails); FOnGetDetailCustomizationInstance GraphNodeDetails = FOnGetDetailCustomizationInstance::CreateStatic(&FBlueprintGraphNodeDetails::MakeInstance, BlueprintEditorPtr); PropertyView->RegisterInstancedCustomPropertyLayout(UEdGraphNode::StaticClass(), GraphNodeDetails); PropertyView->RegisterInstancedCustomPropertyLayout(UChildActorComponent::StaticClass(), FOnGetDetailCustomizationInstance::CreateStatic(&FChildActorComponentDetails::MakeInstance, BlueprintEditorPtr)); } // Create the border that all of the content will get stuffed into ChildSlot [ SNew(SVerticalBox) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("BlueprintInspector"))) + SVerticalBox::Slot() .FillHeight(1.0f) [ SAssignNew( ContextualEditingBorderWidget, SBorder ) .Padding(0) .BorderImage( FEditorStyle::GetBrush("NoBorder") ) ] ]; // Update based on the current (empty) selection set TArray<UObject*> InitialSelectedObjects; FKismetSelectionInfo SelectionInfo; UpdateFromObjects(InitialSelectedObjects, SelectionInfo, SKismetInspector::FShowDetailsOptions(FText::GetEmpty(), true)); }
void SGraphTitleBar::Construct( const FArguments& InArgs ) { EdGraphObj = InArgs._EdGraphObj; OnDifferentGraphCrumbClicked = InArgs._OnDifferentGraphCrumbClicked; check(EdGraphObj); Kismet2Ptr = InArgs._Kismet2; check(Kismet2Ptr.IsValid()); // Set-up shared breadcrumb defaults FMargin BreadcrumbTrailPadding = FMargin(4.f, 2.f); const FSlateBrush* BreadcrumbButtonImage = FEditorStyle::GetBrush("BreadcrumbTrail.Delimiter"); this->ChildSlot [ SNew(SBorder) .BorderImage( FEditorStyle::GetBrush( TEXT("Graph.TitleBackground") ) ) .HAlign(HAlign_Fill) .AddMetaData<FTagMetaData>(FTagMetaData(TEXT("EventGraphTitleBar"))) [ SNew(SVerticalBox) // Title text/icon +SVerticalBox::Slot() .AutoHeight() [ SNew(SHorizontalBox) +SHorizontalBox::Slot() .AutoWidth() [ InArgs._HistoryNavigationWidget.ToSharedRef() ] +SHorizontalBox::Slot() .HAlign(HAlign_Center) .FillWidth(1.f) [ SNew(SHorizontalBox) +SHorizontalBox::Slot() .AutoWidth() .Padding( 10,5 ) .VAlign(VAlign_Center) [ SNew(SImage) .Image( this, &SGraphTitleBar::GetTypeGlyph ) ] // show fake 'root' breadcrumb for the title +SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) .Padding(BreadcrumbTrailPadding) [ SNew(STextBlock) .Text(this, &SGraphTitleBar::GetBlueprintTitle ) .TextStyle( FEditorStyle::Get(), TEXT("GraphBreadcrumbButtonText") ) .Visibility( this, &SGraphTitleBar::IsGraphBlueprintNameVisible ) ] +SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) [ SNew(SImage) .Image( BreadcrumbButtonImage ) .Visibility( this, &SGraphTitleBar::IsGraphBlueprintNameVisible ) ] // New style breadcrumb +SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) [ SAssignNew(BreadcrumbTrail, SBreadcrumbTrail<UEdGraph*>) .ButtonStyle(FEditorStyle::Get(), "GraphBreadcrumbButton") .TextStyle(FEditorStyle::Get(), "GraphBreadcrumbButtonText") .ButtonContentPadding( BreadcrumbTrailPadding ) .DelimiterImage( BreadcrumbButtonImage ) .PersistentBreadcrumbs( true ) .OnCrumbClicked( this, &SGraphTitleBar::OnBreadcrumbClicked ) ] +SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) [ SNew(STextBlock) .Font( FSlateFontInfo(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 14 ) ) .ColorAndOpacity( FLinearColor(1,1,1,0.5) ) .Text( this, &SGraphTitleBar::GetTitleExtra ) ] ] ] ] ]; RebuildBreadcrumbTrail(); UBlueprint* BlueprintObj = FBlueprintEditorUtils::FindBlueprintForGraph(this->EdGraphObj); if (BlueprintObj) { bShowBlueprintTitle = true; BlueprintTitle = FText::FromString(BlueprintObj->GetFriendlyName()); // Register for notifications to refresh UI if( Kismet2Ptr.IsValid() ) { Kismet2Ptr.Pin()->OnRefresh().AddRaw(this, &SGraphTitleBar::Refresh); } } }