diff options
-rw-r--r-- | backends/common/virtual-keyboard.cpp | 135 | ||||
-rw-r--r-- | backends/common/virtual-keyboard.h | 20 | ||||
-rw-r--r-- | common/rect.h | 4 | ||||
-rw-r--r-- | common/shape.h | 1 | ||||
-rw-r--r-- | graphics/surface-keycolored.cpp | 26 | ||||
-rw-r--r-- | graphics/surface-keycolored.h | 2 |
6 files changed, 139 insertions, 49 deletions
diff --git a/backends/common/virtual-keyboard.cpp b/backends/common/virtual-keyboard.cpp index e87d10ab3c..610e6affa4 100644 --- a/backends/common/virtual-keyboard.cpp +++ b/backends/common/virtual-keyboard.cpp @@ -38,7 +38,9 @@ VirtualKeyboard::VirtualKeyboard() : _currentMode(0), _keyDown(0) { _system = g_system; _parser = new VirtualKeyboardParser(this); - _loaded = _displaying = false; + _loaded = _displaying = _drag = false; + _screenWidth = _system->getOverlayWidth(); + _screenHeight = _system->getOverlayHeight(); } VirtualKeyboard::~VirtualKeyboard() { @@ -50,12 +52,16 @@ void VirtualKeyboard::reset() { // TODO: clean up event data pointers _modes.clear(); _initialMode = _currentMode = 0; - _pos.x = _pos.y = 0; + _kbdBound.left = _kbdBound.top + = _kbdBound.right = _kbdBound.bottom = 0; _hAlignment = kAlignCentre; _vAlignment = kAlignBottom; _keyQueue.clear(); _keyDown = 0; - _displaying = false; + _displaying = _drag = false; + _firstRun = true; + _screenWidth = _system->getOverlayWidth(); + _screenHeight = _system->getOverlayHeight(); } bool VirtualKeyboard::loadKeyboardPack(Common::String packName) { @@ -105,53 +111,78 @@ bool VirtualKeyboard::loadKeyboardPack(Common::String packName) { _loaded = _parser->parse(); if (_loaded) printf("Keyboard pack '%s' loaded successfully!\n", packName.c_str()); + return _loaded; } -void VirtualKeyboard::reposition() +void VirtualKeyboard::setDefaultPosition() { - // calculate keyboard co-ordinates - int16 scrW = _system->getOverlayWidth(), scrH = _system->getOverlayHeight(); - int16 keyW = _currentMode->image->w, keyH = _currentMode->image->h; - if (scrW != keyW) { + int16 kbdW = _kbdBound.width(), kbdH = _kbdBound.height(); + int16 posX = 0, posY = 0; + if (_screenWidth != kbdW) { switch (_hAlignment) { + case kAlignLeft: + posX = 0; + break; case kAlignCentre: - _pos.x = (scrW - keyW) / 2; + posX = (_screenWidth - kbdW) / 2; break; case kAlignRight: - _pos.x = scrW - keyW; - break; - default: + posX = _screenWidth - kbdW; break; } } - if (scrH != keyH) { + if (_screenHeight != kbdH) { switch (_vAlignment) { + case kAlignTop: + posY = 0; + break; case kAlignMiddle: - _pos.y = (scrH - keyH) / 2; + posY = (_screenHeight - kbdH) / 2; break; case kAlignBottom: - _pos.y = scrH - keyH; - break; - default: + posY = _screenHeight - kbdH; break; } } + _kbdBound.moveTo(posX, posY); } -void VirtualKeyboard::processClick(int16 x, int16 y) +void VirtualKeyboard::checkResolution() { - x -= _pos.x; - y -= _pos.y; - if (x < 0 || x > _currentMode->image->w) return; - if (y < 0 || y > _currentMode->image->h) return; - - Common::String area = _currentMode->imageMap.findMapArea(x, y); - if (area.empty()) return; - printf("Map area found! - %s\n", area.c_str()); + // check if there is a more suitable resolution + // in the keyboard pack than the current one + // based on the _screenWidth & _screenHeight +} + +void VirtualKeyboard::move(int16 x, int16 y) { + // snap to edge of screen + if (ABS(x) < SNAP_WIDTH) + x = 0; + int16 x2 = _system->getOverlayWidth() - _kbdBound.width(); + if (ABS(x - x2) < SNAP_WIDTH) + x = x2; + if (ABS(y) < SNAP_WIDTH) + y = 0; + int16 y2 = _system->getOverlayHeight() - _kbdBound.height(); + if (ABS(y - y2) < SNAP_WIDTH) + y = y2; + + _kbdBound.moveTo(x, y); +} + +Common::String VirtualKeyboard::findArea(int16 x, int16 y) { + x -= _kbdBound.left; + y -= _kbdBound.top; + if (x < 0 || x > _kbdBound.width()) return ""; + if (y < 0 || y > _kbdBound.height()) return ""; + return _currentMode->imageMap.findMapArea(x, y); +} + +void VirtualKeyboard::processClick(const Common::String& area) { if (!_currentMode->events.contains(area)) return; Event evt = _currentMode->events[area]; - + switch (evt.type) { case kEventKey: // add virtual keypress to queue @@ -170,7 +201,8 @@ void VirtualKeyboard::processClick(int16 x, int16 y) void VirtualKeyboard::switchMode(Mode *newMode) { _currentMode = newMode; - reposition(); + _kbdBound.setWidth(_currentMode->image->w); + _kbdBound.setHeight(_currentMode->image->h); _needRedraw = true; } @@ -179,14 +211,20 @@ void VirtualKeyboard::switchMode(const Common::String& newMode) { warning("Keyboard mode '%s' unknown", newMode.c_str()); return; } - _currentMode = &_modes[newMode]; - reposition(); - _needRedraw = true; + switchMode(&_modes[newMode]); } void VirtualKeyboard::show() { + if (_screenWidth != _system->getOverlayWidth() || _screenHeight != _system->getOverlayHeight()) { + _screenWidth = _system->getOverlayWidth(); + _screenHeight = _system->getOverlayHeight(); + } switchMode(_initialMode); _displaying = true; + if (_firstRun) { + _firstRun = false; + setDefaultPosition(); + } runLoop(); } @@ -198,7 +236,7 @@ void VirtualKeyboard::runLoop() { Common::EventManager *eventMan = _system->getEventManager(); _system->showOverlay(); - // capture mouse clicks + while (_displaying) { if (_needRedraw) redraw(); @@ -207,12 +245,34 @@ void VirtualKeyboard::runLoop() { while (eventMan->pollEvent(event)) { switch (event.type) { case Common::EVENT_LBUTTONDOWN: - _mouseDown = event.mouse; + if (_kbdBound.contains(event.mouse)) { + _areaDown = findArea(event.mouse.x, event.mouse.y); + if (_areaDown.empty()) { + _drag = true; + _dragPoint.x = event.mouse.x - _kbdBound.left; + _dragPoint.y = event.mouse.y - _kbdBound.top; + } + } else + _areaDown.clear(); break; case Common::EVENT_LBUTTONUP: - if (ABS(_mouseDown.x - event.mouse.x) < 5 - && ABS(_mouseDown.y - event.mouse.y) < 5) - processClick(event.mouse.x, event.mouse.y); + if (_drag) _drag = false; + if (!_areaDown.empty() && _areaDown == findArea(event.mouse.x, event.mouse.y)) { + processClick(_areaDown); + _areaDown.clear(); + } + break; + case Common::EVENT_MOUSEMOVE: + if (_drag) { + move(event.mouse.x - _dragPoint.x, + event.mouse.y - _dragPoint.y); + _needRedraw = true; + } + break; + case Common::EVENT_SCREEN_CHANGED: + _screenWidth = _system->getOverlayWidth(); + _screenHeight = _system->getOverlayHeight(); + checkResolution(); break; case Common::EVENT_QUIT: _system->quit(); @@ -231,9 +291,10 @@ void VirtualKeyboard::redraw() { surf.create(_system->getOverlayWidth(), _system->getOverlayHeight(), sizeof(OverlayColor)); + _system->clearOverlay(); _system->grabOverlay((OverlayColor*)surf.pixels, surf.w); - surf.blit(_currentMode->image, _pos.x, _pos.y, _system->RGBToColor(0xff, 0, 0xff)); + surf.blit(_currentMode->image, _kbdBound.left, _kbdBound.top, _system->RGBToColor(0xff, 0, 0xff)); _system->copyRectToOverlay((OverlayColor*)surf.pixels, surf.w, 0, 0, surf.w, surf.h); surf.free(); diff --git a/backends/common/virtual-keyboard.h b/backends/common/virtual-keyboard.h index ff07384e06..a3585296f9 100644 --- a/backends/common/virtual-keyboard.h +++ b/backends/common/virtual-keyboard.h @@ -104,34 +104,44 @@ public: */ bool pollEvent(Common::Event &event); -private: +protected: OSystem *_system; + + static const int SNAP_WIDTH = 10; friend class VirtualKeyboardParser; VirtualKeyboardParser *_parser; // TODO : sort order of all this stuff void reset(); - void reposition(); + void checkResolution(); + void setDefaultPosition(); + void move(int16 x, int16 y); void switchMode(Mode *newMode); void switchMode(const Common::String& newMode); - void processClick(int16 x, int16 y); + Common::String findArea(int16 x, int16 y); + void processClick(const Common::String &area); void runLoop(); void redraw(); bool _loaded; bool _displaying; bool _needRedraw; + bool _firstRun; ModeMap _modes; Mode *_initialMode; Mode *_currentMode; - Common::Point _pos; + int16 _screenWidth, _screenHeight; + Common::Rect _kbdBound; + HorizontalAlignment _hAlignment; VerticalAlignment _vAlignment; - Common::Point _mouseDown; + Common::String _areaDown; + Common::Point _dragPoint; + bool _drag; Common::Array<Common::KeyState> _keyQueue; Common::KeyState *_keyDown; diff --git a/common/rect.h b/common/rect.h index 0cd10a2147..0c149f613f 100644 --- a/common/rect.h +++ b/common/rect.h @@ -40,7 +40,7 @@ namespace Common { Another very wide spread approach to rectangle classes treats (bottom,right) also as a part of the rectangle. - Coneptually, both are sound, but the approach we use saves many intermediate + Conceptually, both are sound, but the approach we use saves many intermediate computations (like computing the height in our case is done by doing this: height = bottom - top; while in the alternate system, it would be @@ -57,6 +57,8 @@ struct Rect : public Shape { Rect(int16 x1, int16 y1, int16 x2, int16 y2) : top(y1), left(x1), bottom(y2), right(x2) { assert(isValidRect()); } + virtual ~Rect() {} + int16 width() const { return right - left; } int16 height() const { return bottom - top; } diff --git a/common/shape.h b/common/shape.h index 981241eee5..2cce365bfc 100644 --- a/common/shape.h +++ b/common/shape.h @@ -72,6 +72,7 @@ struct Point { */ struct Shape { + virtual ~Shape() {} /*! @brief check if given position is inside this shape @param x the horizontal position to check diff --git a/graphics/surface-keycolored.cpp b/graphics/surface-keycolored.cpp index 79beb5d5b5..f533213fb6 100644 --- a/graphics/surface-keycolored.cpp +++ b/graphics/surface-keycolored.cpp @@ -2,22 +2,38 @@ namespace Graphics { -void SurfaceKeyColored::blit(Surface *surf_src, int16 x, int16 y, OverlayColor trans) { +void SurfaceKeyColored::blit(Surface *surf_src, int16 x, int16 y, OverlayColor transparent) { if (bytesPerPixel != sizeof(OverlayColor) || surf_src->bytesPerPixel != sizeof(OverlayColor)) return ; - OverlayColor *dst = (OverlayColor*) getBasePtr(x, y); const OverlayColor *src = (const OverlayColor*)surf_src->pixels; + int blitW = surf_src->w; + int blitH = surf_src->h; - int blitW = (surf_src->w + x > w) ? w - x : surf_src->w; - int blitH = (surf_src->h + y > h) ? h - y : surf_src->h; + // clip co-ordinates + if (x < 0) { + blitW += x; + src -= x; + x = 0; + } + if (y < 0) { + blitH += y; + src -= y * surf_src->w; + y = 0; + } + if (blitW > w - x) blitW = w - x; + if (blitH > h - y) blitH = h - y; + if (blitW <= 0 || blitH <= 0) + return; + + OverlayColor *dst = (OverlayColor*) getBasePtr(x, y); int dstAdd = w - blitW; int srcAdd = surf_src->w - blitW; for (int i = 0; i < blitH; ++i) { for (int j = 0; j < blitW; ++j, ++dst, ++src) { OverlayColor col = *src; - if (col != trans) + if (col != transparent) *dst = col; } dst += dstAdd; diff --git a/graphics/surface-keycolored.h b/graphics/surface-keycolored.h index d2788b204e..608bf7a482 100644 --- a/graphics/surface-keycolored.h +++ b/graphics/surface-keycolored.h @@ -8,7 +8,7 @@ namespace Graphics { struct SurfaceKeyColored : Surface { - void blit(Surface *surf_src, int16 x, int16 y, OverlayColor trans); + void blit(Surface *surf_src, int16 x, int16 y, OverlayColor transparent); }; |