void ConsoleDialog::handleKeyDown(Common::KeyState state) { int i; if (_slideMode != kNoSlideMode) return; switch (state.keycode) { case Common::KEYCODE_RETURN: case Common::KEYCODE_KP_ENTER: { if (_caretVisible) drawCaret(true); nextLine(); assert(_promptEndPos >= _promptStartPos); int len = _promptEndPos - _promptStartPos; bool keepRunning = true; if (len > 0) { Common::String str; // Copy the user input to str for (i = 0; i < len; i++) str.insertChar(buffer(_promptStartPos + i), i); // Add the input to the history addToHistory(str); // Pass it to the input callback, if any if (_callbackProc) keepRunning = (*_callbackProc)(this, str.c_str(), _callbackRefCon); } print(PROMPT); _promptStartPos = _promptEndPos = _currentPos; draw(); if (!keepRunning) slideUpAndClose(); break; } case Common::KEYCODE_ESCAPE: slideUpAndClose(); break; case Common::KEYCODE_BACKSPACE: if (_caretVisible) drawCaret(true); if (_currentPos > _promptStartPos) { _currentPos--; killChar(); } scrollToCurrent(); drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_TAB: { if (_completionCallbackProc) { int len = _currentPos - _promptStartPos; assert(len >= 0); char *str = new char[len + 1]; // Copy the user input to str for (i = 0; i < len; i++) str[i] = buffer(_promptStartPos + i); str[len] = '\0'; Common::String completion; if ((*_completionCallbackProc)(this, str, completion, _callbackRefCon)) { if (_caretVisible) drawCaret(true); insertIntoPrompt(completion.c_str()); scrollToCurrent(); drawLine(pos2line(_currentPos)); } delete[] str; } break; } // Keypad & special keys // - if num lock is set, we always go to the default case // - if num lock is not set, we either fall down to the special key case // or ignore the key press in case of 0 (INSERT) or 5 case Common::KEYCODE_KP0: case Common::KEYCODE_KP5: if (state.flags & Common::KBD_NUM) defaultKeyDownHandler(state); break; case Common::KEYCODE_KP_PERIOD: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_DELETE: if (_currentPos < _promptEndPos) { killChar(); drawLine(pos2line(_currentPos)); } break; case Common::KEYCODE_KP1: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_END: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine = _promptEndPos / kCharsPerLine; if (_scrollLine < _linesPerPage - 1) _scrollLine = _linesPerPage - 1; updateScrollBuffer(); } else { _currentPos = _promptEndPos; } draw(); break; case Common::KEYCODE_KP2: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_DOWN: historyScroll(-1); break; case Common::KEYCODE_KP3: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_PAGEDOWN: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine += _linesPerPage - 1; if (_scrollLine > _promptEndPos / kCharsPerLine) { _scrollLine = _promptEndPos / kCharsPerLine; if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1) _scrollLine = _firstLineInBuffer + _linesPerPage - 1; } updateScrollBuffer(); draw(); } break; case Common::KEYCODE_KP4: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_LEFT: if (_currentPos > _promptStartPos) _currentPos--; drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_KP6: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_RIGHT: if (_currentPos < _promptEndPos) _currentPos++; drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_KP7: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_HOME: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine = _firstLineInBuffer + _linesPerPage - 1; updateScrollBuffer(); } else { _currentPos = _promptStartPos; } draw(); break; case Common::KEYCODE_KP8: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_UP: historyScroll(+1); break; case Common::KEYCODE_KP9: if (state.flags & Common::KBD_NUM) { defaultKeyDownHandler(state); break; } case Common::KEYCODE_PAGEUP: if (state.hasFlags(Common::KBD_SHIFT)) { _scrollLine -= _linesPerPage - 1; if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1) _scrollLine = _firstLineInBuffer + _linesPerPage - 1; updateScrollBuffer(); draw(); } break; default: defaultKeyDownHandler(state); } }
void ConsoleDialog::handleKeyDown(Common::KeyState state) { int i; if (_slideMode != kNoSlideMode) return; switch (state.keycode) { case Common::KEYCODE_RETURN: case Common::KEYCODE_KP_ENTER: { if (_caretVisible) drawCaret(true); nextLine(); assert(_promptEndPos >= _promptStartPos); int len = _promptEndPos - _promptStartPos; bool keepRunning = true; if (len > 0) { // We have to allocate the string buffer with new, since VC++ sadly does not // comply to the C++ standard, so we can't use a dynamic sized stack array. char *str = new char[len + 1]; // Copy the user input to str for (i = 0; i < len; i++) str[i] = buffer(_promptStartPos + i); str[len] = '\0'; // Add the input to the history addToHistory(str); // Pass it to the input callback, if any if (_callbackProc) keepRunning = (*_callbackProc)(this, str, _callbackRefCon); // Get rid of the string buffer delete[] str; } print(PROMPT); _promptStartPos = _promptEndPos = _currentPos; draw(); if (!keepRunning) slideUpAndClose(); break; } case Common::KEYCODE_ESCAPE: slideUpAndClose(); break; case Common::KEYCODE_BACKSPACE: if (_caretVisible) drawCaret(true); if (_currentPos > _promptStartPos) { _currentPos--; killChar(); } scrollToCurrent(); drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_TAB: { if (_completionCallbackProc) { int len = _currentPos - _promptStartPos; assert(len >= 0); char *str = new char[len + 1]; // Copy the user input to str for (i = 0; i < len; i++) str[i] = buffer(_promptStartPos + i); str[len] = '\0'; Common::String completion; if ((*_completionCallbackProc)(this, str, completion, _callbackRefCon)) { if (_caretVisible) drawCaret(true); insertIntoPrompt(completion.c_str()); scrollToCurrent(); drawLine(pos2line(_currentPos)); } delete[] str; } break; } case Common::KEYCODE_DELETE: killChar(); drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_PAGEUP: if (state.flags == Common::KBD_SHIFT) { _scrollLine -= _linesPerPage - 1; if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1) _scrollLine = _firstLineInBuffer + _linesPerPage - 1; updateScrollBuffer(); draw(); } break; case Common::KEYCODE_PAGEDOWN: if (state.flags == Common::KBD_SHIFT) { _scrollLine += _linesPerPage - 1; if (_scrollLine > _promptEndPos / kCharsPerLine) { _scrollLine = _promptEndPos / kCharsPerLine; if (_scrollLine < _firstLineInBuffer + _linesPerPage - 1) _scrollLine = _firstLineInBuffer + _linesPerPage - 1; } updateScrollBuffer(); draw(); } break; case Common::KEYCODE_HOME: if (state.flags == Common::KBD_SHIFT) { _scrollLine = _firstLineInBuffer + _linesPerPage - 1; updateScrollBuffer(); } else { _currentPos = _promptStartPos; } draw(); break; case Common::KEYCODE_END: if (state.flags == Common::KBD_SHIFT) { _scrollLine = _promptEndPos / kCharsPerLine; if (_scrollLine < _linesPerPage - 1) _scrollLine = _linesPerPage - 1; updateScrollBuffer(); } else { _currentPos = _promptEndPos; } draw(); break; case Common::KEYCODE_UP: historyScroll(+1); break; case Common::KEYCODE_DOWN: historyScroll(-1); break; case Common::KEYCODE_RIGHT: if (_currentPos < _promptEndPos) _currentPos++; drawLine(pos2line(_currentPos)); break; case Common::KEYCODE_LEFT: if (_currentPos > _promptStartPos) _currentPos--; drawLine(pos2line(_currentPos)); break; default: if (state.ascii == '~' || state.ascii == '#') { slideUpAndClose(); } else if (state.flags == Common::KBD_CTRL) { specialKeys(state.keycode); } else if ((state.ascii >= 32 && state.ascii <= 127) || (state.ascii >= 160 && state.ascii <= 255)) { for (i = _promptEndPos - 1; i >= _currentPos; i--) buffer(i + 1) = buffer(i); _promptEndPos++; putchar((byte)state.ascii); scrollToCurrent(); } } }