Correct me if I am mistaken, but you cant use Switch statements with FKeys now because they dont convert easily to numbers and EKeys throw this compile error now:
#Compile Error
case expression not constant
#TypeHash
Even if I turn the FKey into a type hash value the above compile error persists for every EKeys:: use.
#Problem
Now I cant make a “Shifted Key” function for my Chat system using FKey
this worked beautifully in the Beta
//returns "" if it was not a letter
FString AVictoryGamePlayerController::ShiftedKeyEntry(FKey key) const
{
switch (key)
{
//chat only
case EKeys::Semicolon : return ":";
case EKeys::Backslash : return "|";
case EKeys::Slash : return "?";
case EKeys::Tilde : return "~";
case EKeys::LeftBracket : return "{";
case EKeys::RightBracket: return "}";
case EKeys::Quote : return """";
case EKeys::Comma : return "<";
case EKeys::Equals : return "+";
//numbers
case EKeys::One : return "!"; case EKeys::Six : return "^";
case EKeys::Two : return "@"; case EKeys::Seven : return "&";
case EKeys::Three : return "#"; case EKeys::Eight : return "*";
case EKeys::Four : return "$"; case EKeys::Nine : return "(";
case EKeys::Five : return "%"; case EKeys::Zero : return ")";
//minus
case EKeys::Underscore : return "_";
//period
case EKeys::Period : return ">";
//no key match found
default: return "";
}
return "";
}
#Goal = Shifted Key
Is there an easier way to get the Shifted version of any FKey ?
Your implementation above is very naive, and doesn’t take into account the OS key-mapping; for example, Shift+2 for me is ", not @, as I have a UK keyboard.
Currently I am using Player Controller and WasInputKeyJustPressed / IsInputKeyDown
I see I can initialize the Slate App and Get it and then use
/**
* Called when a character is entered
*
* @param InCharacterEvent Character event
*
* @return Was this event handled by the Slate application?
*/
bool ProcessKeyCharMessage( FCharacterEvent& InCharacterEvent );
/**
* Called when a key is pressed
*
* @param InKeyboardEvent Keyboard event
*
* @return Was this event handled by the Slate application?
*/
bool ProcessKeyDownMessage( FKeyboardEvent& InKeyboardEvent );
Would that be sufficient or do I need a window that has focus as well?
Thanks!
Rama
PS: I see this issue of the OS vs my local keyboard, and I do need a proper solution, thanks for your help
FSlateApplication::ProcessKeyCharMessage would be mostly correct (but I’m not sure you can hook into it), however it’s still flawed as it doesn’t handle IMEs correctly.
Really, if you want correct input without having to reimplement all of the Slate OS and IME input processing, then SEditableTextBlock is the way to go.
If you want to manually get what amounts to physical keys and map them to logical keys and then characters, you’re re-implementing some lower level logic than this. Conceptually, you need to get a physical key press (IE: Key 0x1A) and map that to a logical key (a/A) and then a character (‘A’ if shifted, ‘a’ otherwise). There’s no cross-platform way to do that at this time AFAIK.
EKeys values look to be logical keys - note that “PS4_Special” is a member of EKeys. You’re doing something even lower level than FKey. Windows Virtual Keys are also more or less logical keys. They seem to map in FInputKeyManager::InitKeyMappings.
Mind, IMEs don’t merely map logical keys into different ones or even characters - some IMEs, especially those of East Asian languages, actually consume input before they reach the application properly, display their own UI over the application, and submit a batch of processed characters to the application.
If you don’t care about IMEs and keyboard layouts that differ from yours, you just need to use if/else flow control rather than a switch case. Some macro magic might trade tedium for familiar readability.