aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Kennedy2008-07-31 17:26:03 +0000
committerStephen Kennedy2008-07-31 17:26:03 +0000
commitf2e71ec6d6008c8ad33272df5d18f1b07455cef0 (patch)
tree471c26d959f0665e1ebb732896b151bc04215306
parentad6563a57a17db297394503aa608106ac87f1a35 (diff)
downloadscummvm-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.cpp148
-rw-r--r--backends/common/virtual-keyboard-gui.h29
-rw-r--r--backends/common/virtual-keyboard-parser.cpp12
-rw-r--r--backends/common/virtual-keyboard.cpp8
-rw-r--r--backends/common/virtual-keyboard.h7
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: