253 lines
9.9 KiB
C++
253 lines
9.9 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "GameplayTagContainer.h"
|
|
#include "Components/SlateWrapperTypes.h"
|
|
#include "GameSettingFilterState.h"
|
|
#include "GameplayTagContainer.h"
|
|
|
|
#include "GameSetting.generated.h"
|
|
|
|
class ULocalPlayer;
|
|
class UGameSettingRegistry;
|
|
|
|
//--------------------------------------
|
|
// UGameSetting
|
|
//--------------------------------------
|
|
|
|
DECLARE_DELEGATE_RetVal_OneParam(FText, FGetGameSettingsDetails, ULocalPlayer& /*InLocalPlayer*/);
|
|
|
|
/**
|
|
*
|
|
*/
|
|
UCLASS(Abstract, BlueprintType)
|
|
class GAMESETTINGS_API UGameSetting : public UObject
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UGameSetting() { }
|
|
|
|
public:
|
|
DECLARE_EVENT_TwoParams(UGameSetting, FOnSettingChanged, UGameSetting* /*InSetting*/, EGameSettingChangeReason /*InChangeReason*/);
|
|
DECLARE_EVENT_OneParam(UGameSetting, FOnSettingEditConditionChanged, UGameSetting* /*InSetting*/);
|
|
|
|
FOnSettingChanged OnSettingChangedEvent;
|
|
FOnSettingEditConditionChanged OnSettingEditConditionChangedEvent;
|
|
|
|
public:
|
|
|
|
/**
|
|
* Gets the non-localized developer name for this setting. This should remain constant, and represent a
|
|
* unique identifier for this setting inside this settings registry.
|
|
*/
|
|
UFUNCTION(BlueprintCallable)
|
|
FName GetDevName() const { return DevName; }
|
|
void SetDevName(const FName& Value) { DevName = Value; }
|
|
|
|
bool GetAdjustListViewPostRefresh() const { return bAdjustListViewPostRefresh; }
|
|
void SetAdjustListViewPostRefresh(const bool Value) { bAdjustListViewPostRefresh = Value; }
|
|
|
|
UFUNCTION(BlueprintCallable)
|
|
FText GetDisplayName() const { return DisplayName; }
|
|
void SetDisplayName(const FText& Value) { DisplayName = Value; }
|
|
#if !UE_BUILD_SHIPPING
|
|
void SetDisplayName(const FString& Value) { SetDisplayName(FText::FromString(Value)); }
|
|
#endif
|
|
UFUNCTION(BlueprintCallable)
|
|
ESlateVisibility GetDisplayNameVisibility() { return DisplayNameVisibility; }
|
|
void SetNameDisplayVisibility(ESlateVisibility InVisibility) { DisplayNameVisibility = InVisibility; }
|
|
|
|
UFUNCTION(BlueprintCallable)
|
|
FText GetDescriptionRichText() const { return DescriptionRichText; }
|
|
void SetDescriptionRichText(const FText& Value) { DescriptionRichText = Value; InvalidateSearchableText(); }
|
|
#if !UE_BUILD_SHIPPING
|
|
/** This version is for cheats and other non-shipping items, that don't need to localize their text. We don't permit this in shipping to prevent unlocalized text being introduced. */
|
|
void SetDescriptionRichText(const FString& Value) { SetDescriptionRichText(FText::FromString(Value)); }
|
|
#endif
|
|
|
|
UFUNCTION(BlueprintCallable)
|
|
const FGameplayTagContainer& GetTags() const { return Tags; }
|
|
void AddTag(const FGameplayTag& TagToAdd) { Tags.AddTag(TagToAdd); }
|
|
|
|
void SetRegistry(UGameSettingRegistry* InOwningRegistry) { OwningRegistry = InOwningRegistry; }
|
|
|
|
/** Gets the searchable plain text for the description. */
|
|
const FString& GetDescriptionPlainText() const;
|
|
|
|
/** Initializes the setting, giving it the owning local player. Containers automatically initialize settings added to them. */
|
|
void Initialize(ULocalPlayer* InLocalPlayer);
|
|
|
|
/** Gets the owning local player for this setting - which all initialized settings will have. */
|
|
ULocalPlayer* GetOwningLocalPlayer() const { return LocalPlayer; }
|
|
|
|
/** Set the dynamic details callback, we query this when building the description panel. This text is not searchable.*/
|
|
void SetDynamicDetails(const FGetGameSettingsDetails& InDynamicDetails) { DynamicDetails = InDynamicDetails; }
|
|
|
|
/**
|
|
* Gets the dynamic details about this setting. This may be information like, how many refunds are remaining
|
|
* on their account, or the account number.
|
|
*/
|
|
UFUNCTION(BlueprintCallable)
|
|
FText GetDynamicDetails() const;
|
|
|
|
UFUNCTION(BlueprintCallable)
|
|
FText GetWarningRichText() const { return WarningRichText; }
|
|
void SetWarningRichText(const FText& Value) { WarningRichText = Value; InvalidateSearchableText(); }
|
|
#if !UE_BUILD_SHIPPING
|
|
/** This version is for cheats and other non-shipping items, that don't need to localize their text. We don't permit this in shipping to prevent unlocalized text being introduced. */
|
|
void SetWarningRichText(const FString& Value) { SetWarningRichText(FText::FromString(Value)); }
|
|
#endif
|
|
|
|
/**
|
|
* Gets the edit state of this property based on the current state of its edit conditions as well as any additional
|
|
* filter state.
|
|
*/
|
|
const FGameSettingEditableState& GetEditState() const { return EditableStateCache; }
|
|
|
|
/** Adds a new edit condition to this setting, allowing you to control the visibility and edit-ability of this setting. */
|
|
void AddEditCondition(const TSharedRef<FGameSettingEditCondition>& InEditCondition);
|
|
|
|
/** Add setting dependency, if these settings change, we'll re-evaluate edit conditions for this setting. */
|
|
void AddEditDependency(UGameSetting* DependencySetting);
|
|
|
|
/** The parent object that owns the setting, in most cases the collection, but for top level settings the registry. */
|
|
void SetSettingParent(UGameSetting* InSettingParent);
|
|
UGameSetting* GetSettingParent() const { return SettingParent; }
|
|
|
|
/** Should this setting be reported to analytics. */
|
|
bool GetIsReportedToAnalytics() const { return bReportAnalytics; }
|
|
void SetIsReportedToAnalytics(bool bReport) { bReportAnalytics = bReport; }
|
|
|
|
/** Gets the analytics value for this setting. */
|
|
virtual FString GetAnalyticsValue() const { return TEXT(""); }
|
|
|
|
/**
|
|
* Some settings may take an async amount of time to finish initializing. The settings system will wait
|
|
* for all settings to be ready before showing the setting.
|
|
*/
|
|
bool IsReady() const { return bReady; }
|
|
|
|
/**
|
|
* Any setting can have children, this is so we can allow for the possibility of "collections" or "actions" that
|
|
* are not directly visible to the user, but are set by some means and need to have initial and restored values.
|
|
* In that case, you would likely have internal settings inside an action subclass that is set on another screen,
|
|
* but never directly listed on the settings panel.
|
|
*/
|
|
virtual TArray<UGameSetting*> GetChildSettings() { return TArray<UGameSetting*>(); }
|
|
|
|
/**
|
|
* Refresh the editable state of the setting and notify that the state has changed so that any UI currently
|
|
* examining this setting is updated with the new options, or whatever.
|
|
*/
|
|
void RefreshEditableState(bool bNotifyEditConditionsChanged = true);
|
|
|
|
/**
|
|
* We expect settings to change the live value immediately, but occasionally there are special settings
|
|
* that go are immediately stored to a temporary location but we don't actually apply them until later
|
|
* like selecting a new resolution.
|
|
*/
|
|
void Apply();
|
|
|
|
/** Gets the current world of the local player that owns these settings. */
|
|
virtual UWorld* GetWorld() const override;
|
|
|
|
protected:
|
|
/** */
|
|
virtual void Startup();
|
|
void StartupComplete();
|
|
|
|
virtual void OnInitialized();
|
|
virtual void OnApply();
|
|
virtual void OnGatherEditState(FGameSettingEditableState& InOutEditState) const;
|
|
virtual void OnDependencyChanged();
|
|
|
|
/** */
|
|
virtual FText GetDynamicDetailsInternal() const;
|
|
|
|
/** */
|
|
void HandleEditDependencyChanged(UGameSetting* DependencySetting, EGameSettingChangeReason Reason);
|
|
void HandleEditDependencyChanged(UGameSetting* DependencySetting);
|
|
|
|
/** Regenerates the plain searchable text if it has been dirtied. */
|
|
void RefreshPlainText() const;
|
|
void InvalidateSearchableText() { bRefreshPlainSearchableText = true; }
|
|
|
|
/** Notify that the setting changed */
|
|
void NotifySettingChanged(EGameSettingChangeReason Reason);
|
|
virtual void OnSettingChanged(EGameSettingChangeReason Reason);
|
|
|
|
/** Notify that the settings edit conditions changed. This may mean it's now invisible, or disabled, or possibly that the options have changed in some meaningful way. */
|
|
void NotifyEditConditionsChanged();
|
|
virtual void OnEditConditionsChanged();
|
|
|
|
/** */
|
|
FGameSettingEditableState ComputeEditableState() const;
|
|
|
|
protected:
|
|
|
|
UPROPERTY(Transient)
|
|
ULocalPlayer* LocalPlayer;
|
|
|
|
UPROPERTY(Transient)
|
|
UGameSetting* SettingParent;
|
|
|
|
UPROPERTY(Transient)
|
|
UGameSettingRegistry* OwningRegistry;
|
|
|
|
FName DevName;
|
|
FText DisplayName;
|
|
ESlateVisibility DisplayNameVisibility = ESlateVisibility::SelfHitTestInvisible;
|
|
FText DescriptionRichText;
|
|
FText WarningRichText;
|
|
|
|
/** A collection of tags for the settings. These can just be arbitrary flags used by the UI to do different things. */
|
|
FGameplayTagContainer Tags;
|
|
|
|
FGetGameSettingsDetails DynamicDetails;
|
|
|
|
/** Any edit conditions for this setting. */
|
|
TArray<TSharedRef<FGameSettingEditCondition>> EditConditions;
|
|
|
|
class FStringCultureCache
|
|
{
|
|
FStringCultureCache(TFunction<FString()> InStringGetter);
|
|
|
|
void Invalidate();
|
|
|
|
FString Get() const;
|
|
|
|
private:
|
|
mutable FString StringCache;
|
|
mutable FCultureRef Culture;
|
|
TFunction<FString()> StringGetter;
|
|
};
|
|
|
|
/** When the text changes, we invalidate the searchable text. */
|
|
mutable bool bRefreshPlainSearchableText = true;
|
|
/** When we set the rich text for a setting, we automatically generate the plain text. */
|
|
mutable FString AutoGenerated_DescriptionPlainText;
|
|
|
|
/** Report as part of analytics, by default no setting reports, except GameSettingValues. */
|
|
bool bReportAnalytics = false;
|
|
|
|
private:
|
|
|
|
/** Most settings are immediately ready, but some may require startup time before it's safe to call their functions. */
|
|
bool bReady = false;
|
|
|
|
/** Prevent re-entrancy problems when announcing a setting has changed. */
|
|
bool bOnSettingChangedEventGuard = false;
|
|
|
|
/** Prevent re-entrancy problems when announcing a setting has changed edit conditions. */
|
|
bool bOnEditConditionsChangedEventGuard = false;
|
|
|
|
/** */
|
|
bool bAdjustListViewPostRefresh = true;
|
|
|
|
/** We cache the editable state of a setting when it changes rather than reprocessing it any time it's needed. */
|
|
FGameSettingEditableState EditableStateCache;
|
|
};
|