[Scummvm-cvs-logs] SF.net SVN: scummvm:[33476] scummvm/branches/gsoc2008-vkeybd/backends/ common

kenny-d at users.sourceforge.net kenny-d at users.sourceforge.net
Thu Jul 31 19:26:03 CEST 2008


Revision: 33476
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33476&view=rev
Author:   kenny-d
Date:     2008-07-31 17:26:03 +0000 (Thu, 31 Jul 2008)

Log Message:
-----------
added display functionality to VirtualKeyboard to allow preview of key presses to be visible

Modified Paths:
--------------
    scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.cpp
    scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.h
    scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-parser.cpp
    scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.cpp
    scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.h

Modified: scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.cpp
===================================================================
--- scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.cpp	2008-07-31 17:23:38 UTC (rev 33475)
+++ scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.cpp	2008-07-31 17:26:03 UTC (rev 33476)
@@ -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 @@
 
 	_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;
 }
 
+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 @@
 	}
 	_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::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 @@
 	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 @@
 				}
 				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,23 +242,101 @@
 	_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));
 
-	_system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h);
+	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;
+	}
 
+	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() {
 	const byte palette[] = {
 		255, 255, 255, 0,

Modified: scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.h
===================================================================
--- scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.h	2008-07-31 17:23:38 UTC (rev 33475)
+++ scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-gui.h	2008-07-31 17:26:03 UTC (rev 33476)
@@ -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 @@
 
 	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 @@
 	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;

Modified: scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-parser.cpp
===================================================================
--- scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-parser.cpp	2008-07-31 17:23:38 UTC (rev 33475)
+++ scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard-parser.cpp	2008-07-31 17:26:03 UTC (rev 33476)
@@ -318,6 +318,14 @@
 	} 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 @@
 	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);

Modified: scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.cpp
===================================================================
--- scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.cpp	2008-07-31 17:23:38 UTC (rev 33475)
+++ scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.cpp	2008-07-31 17:26:03 UTC (rev 33476)
@@ -151,7 +151,7 @@
 }
 
 void VirtualKeyboard::switchMode(Mode *newMode) {
-	_kbdGUI->setKeyboardSurface(newMode->image, newMode->transparentColor);
+	_kbdGUI->initMode(newMode);
 	_currentMode = newMode;
 }
 
@@ -267,8 +267,6 @@
 	kp.key = key;
 	kp.strLen = keyStr.size();
 	_keys.insert(_keyPos, kp);
-
-	
 }
 
 void VirtualKeyboard::KeyPressQueue::deleteKey() {
@@ -337,6 +335,10 @@
 	return _str + flags;
 }
 
+uint VirtualKeyboard::KeyPressQueue::getInsertIndex() {
+	return _strPos;
+}
+
 bool VirtualKeyboard::KeyPressQueue::hasStringChanged() {
 	bool ret = _strChanged;
 	_strChanged = false;

Modified: scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.h
===================================================================
--- scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.h	2008-07-31 17:23:38 UTC (rev 33475)
+++ scummvm/branches/gsoc2008-vkeybd/backends/common/virtual-keyboard.h	2008-07-31 17:26:03 UTC (rev 33476)
@@ -85,9 +85,11 @@
 		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 @@
 		void clear();
 		bool empty();
 		String getString();
+		uint getInsertIndex();
 		bool hasStringChanged();
 
 	private:


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list