Console.cpp

#include “console.h”

namespace cui
{

bool Console::_insertMode = true;
unsigned int Console::_tabsize = 4;

void Console::strdsp(const char* str, int row, int col, int len, int curpos)
{
int i;
setPos(row, col);
for (i = 0; (i < len || !len ) && str[i]; i++) {
putChar(str[i]);
}
for (; i < len; i++) {
putChar(‘ ‘);
}
if (curpos >= 0) {
setPos(row, col + curpos);
}
}

int Console::stredit(char *str, int row, int col, int fieldLength,
int maxStrLength, int* strOffset, int* curPosition, bool InTextEditor,
bool ReadOnly, bool& insertMode)
{
bool done = false;
bool fullLine;
int localOffset = 0;
int initOffset;
int key = 0;
int i = 0;
if (strOffset == (int*) 0) {
strOffset = &localOffset;
}
initOffset = *strOffset;

do {
// Keep the cursor from hitting far left or
// far right unless at the begging/end of line
// Always allows user to see what backspace/del
// will delete. Also means *curPosition can be
// used as a sort of atBeginning/atEnd flag.
/*
if (*curPosition == 0 && *strOffset) {
(*curPosition)++;
(*strOffset)–;
} else if (*curPosition + 1 == fieldLength
&& str[*strOffset + *curPosition]) {
(*curPosition)–;
(*strOffset)++;
}
*/

strdsp(str + *strOffset, row, col, fieldLength, *curPosition);
if (InTextEditor && *strOffset != initOffset) {
key = 0;
} else {
key = console.getKey();
}

switch (key) {

// Cursor navigating
case LEFT:
if (*curPosition) {
(*curPosition)–;
} else if (*strOffset) {
(*strOffset)–;
} else {
// console.alarm(); bad for your ears
}
break;
case RIGHT:
if (*curPosition < fieldLength – 1) {
(*curPosition)++;
} else if (str[*curPosition + *strOffset + 1] != 0) {
(*strOffset)++;
} else {
// console.alarm(); bad for your ears
}
break;
case HOME:
*strOffset = *curPosition = 0;
break;
case END:
for (i = 0; str[bio::strlen(str) – i] == 0; i++) {}
*strOffset = fieldLength – i – 1;
*curPosition = fieldLength – i – 2;
break;
case ENTER:
Console::_insertMode = true;
break;
// Editor commands
case INSERT:
Console::_insertMode = !Console::_insertMode;
break;
case TAB:
case PGDN:
case PGUP:
case UP:
case DOWN:
case F(1):
case F(2):
case F(3):
case F(4):
case F(5):
case F(6):
case F(7):
case F(8):
case F(9):
case F(10):
case F(11):
case F(12):
if (!ReadOnly) {
// Terminate and preserve changes
done = true;
break;
}
// else fallthrough so we don’t modify
// a read only string.
case 0:
// This allows the InTextEditor
// abort condition to return 0
case ESCAPE:
// Terminate and discard changes
done = true;
break;

// Deletions
case DEL:
if (*curPosition + 1 < fieldLength) {
(*curPosition)++;
} else {
break;
}
// DO NOT put a break here or move DEL and
// BACKSPACE relative to eachother – this
// potential fallthrough is intended.
case BACKSPACE:
if (*curPosition) {
(*curPosition)–;
for (i = 0; str[*strOffset + *curPosition + i]; i++) {
str[*strOffset + *curPosition + i] = str[*strOffset
+ *curPosition + 1 + i];
}
}
break;

// Insertions
default:
((bio::strlen(str) == maxStrLength) && (fullLine = true))
|| (fullLine = false);

if ( (Console::_insertMode || str[*strOffset + *curPosition] == 0)
&& !fullLine && key >= ‘ ‘ && key <= ‘~’) {
// if in insertmode OR if it’s a newline char and there’s room for more,
// put the char in. The OR part collects cases of not being in insertmode
// but still needing to increment the length of the string.
for (i = bio::strlen(str); i >= *strOffset + *curPosition; i–) {
str[i + 1] = str[i];
}
str[*strOffset + *curPosition] = key;
(*curPosition)++;
// Don’t run the cursor out of the edit field
if (*curPosition == fieldLength) {
(*curPosition)–;
(*strOffset)++;
}
} else if (!Console::_insertMode && str[*strOffset + *curPosition]) {
// If we’re in replace mode and on a non-null;
str[*strOffset + *curPosition] = key;
(*curPosition)++;
}
break;
}
} while (!done);
return key;
}

Console& Console::operator>>(int& ch)
{
ch = getKey();
return *this;
}

Console& Console::operator<<(const char& ch)
{
putChar(ch);
return *this;
}

Console& Console::operator<<(const char* str)
{
int i;
for (i = 0; str[i]; i++) {
*this << str[i];
}
return *this;
}

Console console;

} // namespace cui end