HW02 - james-bern/CS136 GitHub Wiki

In this challenging homework, we will learn how to use arrays and for loops by implementing a text input field.
A text input field allows a user to type a message inside of a computer program. You've used these things your whole life, but probably haven't given them much thought.
Let's change that. 🙂👍
- Try playing around with one of the search bars on this web page.
- What happens when you...
- press the
Bkey on your keyboard? - press
SHIFT + B? - press the
LEFT_ARROW_KEY? - press the
RIGHT_ARROW_KEY? - press
BACKSPACE? - press
COMMAND + A(orCONTROL + Aon Windows)? - press the left mouse button?
- hold the mouse and drag?
- press
Bwhile some text is highlighted? - press
BACKSPACEwhile some text is highlighted? - double-click?
- press the
- What happens when you...
We need to store a sequence of characters that we'll be changing a lot.
We will use an array, specifically an array of characters (char[]).
-
char[] buffer = new char[8];is an array of 8char's calledbuffer-
buffer.lengthwill be8
-
-
for (int i = 0; i < array.length; ++i) { ... }iterates overarrayforwards -
for (int i = array.length - 1; i >= 0; --i) { ... }iterates overarraybackwards
- I highly recommend drawing simple little pictures of your array for this assignment
- This will be very useful to work out carefully by hand what should happen to your array, rather than just guessing
-
char[] buffer;stores the user's message as an array of characters-
buffercan store a message of length at mostbuffer.length
-
-
int length;is the length of the current message stored in buffer- if
(length == 0)then message is empty - if
(length == buffer.length)then the message completely fills the buffer
- if
-
int cursor;is the current cursor position-
0means all the way to the left -
1means in betweenbuffer[0]andbuffer[1]
-
- the left side of the canvas is
$x = 0.0$ - the right side of the canvas is
$x = \texttt{buffer.length}$ - we are using a monospaced font; this means each character is the same width;
- for simplicity, we have each character be
$1.0$ unit wide -
buffer[0]is drawn from$x = 0.0$ to$x = 1.0$ -
cursorshould be drawn at$x = \texttt{cursor}$
- for simplicity, we have each character be
-
example
- here is the message
COWwritten in a monospaced font, with the cursor all the way to the left-
buffer.lengthis4 -
lengthis3 -
cursoris0
-
| ##### ##### # # | # # # # # | # # # # # # | ##### ##### # # 0 1 2 3 4 -> x - here is the message
- the bottom of the canvas is
$y = -1.0$ and the top is$y = 2.0$ (NOTE: you don't need this fact except for the A++, at which point you'll probably want to write your own text drawing function(s) anyway)
- All features must match the behavior of a typical text input field
- For example, pressing
BACKSPACEshould turnCO|W(length 3) intoC|W(length 2); NOTE: the|is the cursor - You are responsible for discovering what the correct behavior of all commands is by experimenting with a real-world text input field
- For example, pressing
YouTube Link: https://www.youtube.com/watch?v=HTEWeeOiI3s

- You may NOT use any fancy Java standard library functions
- Use for loops, if statements, and the functions inside Cow.java
- You may NOT use the Java
Stringclass anywhere. - You may NOT create any new arrays (just modify the contents of
buffer) - You may NOT use excessive repetition (for example, don't use separate
ifstatements forc == 'A',c == 'B',c == 'C', ...) - You may NOT have any out of bounds errors
-
A-
- Update Cow
- User can press
A-Z(any of the keysA,B, ...) - Draw the cursor bar (location of
cursoras a vertical line) - User can press
0-9 - User can press
SHIFT + A,SHIFT + B... - User can press the space bar
- HINT: this is the character
' '
- HINT: this is the character
- User can press
LEFT_ARROW - User can press
RIGHT_ARROW - User can press
BACKSPACE
-
A
- Make the cursor bar blink
- HINT: You will want to introduce a
frameortimevariable to keep track of the current frame / time - NOTE: Making the cursor bar not blink for a bit after
keyAnyPressedis an optional good idea
- HINT: You will want to introduce a
- Click the mouse to move
cursorto the closestint - If the user presses
ENTERwhile the buffer containsPassw0rd, replace the contents of the buffer withaccepted- HINT: some repetition here is OK
- Make the cursor bar blink
-
A+
- Click and drag the mouse to select/highlight a sequence of characters
- HINT:
int select = 0;can be the "selection cursor"; if(cursor == select)is true, then nothing is selected (and the cursor should be blink as usual); it it is false, then the characters in between the two numbers are selected-
MIN(...)andMAX(...)may be useful
-
- NOTE: pressing
BACKSPACEwhile characters are selected must do the right thing - NOTE: pressing
A,B, ... should also do the right thing
- HINT:
- Press
COMMAND + AorCONTROL + Ato select all characters- NOTE: we want our app to be "cross platform" (work on both Mac and Windows)
- (Optional, but put in free response if you did it) Double-click the mouse to select all characters
- HINT: Be careful about the built-in
mouseHeld(NOTE:mouseHeldis true for the first framemousePressedis true--and likely for a few frames after that as well)
- HINT: Be careful about the built-in
- Improve the animations of the cursor; Inspo: https://diskvoyager.com; Additional very important inspo: https://www.youtube.com/watch?v=emjuqqyq_qc
- Click and drag the mouse to select/highlight a sequence of characters
-
A++ (105)
- Build a full raw text editor like TextEdit/Notepad
- Copy and paste from system clipboard
- Multiple lines
- Build a full raw text editor like TextEdit/Notepad
class HW02 extends Cow {
public static void main(String[] arguments) {
char[] buffer = new char[8];
int length = 0;
int cursor = 0;
canvasConfig(0.0, -1.0, buffer.length, 2.0, WHITE, 512);
while (beginFrame()) {
// TODO
// NOTE: This function draws the first length-many characters of the buffer
HW02_drawText(buffer, length, BLACK);
}
}
}Iterate over the characters A-Z
for (char c = 'A'; c <= 'Z'; ++c) { ... }Convert char from uppercase to lowercase
(char)('a' + (c - 'A'))-
Example:
('D' - 'A') -> 3and(char) ('a' + 3) -> 'd'
How can I make my code for typing letters, numbers and spaces less repetitive?
If you're finding your code looks like this...
for (char c = 'A'; c <= 'Z'; ++c) {
if (keyPressed(c)) {
... // Complicated logic for inserting a character
}
}
for (char c = '1'; c <= '9'; ++c) {
if (keyPressed(c)) {
... // Complicated logic for inserting a character
}
}
if (keyPressed(' ')) {
... // Complicated logic for inserting a character
}Maybe instead consider something like this!
char newCharacter = 0; // initialize to the null (0) character
for (char c = 'A'; c <= 'Z'; ++c) {
... // Simple logic to setting newCharacter
// NOTE: this one also has to handle shift
}
for (char c = '0'; c <= '9'; ++c) {
... // Simple logic for setting newCharacter
}
if (keyPressed(' ')) {
... // Simple logic for setting newCharacter
}
if (newCharacter != 0) {
... // Complicated logic for inserting a character
}👀
class HW02A extends Cow {
public static void main(String[] arguments) {
final char[] buffer = new char[8];
int length = 0;
int cursor = 0;
// NOTE: each character is 1 unit wide
canvasConfig(0.0, -1.0, buffer.length, 2.0, WHITE, 512);
int blinkCounter = 0;
while (beginFrame()) {
boolean insertCharacterValid = (length != buffer.length);
boolean backspaceValid = ((length != 0) && (cursor != 0));
boolean leftArrowKeyValid = (cursor != 0);
boolean rightArrowKeyValid = (cursor != length);
if (keyAnyPressed) {
blinkCounter = 0;
}
if (insertCharacterValid) {
char newCharacter; {
newCharacter = 0;
for (char c = 'A'; c <= 'Z'; ++c) {
if (keyPressed(c)) {
if (!keyHeld(SHIFT)) {
newCharacter = (char)('a' + (c - 'A'));
} else {
newCharacter = c;
}
}
}
for (char c = '0'; c <= '9'; ++c) {
if (keyPressed(c)) newCharacter = c;
}
if (keyPressed(' ')) newCharacter = ' ';
}
if (newCharacter != 0) {
for (int i = length; i > cursor; --i) buffer[i] = buffer[i - 1];
buffer[cursor] = newCharacter;
++cursor;
++length;
}
}
if (backspaceValid && keyPressed(BACKSPACE)) {
for (int i = cursor; i < length; ++i) buffer[i - 1] = buffer[i];
--cursor;
--length;
}
if (leftArrowKeyValid && keyPressed(LEFT_ARROW)) {
--cursor;
}
if (rightArrowKeyValid && keyPressed(RIGHT_ARROW)) {
++cursor;
}
if (mousePressed) {
cursor = length;
for (int i = 0; i < length; ++i) {
if (mouseX < i + 0.5) {
cursor = i;
blinkCounter = 0;
break;
}
}
}
if (keyPressed(ENTER)) {
if (true
&& (buffer[0] == 'P')
&& (buffer[1] == 'a')
&& (buffer[2] == 's')
&& (buffer[3] == 's')
&& (buffer[4] == 'w')
&& (buffer[5] == '0')
&& (buffer[6] == 'r')
&& (buffer[7] == 'd')) {
buffer[0] = 'a';
buffer[1] = 'c';
buffer[2] = 'c';
buffer[3] = 'e';
buffer[4] = 'p';
buffer[5] = 't';
buffer[6] = 'e';
buffer[7] = 'd';
}
}
{ // draw
if ((blinkCounter++ % 14) < 7) drawLine(cursor, -0.5, cursor, 1.5, PURPLE, 5.0);
HW02_drawText(buffer, length, BLACK);
}
}
}
}