// Copyright Epic Games, Inc. All Rights Reserved. #include "LyraSettingKeyboardInput.h" #include "EnhancedInputSubsystems.h" #include "../LyraSettingsLocal.h" #include "Player/LyraLocalPlayer.h" #include "PlayerMappableInputConfig.h" #include "EnhancedInputSubsystems.h" #include "UserSettings/EnhancedInputUserSettings.h" #include UE_INLINE_GENERATED_CPP_BY_NAME(LyraSettingKeyboardInput) class ULocalPlayer; #define LOCTEXT_NAMESPACE "LyraSettings" namespace Lyra::ErrorMessages { static const FText UnknownMappingName = LOCTEXT("LyraErrors_UnknownMappingName", "Unknown Mapping"); } ULyraSettingKeyboardInput::ULyraSettingKeyboardInput() { bReportAnalytics = false; } FText ULyraSettingKeyboardInput::GetSettingDisplayName() const { if (const FKeyMappingRow* Row = FindKeyMappingRow()) { if (Row->HasAnyMappings()) { return Row->Mappings.begin()->GetDisplayName(); } } return Lyra::ErrorMessages::UnknownMappingName; } FText ULyraSettingKeyboardInput::GetSettingDisplayCategory() const { if (const FKeyMappingRow* Row = FindKeyMappingRow()) { if (Row->HasAnyMappings()) { return Row->Mappings.begin()->GetDisplayCategory(); } } return Lyra::ErrorMessages::UnknownMappingName; } const FKeyMappingRow* ULyraSettingKeyboardInput::FindKeyMappingRow() const { if (const UEnhancedPlayerMappableKeyProfile* Profile = FindMappableKeyProfile()) { return Profile->FindKeyMappingRow(ActionMappingName); } ensure(false); return nullptr; } UEnhancedPlayerMappableKeyProfile* ULyraSettingKeyboardInput::FindMappableKeyProfile() const { if (UEnhancedInputUserSettings* Settings = GetUserSettings()) { return Settings->GetKeyProfileWithIdentifier(ProfileIdentifier); } ensure(false); return nullptr; } UEnhancedInputUserSettings* ULyraSettingKeyboardInput::GetUserSettings() const { if(ULyraLocalPlayer* LyraLocalPlayer = Cast(LocalPlayer)) { // Map the key to the player key profile if (UEnhancedInputLocalPlayerSubsystem* System = LyraLocalPlayer->GetSubsystem()) { return System->GetUserSettings(); } } return nullptr; } void ULyraSettingKeyboardInput::OnInitialized() { DynamicDetails = FGetGameSettingsDetails::CreateLambda([this](ULocalPlayer&) { if (const FKeyMappingRow* Row = FindKeyMappingRow()) { if (Row->HasAnyMappings()) { return FText::Format(LOCTEXT("DynamicDetails_KeyboardInputAction", "Bindings for {0}"), Row->Mappings.begin()->GetDisplayName()); } } return FText::GetEmpty(); }); Super::OnInitialized(); } void ULyraSettingKeyboardInput::InitializeInputData(const UEnhancedPlayerMappableKeyProfile* KeyProfile, const FKeyMappingRow& MappingData, const FPlayerMappableKeyQueryOptions& InQueryOptions) { check(KeyProfile); ProfileIdentifier = KeyProfile->GetProfileIdentifer(); QueryOptions = InQueryOptions; for (const FPlayerKeyMapping& Mapping : MappingData.Mappings) { // Only add mappings that pass the query filters that have been provided upon creation if (!KeyProfile->DoesMappingPassQueryOptions(Mapping, QueryOptions)) { continue; } ActionMappingName = Mapping.GetMappingName(); InitialKeyMappings.Add(Mapping.GetSlot(), Mapping.GetCurrentKey()); const FText& MappingDisplayName =Mapping.GetDisplayName(); if (!MappingDisplayName.IsEmpty()) { SetDisplayName(MappingDisplayName); } } const FString NameString = TEXT("KBM_Input_") + ActionMappingName.ToString(); SetDevName(*NameString); } FText ULyraSettingKeyboardInput::GetKeyTextFromSlot(const EPlayerMappableKeySlot InSlot) const { if (const UEnhancedPlayerMappableKeyProfile* Profile = FindMappableKeyProfile()) { FPlayerMappableKeyQueryOptions QueryOptionsForSlot = QueryOptions; QueryOptionsForSlot.SlotToMatch = InSlot; if (const FKeyMappingRow* Row = FindKeyMappingRow()) { for (const FPlayerKeyMapping& Mapping : Row->Mappings) { if (Profile->DoesMappingPassQueryOptions(Mapping, QueryOptionsForSlot)) { return Mapping.GetCurrentKey().GetDisplayName(); } } } } return EKeys::Invalid.GetDisplayName(); } PRAGMA_DISABLE_DEPRECATION_WARNINGS FText ULyraSettingKeyboardInput::GetPrimaryKeyText() const { return GetKeyTextFromSlot(EPlayerMappableKeySlot::First); } FText ULyraSettingKeyboardInput::GetSecondaryKeyText() const { return GetKeyTextFromSlot(EPlayerMappableKeySlot::Second); } PRAGMA_ENABLE_DEPRECATION_WARNINGS void ULyraSettingKeyboardInput::ResetToDefault() { if (UEnhancedInputUserSettings* Settings = GetUserSettings()) { FMapPlayerKeyArgs Args = {}; Args.MappingName = ActionMappingName; FGameplayTagContainer FailureReason; Settings->ResetAllPlayerKeysInRow(Args, FailureReason); NotifySettingChanged(EGameSettingChangeReason::Change); } } void ULyraSettingKeyboardInput::StoreInitial() { if (const UEnhancedPlayerMappableKeyProfile* Profile = FindMappableKeyProfile()) { if(const FKeyMappingRow* Row = FindKeyMappingRow()) { for (const FPlayerKeyMapping& Mapping : Row->Mappings) { if (Profile->DoesMappingPassQueryOptions(Mapping, QueryOptions)) { ActionMappingName = Mapping.GetMappingName(); InitialKeyMappings.Add(Mapping.GetSlot(), Mapping.GetCurrentKey()); } } } } } void ULyraSettingKeyboardInput::RestoreToInitial() { for (TPair Pair : InitialKeyMappings) { ChangeBinding((int32)Pair.Key, Pair.Value); } } bool ULyraSettingKeyboardInput::ChangeBinding(int32 InKeyBindSlot, FKey NewKey) { if (!NewKey.IsGamepadKey()) { FMapPlayerKeyArgs Args = {}; Args.MappingName = ActionMappingName; Args.Slot = (EPlayerMappableKeySlot) (static_cast(InKeyBindSlot)); Args.NewKey = NewKey; // If you want to, you can additionally specify this mapping to only be applied to a certain hardware device or key profile //Args.ProfileId = //Args.HardwareDeviceId = if (UEnhancedInputUserSettings* Settings = GetUserSettings()) { FGameplayTagContainer FailureReason; Settings->MapPlayerKey(Args, FailureReason); NotifySettingChanged(EGameSettingChangeReason::Change); } return true; } return false; } void ULyraSettingKeyboardInput::GetAllMappedActionsFromKey(int32 InKeyBindSlot, FKey Key, TArray& OutActionNames) const { if (const UEnhancedPlayerMappableKeyProfile* Profile = FindMappableKeyProfile()) { Profile->GetMappingNamesForKey(Key, OutActionNames); } } bool ULyraSettingKeyboardInput::IsMappingCustomized() const { bool bResult = false; if (const UEnhancedPlayerMappableKeyProfile* Profile = FindMappableKeyProfile()) { FPlayerMappableKeyQueryOptions QueryOptionsForSlot = QueryOptions; if (const FKeyMappingRow* Row = FindKeyMappingRow()) { for (const FPlayerKeyMapping& Mapping : Row->Mappings) { if (Profile->DoesMappingPassQueryOptions(Mapping, QueryOptionsForSlot)) { bResult |= Mapping.IsCustomized(); } } } } return bResult; } #undef LOCTEXT_NAMESPACE