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  key (such as when inputting a name, age, or sentence).

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  key, and echo the characters as they’re typed, use the GetEchoString function:

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 prompts 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