Text and Number Input
From WikiPrizm
Jump to navigationJump to searchSynopsis
This routine is used for single-line text input on the "homescreen" of the Prizm. It can handle scrolling (strings wider than the screen), it can handle shift, alpha, and alpha-lock modes, it has a cursor, and all that fun stuff. It also has four input modes: text, float, int, and positive int.
Definition
Inputs
int getTextLine(char* buf, int maxstrlen, int x, int y, int maxdisplen, unsigned short inmode);
- char* buf - A buffer of at least maxstrlen+1 characters. May contain initial contents or just '\0'.
- int maxstrlen - The max number of chars the user may enter
- int x - The position of the first character, 1 through 21
- int y - The y-coordinate of the line, 1 through 8
- int maxdisplen - How long the input field can be. The field will scroll if the string is longer.
- unsigned short inmode - The input mode. One of:
- INPUT_MODE_TEXT
- INPUT_MODE_FLOAT
- INPUT_MODE_INT
- INPUT_MODE_POSINT
Outputs
An integer indicating the KEY_PRGM_ code of the key that caused the routine to quit. May be [F1]-[F6], [up], [down], or [enter]. Contents are filled into buf.
textinput.h
// Include file for textinput.c // Created by Christopher Mitchell / Kerm Martian // http://www.cemetech.net #include <keyboard.hpp> #include <color.h> #define bool unsigned char #define INPUT_MODE_TEXT 0 #define INPUT_MODE_FLOAT 1 #define INPUT_MODE_INT 2 #define INPUT_MODE_POSINT 3 #define CURSOR_FLASH_RATE 32 #define true 1 #define false 0 int getTextLine(char* buf, int maxstrlen, int x, int y, int maxdisplen, unsigned short inmode); void DrawCursor(int x, int y, int shiftmode, int alphamode, int cursorstate, char curchar);
textinput.c
// textinput.c for the Casio Prizm and Cemetech's PrizmSDK // Created by Christopher Mitchell / Kerm Martian // http://www.cemetech.net #include "textinput.h" int getTextLine(char* buf, int maxstrlen, int x, int y, int maxdisplen, unsigned short inmode) { //state variables int dispoffset = 0; //the offset of the starting char displayed int stroffset = 0; //the offset of the cursor into the string int curlen = 0; //current string length (<= maxstrlen) int cursorstate = 0; // 0 = char shown, 1 = cursor shown int shiftmode = 0, alphamode = 0; int cursorchangetime = RTC_GetTicks(); //last cursor change time int kcol, krow; bool finished = false; //if routine should end unsigned short key = 0; char dispcharbuf[21+2+1]; //max possible width is 21, 2 chars for the XX, 1 for null term dispcharbuf[0] = dispcharbuf[1] = 'X'; char* row0[18] = { "", "^2", "^", "", "", "", "", "sqrt(", "xrt(", "", "", "", "", "r", "Theta", "", "", ""}; char* row1[18] = { "X", "log(", "ln(", "sin(", "cos(", "tan(", "angle", "10x", "ex", "asin(", "acos(", "atan(", "A", "B", "C", "D", "E", "F"}; char* row2[18] = { "", "", "(", ")", ", ", "", "", "", "cuberoot(", "^-1", "", "", "G", "H", "I", "J", "K", "L"}; char* row3[18] = { "7", "8", "9", "", "", "", "", "", "", "", "", "", "M", "N", "O", "", "", ""}; char* row4[18] = { "4", "5", "6", "*", "/", "", "", "", "", "{", "}", "", "P", "Q", "R", "S", "T", ""}; char* row5[18] = { "1", "2", "3", "+", "-", "", "", "", "", "[", "]", "", "U", "V", "W", "X", "Y", ""}; char* row6[18] = { "0", ".", "E", "-", "", "", "i", "=", "pi", "Ans", "", "", "Z", " ", "\"", "", "", ""}; char** rows[7] = { row0, row1, row2, row3, row4, row5, row6 }; //First, figure out starting position while(buf[curlen] != '\0') { curlen++; if (curlen > maxstrlen) return -1; } stroffset = curlen; if (curlen >= maxdisplen) dispoffset = curlen-maxdisplen+1; //Main loop do { // display initial buffer contents int i=0; //copy chars into the buffer while(i<maxdisplen && buf[dispoffset+i] != '\0') { dispcharbuf[2+i] = buf[dispoffset+i]; i++; } while(i<maxdisplen) { dispcharbuf[2+i++] = ' '; } dispcharbuf[2+i] = '\0'; //null terminate it PrintXY(x,y,dispcharbuf,0,TEXT_COLOR_BLACK); cursorstate = 1; DrawCursor(x+(stroffset-dispoffset),y,shiftmode,alphamode,cursorstate,dispcharbuf[2+stroffset-dispoffset]); bool redraw = false; do { key = kcol = krow = 0; int retval = GetKeyWait_OS(&kcol,&krow,KEYWAIT_HALTON_TIMERON,1,0,&key); Bdisp_EnableColor(1); key = (10*kcol)+(krow - 1); if (retval == 1) { //erase the cursor and switch it back to the letter here cursorstate = 0; cursorchangetime = RTC_GetTicks(); DrawCursor(x+(stroffset-dispoffset),y,shiftmode,alphamode,0,dispcharbuf[2+stroffset-dispoffset]); if (krow == 10 || key == KEY_PRGM_UP || key == KEY_PRGM_DOWN || key == KEY_PRGM_RETURN) return key; if (key == KEY_PRGM_SHIFT) { shiftmode = 1-shiftmode; } else if (key == KEY_PRGM_ALPHA) { if (shiftmode == 1) alphamode = 2; else if (alphamode != 2) alphamode = 1-alphamode; else alphamode = 0; shiftmode = 0; } else if (key == KEY_PRGM_LEFT && stroffset != 0) { redraw = true; //cursor if (stroffset == dispoffset) { dispoffset--; } stroffset--; } else if (key == KEY_PRGM_RIGHT && stroffset < curlen) { redraw = true; //cursor if (stroffset == dispoffset+maxdisplen-1) { dispoffset++; } stroffset++; } else if (key == KEY_PRGM_ACON) { stroffset = dispoffset = 0; buf[0] = '\0'; curlen = 0; redraw = true; } else if (key == KEY_PRGM_DEL && stroffset < curlen) { int i = stroffset; do { buf[i] = buf[i+1]; i++; } while (buf[i] != '\0'); curlen--; redraw = true; } else if (key == KEY_PRGM_DEL && stroffset == curlen && stroffset > 0) { curlen--; stroffset--; buf[stroffset] = '\0'; redraw = true; if (stroffset <= dispoffset && dispoffset > 0) dispoffset--; } else { if (krow <= 8 && krow >= 2) { char** rowdef = rows[8-krow]; char* thisstr = rowdef[6*(shiftmode)+12*(alphamode!=0 && shiftmode == 0)+(7-kcol)]; if (*thisstr != '\0') { int len = _g_strlen(thisstr); signed char valid = (len+curlen < maxstrlen); switch (inmode) { case INPUT_MODE_FLOAT: if (len > 1) valid = false; else if (*thisstr == '-') { if (stroffset != 0 || buf[stroffset] == '-') valid = false; } else if (*thisstr == '.') { for(int i=0; i<curlen; i++) { if (buf[i] == '.') { valid = false; break; } } } else if (*thisstr >= '0' && *thisstr <= '9') { //this is fine } else valid = false; break; case INPUT_MODE_INT: if (len > 1) valid = false; else if (*thisstr == '-') { if (stroffset != 0 || buf[stroffset] == '-') valid = false; } else if (*thisstr >= '0' && *thisstr <= '9') { //this is fine } else valid = false; break; case INPUT_MODE_POSINT: if (len > 1) valid = false; else if (*thisstr >= '0' && *thisstr <= '9') { //this is fine } else valid = false; break; case INPUT_MODE_TEXT: default: valid = true; break; } if (valid) { for(int i=curlen+len;i>=stroffset+len;i--) { //make space to insert this buf[i] = buf[i-len]; } for(int i=0; i<len; i++) { //drop it into the space buf[stroffset++] = thisstr[i]; } curlen+=len; while (stroffset >= dispoffset+maxdisplen-1) { //adjust the cursor to be on-screen redraw = true; dispoffset++; } } redraw = 1; if (shiftmode) shiftmode = 0; else if (alphamode == 1) alphamode = 0; } } } } else if (cursorchangetime + CURSOR_FLASH_RATE < RTC_GetTicks()) { //and !key cursorstate = 1-cursorstate; cursorchangetime = RTC_GetTicks(); DrawCursor(x+(stroffset-dispoffset),y,shiftmode,alphamode,cursorstate,dispcharbuf[2+stroffset-dispoffset]); } } while (!redraw && !finished); } while(!finished); return KEY_PRGM_RETURN; } void DrawCursor(int x, int y, int shiftmode, int alphamode, int cursorstate, char curchar) { char buf2[5] = {'X','X',' ','\0','\0'}; buf2[2] = (curchar?curchar:' '); if (cursorstate) { if (shiftmode == 0 && alphamode == 0) { PrintXY(x,y,buf2,1,TEXT_COLOR_BLACK); Bdisp_PutDisp_DD(); return; } else if (shiftmode) { buf2[2] = 0xE5; buf2[3] = 0xEA; } else if (alphamode == 1) { buf2[2] = 0xE5; buf2[3] = 0x9F; } else { buf2[2] = 0xE7; buf2[3] = 0xAE; } } PrintXY(x,y,buf2,0,TEXT_COLOR_BLACK); Bdisp_PutDisp_DD(); }
Comments
I created this routine for use in Graph3DP. Enjoy!