aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Horn2002-12-14 21:37:40 +0000
committerMax Horn2002-12-14 21:37:40 +0000
commit3af37415625842a392d6372e294e3966752d1d90 (patch)
tree43b73f27db90e3e05b03a269fb727ae4a9e256f2
parent534b4c4be4aa3c07f6e991ef25f36551aff0ff96 (diff)
downloadscummvm-rg350-3af37415625842a392d6372e294e3966752d1d90.tar.gz
scummvm-rg350-3af37415625842a392d6372e294e3966752d1d90.tar.bz2
scummvm-rg350-3af37415625842a392d6372e294e3966752d1d90.zip
improved line editing; reworked various internal details
svn-id: r5965
-rw-r--r--gui/console.cpp143
-rw-r--r--gui/console.h16
2 files changed, 103 insertions, 56 deletions
diff --git a/gui/console.cpp b/gui/console.cpp
index 2c79de0739..662c2b8734 100644
--- a/gui/console.cpp
+++ b/gui/console.cpp
@@ -57,8 +57,7 @@ ConsoleDialog::ConsoleDialog(NewGui *gui)
memset(_buffer, ' ', kBufferSize);
_linesInBuffer = kBufferSize / _lineWidth;
- _currentColumn = 0;
- _currentLine = 0;
+ _currentPos = 0;
_scrollLine = _linesPerPage - 1;
_caretVisible = false;
@@ -73,8 +72,7 @@ ConsoleDialog::ConsoleDialog(NewGui *gui)
print("Console is ready\n");
print(PROMPT);
- _promptLine = _currentLine;
-
+ _promptStartPos = _promptEndPos = _currentPos;
}
void ConsoleDialog::drawDialog()
@@ -124,14 +122,14 @@ void ConsoleDialog::handleMouseWheel(int x, int y, int direction)
_scrollBar->handleMouseWheel(x, y, direction);
}
-void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
-
+void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers)
+{
switch (keycode) {
case '\n': // enter/return
case '\r':
nextLine();
print(PROMPT);
- _promptLine = _currentLine;
+ _promptStartPos = _promptEndPos = _currentPos;
if (_caretVisible)
drawCaret(true);
@@ -141,15 +139,13 @@ void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
close();
break;
case 8: // backspace
- if (_currentColumn == 0 && _currentLine > _promptLine) {
- _currentColumn = _lineWidth - 1;
- _currentLine--;
- } else if (_currentColumn > 0) {
- if (_currentLine > _promptLine || _currentColumn >= (int)sizeof(PROMPT))
- _currentColumn--;
+ if (_currentPos > _promptStartPos) {
+ _currentPos--;
+ for (int i = _currentPos; i < _promptEndPos; i++)
+ _buffer[i % kBufferSize] = _buffer[(i+1) % kBufferSize];
+ _buffer[_promptEndPos % kBufferSize] = ' ';
+ _promptEndPos--;
}
- _buffer[(_currentLine % _linesInBuffer) * _lineWidth + _currentColumn] = ' ';
-
if (_caretVisible)
drawCaret(true);
draw(); // FIXME - not nice to redraw the full console just for one char!
@@ -172,15 +168,37 @@ void ConsoleDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) {
draw();
break;
case 256+23: // end
- _scrollLine = _currentLine;
+ _scrollLine = _currentPos / _lineWidth;
updateScrollBar();
draw();
break;
+ case 275: // cursor right
+ if (_currentPos < _promptEndPos)
+ _currentPos++;
+ draw();
+ break;
+ case 276: // cursor left
+ if (_currentPos > _promptStartPos)
+ _currentPos--;
+ draw();
+ break;
+
default:
if (ascii == '~' || ascii == '#') {
close();
+ } else if (modifiers == OSystem::KBD_CTRL) { // CTRL
+ specialKeys(keycode);
} else if (isprint((char)ascii)) {
- putchar(ascii);
+ for (int i = _promptEndPos-1; i >= _currentPos; i--)
+ _buffer[(i+1) % kBufferSize] = _buffer[i % kBufferSize];
+ _buffer[_currentPos % kBufferSize] = (char)ascii;
+ _currentPos++;
+ _promptEndPos++;
+ if ((_scrollLine + 1) * _lineWidth == _currentPos) {
+ _scrollLine++;
+ updateScrollBar();
+ }
+ draw(); // FIXME - not nice to redraw the full console just for one char!
}
}
}
@@ -198,25 +216,63 @@ void ConsoleDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data
}
}
+void ConsoleDialog::specialKeys(int keycode)
+{
+ switch (keycode) {
+ case 'a':
+ _currentPos = _promptStartPos;
+ draw();
+ break;
+ case 'e':
+ _currentPos = _promptEndPos;
+ draw();
+ break;
+ case 'k':
+ killLine();
+ draw();
+ break;
+ case 'w':
+ killLastWord();
+ draw();
+ break;
+ }
+}
+
+void ConsoleDialog::killLine()
+{
+ for (int i = _currentPos; i < _promptEndPos; i++)
+ _buffer[i % kBufferSize] = ' ';
+ _promptEndPos = _currentPos;
+}
+
+void ConsoleDialog::killLastWord()
+{
+ int pos;
+ while (_currentPos > _promptStartPos) {
+ _currentPos--;
+ pos = getBufferPos();
+ if (_buffer[pos] != ' ')
+ _buffer[pos] = ' ';
+ else
+ break;
+ }
+}
+
void ConsoleDialog::nextLine()
{
- _currentColumn = 0;
- if (_currentLine == _scrollLine)
+ int line = _currentPos / _lineWidth;
+ if (line == _scrollLine)
_scrollLine++;
- _currentLine++;
+ _currentPos = (line + 1) * _lineWidth;
updateScrollBar();
}
void ConsoleDialog::updateScrollBar()
{
- if (_currentLine < _linesInBuffer) {
- _scrollBar->_numEntries = _currentLine + 1;
- _scrollBar->_currentPos = _scrollLine - _linesPerPage + 1;
- } else {
- _scrollBar->_numEntries = _linesInBuffer;
- _scrollBar->_currentPos = _scrollLine - _linesPerPage + 1 - (_currentLine - _linesInBuffer);
- }
+ int line = _currentPos / _lineWidth;
+ _scrollBar->_numEntries = (line < _linesInBuffer) ? line + 1 : _linesInBuffer;
+ _scrollBar->_currentPos = _scrollBar->_numEntries - (line - _scrollLine + _linesPerPage);
_scrollBar->_entriesPerPage = _linesPerPage;
_scrollBar->recalc();
}
@@ -245,32 +301,20 @@ void ConsoleDialog::putchar(int c)
if (c == '\n')
nextLine();
else {
- int pos = (_currentLine % _linesInBuffer) * _lineWidth + _currentColumn;
- _buffer[pos] = (char)c;
- _currentColumn++;
- if (_currentColumn >= _lineWidth)
- nextLine();
+ _buffer[getBufferPos()] = (char)c;
+ _currentPos++;
+ if ((_scrollLine + 1) * _lineWidth == _currentPos) {
+ _scrollLine++;
+ updateScrollBar();
+ }
}
draw(); // FIXME - not nice to redraw the full console just for one char!
}
void ConsoleDialog::print(const char *str)
{
- int pos = (_currentLine % _linesInBuffer) * _lineWidth + _currentColumn;
- while (*str) {
- if (*str == '\n') {
- nextLine();
- pos += _lineWidth - _currentColumn;
- } else {
- _buffer[pos++] = *str;
- _currentColumn++;
- if (_currentColumn >= _lineWidth)
- nextLine();
- }
- pos %= kBufferSize;
- str++;
- }
- draw();
+ while (*str)
+ putchar(*str++);
}
void ConsoleDialog::drawCaret(bool erase)
@@ -279,12 +323,13 @@ void ConsoleDialog::drawCaret(bool erase)
if (!isVisible())
return;
- int displayLine = _currentLine - _scrollLine + _linesPerPage - 1;
+ int line = _currentPos / _lineWidth;
+ int displayLine = line - _scrollLine + _linesPerPage - 1;
if (displayLine < 0 || displayLine >= _linesPerPage)
return;
- int x = _x + 1 + _currentColumn * kCharWidth;
+ int x = _x + 1 + (_currentPos % _lineWidth) * kCharWidth;
int y = _y + displayLine * kLineHeight;
_gui->fillRect(x, y, kCharWidth, kLineHeight, erase ? _gui->_bgcolor : _gui->_textcolor);
diff --git a/gui/console.h b/gui/console.h
index 01d0705661..289bdb8441 100644
--- a/gui/console.h
+++ b/gui/console.h
@@ -44,12 +44,11 @@ protected:
int _lineWidth;
int _linesPerPage;
- int _currentColumn;
- int _currentLine;
+ int _currentPos;
int _scrollLine;
-// char _lineBuffer[kLineBufferSize];
- int _promptLine;
+ int _promptStartPos;
+ int _promptEndPos;
bool _caretVisible;
uint32 _caretTime;
@@ -59,9 +58,6 @@ protected:
public:
ConsoleDialog(NewGui *gui);
-// void open();
-// void close();
-
void drawDialog();
void handleTickle();
@@ -79,6 +75,12 @@ protected:
void print(const char *str);
void nextLine();
void updateScrollBar();
+ inline int getBufferPos() const { return _currentPos % kBufferSize; }
+
+ // Line editing
+ void specialKeys(int keycode);
+ void killLine();
+ void killLastWord();
};
#endif