// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "UObject/ObjectMacros.h" #include "Misc/Guid.h" #include "UObject/Class.h" #include "BaseWidgetBlueprint.h" #include "Binding/DynamicPropertyPath.h" #include "Blueprint/WidgetBlueprintGeneratedClass.h" #include "Animation/WidgetAnimationBinding.h" #include "Templates/ValueOrError.h" #include "WidgetBlueprint.generated.h" class FCompilerResultsLog; class UEdGraph; class UMovieScene; class UTexture2D; class UUserWidget; class UWidget; class UWidgetAnimation; class FKismetCompilerContext; class UWidgetBlueprint; enum class EWidgetTickFrequency : uint8; enum class EWidgetCompileTimeTickPrediction : uint8; class UWidgetEditingProjectSettings; /** Widget Delegates */ class UMGEDITOR_API FWidgetBlueprintDelegates { public: // delegate for generating widget asset registry tags. DECLARE_MULTICAST_DELEGATE_TwoParams(FGetAssetTagsWithContext, const UWidgetBlueprint*, FAssetRegistryTagsContext); DECLARE_MULTICAST_DELEGATE_TwoParams(FGetAssetTags, const UWidgetBlueprint*, TArray&); // called by UWdgetBlueprint::GetAssetRegistryTags() static FGetAssetTagsWithContext GetAssetTagsWithContext; UE_DEPRECATED(5.4, "Subscribe to GetAssetTagsWithContext instead.") static FGetAssetTags GetAssetTags; }; /** */ USTRUCT() struct UMGEDITOR_API FEditorPropertyPathSegment { GENERATED_USTRUCT_BODY() public: FEditorPropertyPathSegment(); FEditorPropertyPathSegment(const FProperty* InProperty); FEditorPropertyPathSegment(const UFunction* InFunction); FEditorPropertyPathSegment(const UEdGraph* InFunctionGraph); UStruct* GetStruct() const { return Struct; } FFieldVariant GetMember() const; void Rebase(UBlueprint* SegmentBase); bool ValidateMember(FDelegateProperty* DelegateProperty, FText& OutError) const; FName GetMemberName() const; FText GetMemberDisplayText() const; FGuid GetMemberGuid() const; private: /** The owner of the path segment (ie. What class or structure was this property from) */ UPROPERTY() TObjectPtr Struct; /** The member name in the structure this segment represents. */ UPROPERTY() FName MemberName; /** * The member guid in this structure this segment represents. If this is valid it should * be used instead of Name to get the true name. */ UPROPERTY() FGuid MemberGuid; /** true if property, false if function */ UPROPERTY() bool IsProperty; }; /** */ USTRUCT() struct UMGEDITOR_API FEditorPropertyPath { GENERATED_USTRUCT_BODY() public: /** */ FEditorPropertyPath(); /** */ FEditorPropertyPath(const TArray& BindingChain); /** */ bool Rebase(UBlueprint* SegmentBase); /** */ bool IsEmpty() const { return Segments.Num() == 0; } /** */ bool Validate(FDelegateProperty* Destination, FText& OutError) const; /** */ FText GetDisplayText() const; /** */ FDynamicPropertyPath ToPropertyPath() const; public: /** The path of properties. */ UPROPERTY() TArray Segments; }; /** */ USTRUCT() struct UMGEDITOR_API FDelegateEditorBinding { GENERATED_USTRUCT_BODY() /** The member widget the binding is on, must be a direct variable of the UUserWidget. */ UPROPERTY() FString ObjectName; /** The property on the ObjectName that we are binding to. */ UPROPERTY() FName PropertyName; /** The function that was generated to return the SourceProperty */ UPROPERTY() FName FunctionName; /** The property we are bindings to directly on the source object. */ UPROPERTY() FName SourceProperty; /** */ UPROPERTY() FEditorPropertyPath SourcePath; /** If it's an actual Function Graph in the blueprint that we're bound to, there's a GUID we can use to lookup that function, to deal with renames better. This is that GUID. */ UPROPERTY() FGuid MemberGuid; UPROPERTY() EBindingKind Kind = EBindingKind::Property; bool operator==( const FDelegateEditorBinding& Other ) const { // NOTE: We intentionally only compare object name and property name, the function is irrelevant since // you're only allowed to bind a property on an object to a single function. return ObjectName == Other.ObjectName && PropertyName == Other.PropertyName; } bool IsAttributePropertyBinding(class UWidgetBlueprint* Blueprint) const; bool DoesBindingTargetExist(UWidgetBlueprint* Blueprint) const; bool IsBindingValid(UClass* Class, class UWidgetBlueprint* Blueprint, FCompilerResultsLog& MessageLog) const; FDelegateRuntimeBinding ToRuntimeBinding(class UWidgetBlueprint* Blueprint) const; }; UENUM() enum class EWidgetSupportsDynamicCreation : uint8 { Default, Yes, No, }; UENUM() enum class EThumbnailPreviewSizeMode : uint8 { MatchDesignerMode, FillScreen, Custom, Desired }; /** * This represents the tickability of a widget computed at compile time * It is designed as a hint so the runtime can determine if ticking needs to be enabled * A lot of widgets set to WillTick means you might have a performance problem */ UENUM() enum class EWidgetCompileTimeTickPrediction : uint8 { /** The widget is manually set to never tick or we dont detect any animations, latent actions, and/or script or possible native tick methods */ WontTick, /** This widget is set to auto tick and we detect animations, latent actions but not script or native tick methods*/ OnDemand, /** This widget has an implemented script tick or native tick */ WillTick, }; /** * The widget blueprint enables extending UUserWidget the user extensible UWidget. */ UCLASS(BlueprintType) class UMGEDITOR_API UWidgetBlueprint : public UBaseWidgetBlueprint { GENERATED_UCLASS_BODY() public: #if WITH_EDITORONLY_DATA UPROPERTY() TArray< FDelegateEditorBinding > Bindings; UPROPERTY() TArray> Animations; /** * Saved Guids for variables generated by this blueprint (Widgets and Animations). * * Used to fixup external references to renamed widgets/animations in this blueprint * * See: OnVariableAdded, OnVariableRenamed, OnVariableRemoved */ UPROPERTY() TMap WidgetVariableNameToGuidMap; /** * Don't directly modify this property to change the palette category. The actual value is stored * in the CDO of the UUserWidget, but a copy is stored here so that it's available in the serialized * Tag data in the asset header for access in the FAssetData. */ UPROPERTY(AssetRegistrySearchable) FString PaletteCategory; /** * Determines whether this widget blueprint can be initialized without * a valid player context (PlayerController, etc.). * Required to be true for use with UMG Widget Preview. */ UPROPERTY(EditAnywhere, Category="Widget") bool bCanCallInitializedWithoutPlayerContext; void OnVariableAdded(const FName& VariableName); void OnVariableRenamed(const FName& OldName, const FName& NewName); void OnVariableRemoved(const FName& VariableName); #endif public: /** UObject interface */ virtual void PostLoad() override; virtual void PostDuplicate(bool bDuplicateForPIE) override; #if WITH_EDITORONLY_DATA virtual void PreSave(FObjectPreSaveContext ObjectSaveContext) override; #endif // WITH_EDITORONLY_DATA #if WITH_EDITOR virtual void GetAssetRegistryTags(FAssetRegistryTagsContext Context) const override; UE_DEPRECATED(5.4, "Implement the version that takes FAssetRegistryTagsContext instead.") virtual void GetAssetRegistryTags(TArray& OutTags) const override; virtual void NotifyGraphRenamed(class UEdGraph* Graph, FName OldName, FName NewName) override; virtual EDataValidationResult IsDataValid(class FDataValidationContext& Context) const override; bool DetectSlateWidgetLeaks(class FDataValidationContext& Context) const; virtual bool FindDiffs(const UBlueprint* OtherBlueprint, FDiffResults& Results) const override; #endif virtual void Serialize(FArchive& Ar) override; UPackage* GetWidgetTemplatePackage() const; virtual void ReplaceDeprecatedNodes() override; //~ Begin UBlueprint Interface virtual UClass* GetBlueprintClass() const override; virtual bool AllowsDynamicBinding() const override; virtual bool SupportsInputEvents() const override; virtual bool SupportedByDefaultBlueprintFactory() const override { return false; } virtual void GetReparentingRules(TSet< const UClass* >& AllowedChildrenOfClasses, TSet< const UClass* >& DisallowedChildrenOfClasses) const override; /** UWidget blueprints are never data only, should always compile on load (data only blueprints cannot declare new variables) */ virtual bool AlwaysCompileOnLoad() const override { return true; } //~ End UBlueprint Interface virtual void GatherDependencies(TSet>& InDependencies) const override; /** Returns true if the supplied user widget will not create a circular reference when added to this blueprint */ bool IsWidgetFreeFromCircularReferences(UUserWidget* UserWidget) const; /** */ TValueOrError HasCircularReferences() const; TValueOrError> HasConflictingWidgetNamesFromInheritance() const; static bool ValidateGeneratedClass(const UClass* InClass); static TSharedPtr GetCompilerForWidgetBP(UBlueprint* BP, FCompilerResultsLog& InMessageLog, const FKismetCompilerOptions& InCompileOptions); void UpdateTickabilityStats(bool& OutHasLatentActions, bool& OutHasAnimations, bool& OutClassRequiresNativeTick); bool ArePropertyBindingsAllowed() const; /** Gets any named slots exposed by the parent generated class that can be slotted into by the subclass. */ TArray GetInheritedAvailableNamedSlots() const; /** Gets named slots exposed by the parent generated class that already have content in the parent widget tree. */ TSet GetInheritedNamedSlotsWithContentInSameTree() const; virtual UWidgetEditingProjectSettings* GetRelevantSettings(); virtual const UWidgetEditingProjectSettings* GetRelevantSettings() const; protected: virtual void LoadModulesRequiredForCompilation() override; private: void FixupLegacySequencePlayerCalls(); private: /** * The desired tick frequency set by the user on the UserWidget's CDO. */ UPROPERTY(AssetRegistrySearchable) EWidgetTickFrequency TickFrequency; /** * The computed frequency that the widget will need to be ticked at. You can find the reasons for * this decision by looking at TickPredictionReason. */ UPROPERTY(AssetRegistrySearchable) EWidgetCompileTimeTickPrediction TickPrediction; /** * The reasons we may need to tick this widget. */ UPROPERTY(AssetRegistrySearchable) FString TickPredictionReason; public: /** * The total number of property bindings. Consider this as a performance warning. */ UPROPERTY(AssetRegistrySearchable) int32 PropertyBindings; UPROPERTY(EditDefaultsOnly, Category = ThumbnailSettings) EThumbnailPreviewSizeMode ThumbnailSizeMode; UPROPERTY(EditDefaultsOnly, Category = ThumbnailSettings) FVector2D ThumbnailCustomSize; UPROPERTY(EditDefaultsOnly, Category = ThumbnailSettings) TObjectPtr ThumbnailImage; };