Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I would use a timer in combination with an int to count the taps. This is pure pseudo code but will give the basic idea.</p> <pre><code>long lastEvent = 0; int lastNum = 0; int taps = 0; eventListener(KeyEventArgs e) { if (e.Value == lastNum) { if ((DateTime.Now.ToFileTimeUtc() - lastEvent) &lt; AppropriateTimeLimit) { taps++; } else { GetLetter(taps, lastNum); lastEvant = DateTime.Now.ToFileTimeUtc(); taps = 0; } } else { GetLetter(taps, lastNum); lastEvant = DateTime.Now.ToFileTimeUtc(); taps = 0; lastNum = e.Value; } } char GetLetter(int taps, int num) { if (num == 1) return punctuationVals[taps % length -1]; else if (num == 0) return ' '; //from what I remember 0 was for spaces on most phones else { int val; if (taps &gt; 3) val = taps % 4; // old phones wrap around back to the first char if I press the key 5 times else val = taps; return values[num][val]; } } char[][] values = new char[9][4]; // statically code all of your chars in these arrays char[] punctuationVals = new char[idkHowMany]; </code></pre> <p>So here's the design overview. Firstly, we have an event listener that is handling all the input events. We know a tap sequence is complete under one of two conditions 1) Time has expired (If you remember typing on old phones if I wanted to type 'abc' I'd have to press 2 once, wait a second or so, press 2 twice wait another second, press 2 three times) or 2) A new key has been pressed.</p> <p>In either case we need to know what the last key pressed was so we track that. If the key input does not match the last key pressed then we can safely output the last key pressed, thus we call <code>GetLetter</code>, reset the taps to 0, set the last even time to now, and set the <code>lastNum</code> to the number that was just pressed. This is the simpler case.</p> <p>In the case of someone trying to input 'abc' we need to know when to distinguish between the end of the first input and start of the next. For this we use a timer. If the difference between the first tap and the one which just occurred is within some limit (perhaps half a second or a second) then we increment the taps, if it's outside of it, we decide that they've moved on from 'a' to 'b' at which point we go through the same output process as when the user presses a key different from the last, except we don't change the value of the last key pressed since it hasn't changed.</p> <p><code>GetLetter</code> is the last thing worth discussing. This is fairly simple, you hard code a 2D array for values 2-9, to make indexing simple we'll retain 0 and 1 but leave them blank.</p> <p>Meaning, the array is something like;</p> <pre><code> '', '','', '' '', '', '', '' '2', 'a', 'b', 'c' '3', 'd', 'e', 'f' //ect </code></pre> <p>This makes indexing simpler, <code>GetLetter(2, 2)</code> simply returns <code>values[2][2]</code> which is correctly 'b'.</p> <p>Because 7 successive taps on the 2 key would produce 'c' we do mod 4 on the value if it's greater than 3 (three because 4 % 4 is 0 which should produce the number itself which I have at index 0). Now <code>GetLetter(6, 2)</code> will return <code>values[2][2]</code> which is correctly 'b'. </p> <p>1 is a special case. For that we just use a one dimensional array with however many values (maybe 20 or something) and we do modulus on it's input as well but obviously it's based of the length of that array. The modulus I have for this case may be wrong, but it would be simple to fix.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload