// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved. #pragma once #include "MathStructCustomizations.h" /** * Helper class used to track the dirty state of a proxy value */ template< typename ObjectType > class TProxyValue { public: TProxyValue() : Value() , bIsSet(false) { } TProxyValue(const ObjectType& InValue) : Value(InValue) , bIsSet(false) { } /** * Set the wrapped value * @param InValue The value to set. */ void Set(const ObjectType& InValue) { Value = InValue; bIsSet = true; } /** * Get the wrapped value * @return the wrapped value */ const ObjectType& Get() const { return Value; } /** * Get the wrapped value * @return the wrapped value */ ObjectType& Get() { return Value; } /** * Check to see if the value is set. * @return whether the value is set. */ bool IsSet() const { return bIsSet; } /** * Mark the value as if it was set. */ void MarkAsSet() { bIsSet = true; } private: /** The value we are tracking */ ObjectType Value; /** Whether the value is set */ bool bIsSet; }; /** * Helper class used to track the state of properties of proxy values. */ template< typename ObjectType, typename PropertyType > class TProxyProperty { public: TProxyProperty(const TSharedRef< TProxyValue >& InValue, PropertyType& InPropertyValue) : Value(InValue) , Property(InPropertyValue) , bIsSet(false) { } /** * Set the value of this property * @param InPropertyValue The value of the property to set */ void Set(const PropertyType& InPropertyValue) { Property = InPropertyValue; Value->MarkAsSet(); bIsSet = true; } /** * Get the value of this property * @return The value of the property */ const PropertyType& Get() const { return Property; } /** * Check to see if the value is set. * @return whether the value is set. */ bool IsSet() const { return bIsSet; } private: /** The proxy value we are tracking */ TSharedRef< TProxyValue > Value; /** The property of the value we are tracking */ PropertyType& Property; /** Whether the value is set */ bool bIsSet; }; /** * Helper class to aid representing math structs to the user in an editable form * e.g. representing a quaternion as a set of euler angles */ class FMathStructProxyCustomization : public FMathStructCustomization { public: /** IPropertyTypeCustomization interface */ virtual void CustomizeChildren( TSharedRef StructPropertyHandle, class IDetailChildrenBuilder& StructBuilder, IPropertyTypeCustomizationUtils& StructCustomizationUtils ) OVERRIDE; /** FMathStructCustomization interface */ virtual void MakeHeaderRow( TSharedRef& InStructPropertyHandle, FDetailWidgetRow& Row ) OVERRIDE; protected: /** * Cache the values from the property to the proxy. * @param WeakHandlePtr The property handle to get values from. * @return true if values(s) were successfully cached */ virtual bool CacheValues( TWeakPtr WeakHandlePtr ) const = 0; /** * Flush the values from the proxy to the property. * @param WeakHandlePtr The property handle to set values to. * @return true if values(s) were successfully flushed */ virtual bool FlushValues( TWeakPtr WeakHandlePtr ) const = 0; /** * Helper function to make a numeric property widget to edit a proxy value. * @param StructPropertyHandle Property handle to the containing struct * @param ProxyValue The value we will be editing in the proxy data. * @param Label A label to use for this value. * @return the newly created widget. */ template TSharedRef MakeNumericProxyWidget(TSharedRef& StructPropertyHandle, TSharedRef< TProxyProperty >& ProxyValue, const FText& Label, const FLinearColor& LabelColor = FCoreStyle::Get().GetColor("DefaultForeground"), const FLinearColor& LabelBackgroundColor = FCoreStyle::Get().GetColor("InvertedForeground")); private: /** * Gets the value as a float for the provided property handle * * @param WeakHandlePtr Handle to the property to get the value from * @param ProxyValue Proxy value to get value from. * @return The value or unset if it could not be accessed */ template TOptional OnGetValue( TWeakPtr WeakHandlePtr, TSharedRef< TProxyProperty > ProxyValue ) 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, TSharedRef< TProxyProperty > ProxyValue ); /** * 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, TSharedRef< TProxyProperty > ProxyValue ); /** 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 ); }; /** * Proxy struct customization that displays a matrix as a position, rotation & scale. */ class FMatrixStructCustomization : public FMathStructProxyCustomization { public: static TSharedRef MakeInstance(); public: FMatrixStructCustomization() : CachedRotation(MakeShareable( new TProxyValue(FRotator::ZeroRotator))) , CachedRotationYaw(MakeShareable( new TProxyProperty(CachedRotation, CachedRotation->Get().Yaw))) , CachedRotationPitch(MakeShareable( new TProxyProperty(CachedRotation, CachedRotation->Get().Pitch))) , CachedRotationRoll(MakeShareable( new TProxyProperty(CachedRotation, CachedRotation->Get().Roll))) , CachedTranslation(MakeShareable( new TProxyValue(FVector::ZeroVector))) , CachedTranslationX(MakeShareable( new TProxyProperty(CachedTranslation, CachedTranslation->Get().X))) , CachedTranslationY(MakeShareable( new TProxyProperty(CachedTranslation, CachedTranslation->Get().Y))) , CachedTranslationZ(MakeShareable( new TProxyProperty(CachedTranslation, CachedTranslation->Get().Z))) , CachedScale(MakeShareable( new TProxyValue(FVector::ZeroVector))) , CachedScaleX(MakeShareable( new TProxyProperty(CachedScale, CachedScale->Get().X))) , CachedScaleY(MakeShareable( new TProxyProperty(CachedScale, CachedScale->Get().Y))) , CachedScaleZ(MakeShareable( new TProxyProperty(CachedScale, CachedScale->Get().Z))) { } /** FMathStructCustomization interface */ virtual void MakeHeaderRow( TSharedRef& StructPropertyHandle, FDetailWidgetRow& Row ) OVERRIDE; protected: /** FMathStructProxyCustomization interface */ virtual bool CacheValues( TWeakPtr WeakHandlePtr ) const OVERRIDE; virtual bool FlushValues( TWeakPtr WeakHandlePtr ) const OVERRIDE; protected: /** Cached rotation values */ mutable TSharedRef< TProxyValue > CachedRotation; mutable TSharedRef< TProxyProperty > CachedRotationYaw; mutable TSharedRef< TProxyProperty > CachedRotationPitch; mutable TSharedRef< TProxyProperty > CachedRotationRoll; /** Cached translation values */ mutable TSharedRef< TProxyValue > CachedTranslation; mutable TSharedRef< TProxyProperty > CachedTranslationX; mutable TSharedRef< TProxyProperty > CachedTranslationY; mutable TSharedRef< TProxyProperty > CachedTranslationZ; /** Cached scale values */ mutable TSharedRef< TProxyValue > CachedScale; mutable TSharedRef< TProxyProperty > CachedScaleX; mutable TSharedRef< TProxyProperty > CachedScaleY; mutable TSharedRef< TProxyProperty > CachedScaleZ; }; /** * Proxy struct customization that displays an FTransform as a position, euler rotation & scale. */ class FTransformStructCustomization : public FMatrixStructCustomization { public: static TSharedRef MakeInstance(); protected: /** FMathStructProxyCustomization interface */ virtual bool CacheValues( TWeakPtr WeakHandlePtr ) const OVERRIDE; virtual bool FlushValues( TWeakPtr WeakHandlePtr ) const OVERRIDE; };