// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Array.h" #include "CoreMinimal.h" #include "CoreTypes.h" #include "Delegates/Delegate.h" #include "IPropertyTypeCustomization.h" #include "Internationalization/Text.h" #include "Math/UnitConversion.h" #include "Misc/Optional.h" #include "PropertyHandle.h" #include "Styling/SlateTypes.h" #include "Templates/SharedPointer.h" #include "Types/SlateEnums.h" #include "Widgets/Input/NumericTypeInterface.h" #include "Widgets/SWidget.h" class FDetailWidgetRow; class IDetailChildrenBuilder; class SWidget; struct FSlateBrush; /** * Base class for math struct customization (e.g, vector, rotator, color) */ class DETAILCUSTOMIZATIONS_API FMathStructCustomization : public IPropertyTypeCustomization { public: static TSharedRef MakeInstance(); /** Notification when the max/min slider values are changed (only apply if SupportDynamicSliderMaxValue or SupportDynamicSliderMinValue are true) */ DECLARE_MULTICAST_DELEGATE_FourParams(FOnNumericEntryBoxDynamicSliderMinMaxValueChanged, float, TWeakPtr, bool, bool); FMathStructCustomization() : bIsUsingSlider(false) , bPreserveScaleRatio(false) { } virtual ~FMathStructCustomization() {} /** IPropertyTypeCustomization instance */ virtual void CustomizeHeader(TSharedRef StructPropertyHandle, FDetailWidgetRow& HeaderRow, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override; virtual void CustomizeChildren(TSharedRef StructPropertyHandle, IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils) override; /** Return max/min slider value changed delegate (only apply if SupportDynamicSliderMaxValue or SupportDynamicSliderMinValue are true) */ FOnNumericEntryBoxDynamicSliderMinMaxValueChanged& GetOnNumericEntryBoxDynamicSliderMaxValueChangedDelegate() { return OnNumericEntryBoxDynamicSliderMaxValueChanged; } FOnNumericEntryBoxDynamicSliderMinMaxValueChanged& GetOnNumericEntryBoxDynamicSliderMinValueChangedDelegate() { return OnNumericEntryBoxDynamicSliderMinValueChanged; } /** Callback when the max/min spinner value are changed (only apply if SupportDynamicSliderMaxValue or SupportDynamicSliderMinValue are true) */ template void OnDynamicSliderMaxValueChanged(NumericType NewMaxSliderValue, TWeakPtr InValueChangedSourceWidget, bool IsOriginator, bool UpdateOnlyIfHigher); template void OnDynamicSliderMinValueChanged(NumericType NewMinSliderValue, TWeakPtr InValueChangedSourceWidget, bool IsOriginator, bool UpdateOnlyIfLower); /** * Called to see if the value is enabled for editing * * @param WeakHandlePtr Handle to the property that the new value is for */ bool IsValueEnabled(TWeakPtr WeakHandlePtr) const; // Argument struct for ExtractNumericMetadata, to make it easier to add new metadata to extract. template struct FNumericMetadata { TOptional MinValue; TOptional MaxValue; TOptional SliderMinValue; TOptional SliderMaxValue; TSharedPtr> TypeInterface; NumericType SliderExponent; NumericType Delta; int32 LinearDeltaSensitivity; float ShiftMultiplier; float CtrlMultiplier; bool bSupportDynamicSliderMaxValue; bool bSupportDynamicSliderMinValue; bool bAllowSpinBox; }; /** Utility function that will extract common Math related numeric metadata */ template DETAILCUSTOMIZATIONS_API static void ExtractNumericMetadata(TSharedRef& PropertyHandle, FNumericMetadata& MetadataOut); template UE_DEPRECATED(5.0, "Use ExtractNumericMetadata overload with struct argument instead.") DETAILCUSTOMIZATIONS_API static void ExtractNumericMetadata(TSharedRef& PropertyHandle, TOptional& MinValue, TOptional& MaxValue, TOptional& SliderMinValue, TOptional& SliderMaxValue, NumericType& SliderExponent, NumericType& Delta, int32& ShiftMouseMovePixelPerDelta, bool& bSupportDynamicSliderMaxValue, bool& bSupportDynamicSliderMinValue); protected: /** * Makes the header row for the customization * * @param StructPropertyHandle Handle to the struct property * @param Row The header row to add widgets to */ virtual void MakeHeaderRow(TSharedRef& StructPropertyHandle, FDetailWidgetRow& Row); /** * Gets the sorted children for the struct * * @param StructPropertyHandle The handle to the struct property * @param OutChildren The child array that should be populated in the order that children should be displayed */ virtual void GetSortedChildren(TSharedRef StructPropertyHandle, TArray< TSharedRef >& OutChildren); /** * Constructs a widget for the property handle * * @param StructurePropertyHandle handle of the struct property * @param PropertyHandle Child handle of the struct property */ virtual TSharedRef MakeChildWidget( TSharedRef& StructurePropertyHandle, TSharedRef& PropertyHandle); /** * Gets the value as a float for the provided property handle * * @param WeakHandlePtr Handle to the property to get the value from * @return The value or unset if it could not be accessed */ template TOptional OnGetValue(TWeakPtr WeakHandlePtr) const; /** * Called when the value is committed from the property editor * * @param NewValue The new value of the property as a float * @param CommitType How the value was committed (unused) * @param WeakHandlePtr Handle to the property that the new value is for */ template void OnValueCommitted(NumericType NewValue, ETextCommit::Type CommitType, TWeakPtr WeakHandlePtr); /** * Called when the value is changed in the property editor * * @param NewValue The new value of the property as a float * @param WeakHandlePtr Handle to the property that the new value is for */ template void OnValueChanged(NumericType NewValue, TWeakPtr WeakHandlePtr); /** * Called to set the value of the property handle. * * @param NewValue The new value of the property as a float * @param Flags The flags to pass when setting the value on the property handle. * @param WeakHandlePtr Handle to the property that the new value is for */ template void SetValue(NumericType NewValue, EPropertyValueSetFlags::Type Flags, TWeakPtr WeakHandlePtr); /** * Gets the tooltip for the value. Displays the property name and the current value * * @praram WeakHandlePtr Handle to the property to get the value from */ template UE_DEPRECATED(5.6, "OnGetValueToolTip is deprecated and no longer called.") FText OnGetValueToolTip(TWeakPtr WeakHandlePtr) const; private: TOptional OnGetValueToolTipTextFormat(TWeakPtr WeakHandlePtr) const; /** Gets the brush to use for the lock icon. */ const FSlateBrush* GetPreserveScaleRatioImage() const; /** Gets the checked value of the preserve scale ratio option */ ECheckBoxState IsPreserveScaleRatioChecked() const; /** Called when the user toggles preserve ratio. */ void OnPreserveScaleRatioToggled(ECheckBoxState NewState, TWeakPtr PropertyHandle); FReply OnNormalizeClicked(TWeakPtr PropertyHandle); private: /** Called when a value starts to be changed by a slider */ void OnBeginSliderMovement(); /** Called when a value stops being changed by a slider */ template void OnEndSliderMovement(NumericType NewValue); template TSharedRef MakeNumericWidget(TSharedRef& StructurePropertyHandle, TSharedRef& PropertyHandle); protected: FOnNumericEntryBoxDynamicSliderMinMaxValueChanged OnNumericEntryBoxDynamicSliderMaxValueChanged; FOnNumericEntryBoxDynamicSliderMinMaxValueChanged OnNumericEntryBoxDynamicSliderMinValueChanged; /** All the sorted children of the struct that should be displayed */ TArray< TSharedRef > SortedChildHandles; /** All created numeric entry box widget for this customization */ TArray> NumericEntryBoxWidgetList; /** True if a value is being changed by dragging a slider */ bool bIsUsingSlider; /** True if the ratio is locked when scaling occurs (uniform scaling) */ bool bPreserveScaleRatio; };