diff options
author | Stephen Kennedy | 2008-07-31 17:26:03 +0000 |
---|---|---|
committer | Stephen Kennedy | 2008-07-31 17:26:03 +0000 |
commit | f2e71ec6d6008c8ad33272df5d18f1b07455cef0 (patch) | |
tree | 471c26d959f0665e1ebb732896b151bc04215306 | |
parent | ad6563a57a17db297394503aa608106ac87f1a35 (diff) | |
download | scummvm-rg350-f2e71ec6d6008c8ad33272df5d18f1b07455cef0.tar.gz scummvm-rg350-f2e71ec6d6008c8ad33272df5d18f1b07455cef0.tar.bz2 scummvm-rg350-f2e71ec6d6008c8ad33272df5d18f1b07455cef0.zip |
added display functionality to VirtualKeyboard to allow preview of key presses to be visible
svn-id: r33476
-rw-r--r-- | backends/common/virtual-keyboard-gui.cpp | 148 | ||||
-rw-r--r-- | backends/common/virtual-keyboard-gui.h | 29 | ||||
-rw-r--r-- | backends/common/virtual-keyboard-parser.cpp | 12 | ||||
-rw-r--r-- | backends/common/virtual-keyboard.cpp | 8 | ||||
-rw-r--r-- | backends/common/virtual-keyboard.h | 7 |
5 files changed, 175 insertions, 29 deletions
diff --git a/backends/common/virtual-keyboard-gui.cpp b/backends/common/virtual-keyboard-gui.cpp index f07ea1a4c9..162ce48240 100644 --- a/backends/common/virtual-keyboard-gui.cpp +++ b/backends/common/virtual-keyboard-gui.cpp @@ -24,9 +24,7 @@ */ #include "backends/common/virtual-keyboard-gui.h" -#include "backends/common/virtual-keyboard.h" #include "graphics/cursorman.h" -#include "graphics/surface-keycolored.h" #include "gui/newgui.h" namespace Common { @@ -43,18 +41,45 @@ VirtualKeyboardGUI::VirtualKeyboardGUI(VirtualKeyboard *kbd) { _displaying = _needRedraw = _drag = false; _firstRun = true; + + _displayEnabled = false; } -void VirtualKeyboardGUI::setKeyboardSurface(Graphics::Surface *sur, OverlayColor trans_color) { - _kbdSurface = sur; - _kbdTransparentColor = trans_color; - _kbdBound.setWidth(_kbdSurface->w); - _kbdBound.setHeight(_kbdSurface->h); +void VirtualKeyboardGUI::initMode(VirtualKeyboard::Mode *mode) { + _kbdSurface = mode->image; + _kbdTransparentColor = mode->transparentColor; + _kbdBound.setWidth(_kbdSurface->w + 1); + _kbdBound.setHeight(_kbdSurface->h + 1); _needRedraw = true; + + _displayEnabled = false; + if (!mode->displayArea) + return; + Rect r = *(mode->displayArea); + + // choose font + _dispFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont); + if (!fontIsSuitable(_dispFont, r)) { + _dispFont = FontMan.getFontByUsage(Graphics::FontManager::kGUIFont); + if (!fontIsSuitable(_dispFont, r)) + return; + } + _dispX = r.left; + _dispY = r.top + (_dispFont->getFontHeight() - r.height() + 1) / 2; + _dispSurface.free(); + _dispSurface.create(r.width() + 1, _dispFont->getFontHeight(), sizeof(OverlayColor)); + _dispI = 0; + _dispForeColor = mode->displayFontColor; + _dispBackColor = _dispForeColor + 0xFF; + _displayEnabled = true; } -void VirtualKeyboardGUI::run() { +bool VirtualKeyboardGUI::fontIsSuitable(const Graphics::Font *font, const Rect& rect) { + return (font->getMaxCharWidth() < rect.width() && + font->getFontHeight() < rect.height()); +} +void VirtualKeyboardGUI::run() { if (_lastScreenChanged != _system->getScreenChangeID()) screenChanged(); @@ -70,14 +95,18 @@ void VirtualKeyboardGUI::run() { } _overlayBackup.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); _system->grabOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w); + resetDirtyRect(); + setupCursor(); _displaying = true; mainLoop(); removeCursor(); + _system->copyRectToOverlay((OverlayColor*)_overlayBackup.pixels, _overlayBackup.w, 0, 0, _overlayBackup.w, _overlayBackup.h); if (!g_gui.isActive()) _system->hideOverlay(); + _overlayBackup.free(); } @@ -129,6 +158,10 @@ void VirtualKeyboardGUI::setDefaultPosition() } void VirtualKeyboardGUI::move(int16 x, int16 y) { + // add old position to dirty area + extendDirtyRect(_kbdBound); + _needRedraw = true; + // snap to edge of screen if (ABS(x) < SNAP_WIDTH) x = 0; @@ -155,8 +188,13 @@ void VirtualKeyboardGUI::mainLoop() { Common::EventManager *eventMan = _system->getEventManager(); while (_displaying) { + if (_displayEnabled) { + if (_kbd->_keyQueue.hasStringChanged()) + _refreshDisplay = true; + animateCaret(); + if (_refreshDisplay) updateDisplay();; + } if (_needRedraw) redraw(); - animateCursor(); _system->updateScreen(); Common::Event event; @@ -175,11 +213,9 @@ void VirtualKeyboardGUI::mainLoop() { } break; case Common::EVENT_MOUSEMOVE: - if (_drag) { + if (_drag) move(event.mouse.x - _dragPoint.x, event.mouse.y - _dragPoint.y); - _needRedraw = true; - } break; case Common::EVENT_SCREEN_CHANGED: screenChanged(); @@ -206,21 +242,99 @@ void VirtualKeyboardGUI::endDrag() { _drag = false; } +void VirtualKeyboardGUI::extendDirtyRect(const Rect &r) { + if (_dirtyRect.isValidRect()) { + _dirtyRect.extend(r); + } else { + _dirtyRect = r; + } + _dirtyRect.clip(Rect(0, 0, _overlayBackup.w, _overlayBackup.h)); +} + +void VirtualKeyboardGUI::resetDirtyRect() { + _dirtyRect.setWidth(-1); +} void VirtualKeyboardGUI::redraw() { - Graphics::SurfaceKeyColored surf; assert(_kbdSurface); - surf.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); + extendDirtyRect(_kbdBound); - memcpy(surf.pixels, _overlayBackup.pixels, surf.w * surf.h * sizeof(OverlayColor)); - surf.blit(_kbdSurface, _kbdBound.left, _kbdBound.top, _kbdTransparentColor); + Graphics::SurfaceKeyColored surf; + surf.create(_dirtyRect.width()+1, _dirtyRect.height()+1, sizeof(OverlayColor)); + + OverlayColor *scr = (OverlayColor *)surf.pixels; + const OverlayColor *ove = (OverlayColor *) _overlayBackup.getBasePtr(_dirtyRect.left, _dirtyRect.top); + int16 h = surf.h; + while (h-- > 0) { + memcpy(scr, ove, surf.w * sizeof(OverlayColor)); + scr += surf.w; + ove += _overlayBackup.w; + } - _system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h); + int16 keyX = _kbdBound.left - _dirtyRect.left; + int16 keyY = _kbdBound.top - _dirtyRect.top; + surf.blit(_kbdSurface, keyX, keyY, _kbdTransparentColor); + if (_displayEnabled) surf.blit(&_dispSurface, keyX + _dispX, keyY + _dispY, _dispBackColor); + _system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, + _dirtyRect.left, _dirtyRect.top, surf.w, surf.h); surf.free(); _needRedraw = false; + + resetDirtyRect(); +} + +uint VirtualKeyboardGUI::calculateEndIndex(const String& str, uint startIndex) { + int16 w = 0; + while (w <= _dispSurface.w && startIndex < str.size()) { + w += _dispFont->getCharWidth(str[startIndex++]); + } + if (w > _dispSurface.w) startIndex--; + return startIndex; +} + +void VirtualKeyboardGUI::animateCaret() { + if (_system->getMillis() % kCaretBlinkTime < kCaretBlinkTime / 2) { + if (!_drawCaret) { + _drawCaret = true; + _refreshDisplay = true; + } + } else { + if (_drawCaret) { + _drawCaret = false; + _refreshDisplay = true; + } + } +} + +void VirtualKeyboardGUI::updateDisplay() { + if (!_displayEnabled) return; + + // calculate the text to display + uint cursorPos = _kbd->_keyQueue.getInsertIndex(); + String wholeText = _kbd->_keyQueue.getString(); + uint dispTextEnd; + if (_dispI > cursorPos) + _dispI = cursorPos; + + dispTextEnd = calculateEndIndex(wholeText, _dispI); + while (cursorPos > dispTextEnd) + dispTextEnd = calculateEndIndex(wholeText, ++_dispI); + + String dispText = String(wholeText.c_str() + _dispI, wholeText.c_str() + dispTextEnd); + + // draw to display surface + _dispSurface.fillRect(Rect(0, 0, _dispSurface.w, _dispSurface.h), _dispBackColor); + _dispFont->drawString(&_dispSurface, dispText, 0, 0, _dispSurface.w, _dispForeColor); + if (_drawCaret) { + String beforeCaret(wholeText.c_str() + _dispI, wholeText.c_str() + cursorPos); + int16 caretX = _dispFont->getStringWidth(beforeCaret); + _dispSurface.drawLine(caretX, 0, caretX, _dispSurface.h, _dispForeColor); + } + + _needRedraw = true; } void VirtualKeyboardGUI::setupCursor() { diff --git a/backends/common/virtual-keyboard-gui.h b/backends/common/virtual-keyboard-gui.h index ce9937d567..10b16f17f7 100644 --- a/backends/common/virtual-keyboard-gui.h +++ b/backends/common/virtual-keyboard-gui.h @@ -26,20 +26,20 @@ #ifndef COMMON_VIRTUAL_KEYBOARD_GUI #define COMMON_VIRTUAL_KEYBOARD_GUI +#include "backends/common/virtual-keyboard.h" #include "common/rect.h" #include "common/system.h" -#include "graphics/surface.h" +#include "graphics/fontman.h" +#include "graphics/surface-keycolored.h" namespace Common { -class VirtualKeyboard; - class VirtualKeyboardGUI { public: VirtualKeyboardGUI(VirtualKeyboard *kbd); - void setKeyboardSurface(Graphics::Surface *sur, OverlayColor trans_color); + void initMode(VirtualKeyboard::Mode *mode); void run(); void hide(); bool isDisplaying() { return _displaying; } @@ -58,6 +58,16 @@ private: Graphics::Surface _overlayBackup; + Rect _dirtyRect; + + bool _displayEnabled; + bool _refreshDisplay; + Graphics::Surface _dispSurface; + const Graphics::Font *_dispFont; + int16 _dispX, _dispY; + uint _dispI; + OverlayColor _dispForeColor, _dispBackColor; + Rect _kbdBound; Point _dragPoint; @@ -72,8 +82,17 @@ private: void move(int16 x, int16 y); void screenChanged(); void mainLoop(); + void extendDirtyRect(const Rect &r); + void resetDirtyRect(); void redraw(); - + void updateDisplay(); + bool fontIsSuitable(const Graphics::Font *font, const Rect& rect); + uint calculateEndIndex(const String& str, uint startIndex); + + bool _drawCaret; + static const int kCaretBlinkTime = 500; + void animateCaret(); + static const int kCursorAnimateDelay = 250; int _cursorAnimateCounter; int _cursorAnimateTimer; diff --git a/backends/common/virtual-keyboard-parser.cpp b/backends/common/virtual-keyboard-parser.cpp index 375b062219..5f1b7e9912 100644 --- a/backends/common/virtual-keyboard-parser.cpp +++ b/backends/common/virtual-keyboard-parser.cpp @@ -318,6 +318,14 @@ bool VirtualKeyboardParser::parserCallback_Layout() { } else _mode->transparentColor = g_system->RGBToColor(255, 0, 255); // default to purple + if (layoutNode->values.contains("display_font_color")) { + int r, g, b; + if (!parseIntegerKey(layoutNode->values["display_font_color"].c_str(), 3, &r, &g, &b)) + return parserError("Could not parse color value"); + _mode->displayFontColor = g_system->RGBToColor(r, g, b); + } else + _mode->displayFontColor = g_system->RGBToColor(0, 0, 0); // default to black + _layoutParsed = true; return true; @@ -352,8 +360,8 @@ bool VirtualKeyboardParser::parserCallback_Area() { if (target == "display_area") { if (shape != "rect") return parserError("display_area must be a rect area"); - _mode->previewArea = new Common::Rect(); - return parseRect(_mode->previewArea, coords); + _mode->displayArea = new Common::Rect(); + return parseRect(_mode->displayArea, coords); } else if (shape == "rect") { Common::Rect *rect = _mode->imageMap.createRectArea(target); return parseRect(rect, coords); diff --git a/backends/common/virtual-keyboard.cpp b/backends/common/virtual-keyboard.cpp index 60c0de2356..c852839871 100644 --- a/backends/common/virtual-keyboard.cpp +++ b/backends/common/virtual-keyboard.cpp @@ -151,7 +151,7 @@ void VirtualKeyboard::processAreaClick(const Common::String& area) { } void VirtualKeyboard::switchMode(Mode *newMode) { - _kbdGUI->setKeyboardSurface(newMode->image, newMode->transparentColor); + _kbdGUI->initMode(newMode); _currentMode = newMode; } @@ -267,8 +267,6 @@ void VirtualKeyboard::KeyPressQueue::insertKey(KeyState key) { kp.key = key; kp.strLen = keyStr.size(); _keys.insert(_keyPos, kp); - - } void VirtualKeyboard::KeyPressQueue::deleteKey() { @@ -337,6 +335,10 @@ String VirtualKeyboard::KeyPressQueue::getString() return _str + flags; } +uint VirtualKeyboard::KeyPressQueue::getInsertIndex() { + return _strPos; +} + bool VirtualKeyboard::KeyPressQueue::hasStringChanged() { bool ret = _strChanged; _strChanged = false; diff --git a/backends/common/virtual-keyboard.h b/backends/common/virtual-keyboard.h index 09ae427a48..c5b77aac0f 100644 --- a/backends/common/virtual-keyboard.h +++ b/backends/common/virtual-keyboard.h @@ -85,9 +85,11 @@ protected: OverlayColor transparentColor; Common::ImageMap imageMap; EventMap events; - Common::Rect *previewArea; + Common::Rect *displayArea; + OverlayColor displayFontColor; - Mode() : image(0), previewArea(0) {} + Mode() : image(0), displayArea(0) {} + ~Mode() { if (displayArea) delete displayArea; } }; typedef Common::HashMap<Common::String, Mode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ModeMap; @@ -122,6 +124,7 @@ protected: void clear(); bool empty(); String getString(); + uint getInsertIndex(); bool hasStringChanged(); private: |