Files
UnrealEngine/Engine/Source/Editor/MaterialEditor/Public/MaterialPropertyHelpers.h
2025-05-18 13:04:45 +08:00

229 lines
10 KiB
C++

// 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<UDEditorParameterValue> Parameter = nullptr;
FName PropertyName;
FEditorParameterGroup Group;
FMaterialParameterInfo ParameterInfo;
TSharedPtr<IDetailTreeNode> ParameterNode;
TSharedPtr<IPropertyHandle> ParameterHandle;
TArray<TSharedPtr<struct FSortedParamData>> Children;
FString NodeKey;
};
USTRUCT()
struct FUnsortedParamData
{
GENERATED_USTRUCT_BODY()
UPROPERTY(Transient)
TObjectPtr<UDEditorParameterValue> Parameter = nullptr;
FEditorParameterGroup ParameterGroup;
TSharedPtr<IDetailTreeNode> ParameterNode;
FName UnsortedName;
TSharedPtr<IPropertyHandle> 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<IDraggableItem>, 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<class FLayerDragDropOp> CreateDragDropOperation(TSharedPtr<IDraggableItem> InOwningStack);
private:
TWeakPtr<IDraggableItem> OwningStack;
};
class FLayerDragDropOp final : public FDecoratedDragDropOp
{
public:
DRAG_DROP_OPERATOR_TYPE(FLayerDragDropOp, FDecoratedDragDropOp)
FLayerDragDropOp(TSharedPtr<IDraggableItem> 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<SWidget> DecoratorWidget;
virtual TSharedPtr<SWidget> GetDefaultDecorator() const override
{
return DecoratorWidget;
}
TWeakPtr<class IDraggableItem> OwningStack;
};
/*-----------------------------------------------------------------------------
FMaterialInstanceBaseParameterDetails
-----------------------------------------------------------------------------*/
class MATERIALEDITOR_API FMaterialPropertyHelpers
{
public:
/** Returns true if the parameter is being overridden */
static bool IsOverriddenExpression(UDEditorParameterValue* Parameter);
static bool IsOverriddenExpression(TObjectPtr<UDEditorParameterValue> Parameter) { return IsOverriddenExpression(Parameter.Get()); }
static bool IsOverriddenExpression(TWeakObjectPtr<UDEditorParameterValue> 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<UDEditorParameterValue> 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<UDEditorParameterValue> Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance) { ResetToDefault(Parameter.Get(), MaterialEditorInstance); }
static bool ShouldShowResetToDefault(UDEditorParameterValue* Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance);
static bool ShouldShowResetToDefault(TObjectPtr<UDEditorParameterValue> Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance) { return ShouldShowResetToDefault(Parameter.Get(), MaterialEditorInstance); }
/** Specific resets for layer and blend asses */
static void ResetLayerAssetToDefault(UDEditorParameterValue* InParameter, TEnumAsByte<EMaterialParameterAssociation> InAssociation, int32 Index, UMaterialEditorInstanceConstant* MaterialEditorInstance);
/** If reset to default button should show for a layer or blend asset*/
static bool ShouldLayerAssetShowResetToDefault(TSharedPtr<FSortedParamData> InParameterData, UMaterialInstanceConstant* InMaterialInstance);
static bool ShouldLayerAssetShowResetToDefault(TSharedPtr<FSortedParamData> InParameterData, TObjectPtr<UMaterialInstanceConstant> InMaterialInstance) { return ShouldLayerAssetShowResetToDefault(InParameterData, InMaterialInstance.Get()); }
static void OnMaterialLayerAssetChanged(const struct FAssetData& InAssetData, int32 Index, EMaterialParameterAssociation MaterialType, TSharedPtr<class IPropertyHandle> 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<class UMaterialInterface> Object, UObject* EditorObject) { return OnClickedSaveNewMaterialInstance(Object.Get(), EditorObject); }
static void CopyMaterialToInstance(class UMaterialInstanceConstant* ChildInstance, TArray<FEditorParameterGroup> &ParameterGroups);
static void TransitionAndCopyParameters(class UMaterialInstanceConstant* ChildInstance, TArray<FEditorParameterGroup> &ParameterGroups, bool bForceCopy = false);
static FReply OnClickedSaveNewFunctionInstance(class UMaterialFunctionInterface* Object, class UMaterialInterface* PreviewMaterial, UObject* EditorObject);
static FReply OnClickedSaveNewLayerInstance(class UMaterialFunctionInterface* Object, TSharedPtr<FSortedParamData> InSortedData);
static void GetVectorChannelMaskComboBoxStrings(TArray<TSharedPtr<FString>>& OutComboBoxStrings, TArray<TSharedPtr<class SToolTip>>& OutToolTips, TArray<bool>& OutRestrictedItems);
static FString GetVectorChannelMaskValue(UDEditorParameterValue* InParameter);
static FString GetVectorChannelMaskValue(TObjectPtr<UDEditorParameterValue> InParameter) { return GetVectorChannelMaskValue(InParameter.Get()); }
static void SetVectorChannelMaskValue(const FString& StringValue, TSharedPtr<IPropertyHandle> PropertyHandle, UDEditorParameterValue* InParameter, UObject* MaterialEditorInstance);
static void SetVectorChannelMaskValue(const FString& StringValue, TSharedPtr<IPropertyHandle> PropertyHandle, TObjectPtr<UDEditorParameterValue> InParameter, UObject* MaterialEditorInstance) { SetVectorChannelMaskValue(StringValue, PropertyHandle, InParameter.Get(), MaterialEditorInstance); }
static TArray<class UFactory*> 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<FEditorParameterGroup>& ParameterGroups);
static TSharedRef<SWidget> MakeStackReorderHandle(TSharedPtr<IDraggableItem> InOwningStack);
static bool OnShouldSetCurveAsset(const FAssetData& AssetData, TSoftObjectPtr<UCurveLinearColorAtlas> InAtlas);
static bool OnShouldFilterCurveAsset(const FAssetData& AssetData, TSoftObjectPtr<UCurveLinearColorAtlas> InAtlas);
static void SetPositionFromCurveAsset(const FAssetData& AssetData, TSoftObjectPtr<UCurveLinearColorAtlas> InAtlas, class UDEditorScalarParameterValue* InParameter, TSharedPtr<IPropertyHandle> PropertyHandle, UObject* MaterialEditorInstance);
static void ResetCurveToDefault(UDEditorParameterValue* Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance);
static void ResetCurveToDefault(TObjectPtr<UDEditorParameterValue> Parameter, UMaterialEditorInstanceConstant* MaterialEditorInstance) { ResetCurveToDefault(Parameter.Get(), MaterialEditorInstance); }
static FText LayerID;
static FText BlendID;
static FName LayerParamName;
};