// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "BlueprintEditor.h" #include "BlueprintManagedListDetails.h" #include "Containers/Array.h" #include "Containers/BitArray.h" #include "Containers/Set.h" #include "Containers/SparseArray.h" #include "Containers/UnrealString.h" #include "Delegates/Delegate.h" #include "EdGraph/EdGraphPin.h" #include "Engine/Blueprint.h" #include "HAL/Platform.h" #include "HAL/PlatformCrt.h" #include "IDetailCustomNodeBuilder.h" #include "IDetailCustomization.h" #include "Input/Reply.h" #include "Internationalization/Text.h" #include "K2Node_EditablePinBase.h" #include "Layout/Visibility.h" #include "Math/Color.h" #include "Misc/AssertionMacros.h" #include "Misc/Optional.h" #include "SMyBlueprint.h" #include "Styling/SlateTypes.h" #include "Templates/SharedPointer.h" #include "Templates/TypeHash.h" #include "Templates/UnrealTemplate.h" #include "Types/SlateEnums.h" #include "UObject/NameTypes.h" #include "UObject/Script.h" #include "UObject/UnrealNames.h" #include "UObject/WeakFieldPtr.h" #include "UObject/WeakObjectPtr.h" #include "UObject/WeakObjectPtrTemplates.h" #include "Widgets/Views/SListView.h" class FDetailWidgetRow; class FMulticastDelegateProperty; class FProperty; class FStructOnScope; class FSubobjectEditorTreeNode; class IDetailChildrenBuilder; class IDetailLayoutBuilder; class IPropertyHandle; class ITableRow; class SBlueprintNamespaceEntry; class SComboButton; class SEditableTextBox; class SGraphPin; class SMultiLineEditableTextBox; class STableViewBase; class STextComboBox; class SWidget; class UClass; class UEdGraph; class UEdGraphNode; class UEdGraphNode_Documentation; class UFunction; class UK2Node_Variable; class UObject; class UStruct; struct FGeometry; struct FPointerEvent; struct FPropertyChangedEvent; struct FTopLevelAssetPath; /** * Variable network replication options. * @see https://docs.unrealengine.com/InteractiveExperiences/Networking/Blueprints */ namespace EVariableReplication { enum Type { /** * Not replicated. */ None, /** * Replicated from server to client. * As values change on the server, client automatically receives new values, if Actor is set to replicate. */ Replicated, /** * Replicated from server to client, with a notification function called on clients when a new value arrives. * An event with the name "On Rep " is created. */ RepNotify, MAX }; } class FBlueprintDetails : public IDetailCustomization { public: FBlueprintDetails(TWeakPtr InMyBlueprint) : Blueprint(InMyBlueprint.Pin()->GetBlueprintObj()) { } FBlueprintDetails(TWeakPtr InBlueprintEditorPtr) : Blueprint(InBlueprintEditorPtr.Pin()->GetBlueprintObj()) { } protected: UBlueprint* GetBlueprintObj() const { return Blueprint.Get(); } /** * Adds any FMulticastDelegateProperties on the given details builder with either * a green "+" symbol to create a bound node, or a "view" option if it already exists. * * @param DetailBuilder Details builder to add the events to * @param PropertyName Name of the selected property * @param ComponentClass The class to find any Multicast delegate properties on */ void AddEventsCategory(IDetailLayoutBuilder& DetailBuilder, FName PropertyName, UClass* ComponentClass); FReply HandleAddOrViewEventForVariable(const FName EventName, FName PropertyName, TWeakObjectPtr PropertyClass); int32 HandleAddOrViewIndexForButton(const FName EventName, FName PropertyName) const; private: /** Pointer back to my parent tab */ TWeakObjectPtr Blueprint; }; /** Details customization for variables selected in the MyBlueprint panel */ class FBlueprintVarActionDetails : public FBlueprintDetails { public: /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr InMyBlueprint) { return MakeShareable(new FBlueprintVarActionDetails(InMyBlueprint)); } FBlueprintVarActionDetails(TWeakPtr InMyBlueprint) : FBlueprintDetails(InMyBlueprint) , MyBlueprint(InMyBlueprint) , bIsVarNameInvalid(false) { } ~FBlueprintVarActionDetails(); /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override; static void PopulateCategories(SMyBlueprint* MyBlueprint, TArray>& CategorySource); private: /** Accessors passed to parent */ UK2Node_Variable* EdGraphSelectionAsVar() const; FProperty* SelectionAsProperty() const; FName GetVariableName() const; /** Commonly queried attributes about the schema action */ bool IsAUserVariable(FProperty* VariableProperty) const; bool IsASCSVariable(FProperty* VariableProperty) const; bool IsABlueprintVariable(FProperty* VariableProperty) const; bool IsALocalVariable(FProperty* VariableProperty) const; UStruct* GetLocalVariableScope(FProperty* VariableProperty) const; // Callbacks for uproperty details customization bool GetVariableNameChangeEnabled() const; FText OnGetVarName() const; void OnVarNameChanged(const FText& InNewText); void OnVarNameCommitted(const FText& InNewName, ETextCommit::Type InTextCommit); bool GetVariableTypeChangeEnabled() const; FEdGraphPinType OnGetVarType() const; void OnVarTypeChanged(const FEdGraphPinType& NewPinType); EVisibility IsTooltipEditVisible() const; void OnBrowseToVarType() const; bool CanBrowseToVarType() const; /** * Callback when changing a variable property * * @param InPropertyChangedEvent Information on the property changed */ void OnFinishedChangingVariable(const FPropertyChangedEvent& InPropertyChangedEvent); /** * Callback when changing a local variable property * * @param InPropertyChangedEvent Information on the property changed * @param InStructData The struct data where the value of the properties are stored * @param InEntryNode Entry node where the default values of local variables are stored */ void OnFinishedChangingLocalVariable(const FPropertyChangedEvent& InPropertyChangedEvent, TSharedPtr InStructData, TWeakObjectPtr InEntryNode); /** * Auto-import any namespaces associated with a variable's value into the current editor context * * @param InProperty A reference to the variable property * @param InContainer A pointer to the data container (e.g. struct or object) where the property's value is stored */ void ImportNamespacesForPropertyValue(const FProperty* InProperty, const void* InContainer); /** Callback to decide if the category drop down menu should be enabled */ bool GetVariableCategoryChangeEnabled() const; FText OnGetTooltipText() const; void OnTooltipTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit, FName VarName); FText OnGetCategoryText() const; void OnCategoryTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit, FName VarName); TSharedRef< ITableRow > MakeCategoryViewWidget( TSharedPtr Item, const TSharedRef< STableViewBase >& OwnerTable ); void OnCategorySelectionChanged( TSharedPtr ProposedSelection, ESelectInfo::Type /*SelectInfo*/ ); EVisibility ShowEditableCheckboxVisibility() const; ECheckBoxState OnEditableCheckboxState() const; void OnEditableChanged(ECheckBoxState InNewState); EVisibility ShowReadOnlyCheckboxVisibility() const; ECheckBoxState OnReadyOnlyCheckboxState() const; void OnReadyOnlyChanged(ECheckBoxState InNewState); EVisibility GetVariableUnitsVisibility() const; TSharedPtr GetVariableUnits() const; void OnVariableUnitsChanged(TSharedPtr ItemSelected, ESelectInfo::Type SelectInfo); ECheckBoxState OnFieldNotifyCheckboxState() const; void OnFieldNotifyChanged(ECheckBoxState InNewState); EVisibility GetFieldNotifyCheckboxListVisibility() const; ECheckBoxState OnCreateWidgetCheckboxState() const; void OnCreateWidgetChanged(ECheckBoxState InNewState); EVisibility Show3DWidgetVisibility() const; bool Is3DWidgetEnabled(); ECheckBoxState OnGetExposedToSpawnCheckboxState() const; void OnExposedToSpawnChanged(ECheckBoxState InNewState); EVisibility ExposeOnSpawnVisibility() const; ECheckBoxState OnGetPrivateCheckboxState() const; void OnPrivateChanged(ECheckBoxState InNewState); EVisibility ExposePrivateVisibility() const; ECheckBoxState OnGetExposedToCinematicsCheckboxState() const; void OnExposedToCinematicsChanged(ECheckBoxState InNewState); EVisibility ExposeToCinematicsVisibility() const; ECheckBoxState OnGetConfigVariableCheckboxState() const; void OnSetConfigVariableState(ECheckBoxState InNewState); EVisibility ExposeConfigVisibility() const; bool IsConfigCheckBoxEnabled() const; FText OnGetMetaKeyValue(FName Key) const; void OnMetaKeyValueChanged(const FText& NewMinValue, ETextCommit::Type CommitInfo, FName Key); EVisibility RangeVisibility() const; ECheckBoxState OnBitmaskCheckboxState() const; EVisibility BitmaskVisibility() const; void OnBitmaskChanged(ECheckBoxState InNewState); TSharedPtr GetBitmaskEnumTypePath() const; void OnBitmaskEnumTypeChanged(TSharedPtr ItemSelected, ESelectInfo::Type SelectInfo); TSharedRef GenerateBitmaskEnumTypeWidget(TSharedPtr Item); FText GetBitmaskEnumTypeName() const; TSharedPtr GetVariableReplicationType() const; void OnChangeReplication(TSharedPtr ItemSelected, ESelectInfo::Type SelectInfo); void ReplicationOnRepFuncChanged(const FString& NewOnRepFunc) const; EVisibility ReplicationVisibility() const; /** Array of replication conditions for the combo text box */ TArray> ReplicationConditionEnumTypeNames; TSharedPtr GetVariableReplicationCondition() const; void OnChangeReplicationCondition(TSharedPtr ItemSelected, ESelectInfo::Type SelectInfo); bool ReplicationConditionEnabled() const; bool ReplicationEnabled() const; FText ReplicationTooltip() const; EVisibility GetTransientVisibility() const; ECheckBoxState OnGetTransientCheckboxState() const; void OnTransientChanged(ECheckBoxState InNewState); EVisibility GetSaveGameVisibility() const; ECheckBoxState OnGetSaveGameCheckboxState() const; void OnSaveGameChanged(ECheckBoxState InNewState); EVisibility GetAdvancedDisplayVisibility() const; ECheckBoxState OnGetAdvancedDisplayCheckboxState() const; void OnAdvancedDisplayChanged(ECheckBoxState InNewState); EVisibility GetMultilineVisibility() const; ECheckBoxState OnGetMultilineCheckboxState() const; void OnMultilineChanged(ECheckBoxState InNewState); EVisibility GetDeprecatedVisibility() const; ECheckBoxState OnGetDeprecatedCheckboxState() const; void OnDeprecatedChanged(ECheckBoxState InNewState); EVisibility GetDropDownOptionsVisibility() const; void OnDropDownOptionSelectionChanged(TSharedPtr InString, ESelectInfo::Type); void OnDropDownOptionTextChanged(const FText& Text, ETextCommit::Type); TSharedRef GenerateDropDownOptionWidget(TSharedPtr InItem) const; void CollectDropDownOptions(); FText GetDropDownOptionDisplayText() const; FString GetDropDownOptionsFunctionName() const; void SetDropDownOptionsFunctionName(const FString& InFunctionName); FText GetDeprecationMessageText() const; void OnDeprecationMessageTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit, FName VarName); /** Refresh the property flags list */ void RefreshPropertyFlags(); /** Generates the widget for the property flag list */ TSharedRef OnGenerateWidgetForPropertyList( TSharedPtr< FString > Item, const TSharedRef& OwnerTable ); /** Delegate to build variable events droplist menu */ TSharedRef BuildEventsMenuForVariable() const; /** Refreshes cached data that changes after a Blueprint recompile */ void OnPostEditorRefresh(); /** Returns the Property's Blueprint */ UBlueprint* GetPropertyOwnerBlueprint() const { return PropertyOwnerBlueprint.Get(); } /** Returns TRUE if the Variable is in the current Blueprint */ bool IsVariableInBlueprint() const { return GetPropertyOwnerBlueprint() == GetBlueprintObj(); } /** Returns TRUE if the Variable is inherited by the current Blueprint */ bool IsVariableInheritedByBlueprint() const; /** Returns TRUE if the Variable is marked as deprecated */ bool IsVariableDeprecated() const; private: /** Pointer back to my parent tab */ TWeakPtr MyBlueprint; /** Array of replication options for our combo text box */ TArray> ReplicationOptions; /** Array of function names that can be used for GetOptions */ TArray> DropDownFunctionOptions; /** Array of units options for our combo text box */ TArray> UnitsOptions; /** Array of enum type names for integers used as bitmasks */ TArray> BitmaskEnumTypePaths; /** The widget used when in variable name editing mode */ TSharedPtr VarNameEditableTextBox; /** Flag to indicate whether or not the variable name is invalid */ bool bIsVarNameInvalid; /** A list of all category names to choose from */ TArray> CategorySource; /** Widgets for the categories */ TWeakPtr CategoryComboButton; TWeakPtr>> CategoryListView; /** Array of names of property flags on the selected property */ TArray< TSharedPtr< FString > > PropertyFlags; /** The listview widget for displaying property flags */ TWeakPtr< SListView< TSharedPtr< FString > > > PropertyFlagWidget; /** Cached property for the variable we are affecting */ TWeakFieldPtr CachedVariableProperty; /** Cached name for the variable we are affecting */ FName CachedVariableName; /** Pointer back to the variable's Blueprint */ TWeakObjectPtr PropertyOwnerBlueprint; /** External detail customizations */ TArray> ExternalDetailCustomizations; }; class FBaseBlueprintGraphActionDetails : public IDetailCustomization { public: virtual ~FBaseBlueprintGraphActionDetails(); FBaseBlueprintGraphActionDetails(TWeakPtr InMyBlueprint) : MyBlueprint(InMyBlueprint) { } /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override { check(false); } /** Gets the graph that we are currently editing */ virtual UEdGraph* GetGraph() const; /** Refreshes the graph and ensures the target node is up to date */ void OnParamsChanged(UK2Node_EditablePinBase* TargetNode, bool bForceRefresh = false); /** Checks if the pin rename can occur */ bool OnVerifyPinRename(UK2Node_EditablePinBase* InTargetNode, const FName InOldName, const FString& InNewName, FText& OutErrorMessage); /** Refreshes the graph and ensures the target node is up to date */ bool OnPinRenamed(UK2Node_EditablePinBase* TargetNode, const FName OldName, const FString& NewName); /** Gets the blueprint we're editing */ TWeakPtr GetMyBlueprint() const {return MyBlueprint.Pin();} /** Gets the node for the function entry point */ TWeakObjectPtr GetFunctionEntryNode() const {return FunctionEntryNodePtr;} /** Sets the delegate to be called when refreshing our children */ void SetRefreshDelegate(FSimpleDelegate RefreshDelegate, bool bForInputs); /** Accessors passed to parent */ UBlueprint* GetBlueprintObj() const {return MyBlueprint.Pin()->GetBlueprintObj();} FReply OnAddNewInputClicked(); /** Called when blueprint changes */ void OnPostEditorRefresh(); protected: /** Tries to create the result node (if there are output args) */ bool AttemptToCreateResultNode(); /** Pointer to the parent */ TWeakPtr MyBlueprint; /** The entry node in the graph */ TWeakObjectPtr FunctionEntryNodePtr; /** The result node in the graph, if the function has any return or out params. This can be the same as the entry point */ TWeakObjectPtr FunctionResultNodePtr; /** Delegates to regenerate the lists of children */ FSimpleDelegate RegenerateInputsChildrenDelegate; FSimpleDelegate RegenerateOutputsChildrenDelegate; /** Details layout builder we need to hold on to to refresh it at times */ IDetailLayoutBuilder* DetailsLayoutPtr; /** Handle for graph refresh delegate */ FDelegateHandle BlueprintEditorRefreshDelegateHandle; /** Array of nodes were were constructed to represent */ TArray< TWeakObjectPtr > ObjectsBeingEdited; }; class FBlueprintDelegateActionDetails : public FBaseBlueprintGraphActionDetails { public: /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr InMyBlueprint) { return MakeShareable(new FBlueprintDelegateActionDetails(InMyBlueprint)); } FBlueprintDelegateActionDetails(TWeakPtr InMyBlueprint) : FBaseBlueprintGraphActionDetails(InMyBlueprint) { } /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override; /** Gets the graph that we are currently editing */ virtual UEdGraph* GetGraph() const override; private: void SetEntryNode(); FMulticastDelegateProperty* GetDelegateProperty() const; void CollectAvailibleSignatures(); void OnFunctionSelected(TSharedPtr FunctionItemData, ESelectInfo::Type SelectInfo); bool IsBlueprintProperty() const; EVisibility OnGetSectionTextVisibility(TWeakPtr RowWidget) const; private: TArray> FunctionsToCopySignatureFrom; TSharedPtr CopySignatureComboButton; }; /** Custom struct for each group of arguments in the function editing details */ class FBlueprintGraphArgumentGroupLayout : public IDetailCustomNodeBuilder, public TSharedFromThis { public: FBlueprintGraphArgumentGroupLayout(TWeakPtr InGraphActionDetails, UK2Node_EditablePinBase* InTargetNode) : GraphActionDetailsPtr(InGraphActionDetails) , TargetNode(InTargetNode) {} private: /** IDetailCustomNodeBuilder Interface*/ virtual void SetOnRebuildChildren( FSimpleDelegate InOnRegenerateChildren ) override; virtual void GenerateHeaderRowContent( FDetailWidgetRow& NodeRow ) override {} virtual void GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) override; virtual void Tick( float DeltaTime ) override {} virtual bool RequiresTick() const override { return false; } virtual FName GetName() const override { return NAME_None; } virtual bool InitiallyCollapsed() const override { return false; } private: /** The parent graph action details customization */ TWeakPtr GraphActionDetailsPtr; /** The target node that this argument is on */ TWeakObjectPtr TargetNode; }; /** Custom struct for each argument in the function editing details */ class FBlueprintGraphArgumentLayout : public IDetailCustomNodeBuilder, public TSharedFromThis { public: FBlueprintGraphArgumentLayout(TWeakPtr PinInfo, UK2Node_EditablePinBase* InTargetNode, TWeakPtr InGraphActionDetails, FName InArgName, bool bInHasDefaultValue) : GraphActionDetailsPtr(InGraphActionDetails) , ParamItemPtr(PinInfo) , TargetNode(InTargetNode) , bHasDefaultValue(bInHasDefaultValue) , ArgumentName(InArgName) {} virtual ~FBlueprintGraphArgumentLayout(); private: /** IDetailCustomNodeBuilder Interface*/ virtual void SetOnRebuildChildren( FSimpleDelegate InOnRegenerateChildren ) override {} virtual void GenerateHeaderRowContent( FDetailWidgetRow& NodeRow ) override; virtual void GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) override; virtual void Tick( float DeltaTime ) override {} virtual bool RequiresTick() const override { return false; } virtual FName GetName() const override { return ArgumentName; } virtual bool InitiallyCollapsed() const override { return true; } private: /** Determines if this pin should not be editable */ bool ShouldPinBeReadOnly(bool bIsEditingPinType = false) const; /** Determines if editing the pins on the node should be read only */ bool IsPinEditingReadOnly(bool bIsEditingPinType = false) const; /** Callbacks for all the functionality for modifying arguments */ void OnRemoveClicked(); void OnArgumentGraphChanged(const FEdGraphEditAction& Action); FText OnGetArgNameText() const; FText OnGetArgToolTipText() const; void OnArgNameChange(const FText& InNewText); void OnArgNameTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit); FEdGraphPinType OnGetPinInfo() const; void PinInfoChanged(const FEdGraphPinType& PinType); void OnPrePinInfoChange(const FEdGraphPinType& PinType); /** Returns the graph pin representing this variable */ UEdGraphPin* GetPin() const; /** Returns whether the "Pass-by-Reference" checkbox is checked or not */ ECheckBoxState IsRefChecked() const; ECheckBoxState IsConstChecked() const; /** Handles toggling the "Pass-by-Reference" checkbox */ void OnRefCheckStateChanged(ECheckBoxState InState); void OnConstCheckStateChanged(ECheckBoxState InState); bool ShouldBeForceConst() const; bool CanChangeConst() const; private: /** The parent graph action details customization */ TWeakPtr GraphActionDetailsPtr; /** The argument pin that this layout reflects */ TWeakPtr ParamItemPtr; /** The target node that this argument is on */ UK2Node_EditablePinBase* TargetNode; /** Whether or not this builder should have a default value edit control (input args only) */ bool bHasDefaultValue; /** The name of this argument for remembering expansion state */ FName ArgumentName; /** Holds a weak pointer to the argument name widget, used for error notifications */ TWeakPtr ArgumentNameWidget; /** The SGraphPin widget created to show/edit default value */ TSharedPtr DefaultValuePinWidget; /** Delegate handle for node changes */ FDelegateHandle GraphChangedHandler; }; // local variables in the details view only support read-only mode at the moment. // the incomplete read/write functionality can be turned on by setting this to true but you'll have to write some more code to make it compile/work #define UE_BP_LOCAL_VAR_LAYOUT_SETTERS_IMPLEMENTED false /** Custom struct for each group of local variables in the function editing details */ class FBlueprintGraphLocalVariableGroupLayout : public IDetailCustomNodeBuilder, public TSharedFromThis { public: FBlueprintGraphLocalVariableGroupLayout(TWeakPtr InGraphActionDetails, TWeakObjectPtr InTargetGraph, TWeakObjectPtr InBlueprintObj, TWeakObjectPtr InOwningFunction, TSharedPtr Property = nullptr) : GraphActionDetailsPtr(InGraphActionDetails) , TargetGraph(InTargetGraph) , BlueprintObj(InBlueprintObj) , PropertyHandle(Property) , OwningFunction(InOwningFunction) {} virtual TSharedPtr GetPropertyHandle() const override {return PropertyHandle;} private: /** IDetailCustomNodeBuilder Interface*/ virtual void GenerateHeaderRowContent( FDetailWidgetRow& NodeRow ) override {} virtual void GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) override; virtual void Tick( float DeltaTime ) override {} virtual bool RequiresTick() const override { return false; } virtual FName GetName() const override { return NAME_None; } virtual bool InitiallyCollapsed() const override { return false; } private: /** The parent graph action details customization */ TWeakPtr GraphActionDetailsPtr; /** The target graph that the local variable's are on */ TWeakObjectPtr TargetGraph; /** The blueprint object that the target graph is in */ TWeakObjectPtr BlueprintObj; /** handle to property for array of FBPVariableDescription's */ TSharedPtr PropertyHandle; /** function that owns the local variable's being displayed */ TWeakObjectPtr OwningFunction; }; /** Custom struct for each local variable in the function editing details */ class FBlueprintGraphLocalVariableLayout : public IDetailCustomNodeBuilder, public TSharedFromThis { public: FBlueprintGraphLocalVariableLayout(TWeakObjectPtr InOwningFunction, const FBPVariableDescription& VariableDescription) : OwningFunction(InOwningFunction) { Data.Set(VariableDescription); } FBlueprintGraphLocalVariableLayout(TWeakObjectPtr InOwningFunction, TSharedPtr Property = nullptr) : OwningFunction(InOwningFunction) { Data.Set>(Property); } virtual TSharedPtr GetPropertyHandle() const override; const FBPVariableDescription& GetVariable() const; void SetVariable(const FBPVariableDescription&); private: /** IDetailCustomNodeBuilder Interface*/ virtual void SetOnRebuildChildren( FSimpleDelegate InOnRegenerateChildren ) override {} virtual void GenerateHeaderRowContent( FDetailWidgetRow& NodeRow ) override; virtual void GenerateChildContent( IDetailChildrenBuilder& ChildrenBuilder ) override; virtual void Tick( float DeltaTime ) override {} virtual bool RequiresTick() const override { return false; } virtual FName GetName() const override { return GetVariable().VarName; } virtual bool InitiallyCollapsed() const override { return true; } private: /** Determines if this pin should not be editable */ bool ShouldVarBeReadOnly(bool bIsEditingPinType = false) const; /** Determines if editing the pins on the node should be read only */ bool IsVariableEditingReadOnly(bool bIsEditingPinType = false) const; /** Callbacks for all the functionality for modifying local variables */ FText OnGetVarNameText() const; FText OnGetVarToolTipText() const; FEdGraphPinType OnGetVariableType() const; // currently this layout is for read only data. If you need to use it for read/write, you can implement the following methods. #if UE_BP_LOCAL_VAR_LAYOUT_SETTERS_IMPLEMENTED void OnRemoveClicked(); void OnVarNameChange(const FText& InNewText); void OnVarNameTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit); void VariableTypeChanged(const FEdGraphPinType& PinType); void OnPreVariableTypeChange(const FEdGraphPinType& PinType); #endif private: /** Holds a weak pointer to the argument name widget, used for error notifications */ TWeakPtr VariableNameWidget; /** The SGraphPin widget created to show/edit default value */ TSharedPtr DefaultValueWidget; /** either the read only copy of FBPVariableDescription or the property handle to the original variable description */ TVariant, FBPVariableDescription> Data; /** function that owns this local variable */ TWeakObjectPtr OwningFunction; }; /** Details customization for functions and graphs selected in the MyBlueprint panel */ class FBlueprintGraphActionDetails : public FBaseBlueprintGraphActionDetails { public: /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr InMyBlueprint, bool bInShowLocalVariables = false) { return MakeShareable(new FBlueprintGraphActionDetails(InMyBlueprint, bInShowLocalVariables)); } FBlueprintGraphActionDetails(TWeakPtr InMyBlueprint, bool bInShowLocalVariables = false) : FBaseBlueprintGraphActionDetails(InMyBlueprint) , bShowLocalVariables(bInShowLocalVariables) { } /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override; private: struct FAccessSpecifierLabel { FText LocalizedName; EFunctionFlags SpecifierFlag; FAccessSpecifierLabel( FText InLocalizedName, EFunctionFlags InSpecifierFlag) : LocalizedName( InLocalizedName ), SpecifierFlag( InSpecifierFlag ) {} }; private: /** Setup for the nodes this details customizer needs to access */ void SetEntryAndResultNodes(); /** Gets the node we are currently editing if available */ UK2Node_EditablePinBase* GetEditableNode() const; /* Get function associated with the selected graph*/ UFunction* FindFunction() const; /** Utility for editing metadata on the function */ FKismetUserDeclaredFunctionMetadata* GetMetadataBlock() const; // Callbacks for uproperty details customization FText OnGetTooltipText() const; void OnTooltipTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit); FText OnGetCategoryText() const; void OnCategoryTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit); FText OnGetKeywordsText() const; void OnKeywordsTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit); FText OnGetCompactNodeTitleText() const; void OnCompactNodeTitleTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit); FText AccessSpecifierProperName( uint32 AccessSpecifierFlag ) const; bool IsAccessSpecifierVisible() const; TSharedRef HandleGenerateRowAccessSpecifier( TSharedPtr SpecifierName, const TSharedRef& OwnerTable ); FText GetCurrentAccessSpecifierName() const; void OnAccessSpecifierSelected( TSharedPtr SpecifierName, ESelectInfo::Type SelectInfo ); bool GetInstanceColorVisibility() const; FLinearColor GetNodeTitleColor() const; FReply ColorBlock_OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent); bool IsCustomEvent() const; void OnIsReliableReplicationFunctionModified(const ECheckBoxState NewCheckedState); ECheckBoxState GetIsReliableReplicatedFunction() const; struct FReplicationSpecifierLabel { FText LocalizedName; FText LocalizedToolTip; uint32 SpecifierFlag; FReplicationSpecifierLabel( FText InLocalizedName, uint32 InSpecifierFlag, FText InLocalizedToolTip ) : LocalizedName( InLocalizedName ), LocalizedToolTip( InLocalizedToolTip ), SpecifierFlag( InSpecifierFlag ) {} }; FText GetCurrentReplicatedEventString() const; FText ReplicationSpecifierProperName( uint32 ReplicationSpecifierFlag ) const; TSharedRef OnGenerateReplicationComboWidget( TSharedPtr InNetFlag, const TSharedRef& OwnerTable ); bool IsPureFunctionVisible() const; void OnIsPureFunctionModified(const ECheckBoxState NewCheckedState); ECheckBoxState GetIsPureFunction() const; bool IsConstFunctionVisible() const; void OnIsConstFunctionModified(const ECheckBoxState NewCheckedState); ECheckBoxState GetIsConstFunction() const; bool IsExecFunctionVisible() const; void OnIsExecFunctionModified(const ECheckBoxState NewCheckedState); ECheckBoxState GetIsExecFunction() const; bool IsThreadSafeFunctionVisible() const; void OnIsThreadSafeFunctionModified(const ECheckBoxState NewCheckedState); ECheckBoxState GetIsThreadSafeFunction() const; bool IsUnsafeDuringActorConstructionVisible() const; void OnIsUnsafeDuringActorConstructionModified(const ECheckBoxState NewCheckedState); ECheckBoxState GetIsUnsafeDuringActorConstruction() const; bool IsFieldNotifyCheckVisible() const; bool GetIsFieldNotfyEnabled() const; ECheckBoxState OnFieldNotifyCheckboxState() const; void OnFieldNotifyChanged(ECheckBoxState InNewState); /** Determines if the selected event is identified as editor callable */ ECheckBoxState GetIsEditorCallableEvent() const; /** Enables/Disables selected event as editor callable */ void OnEditorCallableEventModified( const ECheckBoxState NewCheckedState ) const; bool IsFunctionDeprecated() const; ECheckBoxState OnGetDeprecatedCheckboxState() const; void OnDeprecatedChanged(ECheckBoxState InNewState); FText GetDeprecationMessageText() const; void OnDeprecationMessageTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit); FReply OnAddNewOutputClicked(); /** Callback to determine if the "New" button for adding input/output pins is visible */ EVisibility GetAddNewInputOutputVisibility() const; /** Callback to determine if the "new" button for adding input/output pins is enabled */ bool IsAddNewInputOutputEnabled() const; EVisibility OnGetSectionTextVisibility(TWeakPtr RowWidget) const; /** Called to set the replication type from the details view combo */ static void SetNetFlags( TWeakObjectPtr FunctionEntryNode, uint32 NetFlags); /** Callback when a graph category is changed */ void OnCategorySelectionChanged( TSharedPtr ProposedSelection, ESelectInfo::Type /*SelectInfo*/ ); /** Callback to make category widgets */ TSharedRef< ITableRow > MakeCategoryViewWidget( TSharedPtr Item, const TSharedRef< STableViewBase >& OwnerTable ); private: /** List of available localized access specifiers names */ TArray > AccessSpecifierLabels; /** ComboButton with access specifiers */ TSharedPtr< class SComboButton > AccessSpecifierComboButton; /** Color block for parenting the color picker */ TSharedPtr ColorBlock; /** A list of all category names to choose from */ TArray> CategorySource; /** Widgets for the categories */ TWeakPtr CategoryComboButton; TWeakPtr>> CategoryListView; /** External detail customizations */ TArray> ExternalDetailCustomizations; bool bShowLocalVariables = false; }; /** Blueprint global options - managed list details customization base */ class FBlueprintGlobalOptionsManagedListDetails : public FBlueprintManagedListDetails { public: /** Constructor method */ FBlueprintGlobalOptionsManagedListDetails(TWeakPtr InGlobalOptionsDetailsPtr); protected: /** Access to external resources */ UBlueprint* GetBlueprintObjectChecked() const; TSharedPtr GetPinnedBlueprintEditorPtr() const; /** Helper function to set the Blueprint back into the KismetInspector's details view */ void OnRefreshInDetailsView(); private: /** The parent graph action details customization */ TWeakPtr GlobalOptionsDetailsPtr; }; /** Blueprint Imports List Details */ class FBlueprintImportsLayout : public FBlueprintGlobalOptionsManagedListDetails, public TSharedFromThis { public: FBlueprintImportsLayout(TWeakPtr InGlobalOptionsDetails, bool bInShowDefaultImports); protected: /** FBlueprintManagedListDetails interface*/ virtual TSharedPtr MakeAddItemWidget() override; virtual void GetManagedListItems(TArray& OutListItems) const override; virtual void OnRemoveItem(const FManagedListItem& Item) override; /** END FBlueprintManagedListDetails interface */ void OnNamespaceSelected(const FString& InNamespace); void OnGetNamespacesToExclude(TSet& OutNamespacesToExclude) const; private: /** Whether we should show default (i.e. global) imports versus custom (i.e. local) imports */ bool bShouldShowDefaultImports; }; /** Blueprint Interface List Details */ class FBlueprintInterfaceLayout : public FBlueprintGlobalOptionsManagedListDetails, public TSharedFromThis { public: FBlueprintInterfaceLayout(TWeakPtr InGlobalOptionsDetails, TSharedPtr InInterfacesProperty = nullptr); /** IDetailCustomNodeBuilder interface */ virtual TSharedPtr GetPropertyHandle() const override; /** END IDetailCustomNodeBuilder interface */ protected: /** FBlueprintManagedListDetails interface */ virtual TSharedPtr MakeAddItemWidget() override; virtual void GetManagedListItems(TArray& OutListItems) const override; virtual void OnRemoveItem(const FManagedListItem& Item) override; /** END FBlueprintManagedListDetails interface */ private: /** Callbacks for details UI */ TSharedRef OnGetAddInterfaceMenuContent(); /** Callback function when an interface class is picked */ void OnClassPicked(UClass* PickedClass); private: /** The add interface combo button */ TSharedPtr AddInterfaceComboButton; /** Property that stores interfaces */ TSharedPtr InterfacesProperty; }; /** Details customization for Blueprint settings */ class FBlueprintGlobalOptionsDetails : public IDetailCustomization { public: /** Constructor */ FBlueprintGlobalOptionsDetails(TWeakPtr InBlueprintEditorPtr) :BlueprintEditorPtr(InBlueprintEditorPtr) ,BlueprintObjOverride(nullptr) { } FBlueprintGlobalOptionsDetails(TWeakObjectPtr InBlueprintPtr) :BlueprintObjOverride(InBlueprintPtr) { } /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr InBlueprintEditorPtr) { return MakeShareable(new FBlueprintGlobalOptionsDetails(InBlueprintEditorPtr)); } /** Diff functionality doesn't need access to the FBlueprintEditor so this allows creation without editor access * but with limited functionality */ static TSharedRef MakeInstanceForDiff(TWeakObjectPtr InBlueprintPtr) { return MakeShareable(new FBlueprintGlobalOptionsDetails(InBlueprintPtr)); } /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override; /** Gets the Blueprint being edited */ UBlueprint* GetBlueprintObj() const; /** Gets the Blueprint editor */ TWeakPtr GetBlueprintEditorPtr() const {return BlueprintEditorPtr;} protected: /** Gets the Blueprint parent class name text */ FText GetParentClassName() const; // Determine whether or not we should be allowed to reparent (but still display the parent class regardless) bool CanReparent() const; /** Gets the menu content that's displayed when the parent class combo box is clicked */ TSharedRef GetParentClassMenuContent(); /** Delegate called when a class is selected from the class picker */ void OnClassPicked(UClass* SelectedClass); /** Returns TRUE if the Blueprint can be deprecated */ bool CanDeprecateBlueprint() const; /** Callback when toggling the Deprecate checkbox, handles marking a Blueprint as deprecated */ void OnDeprecateBlueprint(ECheckBoxState InCheckState); /** Callback for Deprecate checkbox, returns checked if the Blueprint is deprecated */ ECheckBoxState IsDeprecatedBlueprint() const; /** Returns the tooltip explaining deprecation */ FText GetDeprecatedTooltip() const; /** Callback for when a new Blueprint namespace value is entered */ void OnNamespaceValueCommitted(const FString& InNamespace); /** Determine Blueprint namespace "reset to default" button visibility */ bool ShouldShowNamespaceResetToDefault() const; /** Invoked when the Blueprint namespace "reset to default" button is clicked */ void OnNamespaceResetToDefaultValue(); /** Called when the assigned Blueprint namespace value is changed */ void HandleNamespaceValueChange(const FString& InOldValue, const FString& InNewValue); private: /** Weak reference to the Blueprint editor */ TWeakPtr BlueprintEditorPtr; /** Weak reference to a Blueprint override - used to customize a blueprint that is displayed without an editor, e.g. for diff */ TWeakObjectPtr BlueprintObjOverride; /** Combo button used to choose a parent class */ TSharedPtr ParentClassComboButton; /** Handle to the customized namespace property */ TSharedPtr NamespacePropertyHandle; /** Widget used for namespace value customization */ TSharedPtr NamespaceValueWidget; /** Desired width for namespace value customization */ static float NamespacePropertyValueCustomization_MinDesiredWidth; }; /** Details customization for Blueprint Component settings */ class FBlueprintComponentDetails : public FBlueprintDetails { public: /** Constructor */ FBlueprintComponentDetails(TWeakPtr InBlueprintEditorPtr) : FBlueprintDetails(InBlueprintEditorPtr) , BlueprintEditorPtr(InBlueprintEditorPtr) , bIsVariableNameInvalid(false) { } /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr InBlueprintEditorPtr) { return MakeShareable(new FBlueprintComponentDetails(InBlueprintEditorPtr)); } /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override; protected: /** Callbacks for widgets */ FText OnGetVariableText() const; void OnVariableTextChanged(const FText& InNewText); void OnVariableTextCommitted(const FText& InNewName, ETextCommit::Type InTextCommit); FText OnGetTooltipText() const; void OnTooltipTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit, FName VarName); bool OnVariableCategoryChangeEnabled() const; FText OnGetVariableCategoryText() const; void OnVariableCategoryTextCommitted(const FText& NewText, ETextCommit::Type InTextCommit, FName VarName); void OnVariableCategorySelectionChanged(TSharedPtr ProposedSelection, ESelectInfo::Type /*SelectInfo*/); TSharedRef MakeVariableCategoryViewWidget(TSharedPtr Item, const TSharedRef< STableViewBase >& OwnerTable); const UClass* GetSelectedEntryClass() const; void HandleNewEntryClassSelected(const UClass* NewEntryClass) const; FText GetSocketName() const; bool CanChangeSocket() const; void OnBrowseSocket(); void OnClearSocket(); void OnSocketSelection( FName SocketName ); void PopulateVariableCategories(); private: /** Weak reference to the Blueprint editor */ TWeakPtr BlueprintEditorPtr; /** The cached tree Node we're editing */ TSharedPtr CachedNodePtr; /** The widget used when in variable name editing mode */ TSharedPtr VariableNameEditableTextBox; /** Flag to indicate whether or not the variable name is invalid */ bool bIsVariableNameInvalid; /** A list of all category names to choose from */ TArray> VariableCategorySource; /** Widgets for the categories */ TSharedPtr VariableCategoryComboButton; TSharedPtr>> VariableCategoryListView; }; /** Details customization for All Graph Nodes */ class FBlueprintGraphNodeDetails : public IDetailCustomization { public: /** Constructor */ FBlueprintGraphNodeDetails(TWeakPtr InBlueprintEditorPtr) : GraphNodePtr(NULL) , BlueprintEditorPtr(InBlueprintEditorPtr) { } /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr InBlueprintEditorPtr) { return MakeShareable(new FBlueprintGraphNodeDetails(InBlueprintEditorPtr)); } /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override; protected: /** Returns the currently edited blueprint */ UBlueprint* GetBlueprintObj() const; private: /** Set error to name textbox */ void SetNameError( const FText& Error ); // Callbacks for uproperty details customization FText OnGetName() const; bool IsNameReadOnly() const; void OnNameChanged(const FText& InNewText); void OnNameCommitted(const FText& InNewName, ETextCommit::Type InTextCommit); /** The widget used when editing a singleline name */ TSharedPtr NameEditableTextBox; /** The widget used when editing a multiline name */ TSharedPtr MultiLineNameEditableTextBox; /** The target GraphNode */ TWeakObjectPtr GraphNodePtr; /** Weak reference to the Blueprint editor */ TWeakPtr BlueprintEditorPtr; }; /** Details customization for ChildActorComponents */ class FChildActorComponentDetails : public IDetailCustomization { public: /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr BlueprintEditorPtr); /** Constructor */ FChildActorComponentDetails(TWeakPtr BlueprintEditorPtr); /** IDetailCustomization interface */ virtual void CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) override; private: /** Weak reference to the Blueprint editor */ TWeakPtr BlueprintEditorPtr; }; /** Details customization for Blueprint Documentation */ class FBlueprintDocumentationDetails : public IDetailCustomization { public: /** Constructor */ FBlueprintDocumentationDetails(TWeakPtr InBlueprintEditorPtr) : BlueprintEditorPtr(InBlueprintEditorPtr) { } /** Makes a new instance of this detail layout class for a specific detail view requesting it */ static TSharedRef MakeInstance(TWeakPtr InBlueprintEditorPtr) { return MakeShareable(new FBlueprintDocumentationDetails(InBlueprintEditorPtr)); } /** IDetailCustomization interface */ virtual void CustomizeDetails( IDetailLayoutBuilder& DetailLayout ) override; protected: /** Accessors passed to parent */ UBlueprint* GetBlueprintObj() const { return BlueprintEditorPtr.Pin()->GetBlueprintObj(); } /** Get the currently selected node from the edgraph */ TWeakObjectPtr EdGraphSelectionAsDocumentNode(); /** Accessor for the current nodes documentation link */ FText OnGetDocumentationLink() const; /** Accessor for the nodes current documentation excerpt */ FText OnGetDocumentationExcerpt() const; /** Accessor to evaluate if the current excerpt can be modified */ bool OnExcerptChangeEnabled() const; /** Handler for the documentation link being committed */ void OnDocumentationLinkCommitted( const FText& InNewName, ETextCommit::Type InTextCommit ); /** Generate table row for excerpt combo */ TSharedRef< ITableRow > MakeExcerptViewWidget( TSharedPtr Item, const TSharedRef< STableViewBase >& OwnerTable ); /** Apply selection changes from the excerpt combo */ void OnExcerptSelectionChanged( TSharedPtr ProposedSelection, ESelectInfo::Type SelectInfo ); /** Generate excerpt list widget from documentation page */ TSharedRef GenerateExcerptList(); private: /** Documentation Link */ FString DocumentationLink; /** Current Excerpt */ FString DocumentationExcerpt; /** Weak reference to the Blueprint editor */ TWeakPtr BlueprintEditorPtr; /** The editor node we're editing */ TWeakObjectPtr DocumentationNodePtr; /** Excerpt combo widget */ TSharedPtr ExcerptComboButton; /** Excerpt List */ TArray> ExcerptList; };