// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Types/SlateEnums.h" #include "Layout/Visibility.h" #include "Materials/MaterialLayersFunctions.h" #include "Input/Reply.h" #include "Widgets/Layout/SSplitter.h" #include "MaterialEditor/MaterialEditorInstanceConstant.h" #include "DragAndDrop/DecoratedDragDropOp.h" #include "RenderUtils.h" #include "MaterialPropertyHelpers.generated.h" struct FAssetData; class IDetailGroup; class IDetailLayoutBuilder; class IDetailTreeNode; class IPropertyHandle; class UDEditorParameterValue; enum class ECheckBoxState : uint8; class UMaterialInterface; DECLARE_DELEGATE_OneParam(FGetShowHiddenParameters, bool&); enum EStackDataType { Stack, Asset, Group, Property, PropertyChild, }; USTRUCT() struct MATERIALEDITOR_API FSortedParamData { GENERATED_USTRUCT_BODY() public: EStackDataType StackDataType; UPROPERTY(Transient) TObjectPtr Parameter = nullptr; FName PropertyName; FEditorParameterGroup Group; FMaterialParameterInfo ParameterInfo; TSharedPtr ParameterNode; TSharedPtr ParameterHandle; TArray> Children; FString NodeKey; }; USTRUCT() struct FUnsortedParamData { GENERATED_USTRUCT_BODY() UPROPERTY(Transient) TObjectPtr Parameter = nullptr; FEditorParameterGroup ParameterGroup; TSharedPtr ParameterNode; FName UnsortedName; TSharedPtr ParameterHandle; }; /* * Interface for items that can be dragged and can show a layer handle */ class IDraggableItem { public: virtual void OnLayerDragEnter(const FDragDropEvent& DragDropEvent) = 0; virtual void OnLayerDragLeave(const FDragDropEvent& DragDropEvent) = 0; virtual void OnLayerDragDetected() = 0; }; class SLayerHandle : public SCompoundWidget { public: SLATE_BEGIN_ARGS(SLayerHandle) {} SLATE_DEFAULT_SLOT(FArguments, Content) SLATE_ARGUMENT(TSharedPtr, OwningStack) SLATE_END_ARGS() void Construct(const FArguments& InArgs); FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override { return FReply::Handled().DetectDrag(SharedThis(this), EKeys::LeftMouseButton); }; FReply OnDragDetected(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; TSharedPtr CreateDragDropOperation(TSharedPtr InOwningStack); private: TWeakPtr OwningStack; }; class FLayerDragDropOp final : public FDecoratedDragDropOp { public: DRAG_DROP_OPERATOR_TYPE(FLayerDragDropOp, FDecoratedDragDropOp) FLayerDragDropOp(TSharedPtr InOwningStack) { if(Substrate::IsMaterialLayeringSupportEnabled()) { MouseCursor = EMouseCursor::GrabHandClosed; } OwningStack = InOwningStack; DecoratorWidget = SNew(SBorder) .BorderImage(FAppStyle::GetBrush("Graph.ConnectorFeedback.Border")) .Content() [ SNew(SHorizontalBox) + SHorizontalBox::Slot() .AutoWidth() .VAlign(VAlign_Center) [ SNew(STextBlock) .Text(NSLOCTEXT("LayerDragDrop", "PlaceLayerHere", "Place Layer and Blend Here")) ] ]; Construct(); }; TSharedPtr DecoratorWidget; virtual TSharedPtr GetDefaultDecorator() const override { return DecoratorWidget; } TWeakPtr OwningStack; }; /*----------------------------------------------------------------------------- FMaterialInstanceBaseParameterDetails -----------------------------------------------------------------------------*/ class MATERIALEDITOR_API FMaterialPropertyHelpers { public: /** Returns true if the parameter is being overridden */ static bool IsOverriddenExpression(UDEditorParameterValue* Parameter); static bool IsOverriddenExpression(TObjectPtr Parameter) { return IsOverriddenExpression(Parameter.Get()); } static bool IsOverriddenExpression(TWeakObjectPtr Parameter) { return IsOverriddenExpression(Parameter.Get()); } static ECheckBoxState IsOverriddenExpressionCheckbox(UDEditorParameterValue* Parameter); static bool UsesCustomPrimitiveData(UDEditorParameterValue* Parameter); /** Gets the expression description of this parameter from the base material */ static FText GetParameterExpressionDescription(UDEditorParameterValue* Parameter, UObject* MaterialEditorInstance); static FText GetParameterTooltip(UDEditorParameterValue* Parameter, UObject* MaterialEditorInstance); /** * Called when a parameter is overridden; */ static void OnOverrideParameter(bool NewValue, UDEditorParameterValue* Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance); static EVisibility ShouldShowExpression(UDEditorParameterValue* Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance, FGetShowHiddenParameters ShowHiddenDelegate); static EVisibility ShouldShowExpression(TObjectPtr Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance, FGetShowHiddenParameters ShowHiddenDelegate) { return ShouldShowExpression(Parameter.Get(), MaterialEditorInstance, ShowHiddenDelegate); } /** Generic material property reset to default implementation. Resets Parameter to default */ static void ResetToDefault(UDEditorParameterValue* Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance); static void ResetToDefault(TObjectPtr Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance) { ResetToDefault(Parameter.Get(), MaterialEditorInstance); } static bool ShouldShowResetToDefault(UDEditorParameterValue* Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance); static bool ShouldShowResetToDefault(TObjectPtr Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance) { return ShouldShowResetToDefault(Parameter.Get(), MaterialEditorInstance); } /** Specific resets for layer and blend asses */ static void ResetLayerAssetToDefault(UDEditorParameterValue* InParameter, TEnumAsByte InAssociation, int32 Index, UMaterialEditorInstanceConstant* MaterialEditorInstance); /** If reset to default button should show for a layer or blend asset*/ static bool ShouldLayerAssetShowResetToDefault(TSharedPtr InParameterData, UMaterialInstanceConstant* InMaterialInstance); static bool ShouldLayerAssetShowResetToDefault(TSharedPtr InParameterData, TObjectPtr InMaterialInstance) { return ShouldLayerAssetShowResetToDefault(InParameterData, InMaterialInstance.Get()); } static void OnMaterialLayerAssetChanged(const struct FAssetData& InAssetData, int32 Index, EMaterialParameterAssociation MaterialType, TSharedPtr InHandle, FMaterialLayersFunctions* InMaterialFunction); static bool FilterLayerAssets(const struct FAssetData& InAssetData, FMaterialLayersFunctions* LayerFunction, EMaterialParameterAssociation MaterialType, int32 Index); static FReply OnClickedSaveNewMaterialInstance(class UMaterialInterface* Object, UObject* EditorObject); static FReply OnClickedSaveNewMaterialInstance(TObjectPtr Object, UObject* EditorObject) { return OnClickedSaveNewMaterialInstance(Object.Get(), EditorObject); } static void CopyMaterialToInstance(class UMaterialInstanceConstant* ChildInstance, TArray &ParameterGroups); static void TransitionAndCopyParameters(class UMaterialInstanceConstant* ChildInstance, TArray &ParameterGroups, bool bForceCopy = false); static FReply OnClickedSaveNewFunctionInstance(class UMaterialFunctionInterface* Object, class UMaterialInterface* PreviewMaterial, UObject* EditorObject); static FReply OnClickedSaveNewLayerInstance(class UMaterialFunctionInterface* Object, TSharedPtr InSortedData); static void GetVectorChannelMaskComboBoxStrings(TArray>& OutComboBoxStrings, TArray>& OutToolTips, TArray& OutRestrictedItems); static FString GetVectorChannelMaskValue(UDEditorParameterValue* InParameter); static FString GetVectorChannelMaskValue(TObjectPtr InParameter) { return GetVectorChannelMaskValue(InParameter.Get()); } static void SetVectorChannelMaskValue(const FString& StringValue, TSharedPtr PropertyHandle, UDEditorParameterValue* InParameter, UObject* MaterialEditorInstance); static void SetVectorChannelMaskValue(const FString& StringValue, TSharedPtr PropertyHandle, TObjectPtr InParameter, UObject* MaterialEditorInstance) { SetVectorChannelMaskValue(StringValue, PropertyHandle, InParameter.Get(), MaterialEditorInstance); } static TArray GetAssetFactories(EMaterialParameterAssociation AssetType); /** * Returns group for parameter. Creates one if needed. * * @param ParameterGroup Name to be looked for. */ static FEditorParameterGroup& GetParameterGroup(class UMaterial* InMaterial, FName& ParameterGroup, TArray& ParameterGroups); static TSharedRef MakeStackReorderHandle(TSharedPtr InOwningStack); static bool OnShouldSetCurveAsset(const FAssetData& AssetData, TSoftObjectPtr InAtlas); static bool OnShouldFilterCurveAsset(const FAssetData& AssetData, TSoftObjectPtr InAtlas); static void SetPositionFromCurveAsset(const FAssetData& AssetData, TSoftObjectPtr InAtlas, class UDEditorScalarParameterValue* InParameter, TSharedPtr PropertyHandle, UObject* MaterialEditorInstance); static void ResetCurveToDefault(UDEditorParameterValue* Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance); static void ResetCurveToDefault(TObjectPtr Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance) { ResetCurveToDefault(Parameter.Get(), MaterialEditorInstance); } static FText LayerID; static FText BlendID; static FName LayerParamName; };