/////////////////////////////////////////////////////////////////////////// // // US_LineInput() - Gets a line of user input at (x,y), the string defaults // to whatever is pointed at by def. Input is restricted to maxchars // chars or maxwidth pixels wide. If the user hits escape (and escok is // true), nothing is copied into buf, and false is returned. If the // user hits return, the current string is copied into buf, and true is // returned // /////////////////////////////////////////////////////////////////////////// boolean US_LineInput(int x,int y,char *buf,const char *def,boolean escok, int maxchars,int maxwidth) { boolean redraw, cursorvis,cursormoved, done,result, checkkey; ScanCode sc; char c; char s[MaxString],olds[MaxString]; int cursor,len; word i, w,h, temp; longword curtime, lasttime, lastdirtime, lastbuttontime, lastdirmovetime; ControlInfo ci; Direction lastdir = dir_None; if (def) strcpy(s,def); else *s = '\0'; *olds = '\0'; cursor = (int) strlen(s); cursormoved = redraw = true; cursorvis = done = false; lasttime = lastdirtime = lastdirmovetime = GetTimeCount(); lastbuttontime = lasttime + TickBase / 4; // 250 ms => first button press accepted after 500 ms LastASCII = key_None; LastScan = sc_None; while (!done) { ReadAnyControl(&ci); if (cursorvis) USL_XORICursor(x,y,s,cursor); sc = LastScan; LastScan = sc_None; c = LastASCII; LastASCII = key_None; checkkey = true; curtime = GetTimeCount(); // After each direction change accept the next change after 250 ms and then everz 125 ms if(ci.dir != lastdir || ((curtime - lastdirtime > TickBase / 4) && (curtime - lastdirmovetime > TickBase / 8))) { if(ci.dir != lastdir) { lastdir = ci.dir; lastdirtime = curtime; } lastdirmovetime = curtime; switch(ci.dir) { case dir_West: if(cursor) { // Remove trailing whitespace if cursor is at end of string if(s[cursor] == ' ' && s[cursor + 1] == 0) s[cursor] = 0; cursor--; } cursormoved = true; checkkey = false; break; case dir_East: if(cursor >= MaxString - 1) break; if(!s[cursor]) { USL_MeasureString(s,&w,&h); if(len >= maxchars || (maxwidth && w >= maxwidth)) break; s[cursor] = ' '; s[cursor + 1] = 0; } cursor++; cursormoved = true; checkkey = false; break; case dir_North: if(!s[cursor]) { USL_MeasureString(s,&w,&h); if(len >= maxchars || (maxwidth && w >= maxwidth)) break; s[cursor + 1] = 0; } s[cursor] = USL_RotateChar(s[cursor], 1); redraw = true; checkkey = false; break; case dir_South: if(!s[cursor]) { USL_MeasureString(s,&w,&h); if(len >= maxchars || (maxwidth && w >= maxwidth)) break; s[cursor + 1] = 0; } s[cursor] = USL_RotateChar(s[cursor], -1); redraw = true; checkkey = false; break; default: break; } } if((int)(curtime - lastbuttontime) > TickBase / 4) // 250 ms { if(ci.button0) // acts as return { strcpy(buf,s); done = true; result = true; checkkey = false; } if(ci.button1 && escok) // acts as escape { done = true; result = false; checkkey = false; } if(ci.button2) // acts as backspace { lastbuttontime = curtime; if(cursor) { strcpy(s + cursor - 1,s + cursor); cursor--; redraw = true; } cursormoved = true; checkkey = false; } } if(checkkey) { switch (sc) { case sc_LeftArrow: if (cursor) cursor--; c = key_None; cursormoved = true; break; case sc_RightArrow: if (s[cursor]) cursor++; c = key_None; cursormoved = true; break; case sc_Home: cursor = 0; c = key_None; cursormoved = true; break; case sc_End: cursor = (int) strlen(s); c = key_None; cursormoved = true; break; case sc_Return: strcpy(buf,s); done = true; result = true; c = key_None; break; case sc_Escape: if (escok) { done = true; result = false; } c = key_None; break; case sc_BackSpace: if (cursor) { strcpy(s + cursor - 1,s + cursor); cursor--; redraw = true; } c = key_None; cursormoved = true; break; case sc_Delete: if (s[cursor]) { strcpy(s + cursor,s + cursor + 1); redraw = true; } c = key_None; cursormoved = true; break; case SDLK_KP5: //0x4c: // Keypad 5 // TODO: hmmm... case sc_UpArrow: case sc_DownArrow: case sc_PgUp: case sc_PgDn: case sc_Insert: c = key_None; break; } if (c) { len = (int) strlen(s); USL_MeasureString(s,&w,&h); if(isprint(c) && (len < MaxString - 1) && ((!maxchars) || (len < maxchars)) && ((!maxwidth) || (w < maxwidth))) { for (i = len + 1;i > cursor;i--) s[i] = s[i - 1]; s[cursor++] = c; redraw = true; } } } if (redraw) { px = x; py = y; temp = fontcolor; fontcolor = backcolor; USL_DrawString(olds); fontcolor = (byte) temp; strcpy(olds,s); px = x; py = y; USL_DrawString(s); redraw = false; } if (cursormoved) { cursorvis = false; lasttime = curtime - TickBase; cursormoved = false; } if (curtime - lasttime > TickBase / 2) // 500 ms { lasttime = curtime; cursorvis ^= true; } else rarch_sleep(5); if (cursorvis) USL_XORICursor(x,y,s,cursor); VW_UpdateScreen(); } if (cursorvis) USL_XORICursor(x,y,s,cursor); if (!result) { px = x; py = y; USL_DrawString(olds); } VW_UpdateScreen(); IN_ClearKeysDown(); return(result); }
qint8 WLUser::US_LineInput(qint32 x, qint32 y, char *buf,const char *def,qint8 escok, qint32 maxchars, qint32 maxwidth) { qint8 redraw, cursorvis, cursormoved, done, result=0, checkkey; ScanCode sc; char c; char s[MaxString],olds[MaxString]; qint32 cursor,len = 0; quint16 i, w, h, temp; quint32 curtime, lasttime, lastdirtime, lastbuttontime, lastdirmovetime; ControlInfo_t ci; Direction lastdir = dir_None; if (def) strcpy(s,def); else *s = '\0'; *olds = '\0'; cursor = (qint32) strlen(s); cursormoved = redraw = true; cursorvis = done = false; lasttime = lastdirtime = lastdirmovetime = g_getTicks->elapsed()*7/100; //GetTicks(); lastbuttontime = lasttime + g_tickBase / 4; // 250 ms => first button press accepted after 500 ms wlinput->setLastScan(sc_None); wlinput->setLastAscii(key_None); while (!done) { ReadAnyControl(&ci); if (cursorvis) USL_XORICursor(x,y,s,cursor); sc = wlinput->lastScan(); wlinput->setLastScan(sc_None); c = wlinput->lastAscii(); wlinput->setLastAscii(key_None); checkkey = true; curtime = g_getTicks->elapsed()*7/100; //GetTicks(); // After each direction change accept the next change after 250 ms and then everz 125 ms if(ci.dir != lastdir || (curtime - lastdirtime > g_tickBase / 4 && curtime - lastdirmovetime > g_tickBase / 8)) { if(ci.dir != lastdir) { lastdir = ci.dir; lastdirtime = curtime; } lastdirmovetime = curtime; switch(ci.dir) { case dir_West: if(cursor) { // Remove trailing whitespace if cursor is at end of string if(s[cursor] == ' ' && s[cursor + 1] == 0) s[cursor] = 0; cursor--; } cursormoved = true; checkkey = false; break; case dir_East: if(cursor >= MaxString - 1) break; if(!s[cursor]) { wlpaint->measurePropString(s, &w, &h); if(len >= maxchars || (maxwidth && w >= maxwidth)) break; s[cursor] = ' '; s[cursor + 1] = 0; } cursor++; cursormoved = true; checkkey = false; break; case dir_North: if(!s[cursor]) { wlpaint->measurePropString(s, &w, &h); if(len >= maxchars || (maxwidth && w >= maxwidth)) break; s[cursor + 1] = 0; } s[cursor] = USL_RotateChar(s[cursor], 1); redraw = true; checkkey = false; break; case dir_South: if(!s[cursor]) { wlpaint->measurePropString(s, &w, &h); if(len >= maxchars || (maxwidth && w >= maxwidth)) break; s[cursor + 1] = 0; } s[cursor] = USL_RotateChar(s[cursor], -1); redraw = true; checkkey = false; break; default: break; } } if((int)(curtime - lastbuttontime) > g_tickBase / 4) { if(ci.button0) { strcpy(buf,s); done = true; result = true; checkkey = false; } if(ci.button1 && escok) { done = true; result = false; checkkey = false; } if(ci.button2) { lastbuttontime = curtime; if(cursor) { strcpy(s + cursor - 1,s + cursor); cursor--; redraw = true; } cursormoved = true; checkkey = false; } } if(checkkey) { switch (sc) { case sc_LeftArrow: if (cursor) cursor--; c = key_None; cursormoved = true; break; case sc_RightArrow: if (s[cursor]) cursor++; c = key_None; cursormoved = true; break; case sc_Home: cursor = 0; c = key_None; cursormoved = true; break; case sc_End: cursor = (int) strlen(s); c = key_None; cursormoved = true; break; case sc_Enter: case sc_Return: strcpy(buf,s); done = true; result = true; c = key_None; break; case sc_Escape: if (escok) { done = true; result = false; } c = key_None; break; case sc_BackSpace: if (cursor) { strcpy(s + cursor - 1,s + cursor); cursor--; redraw = true; } c = key_None; cursormoved = true; break; case sc_Delete: if (s[cursor]) { strcpy(s + cursor,s + cursor + 1); redraw = true; } c = key_None; cursormoved = true; break; case sc_UpArrow: case sc_DownArrow: case sc_PgUp: case sc_PgDn: c = key_None; break; } if (c) { len = (int) strlen(s); wlpaint->measurePropString(s, &w, &h); if(isprint(c) && (len < MaxString - 1) && ((!maxchars) || (len < maxchars)) && ((!maxwidth) || (w < maxwidth))) { for (i = len + 1;i > cursor;i--) s[i] = s[i - 1]; s[cursor++] = c; redraw = true; } } } if (redraw) { px = x; py = y; temp = fontcolor; fontcolor = backcolor; wlpaint->drawPropString(olds); fontcolor = (quint8)temp; strcpy(olds,s); px = x; py = y; wlpaint->drawPropString(s); redraw = false; } if (cursormoved) { cursorvis = false; lasttime = curtime - g_tickBase; cursormoved = false; } if (curtime - lasttime > g_tickBase / 2) { lasttime = curtime; cursorvis ^= true; } else gsleep(20); if (cursorvis) USL_XORICursor(x,y,s,cursor); wlpaint->updateScreen(); } if (cursorvis) USL_XORICursor(x,y,s,cursor); if (!result) { px = x; py = y; wlpaint->drawPropString(olds); } wlpaint->updateScreen(); wlinput->clearKeysDown(); return(result); }