PSYCH 20B Part 4: Getting Multi-Character Keyboard Input
Hello, dear friend, you can consult us at any time if you have any questions, add WeChat: daixieit
PSYCH 20B (Prof. Frane) Part 4: Getting Multi-Character Keyboard Input
Sometimes you want to input not just a single keystroke, but rather multiple characters terminated by the
Get Echoed Input
When getting multi-character input, you typically want to “echo” back what the user is typing. That is, you want to
display each character on the screen as it’s typed, so that the user can see what they’re typing, can backspace if they make an error, etc. To get input as a character-array input terminated by the
textColor = [ 0 0 0] % text color (black)
bkgdColor = [128 128 128] % background color (gray)
% input subject’s name as character array
name = GetEchoString(w, 'Enter your name: ', 60, 300, textColor, bkgdColor) ;
In the above example, we arbitrarily set the text prompt’s horizontal and vertical text coordinates to 60 and 300,
respectively. That means the left edge of the text is 60 pixels from the left edge of the screen, and the top edge of the text is 300 pixels from the top of the screen— Note that this is slightly different than the coordinate system for
DrawFormattedText, which anchors the y-coordinate to the bottom of the text, rather than to the top of the text! Also, GetEchoString doesn’t accept words (such as 'center') in place of coordinates.
IMPORTANT: The background color input argument is necessary for entered characters to be erased from the screen when the user presses the delete key.
Unlike with other functions we’ve used that put things on the screen, we don’t need to say Screen( 'Flip', w) to put the text on the screen when using the GetEchoString function. That’s because flipping the text onto the screen is built into the function. Specifically, GetEchoString flips the text in the manner of ( 'Flip', w, [], 1) so that the text will remain on the screen even after the next 'Flip' (as discussed in the Part 2 handout). Thus, if you don’t want the text from GetEchoString to still be there when you fliip the next object onto the screen, you can use
Screen('Flip', w) after you use GetEchoString. Or a more efficient method is to use 'FillRect ' (as will be discussed in the Part 5 handout), to draw a full-screen filled rectangle after you use GetEchoString (we assume
you’ve defined bkgdColor as the background color of the screen):
Screen( 'FillRect', w, bkgdColor) ; % draw full-screen solid rectangle in bkgdColor
% (so GetEchoString text disappears on next Flip)
Get “Blind” (Non-Echoed) Input
In rare cases, we may want to get multi-character input without echoing the input to the screen. We can do that with the GetString function:
blindlyTypedChar = GetString ; % input blindly-typed character array
Note that you don’t enter a text prompt as one of the input arguments to GetString. If you want a text prompt, you can make one using DrawFormattedText.
Additional Input Arguments to GetEchoString and GetString
By default, functions like GetEchoString and GetString use a function called GetChar to get detect keyboard input. But we can make them use KbCheck instead, by setting the “Use KbCheck” flag (the 7th input to
GetEchoString or the 1st input to GetString) to 1. That allows us additional input options, such as specifying a device number or imposing a time limit on the user’s response. But this flag should only be used if absolutely
necessary, because it slows down response to key-presses considerably and is incompatible with non-U.S. keys.
The device number is the next input argument after the “Use KbCheck” flag. Here we use GetEchoString with the the device number set to - 1 (meaning “check all keyboards”), which can fix your keyboard not being recognized:
name = GetEchoString(w, 'Enter your name: ', 60, 300, textColor, bkgdColor, 1, -1) ;
Get Numeric Input
For getting numeric input, there are functions called GetEchoNumber and GetNumber that are analogous to
GetEchoString and GetString, respectively. However, those functions are slow, so I don’t recommend using them.
A better way to get numeric input is to get character-array input and then convert it to a number using the str2double function:
moodChar = GetEchoString(w, [ 'Rate your current mood on a scale from 1 (worst) ' ...
'to 10 (best): '], 60, 300, textColor, bkgdColor) ; % input mood-rating char-array
mood = str2double(moodChar) ; % convert mood-rating from character array to number
Note that the only reason we put the GetEchoString prompt text in brackets [] in the above example is that we needed an ellipsis ( ...) to wrap the text to the next line of code. If we had put those three dots within the quotes, Matlab would have interpreted them as part of the prompt text. If the text all fit in one line, we wouldn’t need the
brackets.
To constrain the range of numbers that are accepted, use a while-loop:
isMoodValid = 0 ; % initialize logical flag saying whether valid mood was entered
while isMoodValid == 0 % stay in while-loop until valid mood entered
% input mood-rating character-array
moodChar = GetEchoString(w, [ 'Rate your current mood on a scale from 1 ' ...
'(worst) to 10 (best): '], 60, 300, textColor, bkgdColor) ;
Screen('FillRect ', w, bkgdColor) ; % draw full-screen solid rectangle in bkgdColor
% (to erase GetEchoString text on next 'Flip')
mood = str2double(moodChar) ; % convert mood-rating to number
isMoodValid = mood >= 1 && mood <= 10 ; % is that mood valid?
end
If we want to constrain the valid inputs to a finite set of specific numbers, rather than to a continuous range of
numbers, we can use the ismember function. For example, to change the above code to only accept whole numbers between 1 and 10 (inclusive), change this line:
isMoodValid = mood >= 1 && mood <= 10 ; % is the mood valid?
to the following line:
isMoodValid = ismember(mood, 1:10) ; % is the mood valid?
If the delete key doesn’t erase echoed text properly
When entering echoed input, the way characters are erased when the delete key is pressed is by drawing over the character using the background color. Thus, if you neglect to input a background color to GetEchoString, typed characters will not be erased when the delete key is pressed.
Another issue is that on some systems, if the background isn’t black, the text anti-aliasing (a process that makes
rounded edges of the text look smoother) leaves a black outline of each deleted character instead of erasing the
character completely. That can be fixed by any use of the 'TextBounds' subfunction of Screen (see the Part 2
handout) sometime before GetEchoString is used. If you weren’t using 'TextBounds' in your program already anyway, just input any nonempty character array to 'TextBounds'. For instance, below we input a single space as the character array:
Screen( 'TextBounds', w, ' ') ; % make delete key work properly when using GetEchoString
2023-10-20