///////////////////////////////////////////////////////////////////////////
//
//  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);
}
Example #2
0
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);
}