diff options
Diffstat (limited to 'gui')
| -rw-r--r-- | gui/virtualKeyboard.cpp | 111 | ||||
| -rw-r--r-- | gui/virtualKeyboard.h | 35 | ||||
| -rw-r--r-- | gui/virtualKeyboardParser.cpp | 66 | ||||
| -rw-r--r-- | gui/virtualKeyboardParser.h | 10 | 
4 files changed, 195 insertions, 27 deletions
diff --git a/gui/virtualKeyboard.cpp b/gui/virtualKeyboard.cpp index a47f890ce5..02c28bf4a2 100644 --- a/gui/virtualKeyboard.cpp +++ b/gui/virtualKeyboard.cpp @@ -31,19 +31,34 @@  namespace GUI { -VirtualKeyboard::VirtualKeyboard() { +VirtualKeyboard::VirtualKeyboard() : _currentMode(0) {  	assert(g_system);  	_system = g_system;  	_parser = new VirtualKeyboardParser(this); -  }  VirtualKeyboard::~VirtualKeyboard() { +	// TODO: clean up event data pointers +	delete _parser; +} + +void VirtualKeyboard::reset() { +	// TODO: clean up event data pointers +	_modes.clear(); +	_initialMode = _currentMode = 0; +	_pos.x = _pos.y = 0; +	_hAlignment = kAlignCentre; +	_vAlignment = kAlignBottom; +	_keyQueue.clear(); +	_displaying = false;  }  bool VirtualKeyboard::loadKeyboardPack(Common::String packName) { +	// reset to default settings +	reset(); +  	if (ConfMan.hasKey("extrapath"))  		Common::File::addDefaultDirectoryRecursive(ConfMan.get("extrapath")); @@ -84,19 +99,105 @@ bool VirtualKeyboard::loadKeyboardPack(Common::String packName) {  		return false;  	} -	return _parser->parse(); +	if (!_parser->parse()) +		return false; + +	if (!_initialMode) +		warning("Initial mode of keyboard pack not defined"); + +	ModeMap::iterator it; +	for (it = _modes.begin(); it != _modes.end(); it++) { +		// if no image then it means layout tag for the  +		// required resolution was missing from the mode tag. +		if (!it->_value.image) { +			warning("'%s' layout missing from '%s' mode", it->_value.resolution, it->_value.name); +			return false; +		} +	} + +	reposition(); + +	return true;  } -void VirtualKeyboard::show() { +void VirtualKeyboard::reposition() +{ +	// calculate keyboard co-ordinates +	int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight(); +	int16 keyW = _currentMode->image->w, keyH = _currentMode->image->h; +	if (scrW != keyW) { +		switch (_hAlignment) { +		case kAlignCentre: +			_pos.x = (scrW - keyW) / 2; +			break; +		case kAlignRight: +			_pos.x = scrW - keyW; +			break; +		} +	} +	if (scrH != keyH) { +		switch (_vAlignment) { +		case kAlignMiddle: +			_pos.y = (scrH - keyH) / 2; +			break; +		case kAlignBottom: +			_pos.y = scrH - keyH; +			break; +		} +	} +} + +void VirtualKeyboard::processClick(int16 x, int16 y) +{ +	x -= _pos.x; +	y -= _pos.y; +	if (x < 0 || x > _currentMode->image->w) return; +	if (y < 0 || y > _currentMode->image->h) return; + +	Common::MapArea *area = _currentMode->imageMap.findMapArea(x, y); +	if (!area) return; +	if (!_currentMode->events.contains(area->getTarget())) return; +	Event evt = _currentMode->events[area->getTarget()]; +	 +	switch (evt.type) { +	case kEventKey: +		// add virtual keypress to queue +		_keyQueue.push_back(*(Common::KeyState*)evt.data); +		break; +	case kEventSwitchMode: +		// switch to new mode +		switchMode(*(Common::String *)evt.data); +		break; +	case kEventClose: +		// close virtual keyboard +		_displaying = false; +		break; +	} +} +void VirtualKeyboard::switchMode(const Common::String& newMode) { +	if (!_modes.contains(newMode)) return; +	_currentMode = &_modes[newMode]; +	reposition(); +	draw(); +} + +void VirtualKeyboard::show() { +	_displaying = true; +	runLoop();  }  void VirtualKeyboard::runLoop() { +	while (_displaying) { + +	}  }  void VirtualKeyboard::draw() { - +	_system->copyRectToOverlay((OverlayColor*)_currentMode->image->pixels,  +		_currentMode->image->pitch, _pos.x, _pos.y,  +		_currentMode->image->w, _currentMode->image->h);  }  } // end of namespace GUI diff --git a/gui/virtualKeyboard.h b/gui/virtualKeyboard.h index 7885f2cc17..914949aad3 100644 --- a/gui/virtualKeyboard.h +++ b/gui/virtualKeyboard.h @@ -31,6 +31,7 @@ class OSystem;  #include "common/hashmap.h"  #include "common/hash-str.h"  #include "common/imagemap.h" +#include "common/keyboard.h"  #include "common/str.h"  #include "graphics/surface.h" @@ -46,6 +47,7 @@ private:  	enum EventType {  		kEventKey,  		kEventSwitchMode, +		kEventClose,  		kEventMax  	}; @@ -65,6 +67,21 @@ private:  		Graphics::Surface *image;  		Common::ImageMap   imageMap;  		EventMap           events; +		Mode() : image(0) {} +	}; +	 +	typedef Common::HashMap<Common::String, Mode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> ModeMap; + +	enum HorizontalAlignment { +		kAlignLeft, +		kAlignCentre, +		kAlignRight +	}; + +	enum VerticalAlignment { +		kAlignTop, +		kAlignMiddle, +		kAlignBottom  	};  public: @@ -80,10 +97,26 @@ private:  	friend class VirtualKeyboardParser;  	VirtualKeyboardParser *_parser; +	// TODO : sort order of all this stuff +	void reset(); +	void reposition(); +	void switchMode(const Common::String& newMode); +	void processClick(int16 x, int16 y);  	void runLoop();  	void draw(); -	Common::HashMap<Common::String, Mode, Common::IgnoreCase_Hash, Common::IgnoreCase_EqualTo> _modes; +	bool _displaying; + +	ModeMap _modes; +	Mode *_initialMode; +	Mode *_currentMode; + +	Common::Point _pos; +	HorizontalAlignment  _hAlignment; +	VerticalAlignment    _vAlignment; + +	Common::Array<Common::KeyState> _keyQueue; +  }; diff --git a/gui/virtualKeyboardParser.cpp b/gui/virtualKeyboardParser.cpp index ca4a9c521a..93b670e7c9 100644 --- a/gui/virtualKeyboardParser.cpp +++ b/gui/virtualKeyboardParser.cpp @@ -59,9 +59,33 @@ bool VirtualKeyboardParser::parserCallback_Keyboard() {  	if (_kbdParsed)  		return parserError("Only a single keyboard element is allowed"); -  	_kbdParsed = true; +	if (!kbdNode->values.contains("initial_mode")) +		return parserError("Keyboard element must contain initial_mode attribute"); + +	_initialModeName = kbdNode->values["initial_mode"]; + +	if (kbdNode->values.contains("h_align")) { +		Common::String h = kbdNode->values["h_align"]; +		if (h == "left") +			_keyboard->_hAlignment = VirtualKeyboard::kAlignLeft; +		else if (h == "centre" || h == "center") +			_keyboard->_hAlignment = VirtualKeyboard::kAlignCentre; +		else if (h == "right") +			_keyboard->_hAlignment = VirtualKeyboard::kAlignRight; +	} + +	if (kbdNode->values.contains("v_align")) { +		Common::String v = kbdNode->values["h_align"]; +		if (v == "top") +			_keyboard->_vAlignment = VirtualKeyboard::kAlignTop; +		else if (v == "middle" || v == "center") +			_keyboard->_vAlignment = VirtualKeyboard::kAlignMiddle; +		else if (v == "bottom") +			_keyboard->_vAlignment = VirtualKeyboard::kAlignBottom; +	} +  	return true;  } @@ -81,10 +105,16 @@ bool VirtualKeyboardParser::parserCallback_Mode() {  	if (_keyboard->_modes.contains(name))  		return parserError("Mode '%s' has already been defined", name); +	// create new mode  	VirtualKeyboard::Mode mode;  	mode.name = name;  	_keyboard->_modes[name] = mode; -	_currentMode = &(_keyboard->_modes[name]); +	_mode = &(_keyboard->_modes[name]); +	 +	// if this is the keyboard's initial mode +	// then set it to be the current mode +	if (name == _initialModeName) +		_keyboard->_initialMode = _mode;  	Common::String resolutions = modeNode->values["resolutions"];  	Common::StringTokenizer tok(resolutions, " ,"); @@ -98,19 +128,19 @@ bool VirtualKeyboardParser::parserCallback_Mode() {  			parserError("Invalid resolution specification");  		} else {  			if (resX == scrX && resY == scrY) { -				_currentMode->resolution = res; +				_mode->resolution = res;  				break;  			} else if (resX < scrX && resY < scrY) {  				uint16 newDiff = (scrX - resX) + (scrY - resY);  				if (newDiff < diff) {  					diff = newDiff; -					_currentMode->resolution = res; +					_mode->resolution = res;  				}  			}  		}  	} -	if (_currentMode->resolution.empty()) +	if (_mode->resolution.empty())  		return parserError("No acceptable resolution was found");  	return true; @@ -127,10 +157,10 @@ bool VirtualKeyboardParser::parserCallback_Event() {  	if (!evtNode->values.contains("name") || !evtNode->values.contains("type"))  		return parserError("Event element must contain name and type attributes"); -	assert(_currentMode); +	assert(_mode);  	Common::String name = evtNode->values["name"]; -	if (_currentMode->events.contains(name)) +	if (_mode->events.contains(name))  		return parserError("Event '%s' has already been defined", name);  	VirtualKeyboard::Event evt; @@ -170,7 +200,7 @@ bool VirtualKeyboardParser::parserCallback_Event() {  	} else  		return parserError("Event type '%s' not known", type); -	_currentMode->events[name] = evt; +	_mode->events[name] = evt;  	return true;  } @@ -186,24 +216,24 @@ bool VirtualKeyboardParser::parserCallback_Layout() {  	if (!layoutNode->values.contains("resolution") || !layoutNode->values.contains("bitmap"))  		return parserError("Layout element must contain resolution and bitmap attributes"); -	assert(!_currentMode->resolution.empty()); +	assert(!_mode->resolution.empty());  	Common::String res = layoutNode->values["resolution"]; -	if (res != _currentMode->resolution) { +	if (res != _mode->resolution) {  		layoutNode->ignore = true;  		return true;  	} -	_currentMode->bitmapName = layoutNode->values["bitmap"]; +	_mode->bitmapName = layoutNode->values["bitmap"]; -	if (!ImageMan.registerSurface(_currentMode->bitmapName, 0)) -		return parserError("Error loading bitmap '%s'", _currentMode->bitmapName.c_str()); +	if (!ImageMan.registerSurface(_mode->bitmapName, 0)) +		return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str()); -	_currentMode->image = ImageMan.getSurface(_currentMode->bitmapName); -	if (!_currentMode->image) -		return parserError("Error loading bitmap '%s'", _currentMode->bitmapName.c_str()); +	_mode->image = ImageMan.getSurface(_mode->bitmapName); +	if (!_mode->image) +		return parserError("Error loading bitmap '%s'", _mode->bitmapName.c_str());  	return true;  } @@ -237,7 +267,7 @@ bool VirtualKeyboardParser::parserCallback_Area() {  			return parserError("Invalid coords for rect area");  		Common::Rect rect(x1, y1, x2, y2); -		_currentMode->imageMap.addRectMapArea(rect, areaNode->values["target"]); +		_mode->imageMap.addRectMapArea(rect, areaNode->values["target"]);  	} else if (shape == "poly") {  		Common::StringTokenizer tok (areaNode->values["coords"], ", ");  		Common::Polygon poly; @@ -252,7 +282,7 @@ bool VirtualKeyboardParser::parserCallback_Area() {  		}  		if (poly.getPointCount() < 3)  			return parserError("Invalid coords for polygon area"); -		_currentMode->imageMap.addPolygonMapArea(poly, areaNode->values["target"]); +		_mode->imageMap.addPolygonMapArea(poly, areaNode->values["target"]);  	} else  		return parserError("Area shape '%s' not known", shape); diff --git a/gui/virtualKeyboardParser.h b/gui/virtualKeyboardParser.h index b5ed59877f..6ac8e57612 100644 --- a/gui/virtualKeyboardParser.h +++ b/gui/virtualKeyboardParser.h @@ -41,14 +41,18 @@ public:  protected:  	VirtualKeyboard *_keyboard; -	VirtualKeyboard::Mode *_currentMode; +	/** internal state variables of parser */ +	VirtualKeyboard::Mode *_mode; // pointer to mode currently being parsed +	bool _modeParsed; +	Common::String _initialModeName;  // name of initial keyboard mode  	bool _kbdParsed;  	bool keyCallback(Common::String keyName);  	void cleanup() { -		_currentMode = 0; -		_kbdParsed = false; +		_mode = 0; +		_kbdParsed = _modeParsed = false; +		_initialModeName.clear();  	}  	bool parserCallback_Keyboard();  | 
