Thursday, December 25, 2008

Happy Christmas!

Not a release as a present, but a taster of something you can expect. Guess where I'm using this code...?

void CQMenuCvarTextbox::Key (int k)
{
// get the real position of the cursor in the string
int RealTextPos = this->TextPos + this->TextStart;

switch (k)
{
case K_ENTER:
// commit modification
if (!this->Modified) break;

// don't save empty strings
if (this->TempStorage[0] == 0)
{
menu_soundlevel = m_sound_deny;
break;
}

// store back to cvar
if (this->MenuCvar == &cl_name)
{
// this is a hack as name must be changed via the "name" command so broadcasts will work
Cbuf_AddText (va ("name \"%s\"\n", this->TempStorage));
}
else Cvar_Set (this->MenuCvar, this->TempStorage);

// not modified any more
this->Modified = false;
break;

case K_INS:
// toggle insert mode
this->InsertMode = !this->InsertMode;
break;

case K_LEFTARROW:
this->TextPos--;
menu_soundlevel = m_sound_option;

if (this->TextPos < 0)
{
this->TextPos = 0;
this->TextStart--;
}

if (this->TextStart < 0)
{
this->TextStart = 0;
menu_soundlevel = m_sound_deny;
}
break;

case K_RIGHTARROW:
this->TextPos++;
menu_soundlevel = m_sound_option;

if (this->TextPos > strlen (this->TempStorage))
{
menu_soundlevel = m_sound_deny;
this->TextPos = strlen (this->TempStorage);
}

if (this->TextPos > 16)
{
this->TextPos = 16;
this->TextStart++;
}

if (this->TextStart > strlen (this->TempStorage) - 16)
{
this->TextStart = strlen (this->TempStorage) - 16;
menu_soundlevel = m_sound_deny;
}
break;

case K_HOME:
// return to start
menu_soundlevel = m_sound_option;
this->TextPos = 0;
this->TextStart = 0;
break;

case K_END:
// go to end
menu_soundlevel = m_sound_option;
this->TextPos = 16;
if (this->TextPos > strlen (this->TempStorage)) this->TextPos = strlen (this->TempStorage);

this->TextStart = strlen (this->TempStorage) - 16;
if (this->TextStart < 0) this->TextStart = 0;
break;

case K_DEL:
// prevent deletion if at end of string
if (RealTextPos >= strlen (this->TempStorage))
{
menu_soundlevel = m_sound_deny;
break;
}

// simulate the deletion by moving right then deleting before the cursor
this->Key (K_RIGHTARROW);
this->Key (K_BACKSPACE);
menu_soundlevel = m_sound_option;

break;

case K_BACKSPACE:
// prevent deletion at start of string
if (!RealTextPos)
{
menu_soundlevel = m_sound_deny;
break;
}

// delete character before cursor
menu_soundlevel = m_sound_option;
strcpy (this->ScratchPad, &this->TempStorage[RealTextPos]);
strcpy (&this->TempStorage[RealTextPos - 1], this->ScratchPad);

// fix up positioning
this->TextStart--;

if (this->TextStart < 0)
{
this->TextStart = 0;
this->TextPos--;
}

if (this->TextPos < 0) this->TextPos = 0;
break;

default:
// non alphanumeric
if (k < 32 || k > 127)
{
menu_soundlevel = m_sound_deny;
break;
}

// conservative overflow prevent
if (strlen (this->TempStorage) > 1020)
{
menu_soundlevel = m_sound_deny;
break;
}

menu_soundlevel = m_sound_option;

if (this->InsertMode)
{
// insert mode
strcpy (this->ScratchPad, &this->TempStorage[RealTextPos]);
strcpy (&this->TempStorage[RealTextPos + 1], this->ScratchPad);
this->TempStorage[RealTextPos] = k;

// move right
this->Key (K_RIGHTARROW);
}
else
{
// overwrite mode
this->TempStorage[RealTextPos] = k;

// move right
this->Key (K_RIGHTARROW);
}

break;
}

// check for modification
if (stricmp (this->TempStorage, this->MenuCvar->string))
this->Modified = true;
else this->Modified = false;
}

0 comments: